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

Delphi控件源码

开发平台:

Delphi

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