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

Delphi控件源码

开发平台:

Delphi

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