bsSkinBoxCtrls.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:431k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. procedure TbsCustomEdit.DoCut;
  2. begin
  3.   CutToClipboard;
  4. end;
  5. procedure TbsCustomEdit.DoCopy;
  6. begin
  7.   CopyToClipboard;
  8. end;
  9. procedure TbsCustomEdit.DoPaste;
  10. begin
  11.   PasteFromClipboard;
  12. end;
  13. procedure TbsCustomEdit.DoDelete;
  14. begin
  15.   ClearSelection;
  16. end;
  17. procedure TbsCustomEdit.DoSelectAll;
  18. begin
  19.   SelectAll;
  20. end;
  21. procedure TbsCustomEdit.CreateSysPopupMenu;
  22. function FindBSFComponent(AForm: TForm): TbsBusinessSkinForm;
  23. var
  24.   i: Integer;
  25. begin
  26.   Result := nil;
  27.   for i := 0 to AForm.ComponentCount - 1 do
  28.    if AForm.Components[i] is TbsBusinessSkinForm
  29.    then
  30.      begin
  31.        Result := TbsBusinessSkinForm(AForm.Components[i]);
  32.        Break;
  33.      end;
  34. end;
  35. function GetResourceStrData: TbsResourceStrData;
  36. var
  37.   BSF: TbsBusinessSkinForm;
  38. begin
  39.   BSF := FindBSFComponent(TForm(GetParentForm(Self)));
  40.   if (BSF <> nil) and (BSF.SkinData <> nil) and (BSF.SkinData.ResourceStrData <> nil)
  41.   then
  42.     Result :=  BSF.SkinData.ResourceStrData
  43.   else
  44.     Result := nil;  
  45. end;
  46. function IsSelected: Boolean;
  47. var
  48.   i, j: Integer;
  49. begin
  50.   GetSel(i, j);
  51.   Result := (i < j);
  52. end;
  53. function IsFullSelected: Boolean;
  54. var
  55.   i, j: Integer;
  56. begin
  57.   GetSel(i, j);
  58.   Result := (i = 0) and (j = Length(Text));
  59. end;
  60. var
  61.   Item: TMenuItem;
  62.   ResStrData: TbsResourceStrData;
  63. begin
  64.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  65.   FSysPopupMenu := TbsSkinPopupMenu.Create(Self);
  66.   FSysPopupMenu.ComponentForm := TForm(GetParentForm(Self));
  67.   ResStrData := GetResourceStrData;
  68.   Item := TMenuItem.Create(FSysPopupMenu);
  69.   with Item do
  70.   begin
  71.     if ResStrData <> nil
  72.     then
  73.       Caption := ResStrData.GetResStr('EDIT_UNDO')
  74.     else
  75.       Caption := BS_Edit_Undo;
  76.     OnClick := DoUndo;
  77.     Enabled := Self.CanUndo;
  78.   end;
  79.   FSysPopupMenu.Items.Add(Item);
  80.   Item := TMenuItem.Create(FSysPopupMenu);
  81.   Item.Caption := '-';
  82.   FSysPopupMenu.Items.Add(Item);
  83.   Item := TMenuItem.Create(FSysPopupMenu);
  84.   with Item do
  85.   begin
  86.     if ResStrData <> nil
  87.     then
  88.       Caption := ResStrData.GetResStr('EDIT_CUT')
  89.     else
  90.       Caption := BS_Edit_Cut;
  91.     Enabled := IsSelected and not Self.ReadOnly;
  92.     OnClick := DoCut;
  93.   end;
  94.   FSysPopupMenu.Items.Add(Item);
  95.   Item := TMenuItem.Create(FSysPopupMenu);
  96.   with Item do
  97.   begin
  98.     if ResStrData <> nil
  99.     then
  100.       Caption := ResStrData.GetResStr('EDIT_COPY')
  101.     else
  102.       Caption := BS_Edit_Copy;
  103.     Enabled := IsSelected;
  104.     OnClick := DoCopy;
  105.   end;
  106.   FSysPopupMenu.Items.Add(Item);
  107.   Item := TMenuItem.Create(FSysPopupMenu);
  108.   with Item do
  109.   begin
  110.     if ResStrData <> nil
  111.     then
  112.       Caption := ResStrData.GetResStr('EDIT_PASTE')
  113.     else
  114.       Caption := BS_Edit_Paste;
  115.     Enabled := (ClipBoard.AsText <> '') and not ReadOnly;
  116.     OnClick := DoPaste;
  117.   end;
  118.   FSysPopupMenu.Items.Add(Item);
  119.   Item := TMenuItem.Create(FSysPopupMenu);
  120.   with Item do
  121.   begin
  122.     if ResStrData <> nil
  123.     then
  124.       Caption := ResStrData.GetResStr('EDIT_DELETE')
  125.     else
  126.       Caption := BS_Edit_Delete;
  127.     Enabled := IsSelected and not Self.ReadOnly;
  128.     OnClick := DoDelete;
  129.   end;
  130.   FSysPopupMenu.Items.Add(Item);
  131.   Item := TMenuItem.Create(FSysPopupMenu);
  132.   Item.Caption := '-';
  133.   FSysPopupMenu.Items.Add(Item);
  134.   Item := TMenuItem.Create(FSysPopupMenu);
  135.   with Item do
  136.   begin
  137.     if ResStrData <> nil
  138.     then
  139.       Caption := ResStrData.GetResStr('EDIT_SELECTALL')
  140.     else
  141.       Caption := BS_Edit_SelectAll;
  142.     Enabled := not IsFullSelected;
  143.     OnClick := DoSelectAll;
  144.   end;
  145.   FSysPopupMenu.Items.Add(Item);
  146. end;
  147. procedure TbsCustomEdit.CMCancelMode;
  148. begin
  149.   inherited;
  150.   if Assigned(FOnEditCancelMode)
  151.   then FOnEditCancelMode(Message.Sender);
  152. end;
  153. procedure TbsCustomEdit.SetEditTransparent(Value: Boolean);
  154. begin
  155.   FEditTransparent := Value;
  156.   ReCreateWnd;
  157. end;
  158. procedure TbsCustomEdit.WMSetFont;
  159. begin
  160.   inherited;
  161.   SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN or EC_RIGHTMARGIN, MakeLong(2, 0));
  162. end;
  163. procedure TbsCustomEdit.CreateParams(var Params: TCreateParams);
  164. begin
  165.   inherited CreateParams(Params);
  166.   with Params do
  167.   begin
  168.     Style := Style and not WS_BORDER;
  169.     ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
  170.     if FEditTransparent then ExStyle := ExStyle or WS_EX_TRANSPARENT;
  171.     if PasswordChar <> #0
  172.     then
  173.       Style := Style or ES_PASSWORD and not ES_MULTILINE
  174.     else
  175.       Style := Style or ES_MULTILINE;
  176.   end;
  177. end;
  178. procedure TbsCustomEdit.WMCHAR;
  179. var
  180.   Key: Char;
  181.   Key1: Word;
  182. begin
  183.  if Message.CharCode in [VK_ESCAPE]
  184.   then
  185.     begin
  186.       Key1 := Message.CharCode;
  187.       if Assigned(OnKeyDown) then OnKeyDown(Self, Key1, []);
  188.       Key := #27;
  189.       if Assigned(OnKeyPress) then OnKeyPress(Self, Key);
  190.     end;
  191.   if Message.CharCode in [VK_RETURN]
  192.   then
  193.     begin
  194.       Key := #13;
  195.       if Assigned(OnKeyPress) then OnKeyPress(Self, Key);
  196.     end
  197.   else
  198.   if not ReadOnly then inherited;
  199. end;
  200. procedure TbsCustomEdit.CNCtlColorStatic;
  201. begin
  202.  if FEditTransparent
  203.  then
  204.    begin
  205.      with Message do
  206.      begin
  207.        SetBkMode(ChildDC, Windows.Transparent);
  208.        SetTextColor(ChildDC, Font.Color);
  209.        Result := GetStockObject(NULL_BRUSH);
  210.      end
  211.    end
  212.  else
  213.   inherited;
  214. end;
  215. procedure TbsCustomEdit.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
  216. begin
  217.  if FEditTransparent
  218.  then
  219.    begin
  220.      with Message do
  221.      begin
  222.        SetBkMode(ChildDC, Windows.Transparent);
  223.        SetTextColor(ChildDC, Font.Color);
  224.        Result := GetStockObject(NULL_BRUSH);
  225.      end
  226.    end
  227.  else
  228.   inherited;
  229. end;
  230. procedure TbsCustomEdit.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  231. begin
  232.   if FEditTransparent then Invalidate else inherited;
  233. end;
  234. procedure TbsCustomEdit.Invalidate;
  235. var
  236.   R: TRect;
  237. begin
  238.   if FEditTransparent
  239.   then
  240.     begin
  241.       if Parent = nil then Exit;
  242.       R := ClientRect;
  243.       R.TopLeft := Parent.ScreenToClient(ClientToScreen(R.TopLeft));
  244.       R.BottomRight := Parent.ScreenToClient(ClientToScreen(R.BottomRight));
  245.       InvalidateRect(Parent.Handle, @R, True);
  246.       RedrawWindow(Handle, nil, 0, RDW_FRAME + RDW_INVALIDATE);
  247.     end
  248.   else
  249.     inherited;
  250. end;
  251. procedure TbsCustomEdit.Change;
  252. begin
  253.   inherited;
  254.   if FEditTransparent then Invalidate;
  255. end;
  256. procedure TbsCustomEdit.WMKeyDown(var Message: TWMKeyDown);
  257. begin
  258.   if FReadOnly and (Message.CharCode = VK_DELETE) then Exit;
  259.   inherited;
  260.   if FEditTransparent then Invalidate;
  261. end;
  262. procedure TbsCustomEdit.WMKeyUp;
  263. begin
  264.   inherited;
  265. end;
  266. procedure TbsCustomEdit.WMSetText(var Message:TWMSetText);
  267. begin
  268.   inherited;
  269.   if FEditTransparent then Invalidate;
  270. end;
  271. procedure TbsCustomEdit.WMMove(var Message: TMessage);
  272. begin
  273.   inherited;
  274.   if FEditTransparent then Invalidate;
  275. end;
  276. procedure TbsCustomEdit.WMCut(var Message: TMessage);
  277. begin
  278.   if FReadOnly then Exit;
  279.   inherited;
  280.   if FEditTransparent then Invalidate;
  281. end;
  282. procedure TbsCustomEdit.WMPaste(var Message: TMessage);
  283. begin
  284.   if FReadOnly then Exit;
  285.   inherited;
  286.   if FEditTransparent then Invalidate;
  287. end;
  288. procedure TbsCustomEdit.WMClear(var Message: TMessage);
  289. begin
  290.   if FReadOnly then Exit;
  291.   inherited;
  292.   if FEditTransparent then Invalidate;
  293. end;
  294. procedure TbsCustomEdit.WMUndo(var Message: TMessage);
  295. begin
  296.   if FReadOnly then Exit;
  297.   inherited;
  298.   if FEditTransparent then Invalidate;
  299. end;
  300. procedure TbsCustomEdit.WMCONTEXTMENU;
  301. var
  302.   X, Y: Integer;
  303.   P: TPoint;
  304. begin
  305.   if PopupMenu <> nil
  306.   then
  307.     inherited
  308.   else
  309.     begin
  310.       CreateSysPopupMenu;
  311.       X := Message.XPos;
  312.       Y := Message.YPos;
  313.       if (X < 0) or (Y < 0)
  314.       then
  315.         begin
  316.           X := Width div 2;
  317.           Y := Height div 2;
  318.           P := Point(0, 0);
  319.           P := ClientToScreen(P);
  320.           X := X + P.X;
  321.           Y := Y + P.Y;
  322.         end;
  323.       if FSysPopupMenu <> nil
  324.       then
  325.         FSysPopupMenu.Popup2(Self, X, Y)
  326.     end;
  327. end;
  328. procedure TbsCustomEdit.WMLButtonDown(var Message: TMessage);
  329. begin
  330.   inherited;
  331.   FDown := True;
  332.   if FEditTransparent then Invalidate;
  333. end;
  334. procedure TbsCustomEdit.WMSETFOCUS;
  335. begin
  336.   inherited;
  337.   if FEditTransparent then Invalidate;
  338.   if AutoSelect then SelectAll;
  339. end;
  340. procedure TbsCustomEdit.WMKILLFOCUS;
  341. begin
  342.   inherited;
  343.   if FEditTransparent then Invalidate;
  344. end;
  345. procedure TbsCustomEdit.WMMOUSEMOVE;
  346. begin
  347.   inherited;
  348.   if FDown and EditTransparent then Invalidate;
  349. end;
  350. procedure TbsCustomEdit.WMLButtonUp;
  351. begin
  352.   inherited;
  353.   FDown := False;
  354. end;
  355. constructor TbsSkinNumEdit.Create(AOwner: TComponent);
  356. begin
  357.   inherited;
  358.   FEditorEnabled := True;
  359. end;
  360. procedure TbsSkinNumEdit.CMMouseEnter;
  361. begin
  362.   inherited;
  363.   if Assigned(FOnMouseEnter) then FOnMouseEnter(Self);
  364. end;
  365. procedure TbsSkinNumEdit.CMMouseLeave;
  366. begin
  367.   inherited;
  368.   if Assigned(FOnMouseLeave) then FOnMouseLeave(Self);
  369. end;
  370. procedure TbsSkinNumEdit.WMMOUSEWHEEL;
  371. begin
  372.   if Message.WParam > 0
  373.   then
  374.     begin
  375.       if Assigned(FOnDownClick) then FOnDownClick(Self);
  376.     end
  377.   else
  378.     begin
  379.       if Assigned(FOnUpClick) then FOnUpClick(Self);
  380.     end;
  381. end;
  382. procedure TbsSkinNumEdit.KeyDown(var Key: Word; Shift: TShiftState);
  383. begin
  384.   if Key = VK_UP
  385.   then
  386.     begin
  387.       if Assigned(FOnUpClick) then FOnUpClick(Self);
  388.     end
  389.   else
  390.   if Key = VK_DOWN
  391.   then
  392.     begin
  393.       if Assigned(FOnDownClick) then FOnDownClick(Self);
  394.     end
  395.   else
  396.   inherited KeyDown(Key, Shift);
  397. end;
  398. procedure TbsSkinNumEdit.KeyPress(var Key: Char);
  399. begin
  400.   if not IsValidChar(Key) then
  401.   begin
  402.     Key := #0;
  403.     MessageBeep(0)
  404.   end;
  405.   if Key <> #0 then inherited KeyPress(Key);
  406. end;
  407. function TbsSkinNumEdit.IsValidChar(Key: Char): Boolean;
  408. begin
  409.   if FLoat
  410.   then
  411.     Result := (Key in [DecimalSeparator, '-', '0'..'9']) or
  412.     ((Key < #32) and (Key <> Chr(VK_RETURN)))
  413.   else
  414.     Result := (Key in ['-', '0'..'9']) or
  415.      ((Key < #32) and (Key <> Chr(VK_RETURN)));
  416.   if not FEditorEnabled and Result and ((Key >= #32) or
  417.      (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE)))
  418.   then
  419.     Result := False;
  420.   if (Key = DecimalSeparator) and (Pos(DecimalSeparator, Text) <> 0)
  421.   then
  422.     Result := False
  423.   else
  424.   if (Key = '-') and (Pos('-', Text) <> 0)
  425.   then
  426.     Result := False;
  427. end;
  428. const
  429.   HTEDITBUTTON = HTSIZE + 2;
  430.   HTEDITFRAME = HTSIZE + 3;
  431. constructor TbsSkinCustomEdit.Create;
  432. begin
  433.   inherited Create(AOwner);
  434.   ControlStyle := ControlStyle + [csOpaque];
  435.   AutoSize := False;
  436.   FIndex := -1;
  437.   Font.Name := 'Arial';
  438.   Font.Color := clWindowText;
  439.   Font.Style := [];
  440.   Font.Height := 14;
  441.   Height := 20;
  442.   BorderStyle := bsNone;
  443.   Picture := nil;
  444.   EditTransparent := True;
  445.   FSkinDataName := 'edit';
  446.   FDefaultFont := TFont.Create;
  447.   FDefaultFont.OnChange := OnDefaultFontChange;
  448.   FDefaultFont.Assign(Font);
  449.   FDefaultWidth := 0;
  450.   FDefaultHeight := 20;
  451.   FUseSkinFont := True;
  452. end;
  453. destructor TbsSkinCustomEdit.Destroy;
  454. begin
  455.   FDefaultFont.Free;
  456.   inherited;
  457. end;
  458. procedure TbsSkinCustomEdit.Loaded;
  459. begin
  460.   inherited;
  461.   if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  462.   then
  463.     Font.Charset := SkinData.ResourceStrData.CharSet;
  464. end;
  465. procedure TbsSkinCustomEdit.CMEnabledChanged;
  466. begin
  467.   inherited;
  468.   if Enabled
  469.   then
  470.     begin
  471.       if FIndex = -1
  472.       then Font.Color := FDefaultFont.Color
  473.       else Font.Color := FontColor;
  474.     end
  475.   else
  476.     begin
  477.       if FIndex = -1
  478.       then Font.Color := clGrayText
  479.       else Font.Color := DisabledFontColor;
  480.     end;
  481.   Invalidate;  
  482. end;
  483. procedure TbsSkinCustomEdit.SetAlignment(Value: TAlignment);
  484. begin
  485.   if FAlignment <> Value then
  486.   begin
  487.     FAlignment := Value;
  488.     RecreateWnd;
  489.   end;
  490. end;
  491. procedure TbsSkinCustomEdit.SetDefaultWidth;
  492. begin
  493.   FDefaultWidth := Value;
  494.   if (FIndex = -1) and (FDefaultWidth > 0) then Width := FDefaultWidth;
  495. end;
  496. procedure TbsSkinCustomEdit.SetDefaultHeight;
  497. begin
  498.   FDefaultHeight := Value;
  499.   if (FIndex = -1) and (FDefaultHeight > 0) then Height := FDefaultHeight;
  500. end;
  501. procedure TbsSkinCustomEdit.SetDefaultFont;
  502. begin
  503.   FDefaultFont.Assign(Value);
  504.   if FIndex = -1 then Font.Assign(Value);
  505. end;
  506. procedure TbsSkinCustomEdit.OnDefaultFontChange(Sender: TObject);
  507. begin
  508.   if FIndex = -1 then Font.Assign(FDefaultFont);
  509. end;
  510. procedure TbsSkinCustomEdit.CalcRects;
  511. var
  512.   Off: Integer;
  513. begin
  514.   if FIndex = -1
  515.   then
  516.     begin
  517.       if FButtonMode
  518.       then
  519.         begin
  520.           FButtonRect := Rect(Width - Height, 0, Width, Height);
  521.           FEditRect := Rect(2, 2, FButtonRect.Left - 2, Height - 2);
  522.         end
  523.       else
  524.         FEditRect := Rect(2, 2, Width - 2, Height - 2);
  525.     end
  526.   else
  527.     begin
  528.       Off := Width - RectWidth(SkinRect);
  529.       FEditRect := ClRect;
  530.       Inc(FEditRect.Right, Off);
  531.       FButtonRect := ButtonRect;
  532.       if ButtonRect.Left >= RectWidth(SkinRect) - ROffset
  533.       then OffsetRect(FButtonRect, Off, 0);
  534.     end;
  535. end;
  536. procedure TbsSkinCustomEdit.WMMOUSEMOVE;
  537. begin
  538.   inherited;
  539.   if FButtonMode and FButtonActive
  540.   then
  541.     begin
  542.       FButtonActive := False;
  543.       Invalidate;
  544.     end;
  545. end;
  546. procedure TbsSkinCustomEdit.WMNCHITTEST;
  547. var
  548.   P: TPoint;
  549.   BR: TRect;
  550.   ER: TRect;
  551. begin
  552.   if FButtonMode and not (csDesigning in ComponentState)
  553.   then
  554.     begin
  555.       P.X := Message.XPos;
  556.       P.Y := Message.YPos;
  557.       P := ScreenToClient(P);
  558.       if FIndex = -1
  559.       then
  560.         begin
  561.           Inc(P.X, 2);
  562.           Inc(P.Y, 2);
  563.         end
  564.       else
  565.         begin
  566.           Inc(P.X, ClRect.Left);
  567.           Inc(P.Y, ClRect.Top);
  568.         end;
  569.       CalcRects;
  570.       BR := FButtonRect; 
  571.       ER := FEditRect; 
  572.       if PtInRect(BR, P)
  573.       then
  574.         Message.Result := HTEDITBUTTON
  575.       else
  576.         if not PtInRect(ER, P)
  577.       then
  578.         Message.Result := HTEDITFRAME
  579.       else
  580.         inherited;
  581.     end
  582.   else
  583.     inherited;
  584. end;
  585. procedure TbsSkinCustomEdit.WMNCLBUTTONDBCLK;
  586. begin
  587.   if FButtonMode and (Message.HitTest = HTEDITBUTTON) and
  588.      not (csDesigning in ComponentState)
  589.   then
  590.     begin
  591.       FButtonDown := True;
  592.       Invalidate;
  593.     end
  594.   else
  595.     inherited;
  596. end;
  597. procedure TbsSkinCustomEdit.WMNCLBUTTONDOWN;
  598. begin
  599.   if FButtonMode and (Message.HitTest = HTEDITBUTTON) and
  600.      not (csDesigning in ComponentState)
  601.   then
  602.     begin
  603.       FButtonDown := True;
  604.       Invalidate;
  605.     end
  606.   else
  607.     inherited;
  608. end;
  609. procedure TbsSkinCustomEdit.WMNCLBUTTONUP;
  610. begin
  611.   if FButtonMode and (Message.HitTest = HTEDITBUTTON) and
  612.      not (csDesigning in ComponentState)
  613.   then
  614.     begin
  615.       FButtonDown := False;
  616.       Invalidate;
  617.       if not Focused then SetFocus;
  618.       if Assigned(FOnButtonClick) then FOnButtonClick(Self);
  619.     end
  620.   else
  621.     inherited;
  622. end;
  623. procedure TbsSkinCustomEdit.WMNCMOUSEMOVE;
  624. begin
  625.   if FButtonMode and not (csDesigning in ComponentState)
  626.   then
  627.     begin
  628.       if Message.HitTest = HTEDITBUTTON
  629.       then
  630.         begin
  631.           if not FButtonActive
  632.           then
  633.              begin
  634.                FButtonActive := True;
  635.                Invalidate;
  636.              end
  637.         end
  638.       else
  639.         begin
  640.           if FButtonActive
  641.           then
  642.            begin
  643.              FButtonActive := False;
  644.              Invalidate;
  645.            end;
  646.            inherited;
  647.          end
  648.     end
  649.   else
  650.     inherited;
  651. end;
  652. procedure TbsSkinCustomEdit.SetButtonMode;
  653. begin
  654.   FButtonMode := Value;
  655.   ReCreateWnd;
  656.   if (csDesigning in ComponentState) and not
  657.      (csLoading in ComponentState)
  658.   then
  659.     begin
  660.       if FButtonMode
  661.       then FSkinDataName := 'buttonedit'
  662.       else FSkinDataName := 'edit';
  663.     end;
  664. end;
  665. procedure TbsSkinCustomEdit.Invalidate;
  666. begin
  667.   if Parent = nil then Exit;
  668.   RedrawWindow(Handle, nil, 0, RDW_FRAME + RDW_INVALIDATE);
  669. end;
  670. procedure TbsSkinCustomEdit.WMSETFOCUS;
  671. begin
  672.   inherited;
  673.   if not FMouseIn and (FIndex <> -1) then Font.Color := ActiveFontColor;
  674. end;
  675. procedure TbsSkinCustomEdit.WMKILLFOCUS;
  676. begin
  677.   inherited;
  678.   if not FMouseIn and (FIndex <> -1) then Font.Color := FontColor;
  679. end;
  680. procedure TbsSkinCustomEdit.CMMouseEnter;
  681. begin
  682.   inherited;
  683.   FMouseIn := True;
  684.   if not Focused and (FIndex <> -1)
  685.   then
  686.     begin
  687.       Font.Color := ActiveFontColor;
  688.       Invalidate;
  689.     end;
  690.   if Assigned(FOnMouseEnter) then FOnMouseEnter(Self);
  691. end;
  692. procedure TbsSkinCustomEdit.CMMouseLeave;
  693. begin
  694.   inherited;
  695.   FMouseIn := False;
  696.   if not Focused and (FIndex <> -1)
  697.   then
  698.     begin
  699.       Font.Color := FontColor;
  700.       Invalidate;
  701.     end;
  702.   if FButtonDown or FButtonActive
  703.   then
  704.     begin
  705.       FButtonActive := False;
  706.       FButtonDown := False;
  707.       Invalidate;
  708.     end;
  709.   if Assigned(FOnMouseLeave) then FOnMouseLeave(Self);
  710. end;
  711. procedure TbsSkinCustomEdit.SetBounds;
  712. var
  713.   UpDate: Boolean;
  714. begin
  715.   GetSkinData;
  716.   UpDate := ((Width <> AWidth) or (Height <> AHeight)) and (FIndex <> -1);
  717.   if UpDate then AHeight := RectHeight(SkinRect);
  718.   inherited;
  719.   Invalidate;
  720. end;
  721. procedure TbsSkinCustomEdit.WMNCCALCSIZE;
  722. begin
  723.   GetSkinData;
  724.   if FIndex = -1
  725.   then
  726.     with Message.CalcSize_Params^.rgrc[0] do
  727.     begin
  728.       Inc(Left, 2);
  729.       Inc(Top, 2);
  730.       if FButtonMode
  731.       then Dec(Right, 22)
  732.       else Dec(Right, 2);
  733.       Dec(Bottom, 2);
  734.     end
  735.   else
  736.     with Message.CalcSize_Params^.rgrc[0] do
  737.     begin
  738.       Inc(Left, ClRect.Left);
  739.       Inc(Top, ClRect.Top);
  740.       Dec(Right, RectWidth(SkinRect) - ClRect.Right);
  741.       Dec(Bottom, RectHeight(SkinRect) - ClRect.Bottom);
  742.     end;
  743. end;
  744. procedure TbsSkinCustomEdit.CreateParams(var Params: TCreateParams);
  745. const
  746.   Alignments: array[TAlignment] of DWORD = (ES_LEFT, ES_RIGHT, ES_CENTER);
  747. begin
  748.   inherited CreateParams(Params);
  749.   with Params do
  750.   begin
  751.     ExStyle := Exstyle and not WS_EX_Transparent;
  752.     Style := Style and not WS_BORDER or Alignments[FAlignment];
  753.   end;
  754. end;
  755. procedure TbsSkinCustomEdit.DrawSkinEdit;
  756. var
  757.   R: TRect;
  758.   TX, TY, Offset: Integer;
  759.   BR: TRect;
  760.   B: TBitMap;
  761. begin
  762.   GetSkinData;
  763.   CalcRects;
  764.   if FButtonMode then Offset := Width - FButtonRect.Left else Offset := 0;
  765.   B := TBitMap.Create;
  766.   B.Width := Width;
  767.   B.Height := Height;
  768.   try
  769.     if FIndex = -1
  770.     then
  771.       with B.Canvas do
  772.       begin
  773.         Brush.Color := clWindow;
  774.         // draw frame
  775.         R := Rect(0, 0, Width - Offset, Height);
  776.         Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  777.         Frame3D(B.Canvas, R, clBtnFace, clBtnFace, 1);
  778.         // draw button
  779.         if FButtonMode
  780.         then
  781.           begin
  782.             CalcRects;
  783.             R := FButtonRect;
  784.             if FButtonDown and FButtonActive
  785.             then
  786.               begin
  787.                 Frame3D(B.Canvas, R, BS_XP_BTNFRAMECOLOR, BS_XP_BTNFRAMECOLOR, 1);
  788.                 Brush.Color :=  BS_XP_BTNDOWNCOLOR;
  789.                 FillRect(R);
  790.               end
  791.             else
  792.             if FButtonActive
  793.             then
  794.               begin
  795.                 Frame3D(B.Canvas, R, BS_XP_BTNFRAMECOLOR, BS_XP_BTNFRAMECOLOR, 1);
  796.                 Brush.Color :=  BS_XP_BTNACTIVECOLOR;
  797.                 FillRect(R);
  798.               end
  799.             else
  800.               begin
  801.                 Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  802.                 Brush.Color := clBtnFace;
  803.                 FillRect(R);
  804.               end;
  805.           end;
  806.       end
  807.     else
  808.       begin
  809.         if FMouseIn or Focused
  810.         then
  811.           CreateHSkinImage(LOffset, ROffset, B, Picture, ActiveSkinRect, Width,
  812.             RectHeight(ActiveSkinRect))
  813.         else
  814.           CreateHSkinImage(LOffset, ROffset, B, Picture, SkinRect, Width,
  815.                            RectHeight(SkinRect));
  816.         // draw button
  817.         if FButtonMode
  818.         then
  819.           begin
  820.             BR := NullRect;
  821.             if not Enabled and not IsNullRect(UnEnabledButtonRect)
  822.             then
  823.               BR := UnEnabledButtonRect
  824.             else  
  825.             if FButtonDown and FButtonActive
  826.             then
  827.               BR := DownButtonRect
  828.             else if FButtonActive then BR := ActiveButtonRect;
  829.             if not IsNullRect(BR) then
  830.             B.Canvas.CopyRect(FButtonRect, Picture.Canvas, BR);
  831.           end;
  832.         //
  833.       end;
  834.     // Draw text
  835.     if ADrawText
  836.     then
  837.       with B.Canvas do
  838.       begin
  839.         Brush.Style := bsClear;
  840.         if (FIndex = -1) or not FUseSkinFont
  841.         then
  842.           Font := DefaultFont
  843.         else
  844.           begin
  845.             Font.Name := FontName;
  846.             Font.Height := FontHeight;
  847.             Font.Color := FontColor;
  848.             Font.Style := FontStyle;
  849.           end;
  850.         if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  851.         then
  852.           Font.Charset := SkinData.ResourceStrData.CharSet
  853.         else
  854.           Font.CharSet := FDefaultFont.CharSet;
  855.         TY := FEditRect.Top - 1;
  856.         TX := FEditRect.Left + 1;
  857.         case Alignment of
  858.           taCenter:
  859.              TX := TX + RectWidth(FEditRect) div 2 - TextWidth(Text) div 2;
  860.           taRightJustify:
  861.              TX := FEditRect.Right - 1 - TextWidth(Text);
  862.          end;
  863.         TextRect(FEditRect, TX, TY, Text);
  864.       end;
  865.     //
  866.     C.Draw(0, 0, B);
  867.   finally
  868.     B.Free;
  869.   end;
  870. end;
  871. procedure TbsSkinCustomEdit.WMNCPAINT;
  872. var
  873.   DC: HDC;
  874.   C: TCanvas;
  875. begin
  876.   DC := GetWindowDC(Handle);
  877.   C := TControlCanvas.Create;
  878.   C.Handle := DC;
  879.   try
  880.     DrawSkinEdit(C, False);
  881.   finally
  882.     C.Free;
  883.     ReleaseDC(Handle, DC);
  884.   end;
  885. end;
  886. procedure TbsSkinCustomEdit.GetSkinData;
  887. begin
  888.   if FSD = nil
  889.   then
  890.     begin
  891.       FIndex := -1;
  892.       Exit;
  893.     end;
  894.   if FSD.Empty
  895.   then
  896.     FIndex := -1
  897.   else
  898.     FIndex := FSD.GetControlIndex(FSkinDataName);
  899.   if FIndex <> -1
  900.   then
  901.     if TbsDataSkinControl(FSD.CtrlList.Items[FIndex]) is TbsDataSkinEditControl
  902.     then
  903.       with TbsDataSkinEditControl(FSD.CtrlList.Items[FIndex]) do
  904.       begin
  905.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  906.         then
  907.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  908.         else
  909.           Picture := nil;
  910.         Self.SkinRect := SkinRect;
  911.         Self.ActiveSkinRect := ActiveSkinRect;
  912.         if isNullRect(ActiveSkinRect)
  913.         then
  914.           Self.ActiveSkinRect := SkinRect;
  915.         LOffset := LTPoint.X;
  916.         ROffset := RectWidth(SkinRect) - RTPoint.X;
  917.         Self.ClRect := ClRect;
  918.         Self.FontName := FontName;
  919.         Self.FontStyle := FontStyle;
  920.         Self.FontHeight := FontHeight;
  921.         Self.FontColor := FontColor;
  922.         Self.DisabledFontColor := DisabledFontColor;
  923.         Self.ActiveFontColor := ActiveFontColor;
  924.         Self.ButtonRect := ButtonRect;
  925.         Self.ActiveButtonRect := ActiveButtonRect;
  926.         Self.DownButtonRect := DownButtonRect;
  927.         Self.UnEnabledButtonRect := UnEnabledButtonRect;
  928.         if IsNullRect(Self.DownButtonRect)
  929.         then Self.DownButtonRect := Self.ActiveButtonRect;
  930.       end;
  931. end;
  932. procedure TbsSkinCustomEdit.SetSkinData;
  933. begin
  934.   FSD := Value;
  935.   if (FSD <> nil) then
  936.   if not FSD.Empty and not (csDesigning in ComponentState)
  937.   then
  938.     ChangeSkinData;
  939. end;
  940. procedure TbsSkinCustomEdit.Notification;
  941. begin
  942.   inherited Notification(AComponent, Operation);
  943.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  944. end;
  945. procedure TbsSkinCustomEdit.ChangeSkinData;
  946. begin
  947.   GetSkinData;
  948.   //
  949.   if (FIndex <> -1)
  950.   then
  951.     begin
  952.       if FUseSkinFont
  953.       then
  954.         begin
  955.           Font.Name := FontName;
  956.           Font.Style := FontStyle;
  957.           Height := RectHeight(SkinRect);
  958.           Font.Height := FontHeight;
  959.           if Focused
  960.           then
  961.             Font.Color := ActiveFontColor
  962.           else
  963.             Font.Color := FontColor;
  964.         end
  965.       else
  966.         begin
  967.           Font.Assign(FDefaultFont);
  968.           Height := RectHeight(SkinRect);
  969.           if Focused
  970.           then
  971.             Font.Color := ActiveFontColor
  972.           else
  973.             Font.Color := FontColor;
  974.         end;
  975.     end
  976.   else
  977.     begin
  978.       Font.Assign(FDefaultFont);
  979.       if FDefaultWidth > 0 then Width := FDefaultWidth;
  980.       if FDefaultHeight > 0 then Height := FDefaultHeight;
  981.     end;
  982.   //
  983.   if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  984.   then
  985.     Font.Charset := SkinData.ResourceStrData.CharSet
  986.   else
  987.     Font.CharSet := FDefaultFont.CharSet;
  988.   //
  989.   ReCreateWnd;
  990.   if Enabled
  991.   then
  992.     begin
  993.       if FIndex = -1
  994.       then
  995.         Font.Color := FDefaultFont.Color
  996.       else
  997.       if Focused
  998.       then
  999.         Font.Color := ActiveFontColor
  1000.       else
  1001.         Font.Color := FontColor;
  1002.     end
  1003.   else
  1004.     begin
  1005.       if FIndex = -1
  1006.       then Font.Color := clGrayText
  1007.       else Font.Color := DisabledFontColor;
  1008.     end;
  1009. end;
  1010. constructor TbsSkinPopupMonthCalendar.Create(AOwner: TComponent);
  1011. begin
  1012.   inherited Create(AOwner);
  1013.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  1014. end;
  1015. procedure TbsSkinPopupMonthCalendar.CreateParams(var Params: TCreateParams);
  1016. begin
  1017.   inherited CreateParams(Params);
  1018.   with Params do
  1019.   begin
  1020.     Style := WS_POPUP;
  1021.     ExStyle := WS_EX_TOOLWINDOW;
  1022.     WindowClass.Style := CS_SAVEBITS;
  1023.     if CheckWXP then
  1024.       WindowClass.Style := WindowClass.style or CS_DROPSHADOW_;
  1025.   end;
  1026. end;
  1027. procedure TbsSkinPopupMonthCalendar.WMMouseActivate(var Message: TMessage);
  1028. begin
  1029.   Message.Result := MA_NOACTIVATE;
  1030. end;
  1031. constructor TbsSkinDateEdit.Create(AOwner: TComponent);
  1032. begin
  1033.   inherited;
  1034.   EditMask := GetDateMask;
  1035.   FTodayDefault := False;
  1036.   ButtonMode := True;
  1037.   FSkinDataName := 'buttonedit';
  1038.   FMonthCalendar := TbsSkinPopupMonthCalendar.Create(Self);
  1039.   FMonthCalendar.Parent := Self;
  1040.   FMonthCalendar.Visible := False;
  1041.   FMonthCalendar.OnNumberClick := CalendarClick;
  1042.   FAlphaBlend := False;
  1043.   FAlphaBlendValue := 0;
  1044.   FAlphaBlendAnimation := False;
  1045.   OnButtonClick := ButtonClick;
  1046. end;
  1047. destructor TbsSkinDateEdit.Destroy;
  1048. begin
  1049.   FMonthCalendar.Free;
  1050.   inherited;
  1051. end;
  1052. function TbsSkinDateEdit.IsDateInput: Boolean;
  1053. begin
  1054.   Result := IsValidText(Text);
  1055. end;
  1056. function TbsSkinDateEdit.MyStrToDate;
  1057. var
  1058.   S1: array[1..3] of String;
  1059.   i, j: Integer;
  1060.   M, Y, D: Word;
  1061.   MPos, YPos, DPos: Word;
  1062.   F: String;
  1063. begin
  1064.   F := DateToStr(EncodeDate(9999, 12, 31));
  1065.   YPos := 1;
  1066.   MPos := 1;
  1067.   Dpos := 1;
  1068.   j := 1;
  1069.   for i := 1 to 3 do s1[i] := '';
  1070.   for i := 1 to Length(F) do
  1071.    if F[i] = DateSeparator then inc(j) else s1[j] := s1[j] + F[i];
  1072.   for i := 1 to 3 do
  1073.   begin
  1074.     if not IsOnlyNumbers(s1[i])
  1075.     then
  1076.       MPos := i
  1077.     else
  1078.       begin
  1079.         j := StrToInt(s1[i]);
  1080.         case j of
  1081.           31: DPos := i;
  1082.           9999: YPos := i;
  1083.           99: YPos := i;
  1084.         end;
  1085.       end;
  1086.   end;
  1087.   j := 1;
  1088.   for i := 1 to 3 do s1[i] := '';
  1089.   for i := 1 to Length(S) do
  1090.    if S[i] = DateSeparator then inc(j) else s1[j] := s1[j] + S[i];
  1091.   M := DecodeMonth(s1[MPos]);
  1092.   D := StrToInt(s1[DPos]);
  1093.   Y := StrToInt(s1[YPos]);
  1094.   Result := EncodeDate(Y, M, D);
  1095. end;
  1096. function TbsSkinDateEdit.ExtactMonth;
  1097. var
  1098.   F: String;
  1099.   S1: array[1..3] of String;
  1100.   i, j: Integer;
  1101. begin
  1102.   F := DateToStr(ADate);
  1103.   j := 1;
  1104.   for i := 1 to 3 do s1[i] := '';
  1105.   for i := 1 to Length(F) do
  1106.    if F[i] = DateSeparator then inc(j) else s1[j] := s1[j] + F[i];
  1107.   Result := '';
  1108.   for i := 1 to 3 do
  1109.   begin
  1110.     if not IsOnlyNumbers(s1[i])
  1111.     then
  1112.       begin
  1113.         Result := s1[i];
  1114.         Break;
  1115.       end;
  1116.   end;
  1117. end;
  1118. function TbsSkinDateEdit.DecodeMonth(S: String): Word;
  1119. var
  1120.   S1: String;
  1121.   i: Integer;
  1122. begin
  1123.   Result := 1;
  1124.   for i := 1 to 12 do
  1125.   begin
  1126.     S1 := ExtactMonth(EncodeDate(9999, i, 1));
  1127.     if LowerCase(S1) = LowerCase(S)
  1128.     then
  1129.       begin
  1130.         Result := i;
  1131.         Break;
  1132.       end
  1133.   end;
  1134. end;
  1135. function TbsSkinDateEdit.IsMonth(S: String): Boolean;
  1136. var
  1137.   S1: String;
  1138.   i: Integer;
  1139. begin
  1140.   Result := False;
  1141.   for i := 1 to 12 do
  1142.   begin
  1143.     S1 := ExtactMonth(EncodeDate(9999, i, 1));
  1144.     if LowerCase(S1) = LowerCase(S)
  1145.     then
  1146.       begin
  1147.         Result := True;
  1148.         Break;
  1149.       end
  1150.   end;
  1151. end;
  1152. function TbsSkinDateEdit.IsOnlyNumbers;
  1153. const
  1154.   DateSymbols = '0123456789';
  1155. var
  1156.   i: Integer;
  1157. begin
  1158.   Result := True;
  1159.   for i := 1 to Length(S) do
  1160.   begin
  1161.     if (Pos(S[i], DateSymbols) = 0) and (S[i] <> DateSeparator)
  1162.     then
  1163.       begin
  1164.         Result := False;
  1165.         Break;
  1166.       end;
  1167.   end;
  1168. end;
  1169. function TbsSkinDateEdit.GetDateMask: String;
  1170. var
  1171.   S: String;
  1172.   S1: array[1..3] of String;
  1173.   i, j: Integer;
  1174.   MPos, DPos, YPos: Integer;
  1175.   FL: Boolean;
  1176. begin
  1177.   S := DateToStr(EncodeDate(9999, 12, 31));
  1178.   YPos := 1;
  1179.   MPos := 1;
  1180.   Dpos := 1;
  1181.   j := 1;
  1182.   for i := 1 to 3 do s1[i] := '';
  1183.   for i := 1 to Length(S) do
  1184.    if S[i] = DateSeparator then inc(j) else s1[j] := s1[j] + S[i];
  1185.   FL := False;
  1186.   for i := 1 to 3 do
  1187.   begin
  1188.     if not IsOnlyNumbers(s1[i])
  1189.     then
  1190.       begin
  1191.         MPos := i;
  1192.         FL := True;
  1193.       end
  1194.     else
  1195.       begin
  1196.         j := StrToInt(s1[i]);
  1197.         case j of
  1198.          12: MPos := i;
  1199.          31: DPos := i;
  1200.          9999: YPos := i;
  1201.          99: YPos := i;
  1202.         end;
  1203.       end;
  1204.   end;
  1205.   Result := '!';
  1206.   for i := 1 to Length(s1[DPos]) do S1[DPos][i] := '9';
  1207.   if FL
  1208.   then
  1209.     for i := 1 to Length(s1[MPos]) do S1[MPos][i] := 'L'
  1210.   else
  1211.     for i := 1 to Length(s1[MPos]) do S1[MPos][i] := '9';
  1212.   for i := 1 to Length(s1[YPos]) do S1[YPos][i] := '0';
  1213.   Result := Result + s1[1] + '/' + s1[2] + '/' + s1[3] + ';1; ';
  1214. end;
  1215. procedure TbsSkinDateEdit.Loaded;
  1216. begin
  1217.   inherited;
  1218.   EditMask := GetDateMask;
  1219.   if FTodayDefault then Date := Now;
  1220. end;
  1221. procedure TbsSkinDateEdit.SetTodayDefault;
  1222. begin
  1223.   FTodayDefault := Value;
  1224.   if FTodayDefault then Date := Now;
  1225. end;
  1226. function TbsSkinDateEdit.GetCalendarFont;
  1227. begin
  1228.   Result := FMonthCalendar.DefaultFont;
  1229. end;
  1230. procedure TbsSkinDateEdit.SetCalendarFont;
  1231. begin
  1232.   FMonthCalendar.DefaultFont.Assign(Value);
  1233. end;
  1234. function TbsSkinDateEdit.GetCalendarWidth: Integer;
  1235. begin
  1236.   Result := FMonthCalendar.Width;
  1237. end;
  1238. procedure TbsSkinDateEdit.SetCalendarWidth(Value: Integer);
  1239. begin
  1240.   FMonthCalendar.Width := Value;
  1241. end;
  1242. function TbsSkinDateEdit.GetCalendarHeight: Integer;
  1243. begin
  1244.   Result := FMonthCalendar.Height;
  1245. end;
  1246. procedure TbsSkinDateEdit.SetCalendarHeight(Value: Integer);
  1247. begin
  1248.   FMonthCalendar.Height := Value;
  1249. end;
  1250. function TbsSkinDateEdit.GetDate: TDate;
  1251. begin
  1252.   Result := FMonthCalendar.Date;
  1253. end;
  1254. procedure TbsSkinDateEdit.SetDate(Value: TDate);
  1255. begin
  1256.   FMonthCalendar.Date := Value;
  1257.   StopCheck := True;
  1258.   if not (csLoading in ComponentState) or FTodayDefault
  1259.   then
  1260.     begin
  1261.       Text := DateToStr(Value);
  1262.     end;
  1263.   StopCheck := False;
  1264.   if Assigned(FOnDateChange) then FOnDateChange(Self);
  1265. end;
  1266. function TbsSkinDateEdit.IsValidText;
  1267. var
  1268.   F: String;
  1269.   s1, s2: array[1..3] of String;
  1270.   i, j: Integer;
  1271.   MPos, DPos, YPos: Integer;
  1272.   FL: Boolean;
  1273. begin
  1274.   Result := Pos(' ', S) = 0;
  1275.   if not Result then Exit;
  1276.   F := DateToStr(EncodeDate(9999, 12, 31));
  1277.   if (IsOnlyNumbers(F) and not IsOnlyNumbers(S)) or
  1278.      (IsOnlyNumbers(S) and not IsOnlyNumbers(F))
  1279.   then
  1280.     begin
  1281.       Result := False;
  1282.       Exit;
  1283.     end;
  1284.   for i := 1 to 3 do s1[i] := '';
  1285.   for i := 1 to 3 do s2[i] := '';
  1286.   j := 1;
  1287.   YPos := 1;
  1288.   MPos := 1;
  1289.   Dpos := 1;
  1290.   for i := 1 to Length(F) do
  1291.    if F[i] = DateSeparator then inc(j) else s1[j] := s1[j] + F[i];
  1292.   FL := False;
  1293.   for i := 1 to 3 do
  1294.   begin
  1295.     if not IsOnlyNumbers(s1[i])
  1296.     then
  1297.       begin
  1298.         MPos := i;
  1299.         FL := True;
  1300.       end
  1301.     else
  1302.       begin
  1303.         j := StrToInt(s1[i]);
  1304.         case j of
  1305.          12: MPos := i;
  1306.          31: DPos := i;
  1307.          9999: YPos := i;
  1308.          99: YPos := i;
  1309.         end;
  1310.       end;
  1311.   end;
  1312.   j := 1;
  1313.   for i := 1 to Length(S) do
  1314.     if S[i] = DateSeparator then inc(j) else s2[j] := s2[j] + S[i];
  1315.   if StrToInt(s2[Ypos]) = 0
  1316.   then
  1317.     Result := Length(s2[YPos]) < 2
  1318.   else
  1319.     Result := True;
  1320.   Result := Result and (Length(s2[1]) > 0) and (Length(s2[2]) > 0) and
  1321.             (Length(s2[3]) > 0);
  1322.   if not FL
  1323.   then
  1324.     Result := Result and
  1325.               (Length(s1) = Length(s2)) and
  1326.               (StrToInt(s2[Mpos]) > 0) and
  1327.               (StrToInt(s2[Dpos]) > 0) and
  1328.               (StrToInt(s2[1]) <= StrToInt(s1[1])) and
  1329.               (StrToInt(s2[2]) <= StrToInt(s1[2])) and
  1330.               (StrToInt(s2[3]) <= StrToInt(s1[3]))
  1331.   else
  1332.     Result := Result and
  1333.               (Length(s1) = Length(s2)) and
  1334.               (Length(s1[Mpos]) = Length(s2[Mpos])) and
  1335.               IsMonth(s2[Mpos]) and
  1336.               (StrToInt(s2[Dpos]) > 0) and
  1337.               (StrToInt(s2[DPos]) <= StrToInt(s1[DPos])) and
  1338.               (StrToInt(s2[YPos]) <= StrToInt(s1[YPos]))
  1339. end;
  1340. procedure TbsSkinDateEdit.Change;
  1341. begin
  1342.   inherited;
  1343.   if not StopCheck
  1344.   then
  1345.     if IsValidText(Text)
  1346.     then CheckValidDate;
  1347. end;
  1348. procedure TbsSkinDateEdit.CheckValidDate;
  1349. var
  1350.   OldDate: TDate;
  1351. begin
  1352.   if FMonthCalendar = nil then Exit;
  1353.   OldDate := FMonthCalendar.Date;
  1354.   try
  1355.     if IsOnlyNumbers(Text)
  1356.     then
  1357.       FMonthCalendar.Date := StrToDate(Text)
  1358.     else
  1359.       FMonthCalendar.Date := MyStrToDate(Text);
  1360.   finally
  1361.    if OldDate <> FMonthCalendar.Date
  1362.    then
  1363.      if Assigned(FOnDateChange) then FOnDateChange(Self);
  1364.   end;
  1365. end;
  1366. procedure TbsSkinDateEdit.CMCancelMode;
  1367. begin
  1368.  if (Message.Sender <> FMonthCalendar) and
  1369.      not FMonthCalendar.ContainsControl(Message.Sender)
  1370.  then
  1371.    CloseUp(False);
  1372. end;
  1373. procedure TbsSkinDateEdit.WndProc;
  1374. begin
  1375.   inherited;
  1376.   case Message.Msg of
  1377.    WM_KILLFOCUS:
  1378.      begin
  1379.        if not FMonthCalendar.Visible
  1380.        then
  1381.          begin
  1382.            StopCheck := True;
  1383.            Text := DateToStr(FMonthCalendar.Date);
  1384.            StopCheck := False;
  1385.          end
  1386.        else
  1387.        if Message.wParam <> FMonthCalendar.Handle
  1388.        then
  1389.          CloseUp(False);
  1390.      end;
  1391.    WM_KEYDOWN:
  1392.       CloseUp(False);
  1393.   end;
  1394. end;
  1395. procedure TbsSkinDateEdit.DropDown;
  1396. var
  1397.   P: TPoint;
  1398.   I, Y: Integer;
  1399. begin
  1400.   P := Parent.ClientToScreen(Point(Left, Top));
  1401.   Y := P.Y + Height;
  1402.   if Y + FMonthCalendar.Height > Screen.Height then Y := P.Y - FMonthCalendar.Height;
  1403.   //
  1404.   if CheckW2KWXP and FAlphaBlend
  1405.   then
  1406.     begin
  1407.       SetWindowLong(FMonthCalendar.Handle, GWL_EXSTYLE,
  1408.                     GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
  1409.       SetAlphaBlendTransparent(FMonthCalendar.Handle, 0)
  1410.     end;
  1411.   //
  1412.   FMonthCalendar.SkinData := Self.SkinData;
  1413.   SetWindowPos(FMonthCalendar.Handle, HWND_TOP, P.X, Y,
  1414.    0, 0,
  1415.       SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  1416.   FMonthCalendar.Visible := True;
  1417.   if FAlphaBlend and not FAlphaBlendAnimation and CheckW2KWXP
  1418.   then
  1419.     begin
  1420.       Application.ProcessMessages;
  1421.       SetAlphaBlendTransparent(FMonthCalendar.Handle, FAlphaBlendValue)
  1422.     end
  1423.   else
  1424.   if FAlphaBlendAnimation and FAlphaBlend and CheckW2KWXP
  1425.   then
  1426.     begin
  1427.       Application.ProcessMessages;
  1428.       I := 0;
  1429.       repeat
  1430.         Inc(i, 2);
  1431.         if i > FAlphaBlendValue then i := FAlphaBlendValue;
  1432.         SetAlphaBlendTransparent(FMonthCalendar.Handle, i);
  1433.       until i >= FAlphaBlendValue;
  1434.     end;
  1435. end;
  1436. procedure TbsSkinDateEdit.CloseUp(AcceptValue: Boolean);
  1437. begin
  1438.   if FMonthCalendar.Visible
  1439.   then
  1440.     begin
  1441.       SetWindowPos(FMonthCalendar.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  1442.         SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  1443.       FMonthCalendar.Visible := False;
  1444.       if CheckW2KWXP and FAlphaBlend
  1445.       then
  1446.         SetWindowLong(FMonthCalendar.Handle, GWL_EXSTYLE,
  1447.                       GetWindowLong(Handle, GWL_EXSTYLE) and not WS_EX_LAYERED);
  1448.       if AcceptValue
  1449.       then
  1450.         begin
  1451.           StopCheck := True;
  1452.           Text := DateToStr(FMonthCalendar.Date);
  1453.           if Assigned(FOnDateChange) then FOnDateChange(Self);
  1454.           StopCheck := False;
  1455.         end;
  1456.       SetFocus;
  1457.    end;
  1458. end;
  1459. procedure TbsSkinDateEdit.ButtonClick(Sender: TObject);
  1460. begin
  1461.   if FMonthCalendar.Visible
  1462.   then
  1463.     CloseUp(False)
  1464.   else
  1465.     DropDown;
  1466. end;
  1467. procedure TbsSkinDateEdit.CalendarClick;
  1468. begin
  1469.   CloseUp(True);
  1470. end;
  1471. function TbsSkinDateEdit.GetFirstDayOfWeek: TbsDaysOfWeek;
  1472. begin
  1473.   Result := FMonthCalendar.FirstDayOfWeek;
  1474. end;
  1475. procedure TbsSkinDateEdit.SetFirstDayOfWeek(Value: TbsDaysOfWeek);
  1476. begin
  1477.   FMonthCalendar.FirstDayOfWeek := Value;
  1478. end;
  1479. constructor TbsSkinMemo.Create;
  1480. begin
  1481.   inherited Create(AOwner);
  1482.   AutoSize := False;
  1483.   FIndex := -1;
  1484.   Font.Name := 'Arial';
  1485.   Font.Height := 14;
  1486.   FVScrollBar := nil;
  1487.   FDown := False;
  1488.   FSkinDataName := 'memo';
  1489.   FDefaultFont := TFont.Create;
  1490.   FDefaultFont.OnChange := OnDefaultFontChange;
  1491.   FDefaultFont.Assign(Font);
  1492.   ScrollBars := ssNone;
  1493.   FUseSkinFont := True;
  1494.   FSysPopupMenu := nil;
  1495. end;
  1496. procedure TbsSkinMemo.WMCONTEXTMENU;
  1497. var
  1498.   X, Y: Integer;
  1499.   P: TPoint;
  1500. begin
  1501.   if PopupMenu <> nil
  1502.   then
  1503.     inherited
  1504.   else
  1505.     begin
  1506.       CreateSysPopupMenu;
  1507.       X := Message.XPos;
  1508.       Y := Message.YPos;
  1509.       if (X < 0) or (Y < 0)
  1510.       then
  1511.         begin
  1512.           X := Width div 2;
  1513.           Y := Height div 2;
  1514.           P := Point(0, 0);
  1515.           P := ClientToScreen(P);
  1516.           X := X + P.X;
  1517.           Y := Y + P.Y;
  1518.         end;
  1519.       if FSysPopupMenu <> nil
  1520.       then
  1521.         FSysPopupMenu.Popup2(Self, X, Y)
  1522.     end;
  1523. end;
  1524. procedure TbsSkinMemo.WMAFTERDISPATCH;
  1525. begin
  1526.   if FSysPopupMenu <> nil
  1527.   then
  1528.     begin
  1529.       FSysPopupMenu.Free;
  1530.       FSysPopupMenu := nil;
  1531.     end;
  1532. end;
  1533. procedure TbsSkinMemo.DoUndo;
  1534. begin
  1535.   Undo;
  1536. end;
  1537. procedure TbsSkinMemo.DoCut;
  1538. begin
  1539.   CutToClipboard;
  1540. end;
  1541. procedure TbsSkinMemo.DoCopy;
  1542. begin
  1543.   CopyToClipboard;
  1544. end;
  1545. procedure TbsSkinMemo.DoPaste;
  1546. begin
  1547.   PasteFromClipboard;
  1548. end;
  1549. procedure TbsSkinMemo.DoDelete;
  1550. begin
  1551.   ClearSelection;
  1552. end;
  1553. procedure TbsSkinMemo.DoSelectAll;
  1554. begin
  1555.   SelectAll;
  1556. end;
  1557. procedure TbsSkinMemo.CreateSysPopupMenu;
  1558. function IsSelected: Boolean;
  1559. begin
  1560.   Result := GetSelLength > 0;
  1561. end;
  1562. function IsFullSelected: Boolean;
  1563. begin
  1564.   Result := GetSelText = Text;
  1565. end;
  1566. var
  1567.   Item: TMenuItem;
  1568. begin
  1569.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  1570.   FSysPopupMenu := TbsSkinPopupMenu.Create(Self);
  1571.   FSysPopupMenu.ComponentForm := TForm(GetParentForm(Self));
  1572.   Item := TMenuItem.Create(FSysPopupMenu);
  1573.   with Item do
  1574.   begin
  1575.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  1576.     then
  1577.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_UNDO')
  1578.     else
  1579.       Caption := BS_Edit_Undo;
  1580.     OnClick := DoUndo;
  1581.     Enabled := Self.CanUndo;
  1582.   end;
  1583.   FSysPopupMenu.Items.Add(Item);
  1584.   Item := TMenuItem.Create(FSysPopupMenu);
  1585.   Item.Caption := '-';
  1586.   FSysPopupMenu.Items.Add(Item);
  1587.   Item := TMenuItem.Create(FSysPopupMenu);
  1588.   with Item do
  1589.   begin
  1590.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  1591.     then
  1592.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_CUT')
  1593.     else
  1594.       Caption := BS_Edit_Cut;
  1595.     Enabled := IsSelected and not Self.ReadOnly;
  1596.     OnClick := DoCut;
  1597.   end;
  1598.   FSysPopupMenu.Items.Add(Item);
  1599.   Item := TMenuItem.Create(FSysPopupMenu);
  1600.   with Item do
  1601.   begin
  1602.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  1603.     then
  1604.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_COPY')
  1605.     else
  1606.       Caption := BS_Edit_Copy;
  1607.     Enabled := IsSelected;
  1608.     OnClick := DoCopy;
  1609.   end;
  1610.   FSysPopupMenu.Items.Add(Item);
  1611.   Item := TMenuItem.Create(FSysPopupMenu);
  1612.   with Item do
  1613.   begin
  1614.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  1615.     then
  1616.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_PASTE')
  1617.     else
  1618.       Caption := BS_Edit_Paste;
  1619.     Enabled := (ClipBoard.AsText <> '') and not ReadOnly;
  1620.     OnClick := DoPaste;
  1621.   end;
  1622.   FSysPopupMenu.Items.Add(Item);
  1623.   Item := TMenuItem.Create(FSysPopupMenu);
  1624.   with Item do
  1625.   begin
  1626.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  1627.     then
  1628.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_DELETE')
  1629.     else
  1630.       Caption := BS_Edit_Delete;
  1631.     Enabled := IsSelected and not Self.ReadOnly;
  1632.     OnClick := DoDelete;
  1633.   end;
  1634.   FSysPopupMenu.Items.Add(Item);
  1635.   Item := TMenuItem.Create(FSysPopupMenu);
  1636.   Item.Caption := '-';
  1637.   FSysPopupMenu.Items.Add(Item);
  1638.   Item := TMenuItem.Create(FSysPopupMenu);
  1639.   with Item do
  1640.   begin
  1641.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  1642.     then
  1643.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_SELECTALL')
  1644.     else
  1645.       Caption := BS_Edit_SelectAll;
  1646.     Enabled := not IsFullSelected;
  1647.     OnClick := DoSelectAll;
  1648.   end;
  1649.   FSysPopupMenu.Items.Add(Item);
  1650. end;
  1651. procedure TbsSkinMemo.CMEnabledChanged;
  1652. begin
  1653.   inherited;
  1654.   UpDateScrollRange;
  1655.   if Enabled
  1656.   then
  1657.     begin
  1658.       if FIndex = -1
  1659.       then Font.Color := FDefaultFont.Color
  1660.       else Font.Color := FontColor;
  1661.     end
  1662.   else
  1663.     begin
  1664.       if FIndex = -1
  1665.       then Font.Color := clGrayText
  1666.       else Font.Color := clGrayText;
  1667.     end;
  1668. end;
  1669. procedure TbsSkinMemo.SetDefaultFont;
  1670. begin
  1671.   FDefaultFont.Assign(Value);
  1672.   if FIndex = -1 then Font.Assign(Value);
  1673. end;
  1674. procedure TbsSkinMemo.OnDefaultFontChange(Sender: TObject);
  1675. begin
  1676.   if FIndex = -1 then Font.Assign(FDefaultFont);
  1677. end;
  1678. procedure TbsSkinMemo.SetBitMapBG;
  1679. begin
  1680.   FBitMapBG := Value;
  1681.   ReCreateWnd;
  1682. end;
  1683. procedure TbsSkinMemo.WMSize;
  1684. begin
  1685.   inherited;
  1686.   UpDateScrollRange;
  1687.   if not FBitMapBG
  1688.   then
  1689.     SendMessage(Handle, WM_NCPAINT, 0, 0);
  1690. end;
  1691. procedure TbsSkinMemo.Invalidate;
  1692. begin
  1693.   if FBitMapBG
  1694.   then
  1695.     begin
  1696.       if Parent = nil then Exit;
  1697.       RedrawWindow(Handle, nil, 0, RDW_FRAME + RDW_INVALIDATE);
  1698.     end
  1699.   else
  1700.     begin
  1701.       inherited;
  1702.     end;
  1703. end;
  1704. procedure TbsSkinMemo.Change;
  1705. begin
  1706.   inherited;
  1707.   UpDateScrollRange;
  1708. end;
  1709. procedure TbsSkinMemo.WMVSCROLL;
  1710. begin
  1711.   inherited;
  1712.   UpDateScrollRange;
  1713. end;
  1714. procedure TbsSkinMemo.WMHSCROLL;
  1715. begin
  1716.   inherited;
  1717. end;
  1718. procedure TbsSkinMemo.WMLBUTTONDOWN;
  1719. begin
  1720.   inherited;
  1721.   FDown := True;
  1722. end;
  1723. procedure TbsSkinMemo.WMLBUTTONUP;
  1724. begin
  1725.   inherited;
  1726.   if FDown
  1727.   then
  1728.     begin
  1729.       UpDateScrollRange;
  1730.       FDown := False;
  1731.     end;  
  1732. end;
  1733. procedure TbsSkinMemo.WMMOUSEMOVE;
  1734. begin
  1735.   inherited;
  1736.   if FDown then UpDateScrollRange;
  1737. end;
  1738. procedure TbsSkinMemo.SetVScrollBar;
  1739. begin
  1740.   FVScrollBar := Value;
  1741.   FVScrollBar.Min := 0;
  1742.   FVScrollBar.Max := 0;
  1743.   FVScrollBar.Position := 0;
  1744.   if FVScrollBar <> nil then FVScrollBar.OnChange := OnVScrollBarChange;
  1745.   UpDateScrollRange;
  1746. end;
  1747. procedure TbsSkinMemo.OnVScrollBarChange(Sender: TObject);
  1748. begin
  1749.   SendMessage(Handle, WM_VSCROLL,
  1750.     MakeWParam(SB_THUMBPOSITION, FVScrollBar.Position), 0);
  1751.   Invalidate;
  1752. end;
  1753. procedure TbsSkinMemo.UpDateScrollRange;
  1754. function GetVisibleLines: Integer;
  1755. var
  1756.   R: TRect;
  1757.   C: TCanvas;
  1758.   DC: HDC;
  1759.   LineHeight: Integer;
  1760. begin
  1761.   C := TCanvas.Create;
  1762.   C.Font.Assign(Font);
  1763.   DC := GetDC(0);
  1764.   C.Handle := DC;
  1765.   R := GetClientRect;
  1766.   LineHeight := C.TextHeight('Wq');
  1767.   if LineHeight <> 0
  1768.   then
  1769.     Result := RectHeight(R) div LineHeight
  1770.   else
  1771.     Result := 1;
  1772.   ReleaseDC(0, DC);
  1773.   C.Free;
  1774. end;
  1775. var
  1776.   LinesCount: Integer;
  1777.   VisibleLines, Pos: Integer;
  1778.   P: PPoint;
  1779.   X: Integer;
  1780.   R: TRect;
  1781. begin
  1782.   if FVScrollBar <> nil
  1783.   then
  1784.   if not Enabled
  1785.   then
  1786.     FVScrollBar.Enabled := False
  1787.   else
  1788.   with FVScrollBar do
  1789.   begin
  1790.     VisibleLines := GetVisibleLines;
  1791.     LinesCount := SendMessage(Self.Handle, EM_GETLINECOUNT, 0, 0);
  1792.     Pos := SendMessage(Self.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
  1793.     if LinesCount > VisibleLines
  1794.     then
  1795.       begin
  1796.         SetRange(0, LinesCount, Pos, VisibleLines + 1);
  1797.         if not Enabled then Enabled := True;
  1798.       end
  1799.     else
  1800.       begin
  1801.         SetRange(0, 0, 0, 0);
  1802.         if Enabled then Enabled := False;
  1803.       end;
  1804.   end;
  1805. end;
  1806. procedure TbsSkinMEmo.WMMove;
  1807. begin
  1808.   inherited;
  1809. end;
  1810. procedure TbsSkinMemo.WMCut(var Message: TMessage);
  1811. begin
  1812.   if FReadOnly then Exit;
  1813.   inherited;
  1814.   if FBitMapBG then Invalidate;
  1815.   UpDateScrollRange;
  1816. end;
  1817. procedure TbsSkinMemo.WMPaste(var Message: TMessage);
  1818. begin
  1819.   if FReadOnly then Exit;
  1820.   inherited;
  1821.   if FBitMapBG then Invalidate;
  1822.   UpDateScrollRange;
  1823. end;
  1824. procedure TbsSkinMemo.WMClear(var Message: TMessage);
  1825. begin
  1826.   if FReadOnly then Exit;
  1827.   inherited;
  1828.   if FBitMapBG then Invalidate;
  1829.   UpDateScrollRange;
  1830. end;
  1831. procedure TbsSkinMemo.WMUndo(var Message: TMessage);
  1832. begin
  1833.   if FReadOnly then Exit;
  1834.   inherited;
  1835.   if FBitMapBG then Invalidate;
  1836.   UpDateScrollRange;
  1837. end;
  1838. procedure TbsSkinMemo.WMSetText(var Message:TWMSetText);
  1839. begin
  1840.   inherited;
  1841.   if FBitMapBG then Invalidate;
  1842.   UpDateScrollRange;
  1843. end;
  1844. procedure TbsSkinMemo.WMMOUSEWHEEL;
  1845. var
  1846.   LParam, WParam: Integer;
  1847. begin
  1848.   LParam := 0;
  1849.   if Message.WParam > 0
  1850.   then
  1851.     WParam := MakeWParam(SB_LINEUP, 0)
  1852.   else
  1853.     WParam := MakeWParam(SB_LINEDOWN, 0);
  1854.   SendMessage(Handle, WM_VSCROLL, WParam, LParam);
  1855.   if FBitMapBG then Invalidate;
  1856. end;
  1857. procedure TbsSkinMemo.WMCHAR(var Message:TMessage);
  1858. begin
  1859.   if not FReadOnly or (FReadOnly and (TWMCHar(Message).CharCode = 3))
  1860.   then
  1861.     inherited;
  1862.   UpDateScrollRange;
  1863. end;
  1864. procedure TbsSkinMemo.WMKeyDown(var Message: TWMKeyDown);
  1865. begin
  1866.   if FReadOnly and (TWMCHar(Message).CharCode = VK_DELETE) then Exit;
  1867.   inherited;
  1868.   if FBitMapBG then Invalidate;
  1869.   UpDateScrollRange;
  1870. end;
  1871. procedure TbsSkinMemo.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  1872. begin
  1873.   if FBitMapBG then Invalidate else inherited;
  1874. end;
  1875. procedure TbsSkinMemo.CNCtlColorStatic;
  1876. begin
  1877.  if FBitMapBG
  1878.  then
  1879.     with Message do
  1880.     begin
  1881.       SetBkMode(ChildDC, Windows.Transparent);
  1882.       SetTextColor(ChildDC, Font.Color);
  1883.       Result := GetStockObject(NULL_BRUSH);
  1884.     end
  1885.   else
  1886.     inherited;
  1887. end;
  1888. procedure TbsSkinMemo.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
  1889. begin
  1890.   if FBitMapBG
  1891.   then
  1892.   with Message do
  1893.   begin
  1894.     SetBkMode(ChildDC, Windows.Transparent);
  1895.     SetTextColor(ChildDC, Font.Color);
  1896.     Result := GetStockObject(NULL_BRUSH);
  1897.   end
  1898.   else
  1899.     inherited;
  1900. end;
  1901. procedure TbsSkinMemo.WMNCCALCSIZE;
  1902. begin
  1903.   GetSkinData;
  1904.   if FIndex = -1
  1905.   then
  1906.     with Message.CalcSize_Params^.rgrc[0] do
  1907.     begin
  1908.       Inc(Left, 2);
  1909.       Inc(Top, 2);
  1910.       Dec(Right, 2);
  1911.       Dec(Bottom, 2);
  1912.     end
  1913.   else
  1914.     with Message.CalcSize_Params^.rgrc[0] do
  1915.     begin
  1916.       Inc(Left, ClRect.Left);
  1917.       Inc(Top, ClRect.Top);
  1918.       Dec(Right, RectWidth(SkinRect) - ClRect.Right);
  1919.       Dec(Bottom, RectHeight(SkinRect) - ClRect.Bottom);
  1920.     end;
  1921. end;
  1922. procedure TbsSkinMemo.CreateParams(var Params: TCreateParams);
  1923. begin
  1924.   inherited CreateParams(Params);
  1925.   with Params do
  1926.   begin
  1927.     ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
  1928.     ExStyle := Exstyle and not WS_EX_Transparent;
  1929.     Style := Style and not WS_BORDER or ES_MULTILINE;
  1930.     Style := Style and not WS_VSCROLL and not WS_HSCROLL;
  1931.     WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  1932.   end;
  1933. end;
  1934. procedure TbsSkinMemo.SkinNCPaint(C: TCanvas);
  1935. var
  1936.   B: TBitMap;
  1937.   R: TRect;
  1938.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  1939.   NewClRect: TRect;
  1940.   OffX, OffY: Integer;
  1941. begin
  1942.   GetSkinData;
  1943.   B := TBitMap.Create;
  1944.   B.Width := Width;
  1945.   B.Height := Height;
  1946.   //
  1947.   if FIndex = -1
  1948.   then
  1949.     with B.Canvas do
  1950.     begin
  1951.       Brush.Color := clWindow;
  1952.       R := Rect(0, 0, Width, Height);
  1953.       Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  1954.       Frame3D(B.Canvas, R, clBtnFace, clBtnFace, 1);
  1955.     end
  1956.     else
  1957.       begin
  1958.         OffX := Width - RectWidth(SkinRect);
  1959.         OffY := Height - RectHeight(SkinRect);
  1960.         NewLTPoint := LTPoint;
  1961.         NewRTPoint := Point(RTPoint.X + OffX, RTPoint.Y);
  1962.         NewLBPoint := Point(LBPoint.X, LBPoint.Y + OffY);
  1963.         NewRBPoint := Point(RBPoint.X + OffX, RBPoint.Y + OffY);
  1964.         NewClRect := Rect(ClRect.Left, ClRect.Top,
  1965.                           ClRect.Right + OffX, ClRect.Bottom + OffY);
  1966.         if FMouseIn or Focused
  1967.         then
  1968.           CreateSkinImage(LTPoint, RTPoint, LBPoint, RBPoint, CLRect,
  1969.             NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  1970.             B, Picture, ActiveSkinRect, Width, Height, True)
  1971.         else
  1972.           CreateSkinImage(LTPoint, RTPoint, LBPoint, RBPoint, CLRect,
  1973.             NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  1974.             B, Picture, SkinRect, Width, Height, True);
  1975.       end;
  1976.   C.Draw(0, 0, B);
  1977.   B.Free;
  1978. end;
  1979. procedure TbsSkinMemo.SkinFramePaint(C: TCanvas);
  1980. var
  1981.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  1982.   R, NewClRect: TRect;
  1983.   LeftB, TopB, RightB, BottomB: TBitMap;
  1984.   OffX, OffY: Integer;
  1985. begin
  1986.   GetSkinData;
  1987.   if FIndex = -1
  1988.   then
  1989.     with C do
  1990.     begin
  1991.       Brush.Style := bsClear;
  1992.       R := Rect(0, 0, Width, Height);
  1993.       Frame3D(C, R, clBtnShadow, clBtnShadow, 1);
  1994.       Frame3D(C, R, clBtnFace, clBtnFace, 1);
  1995.       Exit;
  1996.     end;
  1997.   LeftB := TBitMap.Create;
  1998.   TopB := TBitMap.Create;
  1999.   RightB := TBitMap.Create;
  2000.   BottomB := TBitMap.Create;
  2001.   OffX := Width - RectWidth(SkinRect);
  2002.   OffY := Height - RectHeight(SkinRect);
  2003.   NewLTPoint := LTPoint;
  2004.   NewRTPoint := Point(RTPoint.X + OffX, RTPoint.Y);
  2005.   NewLBPoint := Point(LBPoint.X, LBPoint.Y + OffY);
  2006.   NewRBPoint := Point(RBPoint.X + OffX, RBPoint.Y + OffY);
  2007.   NewClRect := Rect(ClRect.Left, ClRect.Top,
  2008.                     ClRect.Right + OffX, ClRect.Bottom + OffY);
  2009.   if FMouseIn or Focused
  2010.   then
  2011.     CreateSkinBorderImages(LTPoint, RTPoint, LBPoint, RBPoint, CLRect,
  2012.       NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  2013.       LeftB, TopB, RightB, BottomB, Picture, ActiveSkinRect, Width, Height,
  2014.       False, False, False, False)
  2015.   else
  2016.     CreateSkinBorderImages(LTPoint, RTPoint, LBPoint, RBPoint, CLRect,
  2017.       NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  2018.       LeftB, TopB, RightB, BottomB, Picture, SkinRect, Width, Height,
  2019.       False, False, False, False);
  2020.   C.Draw(0, 0, TopB);
  2021.   C.Draw(0, TopB.Height, LeftB);
  2022.   C.Draw(Width - RightB.Width, TopB.Height, RightB);
  2023.   C.Draw(0, Height - BottomB.Height, BottomB);
  2024.   TopB.Free;
  2025.   LeftB.Free;
  2026.   RightB.Free;
  2027.   BottomB.Free;
  2028. end;
  2029. procedure TbsSkinMemo.WMNCPAINT;
  2030. var
  2031.   DC: HDC;
  2032.   C: TCanvas;
  2033.   R: TRect;
  2034.   kf: Double;
  2035. begin
  2036.   DC := GetWindowDC(Handle);
  2037.   C := TControlCanvas.Create;
  2038.   C.Handle := DC;
  2039.   try
  2040.     if FBitMapBG
  2041.     then
  2042.       SkinNCPaint(C)
  2043.     else
  2044.       SkinFramePaint(C);
  2045.   finally
  2046.     C.Free;
  2047.     ReleaseDC(Handle, DC);
  2048.   end;
  2049. end;
  2050. destructor TbsSkinMemo.Destroy;
  2051. begin
  2052.   FDefaultFont.Free;
  2053.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  2054.   inherited;
  2055. end;
  2056. procedure TbsSkinMemo.WMSETFOCUS;
  2057. begin
  2058.   inherited;
  2059.   if not FMouseIn and (FIndex <> -1)
  2060.   then
  2061.     begin
  2062.       Font.Color := ActiveFontColor;
  2063.       if not FBitMapBG then Color := ActiveBGColor;
  2064.       Invalidate;
  2065.     end;
  2066.   if not FBitMapBG
  2067.   then
  2068.     SendMessage(Handle, WM_NCPAINT, 0, 0);
  2069. end;
  2070. procedure TbsSkinMemo.WMKILLFOCUS;
  2071. begin
  2072.   inherited;
  2073.   if not FMouseIn and (FIndex <> -1)
  2074.   then
  2075.     begin
  2076.       Font.Color := FontColor;
  2077.       if not FBitMapBG then Color := BGColor;
  2078.       Invalidate;
  2079.     end;
  2080.   if not FBitMapBG
  2081.   then
  2082.     SendMessage(Handle, WM_NCPAINT, 0, 0);
  2083. end;
  2084. procedure TbsSkinMemo.CMMouseEnter;
  2085. begin
  2086.   inherited;
  2087.   FMouseIn := True;
  2088.   if not Focused and (FIndex <> -1)
  2089.   then
  2090.     begin
  2091.       Font.Color := ActiveFontColor;
  2092.       if not FBitMapBG then Color := ActiveBGColor;
  2093.       Invalidate;
  2094.     end;
  2095.   if not FBitMapBG
  2096.   then
  2097.     SendMessage(Handle, WM_NCPAINT, 0, 0);
  2098. end;
  2099. procedure TbsSkinMemo.CMMouseLeave;
  2100. begin
  2101.   inherited;
  2102.   FMouseIn := False;
  2103.   if not Focused and (FIndex <> -1)
  2104.   then
  2105.     begin
  2106.       Font.Color := FontColor;
  2107.       if not FBitMapBG then Color := BGColor;
  2108.       Invalidate;
  2109.     end;
  2110.   if not FBitMapBG
  2111.   then
  2112.     SendMessage(Handle, WM_NCPAINT, 0, 0);
  2113. end;
  2114. procedure TbsSkinMemo.GetSkinData;
  2115. begin
  2116.   if FSD = nil
  2117.   then
  2118.     begin
  2119.       FIndex := -1;
  2120.       Exit;
  2121.     end;
  2122.   if FSD.Empty
  2123.   then
  2124.     FIndex := -1
  2125.   else
  2126.     FIndex := FSD.GetControlIndex(FSkinDataName);
  2127.   if FIndex <> -1
  2128.   then
  2129.     if TbsDataSkinControl(FSD.CtrlList.Items[FIndex]) is TbsDataSkinMemoControl
  2130.     then
  2131.       with TbsDataSkinMemoControl(FSD.CtrlList.Items[FIndex]) do
  2132.       begin
  2133.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  2134.         then
  2135.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  2136.         else
  2137.           Picture := nil;
  2138.         Self.SkinRect := SkinRect;
  2139.         Self.ActiveSkinRect := ActiveSkinRect;
  2140.         if isNullRect(ActiveSkinRect)
  2141.         then
  2142.           Self.ActiveSkinRect := SkinRect;
  2143.         Self.LTPoint := LTPoint;
  2144.         Self.RTPoint := RTPoint;
  2145.         Self.LBPoint := LBPoint;
  2146.         Self.RBPoint := RBPoint;
  2147.         Self.ClRect := ClRect;
  2148.         Self.FontName := FontName;
  2149.         Self.FontStyle := FontStyle;
  2150.         Self.FontHeight := FontHeight;
  2151.         Self.FontColor := FontColor;
  2152.         Self.ActiveFontColor := ActiveFontColor;
  2153.         Self.BGColor := BGColor;
  2154.         Self.ActiveBGColor := ActiveBGColor;
  2155.       end;
  2156. end;
  2157. procedure TbsSkinMemo.SetSkinData;
  2158. begin
  2159.   FSD := Value;
  2160.   if (FSD <> nil) then
  2161.   if not FSD.Empty and not (csDesigning in ComponentState)
  2162.   then
  2163.     ChangeSkinData;
  2164. end;
  2165. procedure TbsSkinMemo.Notification;
  2166. begin
  2167.   inherited Notification(AComponent, Operation);
  2168.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  2169.   if (Operation = opRemove) and (AComponent = FVScrollBar)
  2170.   then FVScrollBar := nil;
  2171. end;
  2172. procedure TbsSkinMemo.ChangeSkinData;
  2173. begin
  2174.   GetSkinData;
  2175.   //
  2176.   if FIndex <> -1
  2177.   then
  2178.     begin
  2179.       if FUseSkinFont
  2180.       then
  2181.         begin
  2182.           Font.Name := FontName;
  2183.           Font.Style := FontStyle;
  2184.           Font.Height := FontHeight;
  2185.           if Focused
  2186.           then
  2187.             Font.Color := ActiveFontColor
  2188.           else
  2189.             Font.Color := FontColor;
  2190.         end
  2191.       else
  2192.         begin
  2193.           Font.Assign(FDefaultFont);
  2194.           if Focused
  2195.           then
  2196.             Font.Color := ActiveFontColor
  2197.           else
  2198.             Font.Color := FontColor;
  2199.         end;
  2200.       Color := BGColor;
  2201.     end
  2202.   else
  2203.     Font.Assign(FDefaultFont);
  2204.   //
  2205.   if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2206.   then
  2207.     Font.Charset := SkinData.ResourceStrData.CharSet
  2208.   else
  2209.     Font.CharSet := FDefaultFont.CharSet;
  2210.   //
  2211.   UpDateScrollRange;
  2212.   ReCreateWnd;
  2213.   if FVScrollBar <> nil then FVScrollBar.Align := FVScrollBar.Align;
  2214.   if Enabled
  2215.   then
  2216.     begin
  2217.       if FIndex = -1
  2218.       then Font.Color := FDefaultFont.Color
  2219.       else Font.Color := FontColor;
  2220.     end
  2221.   else
  2222.     begin
  2223.       if FIndex = -1
  2224.       then Font.Color := clGrayText
  2225.       else Font.Color := clGrayText;
  2226.     end;
  2227. end;
  2228. constructor TbsSkinMemo2.Create;
  2229. begin
  2230.   inherited Create(AOwner);
  2231.   AutoSize := False;
  2232.   FIndex := -1;
  2233.   Font.Name := 'Arial';
  2234.   Font.Height := 14;
  2235.   FVScrollBar := nil;
  2236.   FHScrollBar := nil;
  2237.   FDown := False;
  2238.   FSkinDataName := 'memo';
  2239.   FDefaultFont := TFont.Create;
  2240.   FDefaultFont.OnChange := OnDefaultFontChange;
  2241.   FDefaultFont.Assign(Font);
  2242.   ScrollBars := ssBoth;
  2243.   FUseSkinFont := True;
  2244.   FSysPopupMenu := nil;
  2245. end;
  2246. procedure TbsSkinMemo2.WMAFTERDISPATCH;
  2247. begin
  2248.   if FSysPopupMenu <> nil
  2249.   then
  2250.     begin
  2251.       FSysPopupMenu.Free;
  2252.       FSysPopupMenu := nil;
  2253.     end;
  2254. end;
  2255. procedure TbsSkinMemo2.WMCONTEXTMENU;
  2256. var
  2257.   X, Y: Integer;
  2258.   P: TPoint;
  2259. begin
  2260.   if PopupMenu <> nil
  2261.   then
  2262.     inherited
  2263.   else
  2264.     begin
  2265.       CreateSysPopupMenu;
  2266.       X := Message.XPos;
  2267.       Y := Message.YPos;
  2268.       if (X < 0) or (Y < 0)
  2269.       then
  2270.         begin
  2271.           X := Width div 2;
  2272.           Y := Height div 2;
  2273.           P := Point(0, 0);
  2274.           P := ClientToScreen(P);
  2275.           X := X + P.X;
  2276.           Y := Y + P.Y;
  2277.         end;
  2278.       if FSysPopupMenu <> nil
  2279.       then
  2280.         FSysPopupMenu.Popup2(Self, X, Y)
  2281.     end;
  2282. end;
  2283. procedure TbsSkinMemo2.DoUndo;
  2284. begin
  2285.   Undo;
  2286. end;
  2287. procedure TbsSkinMemo2.DoCut;
  2288. begin
  2289.   CutToClipboard;
  2290. end;
  2291. procedure TbsSkinMemo2.DoCopy;
  2292. begin
  2293.   CopyToClipboard;
  2294. end;
  2295. procedure TbsSkinMemo2.DoPaste;
  2296. begin
  2297.   PasteFromClipboard;
  2298. end;
  2299. procedure TbsSkinMemo2.DoDelete;
  2300. begin
  2301.   ClearSelection;
  2302. end;
  2303. procedure TbsSkinMemo2.DoSelectAll;
  2304. begin
  2305.   SelectAll;
  2306. end;
  2307. procedure TbsSkinMemo2.CreateSysPopupMenu;
  2308. function IsSelected: Boolean;
  2309. begin
  2310.   Result := GetSelLength > 0;
  2311. end;
  2312. function IsFullSelected: Boolean;
  2313. begin
  2314.   Result := GetSelText = Text;
  2315. end;
  2316. var
  2317.   Item: TMenuItem;
  2318. begin
  2319.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  2320.   FSysPopupMenu := TbsSkinPopupMenu.Create(Self);
  2321.   FSysPopupMenu.ComponentForm := TForm(GetParentForm(Self));
  2322.   Item := TMenuItem.Create(FSysPopupMenu);
  2323.   with Item do
  2324.   begin
  2325.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2326.     then
  2327.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_UNDO')
  2328.     else
  2329.       Caption := BS_Edit_Undo;
  2330.     OnClick := DoUndo;
  2331.     Enabled := Self.CanUndo;
  2332.   end;
  2333.   FSysPopupMenu.Items.Add(Item);
  2334.   Item := TMenuItem.Create(FSysPopupMenu);
  2335.   Item.Caption := '-';
  2336.   FSysPopupMenu.Items.Add(Item);
  2337.   Item := TMenuItem.Create(FSysPopupMenu);
  2338.   with Item do
  2339.   begin
  2340.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2341.     then
  2342.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_CUT')
  2343.     else
  2344.       Caption := BS_Edit_Cut;
  2345.     Enabled := IsSelected and not Self.ReadOnly;
  2346.     OnClick := DoCut;
  2347.   end;
  2348.   FSysPopupMenu.Items.Add(Item);
  2349.   Item := TMenuItem.Create(FSysPopupMenu);
  2350.   with Item do
  2351.   begin
  2352.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2353.     then
  2354.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_COPY')
  2355.     else
  2356.       Caption := BS_Edit_Copy;
  2357.     Enabled := IsSelected;
  2358.     OnClick := DoCopy;
  2359.   end;
  2360.   FSysPopupMenu.Items.Add(Item);
  2361.   Item := TMenuItem.Create(FSysPopupMenu);
  2362.   with Item do
  2363.   begin
  2364.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2365.     then
  2366.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_PASTE')
  2367.     else
  2368.       Caption := BS_Edit_Paste;
  2369.     Enabled := (ClipBoard.AsText <> '') and not ReadOnly;
  2370.     OnClick := DoPaste;
  2371.   end;
  2372.   FSysPopupMenu.Items.Add(Item);
  2373.   Item := TMenuItem.Create(FSysPopupMenu);
  2374.   with Item do
  2375.   begin
  2376.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2377.     then
  2378.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_DELETE')
  2379.     else
  2380.       Caption := BS_Edit_Delete;
  2381.     Enabled := IsSelected and not Self.ReadOnly;
  2382.     OnClick := DoDelete;
  2383.   end;
  2384.   FSysPopupMenu.Items.Add(Item);
  2385.   Item := TMenuItem.Create(FSysPopupMenu);
  2386.   Item.Caption := '-';
  2387.   FSysPopupMenu.Items.Add(Item);
  2388.   Item := TMenuItem.Create(FSysPopupMenu);
  2389.   with Item do
  2390.   begin
  2391.     if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2392.     then
  2393.       Caption := SkinData.ResourceStrData.GetResStr('EDIT_SELECTALL')
  2394.     else
  2395.       Caption := BS_Edit_SelectAll;
  2396.     Enabled := not IsFullSelected;
  2397.     OnClick := DoSelectAll;
  2398.   end;
  2399.   FSysPopupMenu.Items.Add(Item);
  2400. end;
  2401. procedure TbsSkinMemo2.CMEnabledChanged;
  2402. begin
  2403.   inherited;
  2404.   UpDateScrollRange;
  2405. end;
  2406. procedure TbsSkinMemo2.SetDefaultFont;
  2407. begin
  2408.   FDefaultFont.Assign(Value);
  2409.   if FIndex = -1 then Font.Assign(Value);
  2410. end;
  2411. procedure TbsSkinMemo2.OnDefaultFontChange(Sender: TObject);
  2412. begin
  2413.   if FIndex = -1 then Font.Assign(FDefaultFont);
  2414. end;
  2415. procedure TbsSkinMemo2.WMSize;
  2416. begin
  2417.   inherited;
  2418.   UpDateScrollRange;
  2419. end;
  2420. procedure TbsSkinMemo2.Invalidate;
  2421. begin
  2422.   inherited;
  2423. end;
  2424. procedure TbsSkinMemo2.Change;
  2425. begin
  2426.   inherited;
  2427.   UpDateScrollRange;
  2428. end;
  2429. procedure TbsSkinMemo2.WMVSCROLL;
  2430. begin
  2431.   inherited;
  2432.   UpDateScrollRange;
  2433. end;
  2434. procedure TbsSkinMemo2.WMHSCROLL;
  2435. begin
  2436.   inherited;
  2437.   UpDateScrollRange;
  2438. end;
  2439. procedure TbsSkinMemo2.WMLBUTTONDOWN;
  2440. begin
  2441.   inherited;
  2442.   FDown := True;
  2443. end;
  2444. procedure TbsSkinMemo2.WMLBUTTONUP;
  2445. begin
  2446.   inherited;
  2447.   if FDown
  2448.   then
  2449.     begin
  2450.       UpDateScrollRange;
  2451.       FDown := False;
  2452.     end;  
  2453. end;
  2454. procedure TbsSkinMemo2.WMMOUSEMOVE;
  2455. begin
  2456.   inherited;
  2457.   if FDown then UpDateScrollRange;
  2458. end;
  2459. procedure TbsSkinMemo2.SetVScrollBar;
  2460. begin
  2461.   FVScrollBar := Value;
  2462.   FVScrollBar.Min := 0;
  2463.   FVScrollBar.Max := 0;
  2464.   FVScrollBar.Position := 0;
  2465.   if FVScrollBar <> nil then FVScrollBar.OnChange := OnVScrollBarChange;
  2466.   UpDateScrollRange;
  2467. end;
  2468. procedure TbsSkinMemo2.OnVScrollBarChange(Sender: TObject);
  2469. begin
  2470.   SendMessage(Handle, WM_VSCROLL,
  2471.     MakeWParam(SB_THUMBPOSITION, FVScrollBar.Position), 0);
  2472.   Invalidate;
  2473. end;
  2474. procedure TbsSkinMemo2.SetHScrollBar;
  2475. begin
  2476.   FHScrollBar := Value;
  2477.   FHScrollBar.Min := 0;
  2478.   FHScrollBar.Max := 0;
  2479.   FHScrollBar.Position := 0;
  2480.   if FHScrollBar <> nil then FHScrollBar.OnChange := OnHScrollBarChange;
  2481.   UpDateScrollRange;
  2482. end;
  2483. procedure TbsSkinMemo2.OnHScrollBarChange(Sender: TObject);
  2484. begin
  2485.   SendMessage(Handle, WM_HSCROLL,
  2486.     MakeWParam(SB_THUMBPOSITION, FHScrollBar.Position), 0);
  2487.   Invalidate;
  2488. end;
  2489. procedure TbsSkinMemo2.UpDateScrollRange;
  2490. function GetVisibleLines: Integer;
  2491. var
  2492.   R: TRect;
  2493.   C: TCanvas;
  2494.   DC: HDC;
  2495.   LineHeight: Integer;
  2496. begin
  2497.   C := TCanvas.Create;
  2498.   C.Font.Assign(Font);
  2499.   DC := GetDC(0);
  2500.   C.Handle := DC;
  2501.   R := GetClientRect;
  2502.   LineHeight := C.TextHeight('Wq');
  2503.   if LineHeight <> 0
  2504.   then
  2505.     Result := RectHeight(R) div LineHeight
  2506.   else
  2507.     Result := 1;
  2508.   ReleaseDC(0, DC);
  2509.   C.Free;
  2510. end;
  2511. var
  2512.   SMin, SMax, SPos, SPage: Integer;
  2513. begin
  2514.   if FVScrollBar <> nil
  2515.   then
  2516.   if not Enabled
  2517.   then
  2518.     FVScrollBar.Enabled := False
  2519.   else
  2520.   with FVScrollBar do
  2521.   begin
  2522.     SPage := GetVisibleLines;
  2523.     SPos := GetScrollPos(Self.Handle, SB_VERT);
  2524.     GetScrollRange(Self.Handle, SB_VERT, SMin, SMax);
  2525.     if SMax > SPage
  2526.     then
  2527.       begin
  2528.         SetRange(0, SMax, SPos, SPage + 1);
  2529.         if not Enabled then Enabled := True;
  2530.       end
  2531.     else
  2532.       begin
  2533.         SetRange(0, 0, 0, 0);
  2534.         if Enabled then Enabled := False;
  2535.       end;
  2536.   end;
  2537.   if FHScrollBar <> nil
  2538.   then
  2539.   if not Enabled
  2540.   then
  2541.     FHScrollBar.Enabled := False
  2542.   else
  2543.   with FHScrollBar do
  2544.   begin
  2545.     SPage := Width;
  2546.     SPos := GetScrollPos(Self.Handle, SB_HORZ);
  2547.     GetScrollRange(Self.Handle, SB_HORZ, SMin, SMax);
  2548.     if SMax > SPage
  2549.     then
  2550.       begin
  2551.         SetRange(0, SMax, SPos, SPage + 1);
  2552.         if not Enabled then Enabled := True;
  2553.       end
  2554.     else
  2555.       begin
  2556.         SetRange(0, 0, 0, 0);
  2557.         if Enabled then Enabled := False;
  2558.       end;
  2559.   end;
  2560. end;
  2561. procedure TbsSkinMemo2.WMMove;
  2562. begin
  2563.   inherited;
  2564. end;
  2565. procedure TbsSkinMemo2.WMCut(var Message: TMessage);
  2566. begin
  2567.   inherited;
  2568.   UpDateScrollRange;
  2569. end;
  2570. procedure TbsSkinMemo2.WMPaste(var Message: TMessage);
  2571. begin
  2572.   inherited;
  2573.   UpDateScrollRange;
  2574. end;
  2575. procedure TbsSkinMemo2.WMClear(var Message: TMessage);
  2576. begin
  2577.   inherited;
  2578.   UpDateScrollRange;
  2579. end;
  2580. procedure TbsSkinMemo2.WMUndo(var Message: TMessage);
  2581. begin
  2582.   inherited;
  2583.   UpDateScrollRange;
  2584. end;
  2585. procedure TbsSkinMemo2.WMSetText(var Message:TWMSetText);
  2586. begin
  2587.   inherited;
  2588.   UpDateScrollRange;
  2589. end;
  2590. procedure TbsSkinMemo2.WMMOUSEWHEEL;
  2591. var
  2592.   LParam, WParam: Integer;
  2593. begin
  2594.   LParam := 0;
  2595.   if Message.WParam > 0
  2596.   then
  2597.     WParam := MakeWParam(SB_LINEUP, 0)
  2598.   else
  2599.     WParam := MakeWParam(SB_LINEDOWN, 0);
  2600.   SendMessage(Handle, WM_VSCROLL, WParam, LParam);
  2601. end;
  2602. procedure TbsSkinMemo2.WMCHAR(var Message:TMessage);
  2603. begin
  2604.   inherited;
  2605.   UpDateScrollRange;
  2606. end;
  2607. procedure TbsSkinMemo2.WMKeyDown(var Message: TWMKeyDown);
  2608. begin
  2609.   inherited;
  2610.   UpDateScrollRange;
  2611. end;
  2612. procedure TbsSkinMemo2.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  2613. begin
  2614.   inherited;
  2615. end;
  2616. procedure TbsSkinMemo2.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
  2617. begin
  2618.   inherited;
  2619. end;
  2620. procedure TbsSkinMemo2.WMNCCALCSIZE;
  2621. begin
  2622.  
  2623. end;
  2624. procedure TbsSkinMemo2.CreateParams(var Params: TCreateParams);
  2625. begin
  2626.   inherited CreateParams(Params);
  2627.   with Params do
  2628.   begin
  2629.     ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
  2630.     Style := Style and not WS_BORDER;
  2631.     WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  2632.   end;
  2633. end;
  2634. destructor TbsSkinMemo2.Destroy;
  2635. begin
  2636.   FDefaultFont.Free;
  2637.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  2638.   inherited;
  2639. end;
  2640. procedure TbsSkinMemo2.WMSETFOCUS;
  2641. begin
  2642.   inherited;
  2643.   if not FMouseIn and (FIndex <> -1)
  2644.   then
  2645.     begin
  2646.       Font.Color := ActiveFontColor;
  2647.       Color := ActiveBGColor;
  2648.     end;
  2649. end;
  2650. procedure TbsSkinMemo2.WMKILLFOCUS;
  2651. begin
  2652.   inherited;
  2653.   if not FMouseIn and (FIndex <> -1)
  2654.   then
  2655.     begin
  2656.       Font.Color := FontColor;
  2657.       Color := BGColor;
  2658.     end;
  2659. end;
  2660. procedure TbsSkinMemo2.CMMouseEnter;
  2661. begin
  2662.   inherited;
  2663.   FMouseIn := True;
  2664.   if not Focused and (FIndex <> -1)
  2665.   then
  2666.     begin
  2667.       Font.Color := ActiveFontColor;
  2668.       Color := ActiveBGColor;
  2669.     end;
  2670. end;
  2671. procedure TbsSkinMemo2.CMMouseLeave;
  2672. begin
  2673.   inherited;
  2674.   FMouseIn := False;
  2675.   if not Focused and (FIndex <> -1)
  2676.   then
  2677.     begin
  2678.       Font.Color := FontColor;
  2679.       Color := BGColor;
  2680.     end;
  2681. end;
  2682. procedure TbsSkinMemo2.GetSkinData;
  2683. begin
  2684.   if FSD = nil
  2685.   then
  2686.     begin
  2687.       FIndex := -1;
  2688.       Exit;
  2689.     end;
  2690.   if FSD.Empty
  2691.   then
  2692.     FIndex := -1
  2693.   else
  2694.     FIndex := FSD.GetControlIndex(FSkinDataName);
  2695.   if FIndex <> -1
  2696.   then
  2697.     if TbsDataSkinControl(FSD.CtrlList.Items[FIndex]) is TbsDataSkinMemoControl
  2698.     then
  2699.       with TbsDataSkinMemoControl(FSD.CtrlList.Items[FIndex]) do
  2700.       begin
  2701.         Self.FontName := FontName;
  2702.         Self.FontStyle := FontStyle;
  2703.         Self.FontHeight := FontHeight;
  2704.         Self.FontColor := FontColor;
  2705.         Self.ActiveFontColor := ActiveFontColor;
  2706.         Self.BGColor := BGColor;
  2707.         Self.ActiveBGColor := ActiveBGColor;
  2708.       end;
  2709. end;
  2710. procedure TbsSkinMemo2.SetSkinData;
  2711. begin
  2712.   FSD := Value;
  2713.   if (FSD <> nil) then
  2714.   if not FSD.Empty and not (csDesigning in ComponentState)
  2715.   then
  2716.     ChangeSkinData;
  2717. end;
  2718. procedure TbsSkinMemo2.Notification;
  2719. begin
  2720.   inherited Notification(AComponent, Operation);
  2721.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  2722.   if (Operation = opRemove) and (AComponent = FVScrollBar)
  2723.   then FVScrollBar := nil;
  2724.   if (Operation = opRemove) and (AComponent = FHScrollBar)
  2725.   then FHScrollBar := nil;
  2726. end;
  2727. procedure TbsSkinMemo2.ChangeSkinData;
  2728. begin
  2729.   GetSkinData;
  2730.   //
  2731.   if FIndex <> -1
  2732.   then
  2733.     begin
  2734.       if FUseSkinFont
  2735.       then
  2736.         begin
  2737.           Font.Name := FontName;
  2738.           Font.Style := FontStyle;
  2739.           Font.Height := FontHeight;
  2740.           if Focused
  2741.           then
  2742.             Font.Color := ActiveFontColor
  2743.           else
  2744.             Font.Color := FontColor;
  2745.         end
  2746.       else
  2747.         begin
  2748.           Font.Assign(FDefaultFont);
  2749.           if Focused
  2750.           then
  2751.             Font.Color := ActiveFontColor
  2752.           else
  2753.             Font.Color := FontColor;
  2754.         end;
  2755.       Color := BGColor;
  2756.     end
  2757.   else
  2758.     Font.Assign(FDefaultFont);
  2759.   //
  2760.   if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
  2761.   then
  2762.     Font.Charset := SkinData.ResourceStrData.CharSet
  2763.   else
  2764.     Font.CharSet := FDefaultFont.CharSet;
  2765.   //
  2766.   UpDateScrollRange;
  2767.   ReCreateWnd;
  2768.   if FVScrollBar <> nil then FVScrollBar.Align := FVScrollBar.Align;
  2769. end;
  2770. constructor TbsListBox.Create;
  2771. begin
  2772.   inherited;
  2773.   SkinListBox := nil;
  2774.   Ctl3D := False;
  2775.   BorderStyle := bsNone;
  2776.   ControlStyle := [csCaptureMouse, csOpaque, csDoubleClicks];
  2777.   FHorizontalExtentValue := 0;
  2778.   {$IFDEF VER130}
  2779.   FAutoComplete := True;
  2780.   {$ENDIF}
  2781. end;
  2782. destructor TbsListBox.Destroy;
  2783. begin
  2784.   inherited;
  2785. end;
  2786. procedure TbsListBox.SetBounds;
  2787. var
  2788.   OldWidth: Integer;
  2789. begin
  2790.   OldWidth := Width;
  2791.   inherited;
  2792.   if (OldWidth <> Width) and (FHorizontalExtentValue > 0)
  2793.   then
  2794.     begin
  2795.       FHorizontalExtentValue := FHorizontalExtentValue + (OldWidth - Width);
  2796.       if FHorizontalExtentValue < 0 then FHorizontalExtentValue := 0;
  2797.       RePaint;
  2798.     end;
  2799. end;
  2800. procedure TbsListBox.CreateWnd;
  2801. begin
  2802.   inherited;
  2803.   if SkinListBox <> nil then SkinListBox.ListBoxCreateWnd;
  2804. end;
  2805. procedure TbsListBox.WMNCCALCSIZE;
  2806. begin
  2807. end;
  2808. procedure TbsListBox.CMEnter;
  2809. begin
  2810.   if SkinListBox <> nil then SkinListBox.ListBoxEnter;
  2811.   inherited;
  2812. end;
  2813. procedure TbsListBox.CMExit;
  2814. begin
  2815.   if SkinListBox <> nil then SkinListBox.ListBoxExit;
  2816.   inherited;
  2817. end;
  2818. procedure TbsListBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
  2819.       X, Y: Integer);
  2820. begin
  2821.   if SkinListBox <> nil then SkinListBox.ListBoxMouseDown(Button, Shift, X, Y);
  2822.   inherited;
  2823. end;
  2824. procedure TbsListBox.MouseUp(Button: TMouseButton; Shift: TShiftState;
  2825.       X, Y: Integer);
  2826. begin
  2827.   if SkinListBox <> nil then SkinListBox.ListBoxMouseUp(Button, Shift, X, Y);
  2828.   inherited;
  2829. end;
  2830. procedure TbsListBox.MouseMove(Shift: TShiftState; X, Y: Integer);
  2831. begin
  2832.   if SkinListBox <> nil then SkinListBox.ListBoxMouseMove(Shift, X, Y);
  2833.   inherited;
  2834. end;
  2835. procedure TbsListBox.KeyDown(var Key: Word; Shift: TShiftState);
  2836. begin
  2837.   if SkinListBox <> nil then SkinListBox.ListBoxKeyDown(Key, Shift);
  2838.   if (Key = VK_LEFT) and (SkinListBox.HScrollBar <> nil)
  2839.   then
  2840.     with SkinListBox.HScrollBar do
  2841.     begin
  2842.       Position := Position - SmallChange;
  2843.       Key := 0;
  2844.     end
  2845.   else
  2846.   if (Key = VK_RIGHT) and (SkinListBox.HScrollBar <> nil)
  2847.   then
  2848.     with SkinListBox.HScrollBar do
  2849.     begin
  2850.       Position := Position + SmallChange;
  2851.       Key := 0;
  2852.     end;
  2853.   inherited;
  2854. end;
  2855. procedure TbsListBox.KeyPress(var Key: Char);
  2856.   {$IFDEF VER130}
  2857.   procedure FindString;
  2858.   var
  2859.     Idx: Integer;
  2860.   begin
  2861.     if Length(FFilter) = 1
  2862.     then
  2863.       Idx := SendMessage(Handle, LB_FINDSTRING, ItemIndex, LongInt(PChar(FFilter)))
  2864.     else
  2865.       Idx := SendMessage(Handle, LB_FINDSTRING, -1, LongInt(PChar(FFilter)));
  2866.     if Idx <> LB_ERR then
  2867.     begin
  2868.       if MultiSelect then
  2869.       begin
  2870.         SendMessage(Handle, LB_SELITEMRANGE, 1, MakeLParam(Idx, Idx))
  2871.       end;
  2872.       ItemIndex := Idx;
  2873.       Click;
  2874.     end;
  2875.     if not Ord(Key) in [VK_RETURN, VK_BACK, VK_ESCAPE] then
  2876.       Key := #0;  
  2877.   end;
  2878.   {$ENDIF}
  2879. begin
  2880.   if SkinListBox <> nil then SkinListBox.ListBoxKeyPress(Key);
  2881.   inherited;
  2882.   {$IFDEF VER130}
  2883.   if not FAutoComplete then Exit;
  2884.   if GetTickCount - FLastTime >= 500 then
  2885.     FFilter := '';
  2886.   FLastTime := GetTickCount;
  2887.   if Ord(Key) <> VK_BACK then
  2888.   begin
  2889.     FFilter := FFilter + Key;
  2890.     Key := #0;
  2891.   end
  2892.   else
  2893.     Delete(FFilter, Length(FFilter), 1);
  2894.   if Length(FFilter) > 0 then
  2895.     FindString
  2896.   else
  2897.   begin
  2898.     ItemIndex := 0;
  2899.     Click;
  2900.   end;
  2901.   {$ENDIF}
  2902. end;
  2903. procedure TbsListBox.Click;
  2904. begin
  2905.   if SkinListBox <> nil then SkinListBox.ListBoxClick;
  2906.   inherited;
  2907. end;
  2908. procedure TbsListBox.PaintBGWH;
  2909. var
  2910.   X, Y, XCnt, YCnt, XO, YO, w, h, w1, h1: Integer;
  2911.   Buffer: TBitMap;
  2912. begin
  2913.   w1 := AW;
  2914.   h1 := AH;
  2915.   Buffer := TBitMap.Create;
  2916.   Buffer.Width := w1;
  2917.   Buffer.Height := h1;
  2918.   with Buffer.Canvas, SkinListBox do
  2919.   begin
  2920.     w := RectWidth(ClRect);
  2921.     h := RectHeight(ClRect);
  2922.     XCnt := w1 div w;
  2923.     YCnt := h1 div h;
  2924.     for X := 0 to XCnt do
  2925.     for Y := 0 to YCnt do
  2926.     begin
  2927.       if X * w + w > w1 then XO := X * w + w - w1 else XO := 0;
  2928.       if Y * h + h > h1 then YO := Y * h + h - h1 else YO := 0;
  2929.        CopyRect(Rect(X * w, Y * h, X * w + w - XO, Y * h + h - YO),
  2930.                 Picture.Canvas,
  2931.                 Rect(SkinRect.Left + ClRect.Left, SkinRect.Top + ClRect.Top,
  2932.                 SkinRect.Left + ClRect.Right - XO,
  2933.                 SkinRect.Top + ClRect.Bottom - YO));
  2934.     end;
  2935.   end;
  2936.   Cnvs.Draw(AX, AY, Buffer);
  2937.   Buffer.Free;
  2938. end;
  2939. function TbsListBox.GetState;
  2940. begin
  2941.   Result := [];
  2942.   if AItemID = ItemIndex
  2943.   then
  2944.     begin
  2945.       Result := Result + [odSelected];
  2946.       if Focused then Result := Result + [odFocused];
  2947.     end
  2948.   else
  2949.     if SelCount > 0
  2950.     then
  2951.       if Selected[AItemID] then Result := Result + [odSelected];
  2952. end;
  2953. procedure TbsListBox.PaintBG(DC: HDC);
  2954. var
  2955.   C: TControlCanvas;
  2956. begin
  2957.   C := TControlCanvas.Create;
  2958.   C.Handle := DC;
  2959.   SkinListBox.GetSkinData;
  2960.   if SkinListBox.FIndex <> -1
  2961.   then
  2962.     PaintBGWH(C, Width, Height, 0, 0)
  2963.   else
  2964.     with C do
  2965.     begin
  2966.       Brush.Color := clWindow;
  2967.       FillRect(Rect(0, 0, Width, Height));
  2968.     end;
  2969.   C.Handle := 0;
  2970.   C.Free;
  2971. end;
  2972. procedure TbsListBox.PaintColumnsList(DC: HDC);
  2973. var
  2974.   C: TCanvas;
  2975.   i, j, DrawCount: Integer;
  2976.   IR: TRect;
  2977. begin
  2978.   C := TCanvas.Create;
  2979.   C.Handle := DC;
  2980.   DrawCount := (Height div ItemHeight) * Columns;
  2981.   i := TopIndex;
  2982.   j := i + DrawCount;
  2983.   if j > Items.Count - 1 then j := Items.Count - 1;
  2984.   if Items.Count > 0
  2985.   then
  2986.     for i := TopIndex to j do
  2987.     begin
  2988.       IR := ItemRect(i);
  2989.       if SkinListBox.FIndex <> -1
  2990.       then
  2991.         begin
  2992.           if SkinListBox.UseSkinItemHeight
  2993.           then
  2994.             DrawSkinItem(C, i, IR, GetState(i))
  2995.           else
  2996.             DrawStretchSkinItem(C, i, IR, GetState(i));
  2997.          end
  2998.       else
  2999.         DrawDefaultItem(C, i, IR, GetState(i));
  3000.     end;
  3001.   C.Free;
  3002. end;
  3003. procedure TbsListBox.PaintList(DC: HDC);
  3004. var
  3005.   C: TCanvas;
  3006.   i, j, k, DrawCount: Integer;
  3007.   IR: TRect;
  3008. begin
  3009.   C := TCanvas.Create;
  3010.   C.Handle := DC;
  3011.   DrawCount := Height div ItemHeight;
  3012.   i := TopIndex;
  3013.   j := i + DrawCount;
  3014.   if j > Items.Count - 1 then j := Items.Count - 1;
  3015.   k := 0;
  3016.   if Items.Count > 0
  3017.   then
  3018.     for i := TopIndex to j do
  3019.     begin
  3020.       IR := ItemRect(i);
  3021.       if SkinListBox.FIndex <> -1
  3022.       then
  3023.         begin
  3024.           if SkinListBox.UseSkinItemHeight
  3025.           then
  3026.             DrawSkinItem(C, i, IR, GetState(i))
  3027.           else
  3028.             DrawStretchSkinItem(C, i, IR, GetState(i));
  3029.         end
  3030.       else
  3031.         DrawDefaultItem(C, i, IR, GetState(i));
  3032.       k := IR.Bottom;
  3033.     end;
  3034.   if k < Height
  3035.   then
  3036.     begin
  3037.       SkinListBox.GetSkinData;
  3038.       if SkinListBox.FIndex <> -1
  3039.       then
  3040.         PaintBGWH(C, Width, Height - k, 0, k)
  3041.       else
  3042.         with C do
  3043.         begin
  3044.           C.Brush.Color := clWindow;
  3045.           FillRect(Rect(0, k, Width, Height));
  3046.         end;
  3047.     end;  
  3048.   C.Free;
  3049. end;
  3050. procedure TbsListBox.PaintWindow;
  3051. var
  3052.   SaveIndex: Integer;
  3053. begin
  3054.   if (Width <= 0) or (Height <=0) then Exit;
  3055.   SaveIndex := SaveDC(DC);
  3056.   try
  3057.     if Columns > 0
  3058.     then
  3059.       PaintColumnsList(DC)
  3060.     else
  3061.       PaintList(DC);
  3062.   finally
  3063.     RestoreDC(DC, SaveIndex);
  3064.   end;
  3065. end;
  3066. procedure TbsListBox.WMPaint;
  3067. begin
  3068.   PaintHandler(Msg);
  3069. end;
  3070. procedure TbsListBox.WMEraseBkgnd;
  3071. begin
  3072.   if (Width > 0) and (Height > 0) then PaintBG(Message.DC);
  3073.   Message.Result := 1;
  3074. end;
  3075. procedure TbsListBox.DrawDefaultItem(Cnvs: TCanvas; itemID: Integer; rcItem: TRect;
  3076.                                      State: TOwnerDrawState);
  3077. var
  3078.   Buffer: TBitMap;
  3079.   R, R1: TRect;
  3080.   IIndex, IX, IY, Off: Integer;
  3081. begin
  3082.   if (ItemID < 0) or (ItemID > Items.Count - 1) then Exit;
  3083.   Buffer := TBitMap.Create;
  3084.   Buffer.Width := RectWidth(rcItem);
  3085.   Buffer.Height := RectHeight(rcItem);
  3086.   R := Rect(0, 0, Buffer.Width, Buffer.Height);
  3087.   with Buffer.Canvas do
  3088.   begin
  3089.     Font.Name := SkinListBox.Font.Name;
  3090.     Font.Style := SkinListBox.Font.Style;
  3091.     Font.Height := SkinListBox.Font.Height;
  3092.     if (SkinListBox.SkinData <> nil) and (SkinListBox.SkinData.ResourceStrData <> nil)
  3093.     then
  3094.       Font.Charset := SkinListBox.SkinData.ResourceStrData.CharSet
  3095.     else
  3096.       Font.CharSet := SkinListBox.DefaultFont.CharSet;
  3097.     if odSelected in State
  3098.     then
  3099.       begin
  3100.         Brush.Color := clHighLight;
  3101.         Font.Color := clHighLightText;
  3102.       end
  3103.     else
  3104.       begin
  3105.         Brush.Color := clWindow;
  3106.         Font.Color := SkinListBox.Font.Color;
  3107.       end;
  3108.     FillRect(R);
  3109.   end;
  3110.   R1 := Rect(R.Left + 2, R.Top, R.Right - 2, R.Bottom);
  3111.   if Assigned(SkinListBox.FOnDrawItem)
  3112.   then
  3113.     SkinListBox.FOnDrawItem(Buffer.Canvas, ItemID, Buffer.Width, Buffer.Height,
  3114.     R1, State)
  3115.   else
  3116.     begin
  3117.       if (SkinListBox.Images <> nil)
  3118.       then
  3119.         begin
  3120.           if SkinListBox.ImageIndex > -1
  3121.           then IIndex := SkinListBox.FImageIndex
  3122.           else IIndex := itemID;
  3123.           if IIndex < SkinListBox.Images.Count
  3124.           then
  3125.             begin
  3126.               IX := R1.Left;
  3127.               IY := R1.Top + RectHeight(R1) div 2 - SkinListBox.Images.Height div 2;
  3128.               SkinListBox.Images.Draw(Buffer.Canvas, IX - FHorizontalExtentValue, IY, IIndex);
  3129.             end;
  3130.           Off := SkinListBox.Images.Width + 2
  3131.         end
  3132.       else
  3133.         Off := 0;
  3134.       Buffer.Canvas.Brush.Style := bsClear;
  3135.       BSDrawText3(Buffer.Canvas, Items[ItemID], R1, - FHorizontalExtentValue + Off);
  3136.     end;
  3137.   if odFocused in State then DrawFocusRect(Buffer.Canvas.Handle, R);
  3138.   Cnvs.Draw(rcItem.Left, rcItem.Top, Buffer);
  3139.   Buffer.Free;
  3140. end;
  3141. procedure TbsListBox.DrawStretchSkinItem(Cnvs: TCanvas; itemID: Integer; rcItem: TRect;
  3142.                                   State: TOwnerDrawState);
  3143. var
  3144.   Buffer, Buffer2: TBitMap;
  3145.   R: TRect;
  3146.   W, H: Integer;
  3147.   IX, IY, IIndex, Off: Integer;
  3148. begin
  3149.   if (SkinListBox.Picture = nil) or (ItemID < 0) or (ItemID > Items.Count - 1) then Exit;
  3150.   Buffer := TBitMap.Create;
  3151.   with SkinListBox do
  3152.   begin
  3153.     W := RectWidth(rcItem);
  3154.     H := RectHeight(SItemRect);
  3155.     Buffer.Width := W;
  3156.     if UseSkinItemHeight
  3157.     then
  3158.       Buffer.Height := H
  3159.     else
  3160.       Buffer.Height := RectHeight(SItemRect);  
  3161.     if odFocused in State
  3162.     then
  3163.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3164.       FocusItemRect, W, H)
  3165.     else
  3166.     if odSelected in State
  3167.     then
  3168.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3169.       ActiveItemRect, W, H)
  3170.     else
  3171.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3172.       SItemRect, W, H);
  3173.     R := ItemTextRect;
  3174.     Inc(R.Right, W - RectWidth(SItemRect));
  3175.     Inc(R.Bottom, RectHeight(rcItem) - RectHeight(SItemRect));
  3176.   end;
  3177.   W := RectWidth(rcItem);
  3178.   H := RectHeight(rcItem);
  3179.   Buffer2 := TBitMap.Create;
  3180.   Buffer2.Width := W;
  3181.   Buffer2.Height := H;
  3182.   Buffer2.Canvas.StretchDraw(Rect(0, 0, Buffer2.Width, Buffer2.Height), Buffer);
  3183.   Buffer.Free;
  3184.   with Buffer2.Canvas do
  3185.   begin
  3186.     if SkinListBox.UseSkinFont
  3187.     then
  3188.       begin
  3189.         Font.Name := SkinListBox.FontName;
  3190.         Font.Style := SkinListBox.FontStyle;
  3191.         Font.Height := SkinListBox.FontHeight;
  3192.       end
  3193.     else
  3194.       Font.Assign(SkinListBox.DefaultFont);
  3195.     if (SkinListBox.SkinData <> nil) and (SkinListBox.SkinData.ResourceStrData <> nil)
  3196.     then
  3197.       Font.Charset := SkinListBox.SkinData.ResourceStrData.CharSet
  3198.     else
  3199.       Font.CharSet := SkinListBox.DefaultFont.CharSet;
  3200.     if odFocused in State
  3201.     then
  3202.       Font.Color := SkinListBox.FocusFontColor
  3203.     else
  3204.     if odSelected in State
  3205.     then
  3206.       Font.Color := SkinListBox.ActiveFontColor
  3207.     else
  3208.       Font.Color := SkinListBox.FontColor;
  3209.     Brush.Style := bsClear;
  3210.   end;
  3211.   if Assigned(SkinListBox.FOnDrawItem)
  3212.   then
  3213.     SkinListBox.FOnDrawItem(Buffer2.Canvas, ItemID, W, H, R, State)
  3214.   else
  3215.     begin
  3216.       if (SkinListBox.Images <> nil)
  3217.       then
  3218.         begin
  3219.           if SkinListBox.ImageIndex > -1
  3220.           then IIndex := SkinListBox.FImageIndex
  3221.           else IIndex := itemID;
  3222.           if IIndex < SkinListBox.Images.Count
  3223.           then
  3224.             begin
  3225.               IX := R.Left;
  3226.               IY := R.Top + RectHeight(R) div 2 - SkinListBox.Images.Height div 2;
  3227.               SkinListBox.Images.Draw(Buffer2.Canvas,
  3228.                 IX - FHorizontalExtentValue, IY, IIndex);
  3229.             end;
  3230.           Off := SkinListBox.Images.Width + 2;
  3231.         end
  3232.       else
  3233.         Off := 0;  
  3234.       BSDrawText3(Buffer2.Canvas, Items[ItemID], R, -FHorizontalExtentValue + Off);
  3235.     end;
  3236.   Cnvs.Draw(rcItem.Left, rcItem.Top, Buffer2);
  3237.   Buffer2.Free;
  3238. end;
  3239. procedure TbsListBox.DrawSkinItem(Cnvs: TCanvas; itemID: Integer; rcItem: TRect;
  3240.                                   State: TOwnerDrawState);
  3241. var
  3242.   Buffer: TBitMap;
  3243.   R: TRect;
  3244.   W, H: Integer;
  3245.   IX, IY, IIndex, Off: Integer;
  3246. begin
  3247.   if (SkinListBox.Picture = nil) or (ItemID < 0) or (ItemID > Items.Count - 1) then Exit;
  3248.   Buffer := TBitMap.Create;
  3249.   with SkinListBox do
  3250.   begin
  3251.     W := RectWidth(rcItem);
  3252.     H := RectHeight(SItemRect);
  3253.     Buffer.Width := W;
  3254.     Buffer.Height := H;
  3255.     if odFocused in State
  3256.     then
  3257.       begin
  3258.         if not (odSelected in State)
  3259.         then
  3260.           begin
  3261.             CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3262.               SItemRect, W, H);
  3263.             R := Rect(0, 0, Buffer.Width, Buffer.Height);
  3264.             DrawFocusRect(Buffer.Canvas.Handle, R);
  3265.           end
  3266.         else
  3267.           CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3268.             FocusItemRect, W, H)
  3269.       end
  3270.     else
  3271.     if odSelected in State
  3272.     then
  3273.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3274.       ActiveItemRect, W, H)
  3275.     else
  3276.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  3277.       SItemRect, W, H);
  3278.     R := ItemTextRect;
  3279.     Inc(R.Right, W - RectWidth(SItemRect));
  3280.   end;
  3281.   with Buffer.Canvas do
  3282.   begin
  3283.     if SkinListBox.UseSkinFont
  3284.     then
  3285.       begin
  3286.         Font.Name := SkinListBox.FontName;
  3287.         Font.Style := SkinListBox.FontStyle;
  3288.         Font.Height := SkinListBox.FontHeight;
  3289.       end
  3290.     else
  3291.       Font.Assign(SkinListBox.DefaultFont);
  3292.   if (SkinListBox.SkinData <> nil) and (SkinListBox.SkinData.ResourceStrData <> nil)
  3293.   then
  3294.     Font.Charset := SkinListBox.SkinData.ResourceStrData.CharSet
  3295.   else
  3296.     Font.CharSet := SkinListBox.DefaultFont.CharSet;
  3297.     if odFocused in State
  3298.     then
  3299.       begin
  3300.         if not (odSelected in State)
  3301.         then
  3302.           Font.Color := SkinListBox.FontColor
  3303.         else
  3304.           Font.Color := SkinListBox.FocusFontColor;
  3305.       end
  3306.     else
  3307.     if odSelected in State
  3308.     then
  3309.       Font.Color := SkinListBox.ActiveFontColor
  3310.     else
  3311.       Font.Color := SkinListBox.FontColor;
  3312.     Brush.Style := bsClear;
  3313.   end;
  3314.   if Assigned(SkinListBox.FOnDrawItem)
  3315.   then
  3316.     SkinListBox.FOnDrawItem(Buffer.Canvas, ItemID,
  3317.       Buffer.Width, Buffer.Height,  R, State)
  3318.   else
  3319.     begin
  3320.       if (SkinListBox.Images <> nil)
  3321.       then
  3322.         begin
  3323.           if SkinListBox.ImageIndex > -1
  3324.           then IIndex := SkinListBox.FImageIndex
  3325.           else IIndex := itemID;
  3326.           if IIndex < SkinListBox.Images.Count
  3327.           then
  3328.             begin
  3329.               IX := R.Left;
  3330.               IY := R.Top + RectHeight(R) div 2 - SkinListBox.Images.Height div 2;
  3331.               SkinListBox.Images.Draw(Buffer.Canvas,
  3332.                 IX - FHorizontalExtentValue, IY, IIndex);
  3333.             end;
  3334.           Off := SkinListBox.Images.Width + 2;
  3335.         end
  3336.       else
  3337.         Off := 0;  
  3338.       BSDrawText3(Buffer.Canvas, Items[ItemID], R, -FHorizontalExtentValue + Off);
  3339.     end;
  3340.   Cnvs.Draw(rcItem.Left, rcItem.Top, Buffer);
  3341.   Buffer.Free;
  3342. end;
  3343. procedure TbsListBox.CreateParams;
  3344. begin
  3345.   inherited CreateParams(Params);
  3346.   with Params do
  3347.   begin
  3348.     Style := Style and not WS_BORDER;
  3349.     ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
  3350.     WindowClass.style := CS_DBLCLKS;
  3351.     Style := Style or WS_TABSTOP;
  3352.   end;
  3353. end;
  3354. procedure TbsListBox.CNDrawItem;
  3355. var
  3356.   State: TOwnerDrawState;
  3357. begin
  3358.   with Message.DrawItemStruct^ do
  3359.   begin
  3360.     {$IFDEF VER120}
  3361.       State := TOwnerDrawState(WordRec(LongRec(itemState).Lo).Lo);
  3362.     {$ELSE}
  3363.       {$IFDEF VER125}
  3364.         State := TOwnerDrawState(WordRec(LongRec(itemState).Lo).Lo);
  3365.       {$ELSE}
  3366.         State := TOwnerDrawState(LongRec(itemState).Lo);
  3367.       {$ENDIF}
  3368.     {$ENDIF}
  3369.     Canvas.Handle := hDC;
  3370.     Canvas.Font := Font;
  3371.     Canvas.Brush := Brush;
  3372.     if SkinListBox.FIndex <> -1
  3373.     then
  3374.       begin
  3375.         if SkinListBox.UseSkinItemHeight
  3376.         then
  3377.           DrawSkinItem(Canvas, itemID, rcItem, State)
  3378.         else
  3379.           DrawStretchSkinItem(Canvas, itemID, rcItem, State);
  3380.       end
  3381.     else
  3382.       DrawDefaultItem(Canvas, itemID, rcItem, State);
  3383.     Canvas.Handle := 0;
  3384.   end;
  3385. end;
  3386. procedure TbsListBox.WndProc;
  3387. var
  3388.   LParam, WParam: Integer;
  3389.   Handled: Boolean;
  3390. begin
  3391.   if SkinListBox <> nil then SkinListBox.ListBoxWProc(Message, Handled);
  3392.   if not Handled then Exit;
  3393.   inherited;
  3394.   case Message.Msg of
  3395.     WM_LBUTTONDBLCLK:
  3396.       begin
  3397.         if SkinListBox <> nil then SkinListBox.ListBoxDblClick;
  3398.       end;
  3399.     WM_MOUSEWHEEL:
  3400.       if (SkinListBox <> nil) and (SkinListBox.ScrollBar <> nil)
  3401.       then
  3402.         begin
  3403.           LParam := 0;
  3404.           if Message.WParam > 0
  3405.           then
  3406.             WParam := MakeWParam(SB_LINEUP, 0)
  3407.           else
  3408.             WParam := MakeWParam(SB_LINEDOWN, 0);
  3409.           SendMessage(Handle, WM_VSCROLL, WParam, LParam);
  3410.           SkinListBox.UpDateScrollBar;
  3411.         end
  3412.       else
  3413.         if (SkinListBox <> nil) and (SkinListBox.HScrollBar <> nil)
  3414.         then
  3415.           begin
  3416.             with SkinListBox.HScrollBar do
  3417.             if Message.WParam > 0
  3418.             then
  3419.               Position := Position - SmallChange
  3420.             else
  3421.               Position := Position + SmallChange;
  3422.           end;
  3423.     WM_ERASEBKGND:
  3424.       SkinListBox.UpDateScrollBar;
  3425.     LB_ADDSTRING, LB_INSERTSTRING,
  3426.     LB_DELETESTRING:
  3427.       begin
  3428.         if SkinListBox <> nil
  3429.         then
  3430.           SkinListBox.UpDateScrollBar;
  3431.       end;
  3432.   end;
  3433. end;
  3434. constructor TbsSkinCustomListBox.Create;
  3435. begin
  3436.   inherited;
  3437.   ControlStyle := [csCaptureMouse, csClickEvents,
  3438.     csReplicatable, csOpaque, csDoubleClicks];
  3439.   ControlStyle := ControlStyle + [csAcceptsControls];
  3440.   FUseSkinItemHeight := True;
  3441.   FRowCount := 0;
  3442.   FImageIndex := -1;
  3443.   FGlyph := TBitMap.Create;
  3444.   FNumGlyphs := 1;
  3445.   FSpacing := 2;
  3446.   FDefaultCaptionFont := TFont.Create;
  3447.   FDefaultCaptionFont.OnChange := OnDefaultCaptionFontChange;
  3448.   FDefaultCaptionFont.Name := 'Arial';
  3449.   FDefaultCaptionFont.Height := 14;
  3450.   FDefaultCaptionHeight := 20;
  3451.   ActiveButton := -1;
  3452.   OldActiveButton := -1;
  3453.   CaptureButton := -1;
  3454.   FCaptionMode := False;
  3455.   FDefaultItemHeight := 20;
  3456.   TimerMode := 0;
  3457.   WaitMode := False;
  3458.   Font.Name := 'Arial';
  3459.   Font.Height := 14;
  3460.   Font.Color := clWindowText;
  3461.   Font.Style := [];
  3462.   ScrollBar := nil;
  3463.   HScrollBar := nil;
  3464.   ListBox := TbsListBox.Create(Self);
  3465.   ListBox.SkinListBox := Self;
  3466.   ListBox.Style := lbOwnerDrawFixed;
  3467.   ListBox.ItemHeight := FDefaultItemHeight;
  3468.   ListBox.Parent := Self;
  3469.   ListBox.Visible := True;
  3470.   Height := 120;
  3471.   Width := 120;
  3472.   FSkinDataName := 'listbox';
  3473.   FHorizontalExtent := False;
  3474.   FStopUpDateHScrollBar := False;
  3475. end;
  3476. function TbsSkinCustomListBox.GetAutoComplete: Boolean;
  3477. begin
  3478.   Result := ListBox.AutoComplete;
  3479. end;
  3480. procedure TbsSkinCustomListBox.SetAutoComplete(Value: Boolean);
  3481. begin
  3482.   ListBox.AutoComplete := Value;
  3483. end;
  3484. function TbsSkinCustomListBox.GetOnListBoxEndDrag: TEndDragEvent;
  3485. begin
  3486.   Result := ListBox.OnEndDrag;
  3487. end;
  3488. procedure TbsSkinCustomListBox.SetOnListBoxEndDrag(Value: TEndDragEvent);
  3489. begin
  3490.   ListBox.OnEndDrag := Value;
  3491. end;
  3492. function TbsSkinCustomListBox.GetOnListBoxStartDrag: TStartDragEvent;
  3493. begin
  3494.   Result := ListBox.OnStartDrag;
  3495. end;
  3496. procedure TbsSkinCustomListBox.SetOnListBoxStartDrag(Value: TStartDragEvent);
  3497. begin
  3498.   ListBox.OnStartDrag := Value;
  3499. end;
  3500. function TbsSkinCustomListBox.GetOnListBoxDragOver: TDragOverEvent;
  3501. begin
  3502.   Result := ListBox.OnDragOver;
  3503. end;
  3504. procedure TbsSkinCustomListBox.SetOnListBoxDragOver(Value: TDragOverEvent);
  3505. begin
  3506.   ListBox.OnDragOver := Value;
  3507. end;
  3508. function TbsSkinCustomListBox.GetOnListBoxDragDrop: TDragDropEvent;
  3509. begin
  3510.   Result := ListBox.OnDragDrop;
  3511. end;
  3512. procedure TbsSkinCustomListBox.SetOnListBoxDragDrop(Value: TDragDropEvent);
  3513. begin
  3514.   ListBox.OnDragDrop := Value;
  3515. end;
  3516. procedure TbsSkinCustomListBox.SetHorizontalExtent(Value: Boolean);
  3517. begin
  3518.   FHorizontalExtent := Value;
  3519.   UpdateScrollBar;
  3520. end;
  3521. procedure TbsSkinCustomListBox.ListBoxCreateWnd;
  3522. begin
  3523. end;
  3524. function  TbsSkinCustomListBox.GetColumns;
  3525. begin
  3526.   Result := ListBox.Columns;
  3527. end;
  3528. procedure TbsSkinCustomListBox.SetColumns;
  3529. begin
  3530.   ListBox.Columns := Value;
  3531.   UpDateScrollBar;
  3532. end;
  3533. procedure TbsSkinCustomListBox.SetRowCount;
  3534. begin
  3535.   FRowCount := Value;
  3536.   if FRowCount <> 0
  3537.   then
  3538.     Height := Self.CalcHeight(FRowCount);
  3539. end;
  3540. procedure TbsSkinCustomListBox.SetNumGlyphs;
  3541. begin
  3542.   FNumGlyphs := Value;
  3543.   RePaint;
  3544. end;
  3545. procedure TbsSkinCustomListBox.SetGlyph;
  3546. begin
  3547.   FGlyph.Assign(Value);
  3548.   RePaint;
  3549. end;
  3550. procedure TbsSkinCustomListBox.SetSpacing;
  3551. begin
  3552.   FSpacing := Value;
  3553.   RePaint;
  3554. end;
  3555. procedure TbsSkinCustomListBox.SetImages(Value: TCustomImageList);
  3556. begin
  3557.   FImages := Value;
  3558.   ListBox.RePaint;
  3559. end;
  3560. procedure TbsSkinCustomListBox.SetImageIndex(Value: Integer);
  3561. begin
  3562.   FImageIndex := Value;
  3563.   ListBox.RePaint;
  3564. end;
  3565. procedure TbsSkinCustomListBox.Notification(AComponent: TComponent;
  3566.   Operation: TOperation);
  3567. begin
  3568.   inherited Notification(AComponent, Operation);
  3569.   if (Operation = opRemove) and (AComponent = Images) then
  3570.     Images := nil;
  3571. end;
  3572. procedure TbsSkinCustomListBox.ListBoxWProc(var Message: TMessage; var Handled: Boolean);
  3573. begin
  3574.   Handled := True;
  3575. end;
  3576. procedure TbsSkinCustomListBox.DefaultFontChange;
  3577. begin
  3578.   if FIndex = -1 then Font.Assign(FDefaultFont);
  3579. end;
  3580. procedure TbsSkinCustomListBox.OnDefaultCaptionFontChange;
  3581. begin
  3582.   if (FIndex = -1) and FCaptionMode then RePaint;
  3583. end;
  3584. procedure TbsSkinCustomListBox.SetDefaultCaptionHeight;
  3585. begin
  3586.   FDefaultCaptionHeight := Value;
  3587.   if (FIndex = -1) and FCaptionMode
  3588.   then
  3589.     begin
  3590.       CalcRects;
  3591.       RePaint;
  3592.     end;  
  3593. end;
  3594. procedure TbsSkinCustomListBox.SetDefaultCaptionFont;
  3595. begin
  3596.   FDefaultCaptionFont.Assign(Value);
  3597. end;
  3598. procedure TbsSkinCustomListBox.SetDefaultItemHeight;
  3599. begin
  3600.   FDefaultItemHeight := Value;
  3601.   if FIndex = -1
  3602.   then
  3603.     ListBox.ItemHeight := FDefaultItemHeight;
  3604. end;
  3605. procedure TbsSkinCustomListBox.StartTimer;
  3606. begin
  3607.   KillTimer(Handle, 1);
  3608.   SetTimer(Handle, 1, 100, nil);
  3609. end;
  3610. procedure TbsSkinCustomListBox.StopTimer;
  3611. begin
  3612.   KillTimer(Handle, 1);
  3613.   TimerMode := 0;
  3614. end;
  3615. procedure TbsSkinCustomListBox.WMTimer;
  3616. begin
  3617.   inherited;
  3618.   if WaitMode
  3619.   then
  3620.     begin
  3621.       WaitMode := False;
  3622.       StartTimer;
  3623.       Exit;
  3624.     end;
  3625.   case TimerMode of
  3626.     1: if ItemIndex > 0 then ItemIndex := ItemIndex - 1;
  3627.     2: ItemIndex := ItemIndex + 1;
  3628.   end;
  3629. end;
  3630. procedure TbsSkinCustomListBox.CMMouseEnter;
  3631. begin
  3632.   inherited;
  3633.   if FCaptionMode
  3634.   then
  3635.     TestActive(-1, -1);
  3636. end;
  3637. procedure TbsSkinCustomListBox.CMMouseLeave;
  3638. var
  3639.   i: Integer;
  3640. begin
  3641.   inherited;
  3642.   if FCaptionMode
  3643.   then
  3644.   for i := 0 to 1 do
  3645.     if Buttons[i].MouseIn
  3646.     then
  3647.        begin
  3648.          Buttons[i].MouseIn := False;
  3649.          RePaint;
  3650.        end;
  3651. end;
  3652. procedure TbsSkinCustomListBox.MouseDown;
  3653. begin
  3654.   if FCaptionMode
  3655.   then
  3656.     begin
  3657.       TestActive(X, Y);
  3658.       if ActiveButton <> -1
  3659.       then
  3660.         begin
  3661.           CaptureButton := ActiveButton;
  3662.           ButtonDown(ActiveButton, X, Y);
  3663.       end;
  3664.     end;
  3665.   inherited;
  3666. end;
  3667. procedure TbsSkinCustomListBox.MouseUp;
  3668. begin
  3669.   if FCaptionMode
  3670.   then
  3671.     begin
  3672.       if CaptureButton <> -1
  3673.       then ButtonUp(CaptureButton, X, Y);
  3674.       CaptureButton := -1;
  3675.     end;  
  3676.   inherited;
  3677. end;
  3678. procedure TbsSkinCustomListBox.MouseMove;
  3679. begin
  3680.   inherited;
  3681.   if FCaptionMode then TestActive(X, Y);
  3682. end;
  3683. procedure TbsSkinCustomListBox.TestActive(X, Y: Integer);
  3684. var
  3685.   i, j: Integer;
  3686. begin
  3687.   if (FIndex <> -1) and IsNullRect(UpButtonRect) and IsNullRect(DownButtonRect)
  3688.   then Exit;
  3689.   j := -1;
  3690.   OldActiveButton := ActiveButton;
  3691.   for i := 0 to 2 do
  3692.   begin
  3693.     if PtInRect(Buttons[i].R, Point(X, Y))
  3694.     then
  3695.       begin
  3696.         j := i;
  3697.         Break;
  3698.       end;
  3699.   end;
  3700.   ActiveButton := j;
  3701.   if (CaptureButton <> -1) and
  3702.      (ActiveButton <> CaptureButton) and (ActiveButton <> -1)
  3703.   then
  3704.     ActiveButton := -1;
  3705.   if (OldActiveButton <> ActiveButton)
  3706.   then
  3707.     begin
  3708.       if OldActiveButton <> - 1
  3709.       then
  3710.         ButtonLeave(OldActiveButton);
  3711.       if ActiveButton <> -1
  3712.       then
  3713.         ButtonEnter(ActiveButton);
  3714.     end;
  3715. end;
  3716. procedure TbsSkinCustomListBox.ButtonDown;
  3717. begin
  3718.   Buttons[i].MouseIn := True;
  3719.   Buttons[i].Down := True;
  3720.   DrawButton(Canvas, i);
  3721.   case i of
  3722.     0: if Assigned(FOnUpButtonClick) then Exit;
  3723.     1: if Assigned(FOnDownButtonClick) then Exit;
  3724.     2: if Assigned(FOnCheckButtonClick) then Exit;
  3725.   end;
  3726.   TimerMode := 0;
  3727.   case i of
  3728.     0: TimerMode := 1;
  3729.     1: TimerMode := 2;
  3730.   end;
  3731.   if TimerMode <> 0
  3732.   then
  3733.     begin
  3734.       WaitMode := True;
  3735.       SetTimer(Handle, 1, 500, nil);
  3736.     end;
  3737. end;
  3738. procedure TbsSkinCustomListBox.ButtonUp;
  3739. begin
  3740.   Buttons[i].Down := False;
  3741.   if ActiveButton <> i then Buttons[i].MouseIn := False;
  3742.   DrawButton(Canvas, i);
  3743.   if Buttons[i].MouseIn
  3744.   then
  3745.   case i of
  3746.     0:
  3747.       if Assigned(FOnUpButtonClick)
  3748.       then
  3749.         begin
  3750.           FOnUpButtonClick(Self);
  3751.           Exit;
  3752.         end;
  3753.     1:
  3754.       if Assigned(FOnDownButtonClick)
  3755.       then
  3756.         begin
  3757.           FOnDownButtonClick(Self);
  3758.           Exit;
  3759.         end;
  3760.     2:
  3761.       if Assigned(FOnCheckButtonClick)
  3762.       then
  3763.         begin
  3764.           FOnCheckButtonClick(Self);
  3765.           Exit;
  3766.         end;
  3767.   end;
  3768.   case i of
  3769.     1: ItemIndex := ItemIndex + 1;
  3770.     0: if ItemIndex > 0 then ItemIndex := ItemIndex - 1;
  3771.     2: ListBox.Click;
  3772.   end;
  3773.   if TimerMode <> 0 then StopTimer;
  3774. end;
  3775. procedure TbsSkinCustomListBox.ButtonEnter(I: Integer);
  3776. begin
  3777.   Buttons[i].MouseIn := True;
  3778.   DrawButton(Canvas, i);
  3779.   if (TimerMode <> 0) and Buttons[i].Down
  3780.   then SetTimer(Handle, 1, 50, nil);
  3781. end;
  3782. procedure TbsSkinCustomListBox.ButtonLeave(I: Integer);
  3783. begin
  3784.   Buttons[i].MouseIn := False;
  3785.   DrawButton(Canvas, i);
  3786.   if (TimerMode <> 0) and Buttons[i].Down
  3787.   then KillTimer(Handle, 1);
  3788. end;
  3789. procedure TbsSkinCustomListBox.CMTextChanged;
  3790. begin
  3791.   inherited;
  3792.   if FCaptionMode then RePaint;
  3793. end;
  3794. procedure TbsSkinCustomListBox.SetAlignment(Value: TAlignment);
  3795. begin
  3796.   if FAlignment <> Value
  3797.   then
  3798.     begin
  3799.       FAlignment := Value;
  3800.       if FCaptionMode then RePaint;
  3801.     end;
  3802. end;
  3803. procedure TbsSkinCustomListBox.DrawButton;
  3804. var
  3805.   C: TColor;
  3806.   kf: Double;
  3807.   R1: TRect;
  3808. begin
  3809.   if FIndex = -1
  3810.   then
  3811.     with Buttons[i] do
  3812.     begin
  3813.       R1 := R;