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

Delphi控件源码

开发平台:

Delphi

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