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

Delphi控件源码

开发平台:

Delphi

  1.   C: TCanvas;
  2.   i, j, DrawCount: Integer;
  3.   IR: TRect;
  4. begin
  5.   C := TCanvas.Create;
  6.   C.Handle := DC;
  7.   DrawCount := (Height div ItemHeight) * Columns;
  8.   i := TopIndex;
  9.   j := i + DrawCount;
  10.   if j > Items.Count - 1 then j := Items.Count - 1;
  11.   if Items.Count > 0
  12.   then
  13.     for i := TopIndex to j do
  14.     begin
  15.       IR := ItemRect(i);
  16.       if SkinListBox.FIndex <> -1
  17.       then
  18.         begin
  19.           if SkinListBox.UseSkinItemHeight
  20.           then
  21.             DrawSkinItem(C, i, IR, GetState1(i))
  22.           else
  23.             DrawStretchSkinItem(C, i, IR, GetState1(i));
  24.         end
  25.       else
  26.         DrawDefaultItem(C, i, IR, GetState1(i));
  27.     end;
  28.   C.Free;
  29. end;
  30. procedure TspCheckListBox.PaintList(DC: HDC);
  31. var
  32.   C: TCanvas;
  33.   i, j, k, DrawCount: Integer;
  34.   IR: TRect;
  35. begin
  36.   C := TCanvas.Create;
  37.   C.Handle := DC;
  38.   DrawCount := Height div ItemHeight;
  39.   i := TopIndex;
  40.   j := i + DrawCount;
  41.   if j > Items.Count - 1 then j := Items.Count - 1;
  42.   k := 0;
  43.   if Items.Count > 0
  44.   then
  45.     for i := TopIndex to j do
  46.     begin
  47.       IR := ItemRect(i);
  48.       if SkinListBox.FIndex <> -1
  49.       then
  50.         begin
  51.           if SkinListBox.UseSkinItemHeight
  52.           then
  53.             DrawSkinItem(C, i, IR, GetState1(i))
  54.           else
  55.             DrawStretchSkinItem(C, i, IR, GetState1(i));
  56.         end
  57.       else
  58.         DrawDefaultItem(C, i, IR, GetState1(i));
  59.       k := IR.Bottom;
  60.     end;
  61.   if k < Height
  62.   then
  63.     begin
  64.       SkinListBox.GetSkinData;
  65.       if SkinListBox.FIndex <> -1
  66.       then
  67.         PaintBGWH(C, Width, Height - k, 0, k)
  68.       else
  69.         with C do
  70.         begin
  71.           C.Brush.Color := clWindow;
  72.           FillRect(Rect(0, k, Width, Height));
  73.         end;
  74.     end;
  75.   C.Free;
  76. end;
  77. procedure TspCheckListBox.PaintWindow;
  78. var
  79.   SaveIndex: Integer;
  80. begin
  81.   if (Width <= 0) or (Height <=0) then Exit;
  82.   SaveIndex := SaveDC(DC);
  83.   try
  84.     if Columns > 0
  85.     then
  86.       PaintColumnsList(DC)
  87.     else
  88.       PaintList(DC);
  89.   finally
  90.     RestoreDC(DC, SaveIndex);
  91.   end;
  92. end;
  93. procedure TspCheckListBox.WMPaint;
  94. begin
  95.   PaintHandler(Msg);
  96. end;
  97. procedure TspCheckListBox.WMEraseBkgnd;
  98. begin
  99.   PaintBG(Message.DC);
  100.   Message.Result := 1;
  101. end;
  102. procedure TspCheckListBox.DrawDefaultItem;
  103. var
  104.   Buffer: TBitMap;
  105.   R, R1, CR: TRect;
  106.   AState: TCheckBoxState;
  107.   IIndex, IX, IY: Integer;
  108. begin
  109.   if (ItemID < 0) or (ItemID > Items.Count - 1) then Exit;
  110.   AState := GetState(itemID);
  111.   Buffer := TBitMap.Create;
  112.   Buffer.Width := RectWidth(rcItem);
  113.   Buffer.Height := RectHeight(rcItem);
  114.   R := Rect(20, 0, Buffer.Width, Buffer.Height);
  115.   with Buffer.Canvas do
  116.   begin
  117.     Font.Name := SkinListBox.Font.Name;
  118.     Font.Style := SkinListBox.Font.Style;
  119.     Font.Height := SkinListBox.Font.Height;
  120.     if odSelected in State1
  121.     then
  122.       begin
  123.         Brush.Color := clHighLight;
  124.         Font.Color := clHighLightText;
  125.       end
  126.     else
  127.       begin
  128.         Brush.Color := clWindow;
  129.         Font.Color := SkinListBox.Font.Color;
  130.       end;
  131.     FillRect(R);
  132.   end;
  133.   R1 := Rect(R.Left + 2, R.Top, R.Right - 2, R.Bottom);
  134.   CR := Rect(3, Buffer.Height div 2 - 6, 16, Buffer.Height div 2 + 7);
  135.   Frame3D(Buffer.Canvas, CR, clBtnShadow, clBtnShadow, 1);
  136.   
  137.   if AState = cbChecked
  138.   then
  139.     DrawCheckImage(Buffer.Canvas, 6, Buffer.Height div 2 - 4, clWindowText);
  140.   if Assigned(SkinListBox.FOnDrawItem)
  141.   then
  142.     SkinListBox.FOnDrawItem(Buffer.Canvas, ItemID, Buffer.Width, Buffer.Height,
  143.     R1, State1)
  144.   else
  145.     begin
  146.       if (SkinListBox.Images <> nil)
  147.       then
  148.         begin
  149.           if SkinListBox.ImageIndex > -1
  150.           then IIndex := SkinListBox.FImageIndex
  151.           else IIndex := itemID;
  152.           if IIndex < SkinListBox.Images.Count
  153.           then
  154.             begin
  155.               IX := R1.Left;
  156.               IY := R1.Top + RectHeight(R1) div 2 - SkinListBox.Images.Height div 2;
  157.               SkinListBox.Images.Draw(Buffer.Canvas, IX, IY, IIndex);
  158.             end;
  159.           Inc(R1.Left, SkinListBox.Images.Width + 2);
  160.         end;
  161.       SPDrawText(Buffer.Canvas, Items[ItemID], R1);
  162.     end;
  163.   if odFocused in State1 then DrawFocusRect(Buffer.Canvas.Handle, R);
  164.   Cnvs.Draw(rcItem.Left, rcItem.Top, Buffer);
  165.   Buffer.Free;
  166. end;
  167. procedure TspCheckListBox.DrawStretchSkinItem;
  168. var
  169.   Buffer, Buffer2: TBitMap;
  170.   R, R1: TRect;
  171.   W, H: Integer;
  172.   OX, OY: Integer;
  173.   AState: TCheckBoxState;
  174.   cw, ch, cx, cy: Integer;
  175.   IIndex, IX, IY: Integer;
  176. begin
  177.   if (SkinListBox.Picture = nil) or (ItemID < 0) or (ItemID > Items.Count - 1) then Exit;
  178.   AState := GetState(itemID);
  179.   Buffer := TBitMap.Create;
  180.   with SkinListBox do
  181.   begin
  182.     W := RectWidth(rcItem);
  183.     H := RectHeight(SItemRect);
  184.     Buffer.Width := W;
  185.     Buffer.Height := H;
  186.     if odFocused in State1
  187.     then
  188.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  189.       FocusItemRect, W, H)
  190.     else
  191.     if odSelected in State1
  192.     then
  193.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  194.       ActiveItemRect, W, H)
  195.     else
  196.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  197.       SItemRect, W, H);
  198.     R := ItemTextRect;
  199.     OX :=  W - RectWidth(SItemRect);
  200.     OY := RectHeight(rcItem) - RectHeight(SItemRect);
  201.     Inc(R.Right, OX);
  202.     Inc(R.Bottom, OY);
  203.     R1 := ItemCheckRect;
  204.     if R1.Left >= ItemTextRect.Right then OffsetRect(R1, OX, 0);
  205.     Inc(R1.Bottom, OY);
  206.     cw := RectWidth(CheckImageRect);
  207.     ch := RectHeight(CheckImageRect);
  208.     cx := R1.Left + RectWidth(R1) div 2;
  209.     cy := R1.Top + RectHeight(R1) div 2;
  210.     R1 := Rect(cx - cw div 2, cy - ch div 2,
  211.                cx - cw div 2 + cw, cy - ch div 2 + ch);
  212.   end;
  213.   W := RectWidth(rcItem);
  214.   H := RectHeight(rcItem);
  215.   Buffer2 := TBitMap.Create;
  216.   Buffer2.Width := W;
  217.   Buffer2.Height := H;
  218.   Buffer2.Canvas.StretchDraw(Rect(0, 0, Buffer2.Width, Buffer2.Height), Buffer);
  219.   Buffer.Free;
  220.   //
  221.   if AState = cbChecked
  222.   then
  223.     SkinDrawCheckImage(R1.Left, R1.Top, SkinListBox.Picture.Canvas, SkinListBox.CheckImageRect, Buffer2.Canvas)
  224.   else
  225.     SkinDrawCheckImage(R1.Left, R1.Top, SkinListBox.Picture.Canvas, SkinListBox.UnCheckImageRect, Buffer2.Canvas);
  226.   //
  227.   with Buffer2.Canvas do
  228.   begin
  229.     if SkinListBox.UseSkinFont
  230.     then
  231.       begin
  232.         Font.Name := SkinListBox.FontName;
  233.         Font.Style := SkinListBox.FontStyle;
  234.         Font.Height := SkinListBox.FontHeight;
  235.         Font.CharSet := SkinListBox.DefaultFont.CharSet;
  236.       end
  237.     else
  238.       Font.Assign(SkinListBox.DefaultFont);
  239.     if odFocused in State1
  240.     then
  241.       Font.Color := SkinListBox.FocusFontColor
  242.     else
  243.     if odSelected in State1
  244.     then
  245.       Font.Color := SkinListBox.ActiveFontColor
  246.     else
  247.       Font.Color := SkinListBox.FontColor;
  248.     Brush.Style := bsClear;
  249.   end;
  250.   if Assigned(SkinListBox.FOnDrawItem)
  251.   then
  252.     SkinListBox.FOnDrawItem(Buffer2.Canvas, ItemID, Buffer2.Width, Buffer2.Height,
  253.     R, State1)
  254.   else
  255.     begin
  256.       if (SkinListBox.Images <> nil)
  257.       then
  258.         begin
  259.           if SkinListBox.ImageIndex > -1
  260.           then IIndex := SkinListBox.FImageIndex
  261.           else IIndex := itemID;
  262.           if IIndex < SkinListBox.Images.Count
  263.           then
  264.             begin
  265.               IX := R.Left;
  266.               IY := R.Top + RectHeight(R) div 2 - SkinListBox.Images.Height div 2;
  267.               SkinListBox.Images.Draw(Buffer2.Canvas, IX, IY, IIndex);
  268.             end;
  269.           Inc(R.Left, SkinListBox.Images.Width + 2);
  270.         end;
  271.       SPDrawText2(Buffer2.Canvas, Items[ItemID], R);
  272.     end;
  273.   Cnvs.Draw(rcItem.Left, rcItem.Top, Buffer2);
  274.   Buffer2.Free;
  275. end;
  276. procedure TspCheckListBox.DrawSkinItem;
  277. var
  278.   Buffer: TBitMap;
  279.   R, R1: TRect;
  280.   W, H: Integer;
  281.   OX: Integer;
  282.   AState: TCheckBoxState;
  283.   cw, ch, cx, cy: Integer;
  284.   IIndex, IX, IY: Integer;
  285. begin
  286.   if (SkinListBox.Picture = nil) or (ItemID < 0) or (ItemID > Items.Count - 1) then Exit;
  287.   AState := GetState(itemID);
  288.   Buffer := TBitMap.Create;
  289.   with SkinListBox do
  290.   begin
  291.     W := RectWidth(rcItem);
  292.     H := RectHeight(SItemRect);
  293.     Buffer.Width := W;
  294.     Buffer.Height := H;
  295.     if odFocused in State1
  296.     then
  297.       begin
  298.         if not (odSelected in State1)
  299.         then
  300.           begin
  301.             CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  302.               SItemRect, W, H);
  303.             R := Rect(0, 0, Buffer.Width, Buffer.Height);
  304.             DrawFocusRect(Buffer.Canvas.Handle, R);
  305.           end
  306.         else
  307.           CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  308.             FocusItemRect, W, H)
  309.       end
  310.     else
  311.     if odSelected in State1
  312.     then
  313.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  314.       ActiveItemRect, W, H)
  315.     else
  316.       CreateHSkinImage(ItemLeftOffset, ItemRightOffset, Buffer, Picture,
  317.       SItemRect, W, H);
  318.     R := ItemTextRect;
  319.     OX :=  W - RectWidth(SItemRect);
  320.     Inc(R.Right, OX);
  321.     R1 := ItemCheckRect;
  322.     if R1.Left >= ItemTextRect.Right then OffsetRect(R1, OX, 0);
  323.     cw := RectWidth(CheckImageRect);
  324.     ch := RectHeight(CheckImageRect);
  325.     cx := R1.Left + RectWidth(R1) div 2;
  326.     cy := R1.Top + RectHeight(R1) div 2;
  327.     R1 := Rect(cx - cw div 2, cy - ch div 2,
  328.                cx - cw div 2 + cw, cy - ch div 2 + ch);
  329.     if AState = cbChecked
  330.     then
  331.       SkinDrawCheckImage(R1.Left, R1.Top, Picture.Canvas, CheckImageRect, Buffer.Canvas)
  332.     else
  333.       SkinDrawCheckImage(R1.Left, R1.Top, Picture.Canvas, UnCheckImageRect, Buffer.Canvas);
  334.   end;
  335.   with Buffer.Canvas do
  336.   begin
  337.     if SkinListBox.UseSkinFont
  338.     then
  339.       begin
  340.         Font.Name := SkinListBox.FontName;
  341.         Font.Style := SkinListBox.FontStyle;
  342.         Font.Height := SkinListBox.FontHeight;
  343.         Font.CharSet := SkinListBox.DefaultFont.CharSet;
  344.       end
  345.     else
  346.       Font.Assign(SkinListBox.DefaultFont);
  347.     if odFocused in State1
  348.     then
  349.       begin
  350.         if not (odSelected in State1)
  351.         then
  352.           Font.Color := SkinListBox.FontColor
  353.         else
  354.           Font.Color := SkinListBox.FocusFontColor;
  355.       end
  356.     else
  357.     if odSelected in State1
  358.     then
  359.       Font.Color := SkinListBox.ActiveFontColor
  360.     else
  361.       Font.Color := SkinListBox.FontColor;
  362.     Brush.Style := bsClear;
  363.   end;
  364.   if Assigned(SkinListBox.FOnDrawItem)
  365.   then
  366.     SkinListBox.FOnDrawItem(Buffer.Canvas, ItemID, Buffer.Width, Buffer.Height,
  367.     R, State1)
  368.   else
  369.     begin
  370.       if (SkinListBox.Images <> nil)
  371.       then
  372.         begin
  373.           if SkinListBox.ImageIndex > -1
  374.           then IIndex := SkinListBox.FImageIndex
  375.           else IIndex := itemID;
  376.           if IIndex < SkinListBox.Images.Count
  377.           then
  378.             begin
  379.               IX := R.Left;
  380.               IY := R.Top + RectHeight(R) div 2 - SkinListBox.Images.Height div 2;
  381.               SkinListBox.Images.Draw(Buffer.Canvas, IX, IY, IIndex);
  382.             end;
  383.           Inc(R.Left, SkinListBox.Images.Width + 2);
  384.         end;
  385.       SPDrawText(Buffer.Canvas, Items[ItemID], R);
  386.     end;
  387.   Cnvs.Draw(rcItem.Left, rcItem.Top, Buffer);
  388.   Buffer.Free;
  389. end;
  390. procedure TspCheckListBox.CreateParams;
  391. begin
  392.   inherited CreateParams(Params);
  393.   with Params do
  394.   begin
  395.     Style := Style and not WS_BORDER;
  396.     ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
  397.     WindowClass.style := CS_DBLCLKS;
  398.     Style := Style or WS_TABSTOP;
  399.   end;
  400. end;
  401. procedure TspCheckListBox.CNDrawItem;
  402. var
  403.   State: TOwnerDrawState;
  404. begin
  405.   with Message.DrawItemStruct^ do
  406.   begin
  407.     {$IFDEF VER120}
  408.       State := TOwnerDrawState(WordRec(LongRec(itemState).Lo).Lo);
  409.     {$ELSE}
  410.       {$IFDEF VER125}
  411.         State := TOwnerDrawState(WordRec(LongRec(itemState).Lo).Lo);
  412.       {$ELSE}
  413.         State := TOwnerDrawState(LongRec(itemState).Lo);
  414.       {$ENDIF}
  415.     {$ENDIF}
  416.     Canvas.Handle := hDC;
  417.     Canvas.Font := Font;
  418.     Canvas.Brush := Brush;
  419.     if SkinListBox.FIndex <> -1
  420.     then
  421.       begin
  422.         if SkinListBox.UseSkinItemHeight
  423.         then
  424.           DrawSkinItem(Canvas, itemID, rcItem, State)
  425.         else
  426.           DrawStretchSkinItem(Canvas, itemID, rcItem, State);
  427.       end
  428.     else
  429.       DrawDefaultItem(Canvas, itemID, rcItem, State);
  430.     Canvas.Handle := 0;
  431.   end;
  432. end;
  433. procedure TspCheckListBox.WndProc;
  434. var
  435.   LParam, WParam: Integer;
  436. begin
  437.   inherited;
  438.   case Message.Msg of
  439.     WM_LBUTTONDBLCLK:
  440.       begin
  441.         if SkinListBox <> nil then SkinListBox.ListBoxDblClick;
  442.       end;
  443.     WM_MOUSEWHEEL:
  444.       if (SkinListBox <> nil) and (SkinListBox.ScrollBar <> nil)
  445.       then
  446.       begin
  447.         LParam := 0;
  448.         if Message.WParam > 0
  449.         then
  450.           WParam := MakeWParam(SB_LINEUP, 0)
  451.         else
  452.           WParam := MakeWParam(SB_LINEDOWN, 0);
  453.         SendMessage(Handle, WM_VSCROLL, WParam, LParam);
  454.         SkinListBox.UpDateScrollBar;
  455.       end;
  456.     WM_ERASEBKGND:
  457.       SkinListBox.UpDateScrollBar;
  458.     LB_ADDSTRING, LB_INSERTSTRING,
  459.     LB_DELETESTRING:
  460.       begin
  461.         if SkinListBox <> nil
  462.         then
  463.           SkinListBox.UpDateScrollBar;
  464.       end;
  465.   end;
  466. end;
  467. constructor TspSkinCheckListBox.Create;
  468. begin
  469.   inherited;
  470.   ControlStyle := [csCaptureMouse, csClickEvents,
  471.     csOpaque, csDoubleClicks, csReplicatable, csAcceptsControls];
  472.   FUseSkinItemHeight := True;
  473.   FRowCount := 0;
  474.   FGlyph := TBitMap.Create;
  475.   FNumGlyphs := 1;
  476.   FSpacing := 2;
  477.   FImageIndex := -1;
  478.   FDefaultCaptionFont := TFont.Create;
  479.   FDefaultCaptionFont.OnChange := OnDefaultCaptionFontChange;
  480.   FDefaultCaptionFont.Name := 'Arial';
  481.   FDefaultCaptionFont.Height := 14;
  482.   FDefaultCaptionHeight := 20;
  483.   ActiveButton := -1;
  484.   OldActiveButton := -1;
  485.   CaptureButton := -1;
  486.   FCaptionMode := False;
  487.   FDefaultItemHeight := 20;
  488.   TimerMode := 0;
  489.   WaitMode := False;
  490.   Font.Name := 'Arial';
  491.   Font.Height := 14;
  492.   Font.Color := clWindowText;
  493.   Font.Style := [];
  494.   ScrollBar := nil;
  495.   ListBox := TspCheckListBox.Create(Self);
  496.   ListBox.SkinListBox := Self;
  497.   ListBox.Style := lbOwnerDrawFixed;
  498.   ListBox.ItemHeight := FDefaultItemHeight;
  499.   ListBox.Parent := Self;
  500.   ListBox.Visible := True;
  501.   Height := 120;
  502.   Width := 120;
  503.   FSkinDataName := 'checklistbox';
  504. end;
  505. function TspSkinCheckListBox.GetAutoComplete: Boolean;
  506. begin
  507.   Result := ListBox.AutoComplete;
  508. end;
  509. procedure TspSkinCheckListBox.SetAutoComplete(Value: Boolean);
  510. begin
  511.   ListBox.AutoComplete := Value;
  512. end;
  513. function TspSkinCheckListBox.GetOnListBoxEndDrag: TEndDragEvent;
  514. begin
  515.   Result := ListBox.OnEndDrag;
  516. end;
  517. procedure TspSkinCheckListBox.SetOnListBoxEndDrag(Value: TEndDragEvent);
  518. begin
  519.   ListBox.OnEndDrag := Value;
  520. end;
  521. function TspSkinCheckListBox.GetOnListBoxStartDrag: TStartDragEvent;
  522. begin
  523.   Result := ListBox.OnStartDrag;
  524. end;
  525. procedure TspSkinCheckListBox.SetOnListBoxStartDrag(Value: TStartDragEvent);
  526. begin
  527.   ListBox.OnStartDrag := Value;
  528. end;
  529. function TspSkinCheckListBox.GetOnListBoxDragOver: TDragOverEvent;
  530. begin
  531.   Result := ListBox.OnDragOver;
  532. end;
  533. procedure TspSkinCheckListBox.SetOnListBoxDragOver(Value: TDragOverEvent);
  534. begin
  535.   ListBox.OnDragOver := Value;
  536. end;
  537. function TspSkinCheckListBox.GetOnListBoxDragDrop: TDragDropEvent;
  538. begin
  539.   Result := ListBox.OnDragDrop;
  540. end;
  541. procedure TspSkinCheckListBox.SetOnListBoxDragDrop(Value: TDragDropEvent);
  542. begin
  543.   ListBox.OnDragDrop := Value;
  544. end;
  545. function TspSkinCheckListBox.GetColumns;
  546. begin
  547.   Result := ListBox.Columns;
  548. end;
  549. function TspSkinCheckListBox.GetListBoxDragMode: TDragMode;
  550. begin
  551.   Result := ListBox.DragMode;
  552. end;
  553. procedure TspSkinCheckListBox.SetListBoxDragMode(Value: TDragMode);
  554. begin
  555.   ListBox.DragMode := Value;
  556. end;
  557. function TspSkinCheckListBox.GetListBoxDragKind: TDragKind;
  558. begin
  559.   Result := ListBox.DragKind;
  560. end;
  561. procedure TspSkinCheckListBox.SetListBoxDragKind(Value: TDragKind);
  562. begin
  563.   ListBox.DragKind := Value;
  564. end;
  565. function TspSkinCheckListBox.GetListBoxDragCursor: TCursor;
  566. begin
  567.   Result := ListBox.DragCursor;
  568. end;
  569. procedure TspSkinCheckListBox.SetListBoxDragCursor(Value: TCursor);
  570. begin
  571.   ListBox.DragCursor := Value;
  572. end;
  573. procedure TspSkinCheckListBox.SetColumns;
  574. begin
  575.   ListBox.Columns := Value;
  576.   UpDateScrollBar;
  577. end;
  578. procedure TspSkinCheckListBox.SetRowCount;
  579. begin
  580.   FRowCount := Value;
  581.   if FRowCount <> 0
  582.   then
  583.     Height := Self.CalcHeight(FRowCount);
  584. end;
  585. procedure TspSkinCheckListBox.SetImages(Value: TCustomImageList);
  586. begin
  587.   FImages := Value;
  588.   ListBox.RePaint;
  589. end;
  590. procedure TspSkinCheckListBox.SetImageIndex(Value: Integer);
  591. begin
  592.   FImageIndex := Value;
  593.   ListBox.RePaint;
  594. end;
  595. procedure TspSkinCheckListBox.SetNumGlyphs;
  596. begin
  597.   FNumGlyphs := Value;
  598.   RePaint;
  599. end;
  600. procedure TspSkinCheckListBox.SetGlyph;
  601. begin
  602.   FGlyph.Assign(Value);
  603.   RePaint;
  604. end;
  605. procedure TspSkinCheckListBox.SetSpacing;
  606. begin
  607.   FSpacing := Value;
  608.   RePaint;
  609. end;
  610. procedure TspSkinCheckListBox.Notification(AComponent: TComponent;
  611.   Operation: TOperation);
  612. begin
  613.   inherited Notification(AComponent, Operation);
  614.   if (Operation = opRemove) and (AComponent = Images) then
  615.     Images := nil;
  616. end;
  617. procedure TspSkinCheckListBox.OnDefaultCaptionFontChange;
  618. begin
  619.   if (FIndex = -1) and FCaptionMode then RePaint;
  620. end;
  621. procedure TspSkinCheckListBox.SetDefaultCaptionHeight;
  622. begin
  623.   FDefaultCaptionHeight := Value;
  624.   if (FIndex = -1) and FCaptionMode
  625.   then
  626.     begin
  627.       CalcRects;
  628.       RePaint;
  629.     end;
  630. end;
  631. procedure TspSkinCheckListBox.SetDefaultCaptionFont;
  632. begin
  633.   FDefaultCaptionFont.Assign(Value);
  634. end;
  635. procedure TspSkinCheckListBox.StartTimer;
  636. begin
  637.   KillTimer(Handle, 1);
  638.   SetTimer(Handle, 1, 100, nil);
  639. end;
  640. procedure TspSkinCheckListBox.SetDefaultItemHeight;
  641. begin
  642.   FDefaultItemHeight := Value;
  643.   if FIndex = -1
  644.   then
  645.     ListBox.ItemHeight := FDefaultItemHeight;
  646. end;
  647. procedure TspSkinCheckListBox.StopTimer;
  648. begin
  649.   KillTimer(Handle, 1);
  650.   TimerMode := 0;
  651. end;
  652. procedure TspSkinCheckListBox.WMTimer;
  653. begin
  654.   inherited;
  655.   if WaitMode
  656.   then
  657.     begin
  658.       WaitMode := False;
  659.       StartTimer;
  660.       Exit;
  661.     end;
  662.   case TimerMode of
  663.     1: if ItemIndex > 0 then ItemIndex := ItemIndex - 1;
  664.     2: ItemIndex := ItemIndex + 1;
  665.   end;
  666. end;
  667. procedure TspSkinCheckListBox.CreateControlSkinImage;
  668. var
  669.   GX, GY, GlyphNum, TX, TY, i, OffX, OffY: Integer;
  670. function GetGlyphTextWidth: Integer;
  671. begin
  672.   Result := B.Canvas.TextWidth(Caption);
  673.   if not FGlyph.Empty then Result := Result + FGlyph.Width div FNumGlyphs + FSpacing;
  674. end;
  675. function CalcBRect(BR: TRect): TRect;
  676. var
  677.   R: TRect;
  678. begin
  679.   R := BR;
  680.   if BR.Top <= LTPt.Y
  681.   then
  682.     begin
  683.       if BR.Left > RTPt.X then OffsetRect(R, OffX, 0);
  684.     end
  685.   else
  686.     begin
  687.       OffsetRect(R, 0, OffY);
  688.       if BR.Left > RBPt.X then OffsetRect(R, OffX, 0);
  689.     end;
  690.   Result := R;
  691. end;
  692. begin
  693.   inherited;
  694.   // calc rects
  695.   OffX := Width - RectWidth(SkinRect);
  696.   OffY := Height - RectHeight(SkinRect);
  697.   NewClRect := ClRect;
  698.   Inc(NewClRect.Right, OffX);
  699.   Inc(NewClRect.Bottom, OffY);
  700.   if FCaptionMode
  701.   then
  702.     begin
  703.       NewCaptionRect := CaptionRect;
  704.       if CaptionRect.Right >= RTPt.X
  705.       then
  706.         Inc(NewCaptionRect.Right, OffX);
  707.       Buttons[0].R := CalcBRect(UpButtonRect);
  708.       Buttons[1].R := CalcBRect(DownButtonRect);
  709.       Buttons[2].R := CalcBRect(CheckButtonRect);
  710.     end;  
  711.   // paint caption
  712.   if not IsNullRect(CaptionRect)
  713.   then
  714.     with B.Canvas do
  715.     begin
  716.       Font.Name := CaptionFontName;
  717.       Font.Height := CaptionFontHeight;
  718.       Font.Color := CaptionFontColor;
  719.       Font.Style := CaptionFontStyle;
  720.       Font.CharSet := DefaultCaptionFont.CharSet;
  721.       TY := NewCaptionRect.Top + RectHeight(NewCaptionRect) div 2 -
  722.             TextHeight(Caption) div 2;
  723.       TX := NewCaptionRect.Left + 2;
  724.       case Alignment of
  725.         taCenter: TX := TX + RectWidth(NewCaptionRect) div 2 - GetGlyphTextWidth div 2;
  726.         taRightJustify: TX := NewCaptionRect.Right - GetGlyphTextWidth - 2;
  727.       end;
  728.       Brush.Style := bsClear;
  729.       if not FGlyph.Empty
  730.       then
  731.       begin
  732.         GY := NewCaptionRect.Top + RectHeight(NewCaptionRect) div 2 - FGlyph.Height div 2;
  733.         GX := TX;
  734.         TX := GX + FGlyph.Width div FNumGlyphs + FSpacing;
  735.         GlyphNum := 1;
  736.         if not Enabled and (NumGlyphs = 2) then GlyphNum := 2;
  737.        end;
  738.       TextRect(NewCaptionRect, TX, TY, Caption);
  739.       if not FGlyph.Empty
  740.       then DrawGlyph(B.Canvas, GX, GY, FGlyph, NumGlyphs, GlyphNum);
  741.     end;
  742.   // paint buttons
  743.   for i := 0 to 2 do DrawButton(B.Canvas, i);
  744. end;
  745. procedure TspSkinCheckListBox.CreateControlDefaultImage;
  746. function GetGlyphTextWidth: Integer;
  747. begin
  748.   Result := B.Canvas.TextWidth(Caption);
  749.   if not FGlyph.Empty then Result := Result + FGlyph.Width div FNumGlyphs + FSpacing;
  750. end;
  751. var
  752.   BW, i, TX, TY: Integer;
  753.   R: TRect;
  754.   GX, GY: Integer;
  755.   GlyphNum: Integer;
  756. begin
  757.   inherited;
  758.   if FCaptionMode
  759.   then
  760.     begin
  761.       BW := 17;
  762.       if BW > FDefaultCaptionHeight - 3 then BW := FDefaultCaptionHeight - 3;
  763.       Buttons[0].R := Rect(Width - BW - 2, 2, Width - 2, 1 + BW);
  764.       Buttons[1].R := Rect(Buttons[0].R.Left - BW, 2, Buttons[0].R.Left, 1 + BW);
  765.       Buttons[2].R := Rect(Buttons[1].R.Left - BW, 2, Buttons[1].R.Left, 1 + BW);
  766.     end;  
  767.   R := ClientRect;
  768.   Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  769.   if FCaptionMode
  770.   then
  771.     with B.Canvas do
  772.     begin
  773.       R := Rect(3, 2, Width - BW * 3 - 3, FDefaultCaptionHeight - 2);
  774.       Font.Assign(FDefaultCaptionFont);
  775.       case Alignment of
  776.         taLeftJustify: TX := R.Left;
  777.         taCenter: TX := R.Left + RectWidth(R) div 2 - GetGlyphTextWidth div 2;
  778.         taRightJustify: TX := R.Right - GetGlyphTextWidth;
  779.       end;
  780.       TY := (FDefaultCaptionHeight - 2) div 2 - TextHeight(Caption) div 2;
  781.       if not FGlyph.Empty
  782.       then
  783.         begin
  784.           GY := R.Top + RectHeight(R) div 2 - FGlyph.Height div 2 - 1;
  785.           GX := TX;
  786.           if FNumGlyphs = 0 then FNumGlyphs := 1; 
  787.           TX := GX + FGlyph.Width div FNumGlyphs + FSpacing;
  788.           GlyphNum := 1;
  789.           if not Enabled and (NumGlyphs = 2) then GlyphNum := 2;
  790.         end;
  791.       TextRect(R, TX, TY, Caption);
  792.       if not FGlyph.Empty
  793.       then DrawGlyph(B.Canvas, GX, GY, FGlyph, NumGlyphs, GlyphNum);
  794.       Pen.Color := clBtnShadow;
  795.       MoveTo(1, FDefaultCaptionHeight - 1); LineTo(Width - 1, FDefaultCaptionHeight - 1);
  796.       for i := 0 to 2 do DrawButton(B.Canvas, i);
  797.     end;
  798. end;
  799. procedure TspSkinCheckListBox.CMMouseEnter;
  800. begin
  801.   inherited;
  802.   if FCaptionMode
  803.   then
  804.     TestActive(-1, -1);
  805. end;
  806. procedure TspSkinCheckListBox.CMMouseLeave;
  807. var
  808.   i: Integer;
  809. begin
  810.   inherited;
  811.   if FCaptionMode
  812.   then
  813.   for i := 0 to 1 do
  814.     if Buttons[i].MouseIn
  815.     then
  816.        begin
  817.          Buttons[i].MouseIn := False;
  818.          RePaint;
  819.        end;
  820. end;
  821. procedure TspSkinCheckListBox.MouseDown;
  822. begin
  823.   if FCaptionMode
  824.   then
  825.     begin
  826.       TestActive(X, Y);
  827.       if ActiveButton <> -1
  828.       then
  829.         begin
  830.           CaptureButton := ActiveButton;
  831.           ButtonDown(ActiveButton, X, Y);
  832.       end;
  833.     end;
  834.   inherited;
  835. end;
  836. procedure TspSkinCheckListBox.MouseUp;
  837. begin
  838.   if FCaptionMode
  839.   then
  840.     begin
  841.       if CaptureButton <> -1
  842.       then ButtonUp(CaptureButton, X, Y);
  843.       CaptureButton := -1;
  844.     end;  
  845.   inherited;
  846. end;
  847. procedure TspSkinCheckListBox.MouseMove;
  848. begin
  849.   inherited;
  850.   if FCaptionMode then TestActive(X, Y);
  851. end;
  852. procedure TspSkinCheckListBox.TestActive(X, Y: Integer);
  853. var
  854.   i, j: Integer;
  855. begin
  856.   if (FIndex <> -1) and IsNullRect(UpButtonRect) and IsNullRect(DownButtonRect)
  857.   then Exit; 
  858.   j := -1;
  859.   OldActiveButton := ActiveButton;
  860.   for i := 0 to 2 do
  861.   begin
  862.     if PtInRect(Buttons[i].R, Point(X, Y))
  863.     then
  864.       begin
  865.         j := i;
  866.         Break;
  867.       end;
  868.   end;
  869.   ActiveButton := j;
  870.   if (CaptureButton <> -1) and
  871.      (ActiveButton <> CaptureButton) and (ActiveButton <> -1)
  872.   then
  873.     ActiveButton := -1;
  874.   if (OldActiveButton <> ActiveButton)
  875.   then
  876.     begin
  877.       if OldActiveButton <> - 1
  878.       then
  879.         ButtonLeave(OldActiveButton);
  880.       if ActiveButton <> -1
  881.       then
  882.         ButtonEnter(ActiveButton);
  883.     end;
  884. end;
  885. procedure TspSkinCheckListBox.ButtonDown;
  886. begin
  887.   Buttons[i].MouseIn := True;
  888.   Buttons[i].Down := True;
  889.   DrawButton(Canvas, i);
  890.   case i of
  891.     0: if Assigned(FOnUpButtonClick) then Exit;
  892.     1: if Assigned(FOnDownButtonClick) then Exit;
  893.     2: if Assigned(FOnCheckButtonClick) then Exit;
  894.   end;
  895.   TimerMode := 0;
  896.   case i of
  897.     0: TimerMode := 1;
  898.     1: TimerMode := 2;
  899.   end;
  900.   if TimerMode <> 0
  901.   then
  902.     begin
  903.       WaitMode := True;
  904.       SetTimer(Handle, 1, 500, nil);
  905.     end;
  906. end;
  907. procedure TspSkinCheckListBox.ButtonUp;
  908. begin
  909.   Buttons[i].Down := False;
  910.   if ActiveButton <> i then Buttons[i].MouseIn := False;
  911.   DrawButton(Canvas, i);
  912.   case i of
  913.     0:
  914.       if Assigned(FOnUpButtonClick)
  915.       then
  916.         begin
  917.           FOnUpButtonClick(Self);
  918.           Exit;
  919.         end;
  920.     1:
  921.       if Assigned(FOnDownButtonClick)
  922.       then
  923.         begin
  924.           FOnDownButtonClick(Self);
  925.           Exit;
  926.         end;
  927.     2:
  928.       if Assigned(FOnCheckButtonClick)
  929.       then
  930.         begin
  931.           FOnCheckButtonClick(Self);
  932.           Exit;
  933.         end;
  934.   end;
  935.   case i of
  936.     1: ItemIndex := ItemIndex + 1;
  937.     0: if ItemIndex > 0 then ItemIndex := ItemIndex - 1;
  938.     2: if ItemIndex > -1
  939.        then
  940.          begin
  941.            Checked[ItemIndex] := not Checked[ListBox.ItemIndex];
  942.            ListBoxOnClickCheck(Self);
  943.         end;
  944.   end;
  945.   if TimerMode <> 0 then StopTimer;
  946. end;
  947. procedure TspSkinCheckListBox.ButtonEnter(I: Integer);
  948. begin
  949.   Buttons[i].MouseIn := True;
  950.   DrawButton(Canvas, i);
  951.   if (TimerMode <> 0) and Buttons[i].Down
  952.   then SetTimer(Handle, 1, 50, nil);
  953. end;
  954. procedure TspSkinCheckListBox.ButtonLeave(I: Integer);
  955. begin
  956.   Buttons[i].MouseIn := False;
  957.   DrawButton(Canvas, i);
  958.   if (TimerMode <> 0) and Buttons[i].Down
  959.   then KillTimer(Handle, 1);
  960. end;
  961. procedure TspSkinCheckListBox.CMTextChanged;
  962. begin
  963.   inherited;
  964.   if FCaptionMode then RePaint;
  965. end;
  966. procedure TspSkinCheckListBox.SetAlignment(Value: TAlignment);
  967. begin
  968.   if FAlignment <> Value
  969.   then
  970.     begin
  971.       FAlignment := Value;
  972.       if FCaptionMode then RePaint;
  973.     end;
  974. end;
  975. procedure TspSkinCheckListBox.DrawButton;
  976. var
  977.   C: TColor;
  978.   kf: Double;
  979.   R1: TRect;
  980. begin
  981.   if FIndex = -1
  982.   then
  983.     with Buttons[i] do
  984.     begin
  985.       R1 := R;
  986.       if Down and MouseIn
  987.       then
  988.         begin
  989.           Frame3D(Cnvs, R1, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  990.           Cnvs.Brush.Color := SP_XP_BTNDOWNCOLOR;
  991.           Cnvs.FillRect(R1);
  992.         end
  993.       else
  994.         if MouseIn
  995.         then
  996.           begin
  997.             Frame3D(Cnvs, R1, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  998.             Cnvs.Brush.Color := SP_XP_BTNACTIVECOLOR;
  999.             Cnvs.FillRect(R1);
  1000.           end
  1001.         else
  1002.           begin
  1003.             Cnvs.Brush.Color := clBtnFace;
  1004.             Cnvs.FillRect(R1);
  1005.           end;
  1006.       C := clBlack;
  1007.       case i of
  1008.         0: DrawArrowImage(Cnvs, R, C, 3);
  1009.         1: DrawArrowImage(Cnvs, R, C, 4);
  1010.         2: DrawCheckImage(Cnvs, R.Left + 4, R.Top + 4, C);
  1011.       end;
  1012.     end
  1013.   else
  1014.     with Buttons[i] do
  1015.     if not IsNullRect(R) then
  1016.     begin
  1017.       R1 := NullRect;
  1018.       case I of
  1019.         0:
  1020.           begin
  1021.             if Down and MouseIn
  1022.             then R1 := DownUpButtonRect
  1023.             else if MouseIn then R1 := ActiveUpButtonRect;
  1024.           end;
  1025.         1:
  1026.           begin
  1027.             if Down and MouseIn
  1028.             then R1 := DownDownButtonRect
  1029.             else if MouseIn then R1 := ActiveDownButtonRect;
  1030.           end;
  1031.         2: begin
  1032.             if Down and MouseIn
  1033.             then R1 := DownCheckButtonRect
  1034.             else if MouseIn then R1 := ActiveCheckButtonRect;
  1035.            end;
  1036.       end;
  1037.       if not IsNullRect(R1)
  1038.       then
  1039.         Cnvs.CopyRect(R, Picture.Canvas, R1)
  1040.       else
  1041.         begin
  1042.           case I of
  1043.             0: R1 := UpButtonRect;
  1044.             1: R1 := DownButtonRect;
  1045.             2: R1 := CheckButtonRect;
  1046.           end;
  1047.           OffsetRect(R1, SkinRect.Left, SkinRect.Top);
  1048.           Cnvs.CopyRect(R, Picture.Canvas, R1);
  1049.         end;
  1050.     end;
  1051. end;
  1052. procedure TspSkinCheckListBox.SetCaptionMode;
  1053. begin
  1054.   FCaptionMode := Value;
  1055.   if FIndex = -1
  1056.   then
  1057.     begin
  1058.       CalcRects;
  1059.       RePaint;
  1060.     end;
  1061. end;
  1062. procedure TspSkinCheckListBox.ListBoxOnClickCheck(Sender: TObject);
  1063. begin
  1064.   if Assigned(FOnClickCheck) then FOnClickCheck(Self);
  1065. end;
  1066. procedure TspSkinCheckListBox.SetChecked;
  1067. begin
  1068.   ListBox.Checked[Index] := Checked;
  1069. end;
  1070. function TspSkinCheckListBox.GetChecked;
  1071. begin
  1072.   Result := ListBox.Checked[Index];
  1073. end;
  1074. procedure TspSkinCheckListBox.SetState;
  1075. begin
  1076.   ListBox.State[Index] := AState;
  1077. end;
  1078. function TspSkinCheckListBox.GetState;
  1079. begin
  1080.   Result := ListBox.State[Index];
  1081. end;
  1082. function TspSkinCheckListBox.CalcHeight;
  1083. begin
  1084.   if FIndex = -1
  1085.   then
  1086.     Result := AitemsCount * ListBox.ItemHeight + 4
  1087.   else
  1088.     Result := ClRect.Top + AitemsCount * ListBox.ItemHeight +
  1089.               RectHeight(SkinRect) - ClRect.Bottom;
  1090. end;
  1091. procedure TspSkinCheckListBox.Clear;
  1092. begin
  1093.   ListBox.Clear;
  1094. end;
  1095. function TspSkinCheckListBox.ItemAtPos(Pos: TPoint; Existing: Boolean): Integer;
  1096. begin
  1097.   Result := ListBox.ItemAtPos(Pos, Existing);
  1098. end;
  1099. function TspSkinCheckListBox.ItemRect(Item: Integer): TRect;
  1100. begin
  1101.   Result := ListBox.ItemRect(Item);
  1102. end;
  1103. function TspSkinCheckListBox.GetListBoxPopupMenu;
  1104. begin
  1105.   Result := ListBox.PopupMenu;
  1106. end;
  1107. procedure TspSkinCheckListBox.SetListBoxPopupMenu;
  1108. begin
  1109.   ListBox.PopupMenu := Value;
  1110. end;
  1111. function TspSkinCheckListBox.GetCanvas: TCanvas;
  1112. begin
  1113.   Result := ListBox.Canvas;
  1114. end;
  1115. function TspSkinCheckListBox.GetExtandedSelect: Boolean;
  1116. begin
  1117.   Result := ListBox.ExtendedSelect;
  1118. end;
  1119. procedure TspSkinCheckListBox.SetExtandedSelect(Value: Boolean);
  1120. begin
  1121.   ListBox.ExtendedSelect := Value;
  1122. end;
  1123. function TspSkinCheckListBox.GetSelCount: Integer;
  1124. begin
  1125.   Result := ListBox.SelCount;
  1126. end;
  1127. function TspSkinCheckListBox.GetSelected(Index: Integer): Boolean;
  1128. begin
  1129.   Result := ListBox.Selected[Index];
  1130. end;
  1131. procedure TspSkinCheckListBox.SetSelected(Index: Integer; Value: Boolean);
  1132. begin
  1133.   ListBox.Selected[Index] := Value;
  1134. end;
  1135. function TspSkinCheckListBox.GetSorted: Boolean;
  1136. begin
  1137.   Result := ListBox.Sorted;
  1138. end;
  1139. procedure TspSkinCheckListBox.SetSorted(Value: Boolean);
  1140. begin
  1141.   if ScrollBar <> nil then HideScrollBar;
  1142.   ListBox.Sorted := Value;
  1143. end;
  1144. function TspSkinCheckListBox.GetTopIndex: Integer;
  1145. begin
  1146.   Result := ListBox.TopIndex;
  1147. end;
  1148. procedure TspSkinCheckListBox.SetTopIndex(Value: Integer);
  1149. begin
  1150.   ListBox.TopIndex := Value;
  1151. end;
  1152. function TspSkinCheckListBox.GetMultiSelect: Boolean;
  1153. begin
  1154.   Result := ListBox.MultiSelect;
  1155. end;
  1156. procedure TspSkinCheckListBox.SetMultiSelect(Value: Boolean);
  1157. begin
  1158.   ListBox.MultiSelect := Value;
  1159. end;
  1160. function TspSkinCheckListBox.GetListBoxFont: TFont;
  1161. begin
  1162.   Result := ListBox.Font;
  1163. end;
  1164. procedure TspSkinCheckListBox.SetListBoxFont(Value: TFont);
  1165. begin
  1166.   ListBox.Font.Assign(Value);
  1167. end;
  1168. function TspSkinCheckListBox.GetListBoxTabOrder: TTabOrder;
  1169. begin
  1170.   Result := ListBox.TabOrder;
  1171. end;
  1172. procedure TspSkinCheckListBox.SetListBoxTabOrder(Value: TTabOrder);
  1173. begin
  1174.   ListBox.TabOrder := Value;
  1175. end;
  1176. function TspSkinCheckListBox.GetListBoxTabStop: Boolean;
  1177. begin
  1178.   Result := ListBox.TabStop;
  1179. end;
  1180. procedure TspSkinCheckListBox.SetListBoxTabStop(Value: Boolean);
  1181. begin
  1182.   ListBox.TabStop := Value;
  1183. end;
  1184. procedure TspSkinCheckListBox.ShowScrollBar;
  1185. begin
  1186.   ScrollBar := TspSkinScrollBar.Create(Self);
  1187.   with ScrollBar do
  1188.   begin
  1189.     Parent := Self;
  1190.     if Columns > 0
  1191.     then
  1192.       Kind := sbHorizontal
  1193.     else
  1194.       Kind := sbVertical;
  1195.     Height := 100;
  1196.     Width := 20;
  1197.     Parent := Self;
  1198.     PageSize := 0;
  1199.     Min := 0;
  1200.     Position := 0;
  1201.     OnChange := SBChange;
  1202.     if Self.FIndex = -1
  1203.     then
  1204.       SkinDataName := ''
  1205.     else
  1206.       if Columns > 0
  1207.       then
  1208.         SkinDataName := HScrollBarName
  1209.       else
  1210.         SkinDataName := VScrollBarName;
  1211.     SkinData := Self.SkinData;
  1212.     CalcRects;
  1213.     Visible := True;
  1214.   end;
  1215.   RePaint;
  1216. end;
  1217. procedure TspSkinCheckListBox.ListBoxEnter;
  1218. begin
  1219. end;
  1220. procedure TspSkinCheckListBox.ListBoxExit;
  1221. begin
  1222. end;
  1223. procedure TspSkinCheckListBox.ListBoxKeyDown;
  1224. begin
  1225.   if Assigned(FOnListBoxKeyDown) then FOnListBoxKeyDown(Self, Key, Shift);
  1226. end;
  1227. procedure TspSkinCheckListBox.ListBoxKeyUp;
  1228. begin
  1229.   if Assigned(FOnListBoxKeyUp) then FOnListBoxKeyUp(Self, Key, Shift);
  1230. end;
  1231. procedure TspSkinCheckListBox.ListBoxKeyPress;
  1232. begin
  1233.   if Assigned(FOnListBoxKeyPress) then FOnListBoxKeyPress(Self, Key);
  1234. end;
  1235. procedure TspSkinCheckListBox.ListBoxDblClick;
  1236. begin
  1237.   if Assigned(FOnListBoxDblClick) then FOnListBoxDblClick(Self);
  1238. end;
  1239. procedure TspSkinCheckListBox.ListBoxClick;
  1240. begin
  1241.   if Assigned(FOnListBoxClick) then FOnListBoxClick(Self);
  1242. end;
  1243. procedure TspSkinCheckListBox.ListBoxMouseDown;
  1244. begin
  1245.   if Assigned(FOnListBoxMouseDown) then FOnListBoxMouseDown(Self, Button, Shift, X, Y);
  1246. end;
  1247. procedure TspSkinCheckListBox.ListBoxMouseMove;
  1248. begin
  1249.   if Assigned(FOnListBoxMouseMove) then FOnListBoxMouseMove(Self, Shift, X, Y);
  1250. end;
  1251. procedure TspSkinCheckListBox.ListBoxMouseUp;
  1252. begin
  1253.   if Assigned(FOnListBoxMouseUp) then FOnListBoxMouseUp(Self, Button, Shift, X, Y);
  1254. end;
  1255. procedure TspSkinCheckListBox.HideScrollBar;
  1256. begin
  1257.   ScrollBar.Visible := False;
  1258.   ScrollBar.Free;
  1259.   ScrollBar := nil;
  1260.   CalcRects;
  1261. end;
  1262. procedure TspSkinCheckListBox.CreateParams(var Params: TCreateParams);
  1263. begin
  1264.   inherited CreateParams(Params);
  1265.   with Params do
  1266.   begin
  1267.     WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  1268.   end;
  1269. end;
  1270. procedure TspSkinCheckListBox.SBChange;
  1271. var
  1272.   LParam, WParam: Integer;
  1273. begin
  1274.   LParam := 0;
  1275.   WParam := MakeWParam(SB_THUMBPOSITION, ScrollBar.Position);
  1276.   if Columns > 0
  1277.   then
  1278.     SendMessage(ListBox.Handle, WM_HSCROLL, WParam, LParam)
  1279.   else
  1280.     SendMessage(ListBox.Handle, WM_VSCROLL, WParam, LParam);
  1281. end;
  1282. function TspSkinCheckListBox.GetItemIndex;
  1283. begin
  1284.   Result := ListBox.ItemIndex;
  1285. end;
  1286. procedure TspSkinCheckListBox.SetItemIndex;
  1287. begin
  1288.   ListBox.ItemIndex := Value;
  1289. end;
  1290. procedure TspSkinCheckListBox.SetItems;
  1291. begin
  1292.   ListBox.Items.Assign(Value);
  1293.   UpDateScrollBar;
  1294. end;
  1295. function TspSkinCheckListBox.GetItems;
  1296. begin
  1297.   Result := ListBox.Items;
  1298. end;
  1299. destructor TspSkinCheckListBox.Destroy;
  1300. begin
  1301.   if ScrollBar <> nil then ScrollBar.Free;
  1302.   if ListBox <> nil then ListBox.Free;
  1303.   FDefaultCaptionFont.Free;
  1304.   FGlyph.Free;
  1305.   inherited;
  1306. end;
  1307. procedure TspSkinCheckListBox.CalcRects;
  1308. var
  1309.   LTop: Integer;
  1310.   OffX, OffY: Integer;
  1311. begin
  1312.   if FIndex <> -1
  1313.   then
  1314.     begin
  1315.       OffX := Width - RectWidth(SkinRect);
  1316.       OffY := Height - RectHeight(SkinRect);
  1317.       NewClRect := ClRect;
  1318.       Inc(NewClRect.Right, OffX);
  1319.       Inc(NewClRect.Bottom, OffY);
  1320.     end
  1321.   else
  1322.     if FCaptionMode
  1323.     then
  1324.       LTop := FDefaultCaptionHeight
  1325.     else
  1326.       LTop := 1;
  1327.   if (ScrollBar <> nil) and ScrollBar.Visible
  1328.   then
  1329.     begin
  1330.       if FIndex = -1
  1331.       then
  1332.         begin
  1333.           if Columns > 0
  1334.           then
  1335.             begin
  1336.               ScrollBar.SetBounds(1, Height - 20, Width - 2, 19);
  1337.               ListRect := Rect(2, LTop + 1, Width - 2, ScrollBar.Top);
  1338.             end
  1339.           else
  1340.             begin
  1341.               ScrollBar.SetBounds(Width - 20, LTop, 19, Height - 1 - LTop);
  1342.               ListRect := Rect(2, LTop + 1, ScrollBar.Left, Height - 2);
  1343.             end;
  1344.         end
  1345.       else
  1346.         begin
  1347.           if Columns > 0
  1348.           then
  1349.             begin
  1350.               ScrollBar.SetBounds(NewClRect.Left,
  1351.                 NewClRect.Bottom - ScrollBar.Height,
  1352.                 RectWidth(NewClRect), ScrollBar.Height);
  1353.               ListRect := NewClRect;
  1354.               Dec(ListRect.Bottom, ScrollBar.Height);
  1355.             end
  1356.           else
  1357.             begin
  1358.               ScrollBar.SetBounds(NewClRect.Right - ScrollBar.Width,
  1359.                 NewClRect.Top, ScrollBar.Width, RectHeight(NewClRect));
  1360.               ListRect := NewClRect;
  1361.               Dec(ListRect.Right, ScrollBar.Width);
  1362.             end;
  1363.         end;
  1364.     end
  1365.   else
  1366.     begin
  1367.       if FIndex = -1
  1368.       then
  1369.         ListRect := Rect(2, LTop + 1, Width - 2, Height - 2)
  1370.       else
  1371.         ListRect := NewClRect;
  1372.     end;
  1373.   if ListBox <> nil
  1374.   then
  1375.     ListBox.SetBounds(ListRect.Left, ListRect.Top,
  1376.       RectWidth(ListRect), RectHeight(ListRect));
  1377. end;
  1378. procedure TspSkinCheckListBox.GetSkinData;
  1379. begin
  1380.   inherited;
  1381.   if FIndex <> -1
  1382.   then
  1383.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinListBox
  1384.     then
  1385.       with TspDataSkinCheckListBox(FSD.CtrlList.Items[FIndex]) do
  1386.       begin
  1387.         Self.FontName := FontName;
  1388.         Self.FontStyle := FontStyle;
  1389.         Self.FontHeight := FontHeight;
  1390.         Self.SItemRect := SItemRect;
  1391.         Self.ActiveItemRect := ActiveItemRect;
  1392.         if isNullRect(ActiveItemRect)
  1393.         then
  1394.           Self.ActiveItemRect := SItemRect;
  1395.         Self.FocusItemRect := FocusItemRect;
  1396.         if isNullRect(FocusItemRect)
  1397.         then
  1398.           Self.FocusItemRect := SItemRect;
  1399.         Self.UnCheckImageRect := UnCheckImageRect;
  1400.         Self.CheckImageRect := CheckImageRect;
  1401.         Self.ItemLeftOffset := ItemLeftOffset;
  1402.         Self.ItemRightOffset := ItemRightOffset;
  1403.         Self.ItemTextRect := ItemTextRect;
  1404.         Self.ItemCheckRect := ItemCheckRect;
  1405.         Self.FontColor := FontColor;
  1406.         Self.ActiveFontColor := ActiveFontColor;
  1407.         Self.FocusFontColor := FocusFontColor;
  1408.         Self.VScrollBarName := VScrollBarName;
  1409.         Self.HScrollBarName := HScrollBarName;
  1410.         Self.CaptionRect := CaptionRect;
  1411.         Self.CaptionFontName := CaptionFontName;
  1412.         Self.CaptionFontStyle := CaptionFontStyle;
  1413.         Self.CaptionFontHeight := CaptionFontHeight;
  1414.         Self.CaptionFontColor := CaptionFontColor;
  1415.         Self.UpButtonRect := UpButtonRect;
  1416.         Self.ActiveUpButtonRect := ActiveUpButtonRect;
  1417.         Self.DownUpButtonRect := DownUpButtonRect;
  1418.         if IsNullRect(Self.DownUpButtonRect)
  1419.         then Self.DownUpButtonRect := Self.ActiveUpButtonRect;
  1420.         Self.DownButtonRect := DownButtonRect;
  1421.         Self.ActiveDownButtonRect := ActiveDownButtonRect;
  1422.         Self.DownDownButtonRect := DownDownButtonRect;
  1423.         if IsNullRect(Self.DownDownButtonRect)
  1424.         then Self.DownDownButtonRect := Self.ActiveDownButtonRect;
  1425.         Self.CheckButtonRect := CheckButtonRect;
  1426.         Self.ActiveCheckButtonRect := ActiveCheckButtonRect;
  1427.         Self.DownCheckButtonRect := DownCheckButtonRect;
  1428.         if IsNullRect(Self.DownCheckButtonRect)
  1429.         then Self.DownCheckButtonRect := Self.ActiveCheckButtonRect;
  1430.       end;
  1431. end;
  1432. procedure TspSkinCheckListBox.ChangeSkinData;
  1433. begin
  1434.   inherited;
  1435.   //
  1436.   if FIndex <> -1
  1437.   then
  1438.     begin
  1439.       if FUseSkinItemHeight
  1440.       then
  1441.         ListBox.ItemHeight := RectHeight(sItemRect);
  1442.     end
  1443.   else
  1444.     begin
  1445.       ListBox.ItemHeight := FDefaultItemHeight;
  1446.       Font.Assign(FDefaultFont);
  1447.     end;
  1448.   if ScrollBar <> nil
  1449.   then
  1450.     with ScrollBar do
  1451.     begin
  1452.       if Self.FIndex = -1
  1453.       then
  1454.         SkinDataName := ''
  1455.       else
  1456.         if Columns > 0
  1457.         then
  1458.           SkinDataName := HScrollBarName
  1459.         else
  1460.           SkinDataName := VScrollBarName;
  1461.       SkinData := Self.SkinData;
  1462.     end;
  1463.   if FRowCount <> 0
  1464.   then
  1465.     Height := Self.CalcHeight(FRowCount);
  1466.   CalcRects;
  1467.   UpDateScrollBar;
  1468.   ListBox.RePaint;
  1469. end;
  1470. procedure TspSkinCheckListBox.WMSIZE;
  1471. begin
  1472.   inherited;
  1473.   CalcRects;
  1474.   UpDateScrollBar;
  1475.   if ScrollBar <> nil then ScrollBar.Repaint;
  1476. end;
  1477. procedure TspSkinCheckListBox.SetBounds;
  1478. begin
  1479.   inherited;
  1480.   if FIndex = -1 then RePaint;
  1481. end;
  1482. procedure TspSkinCheckListBox.UpDateScrollBar;
  1483. var
  1484.   Min, Max, Pos, Page: Integer;
  1485. begin
  1486.   if (ListBox = nil) or ((FRowCount > 0) and (RowCount = Items.Count))
  1487.   then Exit;
  1488.   if Columns > 0
  1489.   then
  1490.     begin
  1491.       GetScrollRange(ListBox.Handle, SB_HORZ, Min, Max);
  1492.       Pos := GetScrollPos(ListBox.Handle, SB_HORZ);
  1493.       Page := ListBox.Columns;
  1494.       if (Max > Min) and (Pos <= Max) and (Page <= Max)
  1495.       then
  1496.         begin
  1497.           if ScrollBar = nil
  1498.           then ShowScrollBar;
  1499.           ScrollBar.SetRange(Min, Max, Pos, Page);
  1500.         end
  1501.      else
  1502.        if (ScrollBar <> nil) and (ScrollBar.Visible) then HideScrollBar;
  1503.     end
  1504.   else
  1505.     begin
  1506.       if not ((FRowCount > 0) and (RowCount = Items.Count))
  1507.       then
  1508.         begin
  1509.           GetScrollRange(ListBox.Handle, SB_VERT, Min, Max);
  1510.           Pos := GetScrollPos(ListBox.Handle, SB_VERT);
  1511.           Page := ListBox.Height div ListBox.ItemHeight;
  1512.           if (Max > Min) and (Pos <= Max) and (Page < Items.Count)
  1513.           then
  1514.             begin
  1515.               if ScrollBar = nil then ShowScrollBar;
  1516.               ScrollBar.SetRange(Min, Max, Pos, Page);
  1517.               ScrollBar.LargeChange := Page;
  1518.             end
  1519.           else
  1520.             if (ScrollBar <> nil) and ScrollBar.Visible then HideScrollBar;
  1521.         end
  1522.       else
  1523.         if (ScrollBar <> nil) and ScrollBar.Visible then HideScrollBar;
  1524.     end;
  1525. end;
  1526. constructor TspSkinScrollBox.Create(AOwner: TComponent);
  1527. begin
  1528.   inherited;
  1529.   ControlStyle := ControlStyle + [csAcceptsControls];
  1530.   FInCheckScrollBars := False;
  1531.   FVSizeOffset := 0;
  1532.   FHSizeOffset := 0;
  1533.   FVScrollBar := nil;
  1534.   FHScrollBar := nil;
  1535.   FOldVScrollBarPos := 0;
  1536.   FOldHScrollBarPos := 0;
  1537.   FDown := False;
  1538.   FSkinDataName := 'scrollbox';
  1539.   BGPictureIndex := -1;
  1540.   Width := 150;
  1541.   Height := 150;
  1542. end;
  1543. destructor TspSkinScrollBox.Destroy;
  1544. begin
  1545.   inherited;
  1546. end;
  1547. procedure TspSkinScrollBox.UpdateScrollRange;
  1548. begin
  1549.   GetHRange;
  1550.   GetVRange;
  1551. end;
  1552. procedure TspSkinScrollBox.CMVisibleChanged;
  1553. begin
  1554.   inherited;
  1555.   if FVScrollBar <> nil then FVScrollBar.Visible := Self.Visible;
  1556.   if FHScrollBar <> nil then FHScrollBar.Visible := Self.Visible;
  1557. end;
  1558. procedure TspSkinScrollBox.OnHScrollBarChange(Sender: TObject);
  1559. begin
  1560.   HScrollControls(FHScrollBar.Position - FOldHScrollBarPos);
  1561.   FOldHScrollBarPos := HScrollBar.Position;
  1562. end;
  1563. procedure TspSkinScrollBox.OnVScrollBarChange(Sender: TObject);
  1564. begin
  1565.   VScrollControls(FVScrollBar.Position - FOldVScrollBarPos);
  1566.   FOldVScrollBarPos := VScrollBar.Position;
  1567. end;
  1568. procedure TspSkinScrollBox.OnHScrollBarLastChange(Sender: TObject);
  1569. begin
  1570.   Invalidate;
  1571. end;
  1572. procedure TspSkinScrollBox.OnVScrollBarLastChange(Sender: TObject);
  1573. begin
  1574.   Invalidate;
  1575. end;
  1576. procedure TspSkinScrollBox.ChangeSkinData;
  1577. begin
  1578.   inherited;
  1579.   ReCreateWnd;
  1580.   if FVScrollBar <> nil then FVScrollBar.Align := FVScrollBar.Align;
  1581.   if FHScrollBar <> nil then FHScrollBar.Align := FHScrollBar.Align;
  1582. end;
  1583. procedure TspSkinScrollBox.HScroll;
  1584. begin
  1585.   if (FHScrollBar <> nil) and (FHScrollBar.PageSize <> 0)
  1586.   then
  1587.     with FHScrollBar do
  1588.     begin
  1589.       HScrollControls(APosition - Position);
  1590.       Position := APosition;
  1591.     end;
  1592. end;
  1593. procedure TspSkinScrollBox.VScroll;
  1594. begin
  1595.   if (FVScrollBar <> nil) and (FVScrollBar.PageSize <> 0)
  1596.   then
  1597.     with FVScrollBar do
  1598.     begin
  1599.       if APosition > Max - PageSize then APosition := Max - PageSize;
  1600.       VScrollControls(APosition - Position);
  1601.       Position := APosition;
  1602.     end;
  1603. end;
  1604. procedure TspSkinScrollBox.SetBorderStyle;
  1605. begin
  1606.   FBorderStyle := Value;
  1607.   ReCreateWnd;
  1608. end;
  1609. procedure TspSkinScrollBox.GetSkinData;
  1610. begin
  1611.   inherited;
  1612.   BGPictureIndex := -1;
  1613.   if FIndex <> -1
  1614.   then
  1615.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinScrollBoxControl
  1616.     then
  1617.       with TspDataSkinScrollBoxControl(FSD.CtrlList.Items[FIndex]) do
  1618.       begin
  1619.         Self.BGPictureIndex := BGPictureIndex;
  1620.       end;
  1621. end;
  1622. procedure TspSkinScrollBox.Notification;
  1623. begin
  1624.   inherited Notification(AComponent, Operation);
  1625.   if (Operation = opRemove) and (AComponent = FHScrollBar)
  1626.   then FHScrollBar := nil;
  1627.   if (Operation = opRemove) and (AComponent = FVScrollBar)
  1628.   then FVScrollBar := nil;
  1629. end;
  1630. procedure TspSkinScrollBox.SetVScrollBar;
  1631. begin
  1632.   FVScrollBar := Value;
  1633.   if FVScrollBar <> nil
  1634.   then
  1635.     with FVScrollBar do
  1636.     begin
  1637.       CanFocused := False;
  1638.       OnChange := OnVScrollBarChange;
  1639.       OnLastChange := OnVScrollBarLastChange;
  1640.       Enabled := True;
  1641.       Visible := False;
  1642.     end;
  1643.   GetVRange;
  1644. end;
  1645. procedure TspSkinScrollBox.SetHScrollBar;
  1646. begin
  1647.   FHScrollBar := Value;
  1648.   if FHScrollBar <> nil
  1649.   then
  1650.     with FHScrollBar do
  1651.     begin
  1652.       CanFocused := False;
  1653.       Enabled := True;
  1654.       Visible := False;
  1655.       OnChange := OnHScrollBarChange;
  1656.       OnLastChange := OnHScrollBarLastChange;
  1657.     end;
  1658.   GetHRange;
  1659. end;
  1660. procedure TspSkinScrollBox.CreateControlDefaultImage;
  1661. var
  1662.   R: TRect;
  1663. begin
  1664.   with B.Canvas do
  1665.   begin
  1666.     Brush.Color := clBtnFace;
  1667.     R := ClientRect;
  1668.     FillRect(R);
  1669.   end;
  1670. end;
  1671. type
  1672.   TParentControl = class(TWinControl);
  1673. procedure TspSkinScrollBox.GetVRange;
  1674. var
  1675.   i, MaxBottom, H, Offset: Integer;
  1676.   FMax: Integer;
  1677.   VisibleChanged, IsVisible: Boolean;
  1678.   R: TRect;
  1679. begin
  1680.   if (FVScrollBar = nil) or FInCheckScrollBars or (Parent = nil) then Exit;
  1681.   VisibleChanged := False;
  1682.   H := ClientHeight;
  1683.   MaxBottom := 0;
  1684.   for i := 0 to ControlCount - 1 do
  1685.   with Controls[i] do
  1686.   begin
  1687.    if Visible
  1688.    then
  1689.      if Top + Height > MaxBottom then MaxBottom := Top + Height;
  1690.   end;
  1691.   with FVScrollBar do
  1692.   begin
  1693.     FMax := MaxBottom + Position;
  1694.     if FMax > H
  1695.     then
  1696.       begin
  1697.         if not Visible
  1698.         then
  1699.           begin
  1700.             IsVisible := True;
  1701.             VisibleChanged := True;
  1702.           end;
  1703.         if (Position > 0) and (MaxBottom < H) and (FVSizeOffset > 0)
  1704.         then
  1705.           begin
  1706.             if FVSizeOffset > Position then FVSizeOffset := Position;
  1707.             SetRange(0, FMax - 1, Position - FVSizeOffset, H);
  1708.             VScrollControls(- FVSizeOffset);
  1709.             FVSizeOffset := 0;
  1710.             FOldVScrollBarPos := Position;
  1711.           end
  1712.         else
  1713.           begin
  1714.             if (FVSizeOffset = 0) and ((FMax - 1) < Max) and (Position > 0) and
  1715.                (MaxBottom < H)
  1716.             then
  1717.               begin
  1718.                 Offset := Max - (FMax - 1);
  1719.                 Offset := Offset + (Max - PageSize + 1) + Position;
  1720.                 if Offset > Position then  Offset := Position;
  1721.                 VScrollControls(-Offset);
  1722.                 SetRange(0, FMax - 1, Position - OffSet, H);
  1723.               end
  1724.             else
  1725.               SetRange(0, FMax - 1, Position, H);
  1726.             FVSizeOffset := 0;
  1727.             FOldVScrollBarPos := Position;
  1728.           end;
  1729.       end
  1730.     else
  1731.       begin
  1732.         if Position > 0
  1733.         then VScrollControls(-Position);
  1734.         FVSizeOffset := 0;
  1735.         FOldVScrollBarPos := 0;
  1736.         SetRange(0, 0, 0, 0);
  1737.         if Visible
  1738.         then
  1739.           begin
  1740.             IsVisible := False;
  1741.             VisibleChanged := True;
  1742.           end;
  1743.       end;
  1744.    end;
  1745.    if (FVScrollBar <> nil) and (FHScrollBar <> nil)
  1746.    then
  1747.     begin
  1748.       if not FVScrollBar.Visible and FHScrollBar.Both
  1749.       then
  1750.         FHScrollBar.Both := False
  1751.       else
  1752.       if FVScrollBar.Visible and not FHScrollBar.Both
  1753.       then
  1754.         FHScrollBar.Both := True;
  1755.     end;
  1756.   if VisibleChanged
  1757.   then
  1758.     begin
  1759.       FInCheckScrollBars := True;
  1760.       FVScrollBar.Visible := IsVisible;
  1761.       if (Align <> alNone)
  1762.       then
  1763.         begin
  1764.           R := Parent.ClientRect;
  1765.           TParentControl(Parent).AlignControls(nil, R);
  1766.         end;
  1767.        FInCheckScrollBars := False;  
  1768.     end;
  1769. end;
  1770. procedure TspSkinScrollBox.VScrollControls;
  1771. begin
  1772.   ScrollBy(0,  -AOffset);
  1773. end;
  1774. procedure TspSkinScrollBox.AdjustClientRect(var Rect: TRect);
  1775. var
  1776.   RLeft, RTop, VMax, HMax: Integer;
  1777. begin
  1778.   if (VScrollbar <> nil) and VScrollbar.Visible
  1779.   then
  1780.     begin
  1781.       RTop := -VScrollbar.Position;
  1782.       VMax := Max(VScrollBar.Max, ClientHeight);
  1783.     end
  1784.   else
  1785.     begin
  1786.       RTop := 0;
  1787.       VMax := ClientHeight;
  1788.     end;
  1789.   if (HScrollbar <> nil) and HScrollbar.Visible
  1790.   then
  1791.     begin
  1792.       RLeft := -HScrollbar.Position;
  1793.       HMax := Max(HScrollBar.Max, ClientWidth);
  1794.     end
  1795.   else
  1796.     begin
  1797.       RLeft := 0;
  1798.       HMax := ClientWidth;
  1799.     end;
  1800.   Rect := Bounds(RLeft, RTop,  HMax, VMax);
  1801.   inherited AdjustClientRect(Rect);
  1802. end;
  1803. procedure TspSkinScrollBox.GetHRange;
  1804. var
  1805.   i, MaxRight, W, Offset: Integer;
  1806.   FMax: Integer;
  1807.   VisibleChanged, IsVisible: Boolean;
  1808.   R: TRect;
  1809. begin
  1810.   if (FHScrollBar = nil) or FInCheckScrollBars or (Parent = nil)  then Exit;
  1811.   VisibleChanged := False;
  1812.   W := ClientWidth;
  1813.   MaxRight := 0;
  1814.   for i := 0 to ControlCount - 1 do
  1815.   with Controls[i] do
  1816.   begin
  1817.    if Visible
  1818.    then
  1819.      if Left + Width > MaxRight then MaxRight := left + Width;
  1820.   end;
  1821.   with FHScrollBar do
  1822.   begin
  1823.     FMax := MaxRight + Position;
  1824.     if FMax > W
  1825.     then
  1826.       begin
  1827.         if not Visible
  1828.         then
  1829.           begin
  1830.             IsVisible := True;
  1831.             VisibleChanged := True;
  1832.           end;
  1833.         if (Position > 0) and (MaxRight < W) and (FHSizeOffset > 0)
  1834.         then
  1835.           begin
  1836.             if FHSizeOffset > Position
  1837.             then FHSizeOffset := Position;
  1838.             SetRange(0, FMax - 1, Position - FHSizeOffset , W);
  1839.             HScrollControls(-FHSizeOffset);
  1840.             FOldHScrollBarPos := Position;
  1841.           end
  1842.         else
  1843.           begin
  1844.             if (FHSizeOffset = 0) and ((FMax - 1) < Max) and (Position > 0) and
  1845.                (MaxRight < W)
  1846.             then
  1847.               begin
  1848.                 Offset := Max - (FMax - 1);
  1849.                 Offset := Offset + (Max - PageSize + 1) + Position;
  1850.                 if Offset > Position then  Offset := Position;
  1851.                 HScrollControls(-Offset);
  1852.                 SetRange(0, FMax - 1, Position - Offset, W);
  1853.               end
  1854.             else
  1855.               SetRange(0, FMax - 1, Position, W);
  1856.             FHSizeOffset := 0;
  1857.             FOldHScrollBarPos := Position;
  1858.           end;
  1859.       end
  1860.     else
  1861.       begin
  1862.         if Position > 0
  1863.         then HScrollControls(-Position);
  1864.         FHSizeOffset := 0;
  1865.         FOldHScrollBarPos := 0;
  1866.         SetRange(0, 0, 0, 0);
  1867.         if Visible
  1868.         then
  1869.           begin
  1870.             IsVisible := False;
  1871.             VisibleChanged := True;
  1872.           end;
  1873.       end;
  1874.    end;
  1875.   if (FVScrollBar <> nil) and (FHScrollBar <> nil)
  1876.   then
  1877.     begin
  1878.       if not FVScrollBar.Visible and FHScrollBar.Both
  1879.       then
  1880.         FHScrollBar.Both := False
  1881.       else
  1882.       if FVScrollBar.Visible and not FHScrollBar.Both
  1883.       then
  1884.         FHScrollBar.Both := True;
  1885.     end;
  1886.   if VisibleChanged
  1887.   then
  1888.     begin
  1889.       FInCheckScrollBars := True;
  1890.       FHScrollBar.Visible := IsVisible;
  1891.       FInCheckScrollBars := False;
  1892.       if (Align <> alNone)
  1893.       then
  1894.         begin
  1895.           R := Parent.ClientRect;
  1896.           TParentControl(Parent).AlignControls(nil, R);
  1897.         end;
  1898.     end;
  1899. end;
  1900. procedure TspSkinScrollBox.HScrollControls;
  1901. begin
  1902.   ScrollBy(-AOffset, 0);
  1903. end;
  1904. procedure TspSkinScrollBox.WMWindowPosChanging;
  1905. begin
  1906.   inherited;
  1907.   if HandleAllocated and (Align = alNone)
  1908.   then
  1909.     begin
  1910.       GetVRange;
  1911.       GetHRange;
  1912.     end;
  1913. end;
  1914. procedure TspSkinScrollBox.SetBounds;
  1915. var
  1916.   OldHeight, OldWidth: Integer;
  1917.   R: TRect;
  1918. begin
  1919.   OldWidth := Width;
  1920.   OldHeight := Height;
  1921.   inherited;
  1922.   if (OldWidth <> Width)
  1923.   then
  1924.     begin
  1925.       if (OldWidth < Width) and (OldWidth <> 0)
  1926.       then FHSizeOffset := Width - OldWidth
  1927.       else FHSizeOffset := 0;
  1928.     end
  1929.   else
  1930.     FHSizeOffset := 0;
  1931.   if (OldHeight <> Height)
  1932.   then
  1933.     begin
  1934.       if (OldHeight < Height) and (OldHeight <> 0)
  1935.       then FVSizeOffset := Height - OldHeight
  1936.       else FVSizeOffset := 0;
  1937.     end
  1938.   else
  1939.     FVSizeOffset := 0;
  1940.   if Align <> alNone
  1941.   then
  1942.     begin
  1943.       GetVRange;
  1944.       GetHRange;
  1945.     end;  
  1946. end;
  1947. procedure TspSkinScrollBox.WMNCCALCSIZE;
  1948. begin
  1949.   GetSkinData;
  1950.   if FIndex = -1
  1951.   then
  1952.     with Message.CalcSize_Params^.rgrc[0] do
  1953.     begin
  1954.       if FBorderStyle <> bvNone
  1955.       then
  1956.         begin
  1957.           Inc(Left, 1);
  1958.           Inc(Top, 1);
  1959.           Dec(Right, 1);
  1960.           Dec(Bottom, 1);
  1961.         end;
  1962.     end
  1963.   else
  1964.     if (BGPictureIndex = -1) and (FBorderStyle <> bvNone) then
  1965.     with Message.CalcSize_Params^.rgrc[0] do
  1966.     begin
  1967.       Inc(Left, ClRect.Left);
  1968.       Inc(Top, ClRect.Top);
  1969.       Dec(Right, RectWidth(SkinRect) - ClRect.Right);
  1970.       Dec(Bottom, RectHeight(SkinRect) - ClRect.Bottom);
  1971.     end;
  1972. end;
  1973. procedure TspSkinScrollBox.WMNCPAINT;
  1974. var
  1975.   DC: HDC;
  1976.   C: TCanvas;
  1977.   R: TRect;
  1978. begin
  1979.   if (BGPictureIndex <> -1) or (FBorderStyle = bvNone) then Exit;
  1980.   DC := GetWindowDC(Handle);
  1981.   C := TControlCanvas.Create;
  1982.   C.Handle := DC;
  1983.   try
  1984.     PaintFrame(C);
  1985.   finally
  1986.     C.Free;
  1987.     ReleaseDC(Handle, DC);
  1988.   end;
  1989. end;
  1990. procedure TspSkinScrollBox.PaintFrame;
  1991. var
  1992.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  1993.   R, NewClRect: TRect;
  1994.   LeftB, TopB, RightB, BottomB: TBitMap;
  1995.   OffX, OffY: Integer;
  1996.   AW, AH: Integer;
  1997. begin
  1998.   GetSkinData;
  1999.   if (FIndex = -1)
  2000.   then
  2001.     with C do
  2002.     begin
  2003.       if FBorderStyle <> bvNone
  2004.       then
  2005.         begin
  2006.           Brush.Style := bsClear;
  2007.           R := Rect(0, 0, Width, Height);
  2008.           case FBorderStyle of
  2009.             bvLowered: Frame3D(C, R, clBtnHighLight, clBtnShadow, 1);
  2010.             bvRaised: Frame3D(C, R, clBtnShadow, clBtnHighLight, 1);
  2011.             bvFrame: Frame3D(C, R, clBtnShadow, clBtnShadow, 1);
  2012.           end;
  2013.         end;
  2014.       Exit;
  2015.     end;
  2016.   LeftB := TBitMap.Create;
  2017.   TopB := TBitMap.Create;
  2018.   RightB := TBitMap.Create;
  2019.   BottomB := TBitMap.Create;
  2020.   OffX := Width - RectWidth(SkinRect);
  2021.   OffY := Height - RectHeight(SkinRect);
  2022.   AW := Width;
  2023.   AH := Height;
  2024.   NewLTPoint := LTPt;
  2025.   NewRTPoint := Point(RTPt.X + OffX, RTPt.Y);
  2026.   NewLBPoint := Point(LBPt.X, LBPt.Y + OffY);
  2027.   NewRBPoint := Point(RBPt.X + OffX, RBPt.Y + OffY);
  2028.   NewClRect := Rect(ClRect.Left, ClRect.Top,
  2029.                     ClRect.Right + OffX, ClRect.Bottom + OffY);
  2030.   CreateSkinBorderImages(LTPt, RTPt, LBPt, RBPt, CLRect,
  2031.       NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  2032.       LeftB, TopB, RightB, BottomB, Picture, SkinRect, Width, Height,
  2033.       False, False, False, False);
  2034.   C.Draw(0, 0, TopB);
  2035.   C.Draw(0, TopB.Height, LeftB);
  2036.   C.Draw(Width - RightB.Width, TopB.Height, RightB);
  2037.   C.Draw(0, Height - BottomB.Height, BottomB);
  2038.   TopB.Free;
  2039.   LeftB.Free;
  2040.   RightB.Free;
  2041.   BottomB.Free;
  2042. end;
  2043. procedure TspSkinScrollBox.Paint;
  2044. var
  2045.   X, Y, XCnt, YCnt, w, h,
  2046.   rw, rh, XO, YO: Integer;
  2047.   Buffer: TBitMap;
  2048.   R: TRect;
  2049. begin
  2050.   GetSkinData;
  2051.   if FIndex = -1
  2052.   then
  2053.     begin
  2054.       inherited;
  2055.       Exit;
  2056.     end;
  2057.   if (ClientWidth > 0) and (ClientHeight > 0) then
  2058.   if BGPictureIndex <> -1
  2059.   then
  2060.     begin
  2061.       Buffer := TBitMap(FSD.FActivePictures.Items[BGPictureIndex]);
  2062.       XCnt := Width div Buffer.Width;
  2063.       YCnt := Height div Buffer.Height;
  2064.       for X := 0 to XCnt do
  2065.       for Y := 0 to YCnt do
  2066.         Canvas.Draw(X * Buffer.Width, Y * Buffer.Height, Buffer);
  2067.     end
  2068.   else
  2069.     begin
  2070.       Buffer := TBitMap.Create;
  2071.       Buffer.Width := ClientWidth;
  2072.       Buffer.Height := ClientHeight;
  2073.       w := RectWidth(ClRect);
  2074.       h := RectHeight(ClRect);
  2075.       rw := Buffer.Width;
  2076.       rh := Buffer.Height;
  2077.       with Buffer.Canvas do
  2078.       begin
  2079.         XCnt := rw div w;
  2080.         YCnt := rh div h;
  2081.         for X := 0 to XCnt do
  2082.         for Y := 0 to YCnt do
  2083.         begin
  2084.           if X * w + w > rw then XO := X * W + W - rw else XO := 0;
  2085.           if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  2086.             CopyRect(Rect(X * w, Y * h,X * w + w - XO, Y * h + h - YO),
  2087.                      Picture.Canvas,
  2088.                      Rect(SkinRect.Left + ClRect.Left,
  2089.                      SkinRect.Top + ClRect.Top,
  2090.                      SkinRect.Left + ClRect.Right - XO,
  2091.                      SkinRect.Top + ClRect.Bottom - YO));
  2092.         end;
  2093.         Canvas.Draw(0, 0, Buffer);
  2094.         Buffer.Free;
  2095.       end;
  2096.    end;
  2097. end;
  2098. procedure TspSkinScrollBox.WMSIZE;
  2099. begin
  2100.   inherited;
  2101.   SendMessage(Handle, WM_NCPAINT, 0, 0);
  2102. end;
  2103. procedure TspSkinScrollBox.CreateParams(var Params: TCreateParams);
  2104. begin
  2105.   inherited CreateParams(Params);
  2106.   with Params do
  2107.   begin
  2108.     WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  2109.   end;
  2110. end;
  2111. constructor TspPopupCalendar.Create(AOwner: TComponent);
  2112. begin
  2113.   inherited Create(AOwner);
  2114.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  2115. end;
  2116. procedure TspPopupCalendar.CreateParams(var Params: TCreateParams);
  2117. begin
  2118.   inherited CreateParams(Params);
  2119.   with Params do
  2120.   begin
  2121.     Style := WS_POPUP;
  2122.     ExStyle := WS_EX_TOOLWINDOW;
  2123.     WindowClass.Style := CS_SAVEBITS;
  2124.   end;
  2125. end;
  2126. procedure TspPopupCalendar.WMMouseActivate(var Message: TMessage);
  2127. begin
  2128.   Message.Result := MA_NOACTIVATE;
  2129. end;
  2130. constructor TspSkinDateEdit.Create(AOwner: TComponent);
  2131. begin
  2132.   inherited;
  2133.   EditMask := GetDateMask;
  2134.   FTodayDefault := False;
  2135.   ButtonMode := True;
  2136.   FSkinDataName := 'buttonedit';
  2137.   FMonthCalendar := TspPopupCalendar.Create(Self);
  2138.   FMonthCalendar.Parent := Self;
  2139.   FMonthCalendar.Visible := False;
  2140.   FMonthCalendar.OnNumberClick := CalendarClick;
  2141.   OnButtonClick := ButtonClick;
  2142.   FCalendarAlphaBlend := False;
  2143.   FCalendarAlphaBlendValue := 0;
  2144.   FCalendarAlphaBlendAnimation := False;
  2145. end;
  2146. destructor TspSkinDateEdit.Destroy;
  2147. begin
  2148.   FMonthCalendar.Free;
  2149.   inherited;
  2150. end;
  2151. function TspSkinDateEdit.IsDateInput: Boolean;
  2152. begin
  2153.   Result := IsValidText(Text);
  2154. end;
  2155. function TspSkinDateEdit.GetFirstDayOfWeek;
  2156. begin
  2157.   Result := FMonthCalendar.FirstDayOfWeek;
  2158. end;
  2159. procedure TspSkinDateEdit.SetFirstDayOfWeek;
  2160. begin
  2161.   FMonthCalendar.FirstDayOfWeek := Value;
  2162. end;
  2163. function TspSkinDateEdit.GetDate: TDate;
  2164. begin
  2165.   Result := FMonthCalendar.Date;
  2166. end;
  2167. procedure TspSkinDateEdit.SetDate(Value: TDate);
  2168. begin
  2169.   FMonthCalendar.Date := Value;
  2170.   StopCheck := True;
  2171.   if not (csLoading in ComponentState) or FTodayDefault
  2172.   then
  2173.     begin
  2174.       Text := DateToStr(Value);
  2175.     end;
  2176.   StopCheck := False;
  2177.   if Assigned(FOnDateChange) then FOnDateChange(Self);
  2178. end;
  2179. function TspSkinDateEdit.GetDateMask: String;
  2180. var
  2181.   S: String;
  2182.   S1: array[1..3] of String;
  2183.   i, j: Integer;
  2184.   MPos, DPos, YPos: Integer;
  2185. begin
  2186.   S := DateToStr(EncodeDate(9999, 12, 31));
  2187.   YPos := 1;
  2188.   MPos := 1;
  2189.   Dpos := 1;
  2190.   j := 1;
  2191.   for i := 1 to 3 do s1[i] := '';
  2192.   for i := 1 to Length(S) do
  2193.    if S[i] = DateSeparator then inc(j) else s1[j] := s1[j] + S[i];
  2194.   for i := 1 to 3 do
  2195.   begin
  2196.     j := StrToInt(s1[i]);
  2197.     case j of
  2198.       12: MPos := i;
  2199.       31: DPos := i;
  2200.       9999: YPos := i;
  2201.       99: YPos := i;
  2202.     end;
  2203.   end;
  2204.   Result := '!';
  2205.   for i := 1 to Length(s1[DPos]) do S1[DPos][i] := '9';
  2206.   for i := 1 to Length(s1[MPos]) do S1[MPos][i] := '9';
  2207.   for i := 1 to Length(s1[YPos]) do S1[YPos][i] := '0';
  2208.   Result := Result + s1[1] + '/' + s1[2] + '/' + s1[3] + ';1; ';
  2209. end;
  2210. procedure TspSkinDateEdit.Loaded;
  2211. begin
  2212.   inherited;
  2213.   EditMask := GetDateMask;
  2214.   if FTodayDefault then Date := Now;
  2215. end;
  2216. procedure TspSkinDateEdit.SetTodayDefault;
  2217. begin
  2218.   FTodayDefault := Value;
  2219.   if FTodayDefault then Date := Now;
  2220. end;
  2221. function TspSkinDateEdit.GetCalendarFont;
  2222. begin
  2223.   Result := FMonthCalendar.DefaultFont;
  2224. end;
  2225. procedure TspSkinDateEdit.SetCalendarFont;
  2226. begin
  2227.   FMonthCalendar.DefaultFont.Assign(Value);
  2228. end;
  2229. function TspSkinDateEdit.GetCalendarWidth: Integer;
  2230. begin
  2231.   Result := FMonthCalendar.Width;
  2232. end;
  2233. procedure TspSkinDateEdit.SetCalendarWidth(Value: Integer);
  2234. begin
  2235.   FMonthCalendar.Width := Value;
  2236. end;
  2237. function TspSkinDateEdit.GetCalendarHeight: Integer;
  2238. begin
  2239.   Result := FMonthCalendar.Height;
  2240. end;
  2241. procedure TspSkinDateEdit.SetCalendarHeight(Value: Integer);
  2242. begin
  2243.   FMonthCalendar.Height := Value;
  2244. end;
  2245. procedure TspSkinDateEdit.Change;
  2246. begin
  2247.   inherited;
  2248.   if not StopCheck
  2249.   then
  2250.     if IsValidText(Text) then CheckValidDate;
  2251. end;
  2252. procedure TspSkinDateEdit.CheckValidDate;
  2253. var
  2254.   OldDate: TDate;
  2255. begin
  2256.   OldDate := FMonthCalendar.Date;
  2257.   try
  2258.     FMonthCalendar.Date := StrToDate(Text);
  2259.   finally
  2260.    if OldDate <> FMonthCalendar.Date
  2261.    then
  2262.      if Assigned(FOnDateChange) then FOnDateChange(Self);
  2263.   end;
  2264. end;
  2265. function TspSkinDateEdit.IsValidText;
  2266. var
  2267.   F: String;
  2268.   s1, s2: array[1..3] of String;
  2269.   i, j: Integer;
  2270.   MPos, DPos, YPos: Integer;
  2271. begin
  2272.   Result := Pos(' ', S) = 0;
  2273.   if not Result then Exit;
  2274.   F := DateToStr(EncodeDate(9999, 12, 31));
  2275.   for i := 1 to 3 do s1[i] := '';
  2276.   for i := 1 to 3 do s2[i] := '';
  2277.   j := 1;
  2278.   YPos := 1;
  2279.   MPos := 1;
  2280.   Dpos := 1;
  2281.   for i := 1 to Length(F) do
  2282.    if F[i] = DateSeparator then inc(j) else s1[j] := s1[j] + F[i];
  2283.   for i := 1 to 3 do
  2284.   begin
  2285.     j := StrToInt(s1[i]);
  2286.     case j of
  2287.       12: MPos := i;
  2288.       31: DPos := i;
  2289.       9999: YPos := i;
  2290.       99: YPos := i;
  2291.     end;
  2292.   end;
  2293.   j := 1;
  2294.   for i := 1 to Length(S) do
  2295.     if S[i] = DateSeparator then inc(j) else s2[j] := s2[j] + S[i];
  2296.   if StrToInt(s2[Ypos]) = 0
  2297.   then
  2298.     Result := Length(s2[YPos]) < 2
  2299.   else
  2300.     Result := True;
  2301.   Result := Result and
  2302.             (Length(s1) = Length(s2)) and
  2303.             (StrToInt(s2[Mpos]) > 0) and
  2304.             (StrToInt(s2[Dpos]) > 0) and
  2305.             (StrToInt(s2[1]) <= StrToInt(s1[1])) and
  2306.             (StrToInt(s2[2]) <= StrToInt(s1[2])) and
  2307.             (StrToInt(s2[3]) <= StrToInt(s1[3]));
  2308. end;
  2309. procedure TspSkinDateEdit.CMCancelMode;
  2310. begin
  2311.  if (Message.Sender <> FMonthCalendar) and
  2312.      not FMonthCalendar.ContainsControl(Message.Sender)
  2313.  then
  2314.    CloseUp(False);
  2315. end;
  2316. procedure TspSkinDateEdit.WndProc;
  2317. begin
  2318.   inherited;
  2319.   case Message.Msg of
  2320.    WM_KILLFOCUS:
  2321.      begin
  2322.        if not FMonthCalendar.Visible
  2323.        then
  2324.          begin
  2325.            StopCheck := True;
  2326.            Text := DateToStr(FMonthCalendar.Date);
  2327.            StopCheck := False;
  2328.          end
  2329.        else
  2330.        if Message.wParam <> FMonthCalendar.Handle
  2331.        then
  2332.          CloseUp(False);
  2333.      end;
  2334.    WM_KEYDOWN:
  2335.       CloseUp(False);
  2336.   end;
  2337. end;
  2338. procedure TspSkinDateEdit.DropDown;
  2339. var
  2340.   P: TPoint;
  2341.   Y, I: Integer;
  2342. begin
  2343.   P := Parent.ClientToScreen(Point(Left, Top));
  2344.   Y := P.Y + Height;
  2345.   if Y + FMonthCalendar.Height > Screen.Height then Y := P.Y - FMonthCalendar.Height;
  2346.   //
  2347.   if CheckW2KWXP and FCalendarAlphaBlend
  2348.   then
  2349.     begin
  2350.       SetWindowLong(FMonthCalendar.Handle, GWL_EXSTYLE,
  2351.                     GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
  2352.       SetAlphaBlendTransparent(FMonthCalendar.Handle, 0)
  2353.     end;
  2354.   //
  2355.   FMonthCalendar.SkinData := Self.SkinData;
  2356.   SetWindowPos(FMonthCalendar.Handle, HWND_TOP, P.X, Y, 0, 0,
  2357.       SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  2358.   FMonthCalendar.Visible := True;
  2359.   //
  2360.   if FCalendarAlphaBlend and not FCalendarAlphaBlendAnimation and CheckW2KWXP
  2361.   then
  2362.     begin
  2363.       Application.ProcessMessages;
  2364.       SetAlphaBlendTransparent(FMonthCalendar.Handle, FCalendarAlphaBlendValue)
  2365.     end
  2366.   else
  2367.   if FCalendarAlphaBlendAnimation and FCalendarAlphaBlend and CheckW2KWXP
  2368.   then
  2369.     begin
  2370.       Application.ProcessMessages;
  2371.       I := 0;
  2372.       repeat
  2373.         Inc(i, 2);
  2374.         if i > FCalendarAlphaBlendValue then i := FCalendarAlphaBlendValue;
  2375.         SetAlphaBlendTransparent(FMonthCalendar.Handle, i);
  2376.       until i >= FCalendarAlphaBlendValue;
  2377.     end;
  2378. end;
  2379. procedure TspSkinDateEdit.CloseUp(AcceptValue: Boolean);
  2380. begin
  2381.   if FMonthCalendar.Visible
  2382.   then
  2383.     begin
  2384.       SetWindowPos(FMonthCalendar.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  2385.         SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  2386.       FMonthCalendar.Visible := False;
  2387.       if CheckW2KWXP and FCalendarAlphaBlend
  2388.       then
  2389.         SetWindowLong(FMonthCalendar.Handle, GWL_EXSTYLE,
  2390.                       GetWindowLong(Handle, GWL_EXSTYLE) and not WS_EX_LAYERED);
  2391.       if AcceptValue
  2392.       then
  2393.         begin
  2394.           StopCheck := True;
  2395.           Text := DateToStr(FMonthCalendar.Date);
  2396.           if Assigned(FOnDateChange) then FOnDateChange(Self);
  2397.           StopCheck := False;
  2398.         end;
  2399.       SetFocus;
  2400.    end;
  2401. end;
  2402. procedure TspSkinDateEdit.ButtonClick(Sender: TObject);
  2403. begin
  2404.   if FMonthCalendar.Visible
  2405.   then
  2406.     CloseUp(False)
  2407.   else
  2408.     DropDown;
  2409. end;
  2410. procedure TspSkinDateEdit.CalendarClick;
  2411. begin
  2412.   CloseUp(True);
  2413. end;
  2414. constructor TspPopupListBox.Create(AOwner: TComponent);
  2415. begin
  2416.   inherited Create(AOwner);
  2417.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable,
  2418.     csAcceptsControls];
  2419.   Ctl3D := False;
  2420.   ParentCtl3D := False;
  2421.   Visible := False;
  2422.   FOldAlphaBlend := False;
  2423.   FOldAlphaBlendValue := 0;
  2424. end;
  2425. procedure TspPopupListBox.CreateParams(var Params: TCreateParams);
  2426. begin
  2427.   inherited CreateParams(Params);
  2428.   with Params do begin
  2429.     Style := WS_POPUP or WS_CLIPCHILDREN;
  2430.     ExStyle := WS_EX_TOOLWINDOW;
  2431.     WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
  2432.   end;
  2433. end;
  2434. procedure TspPopupListBox.WMMouseActivate(var Message: TMessage);
  2435. begin
  2436.   Message.Result := MA_NOACTIVATE;
  2437. end;
  2438. procedure TspPopupListBox.Hide;
  2439. begin
  2440.   SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  2441.     SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  2442.   Visible := False;
  2443. end;
  2444. procedure TspPopupListBox.Show(Origin: TPoint);
  2445. var
  2446.   PLB: TspSkinCustomComboBox;
  2447.   I: Integer;
  2448. begin
  2449.   PLB := nil;
  2450.   //
  2451.   if CheckW2KWXP and (Owner is TspSkinCustomComboBox)
  2452.   then
  2453.     begin
  2454.       PLB := TspSkinCustomComboBox(Owner);
  2455.       if PLB.ListBoxAlphaBlend and not FOldAlphaBlend
  2456.       then
  2457.         begin
  2458.           SetWindowLong(Handle, GWL_EXSTYLE,
  2459.                         GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
  2460.         end
  2461.       else
  2462.       if not PLB.ListBoxAlphaBlend and FOldAlphaBlend
  2463.       then
  2464.         begin
  2465.          SetWindowLong(Handle, GWL_EXSTYLE,
  2466.             GetWindowLong(Handle, GWL_EXSTYLE) and (not WS_EX_LAYERED));
  2467.         end;
  2468.       FOldAlphaBlend := PLB.ListBoxAlphaBlend;
  2469.       if (FOldAlphaBlendValue <> PLB.ListBoxAlphaBlendValue) and PLB.ListBoxAlphaBlend
  2470.       then
  2471.         begin
  2472.           if PLB.ListBoxAlphaBlendAnimation
  2473.           then
  2474.             begin
  2475.               SetAlphaBlendTransparent(Handle, 0);
  2476.               FOldAlphaBlendValue := 0;
  2477.             end
  2478.           else
  2479.             begin
  2480.               SetAlphaBlendTransparent(Handle, PLB.ListBoxAlphaBlendValue);
  2481.               FOldAlphaBlendValue := PLB.ListBoxAlphaBlendValue;
  2482.              end;
  2483.         end;
  2484.     end;
  2485.   //
  2486.   SetWindowPos(Handle, HWND_TOP, Origin.X, Origin.Y, 0, 0,
  2487.     SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_NOSIZE);
  2488.   Visible := True;
  2489.   if CheckW2KWXP and (PLB <> nil) and PLB.ListBoxAlphaBlendAnimation and PLB.ListBoxAlphaBlend
  2490.   then
  2491.     begin
  2492.       Application.ProcessMessages;
  2493.       I := 0;
  2494.       repeat
  2495.         Inc(i, 2);
  2496.         if i > PLB.ListBoxAlphaBlendValue then i := PLB.ListBoxAlphaBlendValue;
  2497.         SetAlphaBlendTransparent(Handle, i);
  2498.       until i >= PLB.ListBoxAlphaBlendValue;
  2499.     end;
  2500. end;
  2501. // ======================== TspSkinTrackEdit ========================== //
  2502. constructor TspSkinTrackEdit.Create(AOwner: TComponent);
  2503. begin
  2504.   inherited;
  2505.   FTrackBarWidth := 0;
  2506.   FTrackBarSkinDataName := 'htrackbar';
  2507.   ButtonMode := True;
  2508.   FMinValue := 0;
  2509.   FMaxValue := 100;
  2510.   FValue := 0;
  2511.   StopCheck := True;
  2512.   Text := '0';
  2513.   StopCheck := False;
  2514.   Width := 120;
  2515.   Height := 20;
  2516.   FSkinDataName := 'buttonedit';
  2517.   OnButtonClick := ButtonClick;
  2518.   FPopupTrackBar := TspSkinPopupTrackBar.Create(Self);
  2519.   FPopupTrackBar.Visible := False;
  2520.   FPopupTrackBar.TrackEdit := Self;
  2521.   FPopupTrackBar.Parent := Self;
  2522.   FPopupTrackBar.OnChange := TrackBarChange;
  2523.   FTrackBarAlphaBlend := False;
  2524.   FTrackBarAlphaBlendAnimation := False;
  2525.   FTrackBarAlphaBlendValue := 0;
  2526. end;
  2527. destructor TspSkinTrackEdit.Destroy;
  2528. begin
  2529.   FPopupTrackBar.Free;
  2530.   inherited;
  2531. end;
  2532. function TspSkinTrackEdit.GetJumpWhenClick: Boolean;
  2533. begin
  2534.   Result := FPopupTrackBar.JumpWhenClick;
  2535. end;
  2536. procedure TspSkinTrackEdit.SetJumpWhenClick(Value: Boolean);
  2537. begin
  2538.   FPopupTrackBar.JumpWhenClick := Value;
  2539. end;
  2540. procedure TspSkinTrackEdit.WMMOUSEWHEEL;
  2541. begin
  2542.   if not FPopupTrackBar.Visible
  2543.   then
  2544.     begin
  2545.       if Message.WParam > 0
  2546.       then
  2547.         Value := Value - 1
  2548.       else
  2549.         Value := Value + 1;
  2550.     end
  2551.   else
  2552.     begin
  2553.       if Message.WParam > 0
  2554.       then
  2555.         FPopupTrackBar.Value := FPopupTrackBar.Value - 1
  2556.       else
  2557.         FPopupTrackBar.Value := FPopupTrackBar.Value + 1;
  2558.     end;
  2559. end;
  2560. procedure TspSkinTrackEdit.CMCancelMode(var Message: TCMCancelMode);
  2561. begin
  2562.  if (Message.Sender <> FPopupTrackBar)
  2563.  then
  2564.    CloseUp;
  2565. end;
  2566. procedure TspSkinTrackEdit.CloseUp;
  2567. begin
  2568.   if FPopupTrackbar.Visible
  2569.   then
  2570.     begin
  2571.       SetWindowPos(FPopupTrackBar.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  2572.                    SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  2573.       FPopupTrackBar.Visible := False;
  2574.       if CheckW2KWXP and FTrackBarAlphaBlend
  2575.       then
  2576.         SetWindowLong(FPopupTrackBar.Handle, GWL_EXSTYLE,
  2577.                       GetWindowLong(Handle, GWL_EXSTYLE) and not WS_EX_LAYERED);
  2578.     end;  
  2579. end;
  2580. procedure TspSkinTrackEdit.DropDown;
  2581. var
  2582.   P: TPoint;
  2583.   X, Y, I: Integer;
  2584. begin
  2585.   with FPopupTrackBar do
  2586.   begin
  2587.     if FTrackBarWidth = 0
  2588.     then
  2589.       Width := Self.Width
  2590.     else
  2591.       Width := FTrackBarWidth;
  2592.     DefaultHeight := Self.Height;
  2593.     SkinDataName := FTrackBarSkinDataName;
  2594.     SkinData := Self.SkinData;
  2595.     MinValue := Self.MinValue;
  2596.     MaxValue := Self.MaxValue;
  2597.     Value := Self.Value;
  2598.   end;
  2599.   P := Parent.ClientToScreen(Point(Left, Top));
  2600.   Y := P.Y + Height;
  2601.   if P.X + FPopupTrackBar.Width > Screen.Width
  2602.   then
  2603.     P.X := P.X - ((P.X + FPopupTrackBar.Width) - Screen.Width);
  2604.   if Y + FPopupTrackBar.Height > Screen.Height
  2605.   then
  2606.     Y := P.Y - FPopupTrackBar.Height;
  2607.   //
  2608.   if CheckW2KWXP and FTrackBarAlphaBlend
  2609.   then
  2610.     begin
  2611.       SetWindowLong(FPopupTrackBar.Handle, GWL_EXSTYLE,
  2612.                     GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
  2613.       if FTrackBarAlphaBlendAnimation
  2614.       then
  2615.         SetAlphaBlendTransparent(FPopupTrackBar.Handle, 0)
  2616.       else
  2617.         SetAlphaBlendTransparent(FPopupTrackBar.Handle, FTrackBarAlphaBlendValue);
  2618.     end;
  2619.   //
  2620.   SetWindowPos(FPopupTrackBar.Handle, HWND_TOP, P.X, Y, 0, 0,
  2621.       SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  2622.   FPopupTrackBar.Visible := True;
  2623.   if FTrackBarAlphaBlendAnimation and FTrackBarAlphaBlend and CheckW2KWXP
  2624.   then
  2625.     begin
  2626.       Application.ProcessMessages;
  2627.       I := 0;
  2628.       repeat
  2629.         Inc(i, 1);
  2630.         if i > FTrackBarAlphaBlendValue then i := FTrackBarAlphaBlendValue;
  2631.         SetAlphaBlendTransparent(FPopupTrackBar.Handle, i);
  2632.       until i >= FTrackBarAlphaBlendValue;
  2633.     end;
  2634. end;
  2635. procedure TspSkinTrackEdit.ButtonClick(Sender: TObject);
  2636. begin
  2637.   SetFocus;
  2638.   if not FPopupTrackBar.Visible then DropDown else CloseUp;
  2639. end;
  2640. function TspSkinTrackEdit.CheckValue;
  2641. begin
  2642.   Result := NewValue;
  2643.   if (FMaxValue <> FMinValue)
  2644.   then
  2645.     begin
  2646.       if NewValue < FMinValue then
  2647.       Result := FMinValue
  2648.       else if NewValue > FMaxValue then
  2649.       Result := FMaxValue;
  2650.     end;
  2651. end;
  2652. procedure TspSkinTrackEdit.SetMinValue;
  2653. begin
  2654.   FMinValue := AValue;
  2655. end;
  2656. procedure TspSkinTrackEdit.SetMaxValue;
  2657. begin
  2658.   FMaxValue := AValue;
  2659. end;
  2660. function TspSkinTrackEdit.IsNumText;
  2661. function GetMinus: Boolean;
  2662. var
  2663.   i: Integer;
  2664.   S: String;
  2665. begin
  2666.   S := AText;
  2667.   i := Pos('-', S);
  2668.   if i > 1
  2669.   then
  2670.     Result := False
  2671.   else
  2672.     begin
  2673.       Delete(S, i, 1);
  2674.       Result := Pos('-', S) = 0;
  2675.     end;
  2676. end;
  2677. const
  2678.   EditChars = '01234567890-';
  2679. var
  2680.   i: Integer;
  2681.   S: String;
  2682. begin
  2683.   S := EditChars;
  2684.   Result := True;
  2685.   if (Text = '') or (Text = '-')
  2686.   then
  2687.     begin
  2688.       Result := False;
  2689.       Exit;
  2690.     end;
  2691.   for i := 1 to Length(Text) do
  2692.   begin
  2693.     if Pos(Text[i], S) = 0
  2694.     then
  2695.       begin
  2696.         Result := False;
  2697.         Break;
  2698.       end;
  2699.   end;
  2700.   Result := Result and GetMinus;
  2701. end;
  2702. procedure TspSkinTrackEdit.Change;
  2703. var
  2704.   NewValue, TmpValue: Integer;
  2705. begin
  2706.   if FromEdit then Exit;
  2707.   if not StopCheck and IsNumText(Text)
  2708.   then
  2709.     begin
  2710.       TmpValue := StrToInt(Text);
  2711.       NewValue := CheckValue(TmpValue);
  2712.       if NewValue <> FValue
  2713.       then
  2714.         begin
  2715.           FValue := NewValue;
  2716.          end;
  2717.       if NewValue <> TmpValue
  2718.       then
  2719.         begin
  2720.           FromEdit := True;
  2721.           Text := IntToStr(Round(NewValue));
  2722.           FromEdit := False;
  2723.         end;
  2724.     end;
  2725.   inherited;  
  2726. end;
  2727. procedure TspSkinTrackEdit.SetValue;
  2728. begin
  2729.   FValue := CheckValue(AValue);
  2730.   StopCheck := True;
  2731.   Text := IntToStr(Round(CheckValue(AValue)));
  2732.   StopCheck := False;
  2733. end;
  2734. procedure TspSkinTrackEdit.KeyPress(var Key: Char);
  2735. begin
  2736.   if Key = Char(VK_ESCAPE)
  2737.   then
  2738.     begin
  2739.       if FPopupTrackBar.Visible then CloseUp; 
  2740.     end
  2741.   else
  2742.   if not IsValidChar(Key) then
  2743.   begin
  2744.     Key := #0;
  2745.     MessageBeep(0)
  2746.   end;
  2747.   inherited KeyPress(Key);
  2748. end;
  2749. function TspSkinTrackEdit.IsValidChar(Key: Char): Boolean;
  2750. begin
  2751.   Result := (Key in ['-', '0'..'9']) or
  2752.             ((Key < #32) and (Key <> Chr(VK_RETURN)));
  2753.   if (Key = '-') and (Pos('-', Text) <> 0)
  2754.   then
  2755.     Result := False;
  2756.   if ReadOnly and Result and ((Key >= #32) or
  2757.      (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE)))
  2758.   then
  2759.     Result := False;
  2760. end;
  2761. procedure TspSkinTrackEdit.WMKillFocus(var Message: TWMKillFocus);
  2762. begin
  2763.   inherited;
  2764.   CloseUp;
  2765. end;
  2766. procedure TspSkinTrackEdit.TrackBarChange(Sender: TObject);
  2767. begin
  2768.   if Value <> FPopupTrackBar.Value
  2769.   then
  2770.     Value := FPopupTrackBar.Value;
  2771. end;
  2772. constructor TspSkinPopupTrackBar.Create(AOwner: TComponent);
  2773. begin
  2774.   inherited Create(AOwner);
  2775.   ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  2776.   SkinDataName := 'htrackbar'; 
  2777. end;
  2778. procedure TspSkinPopupTrackBar.CreateParams(var Params: TCreateParams);
  2779. begin
  2780.   inherited CreateParams(Params);
  2781.   with Params do
  2782.   begin
  2783.     Style := WS_POPUP;
  2784.     ExStyle := WS_EX_TOOLWINDOW;
  2785.     WindowClass.Style := CS_SAVEBITS;
  2786.   end;
  2787. end;
  2788. procedure TspSkinPopupTrackBar.WMMouseActivate(var Message: TMessage);
  2789. begin
  2790.   Message.Result := MA_NOACTIVATE;
  2791. end;
  2792. constructor TspSkinTimeEdit.Create(AOwner: TComponent);
  2793. begin
  2794.    inherited;
  2795.    fShowMSec := false;
  2796.    EditMask := '!90:00:00;1; ';
  2797.    Text := '00:00:00';
  2798.    OnKeyPress := HandleOnKeyPress;
  2799. end;
  2800. procedure TspSkinTimeEdit.CheckSpace(var S: String);
  2801. var
  2802.   i: Integer;
  2803. begin
  2804.   for i := 0 to Length(S) do
  2805.   begin
  2806.     if S[i] = ' ' then S[i] := '0';
  2807.   end;
  2808. end;
  2809. procedure TspSkinTimeEdit.HandleOnKeyPress(Sender: TObject; var Key: Char);
  2810. var
  2811.   TimeStr: string;
  2812.   aHour, aMinute, aSecond, aMillisecond: Word;
  2813.   aHourSt, aMinuteSt, aSecondSt, aMillisecondSt: string;
  2814. begin
  2815.    if (Key <> #13) and (Key <> #8)
  2816.    then
  2817.    begin
  2818.    TimeStr := Text;
  2819.    if SelLength > 1 then SelLength := 1;
  2820.    if IsValidChar(Key)
  2821.    then
  2822.      begin
  2823.        Delete(TimeStr,SelStart + 1, 1);
  2824.        Insert(string(Key), TimeStr, SelStart + 1);
  2825.      end;
  2826.       try
  2827.          aHourSt := Copy(TimeStr, 1, 2);
  2828.          CheckSpace(aHourSt);
  2829.          aMinuteSt := Copy(TimeStr, 4, 2);
  2830.          CheckSpace(aMinuteSt);
  2831.          aSecondSt := Copy(TimeStr, 7, 2);
  2832.          CheckSpace(aSecondSt);
  2833.          if fShowMSec then begin
  2834.             aMillisecondSt := Copy(TimeStr, 10, 3);
  2835.          end else begin
  2836.             aMillisecondSt := '0';
  2837.          end;
  2838.          CheckSpace(aMillisecondSt);
  2839.          aHour := StrToInt(aHourSt);
  2840.          aMinute := StrToInt(aMinuteSt);
  2841.          aSecond := StrToInt(aSecondSt);
  2842.          aMillisecond := StrToInt(aMillisecondSt);
  2843.          if not IsValidTime(aHour, aMinute, aSecond, aMillisecond) then begin
  2844.             Key := #0;
  2845.          end;
  2846.       except
  2847.          Key := #0;
  2848.       end;
  2849.    end;
  2850. end;
  2851. procedure TspSkinTimeEdit.SetShowMilliseconds(const Value: Boolean);
  2852. begin
  2853.    if fShowMSec <> Value then begin
  2854.       fShowMSec := Value;
  2855.       if fShowMSec then begin
  2856.          EditMask := '!90:00:00.000;1; ';
  2857.          Text := '00:00:00.000';
  2858.       end else begin
  2859.          EditMask := '!90:00:00;1; ';
  2860.          Text := '00:00:00';
  2861.       end;
  2862.    end;
  2863. end;
  2864. procedure TspSkinTimeEdit.SetMilliseconds(const Value: integer);
  2865. var
  2866.    aHour, aMinute, aSecond, aMillisecond: integer;
  2867.    St: string;
  2868. begin
  2869.    aSecond := Value div 1000;
  2870.    aMillisecond := Value mod 1000;
  2871.    aMinute := aSecond div 60;
  2872.    aSecond := aSecond mod 60;
  2873.    aHour := aMinute div 60;
  2874.    aMinute := aMinute mod 60;
  2875.    St := Format('%2.2d:%2.2d:%2.2d.%3.3d', [aHour, aMinute, aSecond, aMillisecond]);
  2876.    try
  2877.       Text := St;
  2878.    except
  2879.       Text := '00:00:00.000';
  2880.    end;
  2881. end;
  2882. function TspSkinTimeEdit.GetMilliseconds: integer;
  2883. var
  2884.    TimeStr: string;
  2885.    aHour, aMinute, aSecond, aMillisecond: integer;
  2886.    aHourSt, aMinuteSt, aSecondSt, aMillisecondSt: string;
  2887. begin
  2888.    TimeStr := Text;
  2889.    try
  2890.       aHourSt := Copy(TimeStr, 1, 2);
  2891.       CheckSpace(aHourSt);
  2892.       aMinuteSt := Copy(TimeStr, 4, 2);
  2893.       CheckSpace(aMinuteSt);
  2894.       aSecondSt := Copy(TimeStr, 7, 2);
  2895.       CheckSpace(aSecondSt);
  2896.       aMillisecondSt := Copy(TimeStr, 10, 3);
  2897.       CheckSpace(aMillisecondSt);
  2898.       aHour := StrToInt(aHourSt);
  2899.       aMinute := StrToInt(aMinuteSt);
  2900.       aSecond := StrToInt(aSecondSt);
  2901.       aMillisecond := StrToInt(aMillisecondSt);
  2902.       Result := ((((aHour * 60) + aMinute) * 60) + aSecond) * 1000 + aMillisecond;
  2903.    except
  2904.       Result := 0;
  2905.    end;
  2906. end;
  2907. procedure TspSkinTimeEdit.SetTime(const Value: string);
  2908. var
  2909.    TimeStr: string;
  2910.    aHour, aMinute, aSecond, aMillisecond: integer;
  2911.    aHourSt, aMinuteSt, aSecondSt, aMillisecondSt: string;
  2912. begin
  2913.    TimeStr := Value;
  2914.    try
  2915.       aHourSt := Copy(TimeStr, 1, 2);
  2916.       CheckSpace(aHourSt);
  2917.       aMinuteSt := Copy(TimeStr, 4, 2);
  2918.       CheckSpace(aMinuteSt);
  2919.       aSecondSt := Copy(TimeStr, 7, 2);
  2920.       CheckSpace(aSecondSt);
  2921.       aHour := StrToInt(aHourSt);
  2922.       aMinute := StrToInt(aMinuteSt);
  2923.       aSecond := StrToInt(aSecondSt);
  2924.       if fShowMSec then begin
  2925.          aMillisecondSt := Copy(TimeStr, 10, 3);
  2926.          CheckSpace(aMillisecondSt);
  2927.          aMillisecond := StrToInt(aMillisecondSt);
  2928.          Text := Format('%2.2d:%2.2d:%2.2d.%3.3d', [aHour, aMinute, aSecond, aMillisecond]);
  2929.       end else begin
  2930.          Text := Format('%2.2d:%2.2d:%2.2d', [aHour, aMinute, aSecond]);
  2931.       end;
  2932.    except
  2933.       if fShowMSec then begin
  2934.          Text := '00:00:00.000';
  2935.       end else begin
  2936.          Text := '00:00:00';
  2937.       end;
  2938.    end;
  2939. end;
  2940. function TspSkinTimeEdit.GetTime: string;
  2941. begin
  2942.   Result := Text;
  2943. end;
  2944. function TspSkinTimeEdit.IsValidTime(const AHour, AMinute, ASecond, AMilliSecond: Word): Boolean;
  2945. begin
  2946.   Result := ((AHour < 24) and (AMinute < 60) and
  2947.              (ASecond < 60) and (AMilliSecond < 1000)) or
  2948.             ((AHour = 24) and (AMinute = 0) and
  2949.              (ASecond = 0) and (AMilliSecond = 0));
  2950. end;
  2951. function TspSkinTimeEdit.IsValidChar(Key: Char): Boolean;
  2952. begin
  2953.   Result := Key in ['0'..'9'];
  2954. end;
  2955. procedure TspSkinTimeEdit.DecodeTime(var Hour, Min, Sec, MSec: Word);
  2956. var
  2957.   TimeStr: string;
  2958.   aHourSt, aMinuteSt, aSecondSt, aMillisecondSt: string;
  2959. begin
  2960.   TimeStr := Text;
  2961.   aHourSt := Copy(TimeStr, 1, 2);
  2962.   CheckSpace(aHourSt);
  2963.   aMinuteSt := Copy(TimeStr, 4, 2);
  2964.   CheckSpace(aMinuteSt);
  2965.   aSecondSt := Copy(TimeStr, 7, 2);
  2966.   CheckSpace(aSecondSt);
  2967.   Hour := StrToInt(aHourSt);
  2968.   Min := StrToInt(aMinuteSt);
  2969.   Sec := StrToInt(aSecondSt);
  2970.   if fShowMSec
  2971.   then
  2972.     aMillisecondSt := Copy(TimeStr, 10, 3)
  2973.   else
  2974.     aMillisecondSt := '000';
  2975.   CheckSpace(aMillisecondSt);
  2976.   Msec := StrToInt(aMillisecondSt);
  2977. end;
  2978. procedure TspSkinTimeEdit.EncodeTime(Hour, Min, Sec, MSec: Word);
  2979. begin
  2980.   if not IsValidTime(Hour, Min, Sec, MSec) then Exit;
  2981.   try
  2982.     if fShowMSec
  2983.     then
  2984.       Text := Format('%2.2d:%2.2d:%2.2d.%3.3d', [Hour, Min, Sec, MSec])
  2985.     else
  2986.       Text := Format('%2.2d:%2.2d:%2.2d', [Hour, Min, Sec]);
  2987.   except
  2988.     if fShowMSec
  2989.     then
  2990.       Text := '00:00:00.000'
  2991.     else
  2992.       Text := '00:00:00';
  2993.   end;
  2994. end;
  2995. constructor TspSkinMemo2.Create;
  2996. begin
  2997.   inherited Create(AOwner);
  2998.   AutoSize := False;
  2999.   FIndex := -1;
  3000.   Font.Name := 'Arial';
  3001.   Font.Height := 14;
  3002.   FVScrollBar := nil;
  3003.   FHScrollBar := nil;
  3004.   FDown := False;
  3005.   FSkinDataName := 'memo';
  3006.   FDefaultFont := TFont.Create;
  3007.   FDefaultFont.OnChange := OnDefaultFontChange;
  3008.   FDefaultFont.Assign(Font);
  3009.   ScrollBars := ssBoth;
  3010.   FUseSkinFont := True;
  3011.   FSysPopupMenu := nil;
  3012. end;
  3013. procedure TspSkinMemo2.WMCONTEXTMENU;
  3014. var
  3015.   X, Y: Integer;
  3016.   P: TPoint;
  3017. begin
  3018.   if PopupMenu <> nil
  3019.   then
  3020.     inherited
  3021.   else
  3022.     begin
  3023.       CreateSysPopupMenu;
  3024.       X := Message.XPos;
  3025.       Y := Message.YPos;
  3026.       if (X < 0) or (Y < 0)
  3027.       then
  3028.         begin
  3029.           X := Width div 2;
  3030.           Y := Height div 2;
  3031.           P := Point(0, 0);
  3032.           P := ClientToScreen(P);
  3033.           X := X + P.X;
  3034.           Y := Y + P.Y;
  3035.         end;
  3036.       if FSysPopupMenu <> nil
  3037.       then
  3038.         FSysPopupMenu.Popup2(Self, X, Y)
  3039.     end;
  3040. end;
  3041. procedure TspSkinMemo2.WMAFTERDISPATCH;
  3042. begin
  3043.   if FSysPopupMenu <> nil
  3044.   then
  3045.     begin
  3046.       FSysPopupMenu.Free;
  3047.       FSysPopupMenu := nil;
  3048.     end;
  3049. end;
  3050. procedure TspSkinMemo2.DoUndo;
  3051. begin
  3052.   Undo;
  3053. end;
  3054. procedure TspSkinMemo2.DoCut;
  3055. begin
  3056.   CutToClipboard;
  3057. end;
  3058. procedure TspSkinMemo2.DoCopy;
  3059. begin
  3060.   CopyToClipboard;
  3061. end;
  3062. procedure TspSkinMemo2.DoPaste;
  3063. begin
  3064.   PasteFromClipboard;
  3065. end;
  3066. procedure TspSkinMemo2.DoDelete;
  3067. begin
  3068.   ClearSelection;
  3069. end;
  3070. procedure TspSkinMemo2.DoSelectAll;
  3071. begin
  3072.   SelectAll;
  3073. end;
  3074. procedure TspSkinMemo2.CreateSysPopupMenu;
  3075. function IsSelected: Boolean;
  3076. begin
  3077.   Result := GetSelLength > 0;
  3078. end;
  3079. function IsFullSelected: Boolean;
  3080. begin
  3081.   Result := GetSelText = Text;
  3082. end;
  3083. var
  3084.   Item: TMenuItem;
  3085. begin
  3086.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  3087.   FSysPopupMenu := TspSkinPopupMenu.Create(Self);
  3088.   FSysPopupMenu.ComponentForm := TForm(GetParentForm(Self));
  3089.   Item := TMenuItem.Create(FSysPopupMenu);
  3090.   with Item do
  3091.   begin
  3092.     Caption := SP_Edit_Undo;
  3093.     OnClick := DoUndo;
  3094.     Enabled := Self.CanUndo;
  3095.   end;
  3096.   FSysPopupMenu.Items.Add(Item);
  3097.   Item := TMenuItem.Create(FSysPopupMenu);
  3098.   Item.Caption := '-';
  3099.   FSysPopupMenu.Items.Add(Item);
  3100.   Item := TMenuItem.Create(FSysPopupMenu);
  3101.   with Item do
  3102.   begin
  3103.     Caption := SP_Edit_Cut;
  3104.     Enabled := IsSelected and not Self.ReadOnly;
  3105.     OnClick := DoCut;
  3106.   end;
  3107.   FSysPopupMenu.Items.Add(Item);
  3108.   Item := TMenuItem.Create(FSysPopupMenu);
  3109.   with Item do
  3110.   begin
  3111.     Caption := SP_Edit_Copy;
  3112.     Enabled := IsSelected;
  3113.     OnClick := DoCopy;
  3114.   end;
  3115.   FSysPopupMenu.Items.Add(Item);
  3116.   Item := TMenuItem.Create(FSysPopupMenu);
  3117.   with Item do
  3118.   begin
  3119.     Caption := SP_Edit_Paste;
  3120.     Enabled := (ClipBoard.AsText <> '') and not ReadOnly;
  3121.     OnClick := DoPaste;
  3122.   end;
  3123.   FSysPopupMenu.Items.Add(Item);
  3124.   Item := TMenuItem.Create(FSysPopupMenu);
  3125.   with Item do
  3126.   begin
  3127.     Caption := SP_Edit_Delete;
  3128.     Enabled := IsSelected and not Self.ReadOnly;
  3129.     OnClick := DoDelete;
  3130.   end;
  3131.   FSysPopupMenu.Items.Add(Item);
  3132.   Item := TMenuItem.Create(FSysPopupMenu);
  3133.   Item.Caption := '-';
  3134.   FSysPopupMenu.Items.Add(Item);
  3135.   Item := TMenuItem.Create(FSysPopupMenu);
  3136.   with Item do
  3137.   begin
  3138.     Caption := SP_Edit_SelectAll;
  3139.     Enabled := not IsFullSelected;
  3140.     OnClick := DoSelectAll;
  3141.   end;
  3142.   FSysPopupMenu.Items.Add(Item);
  3143. end;
  3144. procedure TspSkinMemo2.CMEnabledChanged;
  3145. begin
  3146.   inherited;
  3147.   UpDateScrollRange;
  3148. end;
  3149. procedure TspSkinMemo2.SetDefaultFont;
  3150. begin
  3151.   FDefaultFont.Assign(Value);
  3152.   if FIndex = -1 then Font.Assign(Value);
  3153. end;
  3154. procedure TspSkinMemo2.OnDefaultFontChange(Sender: TObject);
  3155. begin
  3156.   if FIndex = -1 then Font.Assign(FDefaultFont);
  3157. end;
  3158. procedure TspSkinMemo2.WMSize;
  3159. begin
  3160.   inherited;
  3161.   UpDateScrollRange;
  3162. end;
  3163. procedure TspSkinMemo2.Invalidate;
  3164. begin
  3165.   inherited;
  3166. end;
  3167. procedure TspSkinMemo2.Change;
  3168. begin
  3169.   inherited;
  3170.   UpDateScrollRange;
  3171. end;
  3172. procedure TspSkinMemo2.WMVSCROLL;
  3173. begin
  3174.   inherited;
  3175.   UpDateScrollRange;
  3176. end;
  3177. procedure TspSkinMemo2.WMHSCROLL;
  3178. begin
  3179.   inherited;
  3180.   UpDateScrollRange;
  3181. end;
  3182. procedure TspSkinMemo2.WMLBUTTONDOWN;
  3183. begin
  3184.   inherited;
  3185.   FDown := True;
  3186. end;
  3187. procedure TspSkinMemo2.WMLBUTTONUP;
  3188. begin
  3189.   inherited;
  3190.   if FDown
  3191.   then
  3192.     begin
  3193.       UpDateScrollRange;
  3194.       FDown := False;
  3195.     end;  
  3196. end;
  3197. procedure TspSkinMemo2.WMMOUSEMOVE;
  3198. begin
  3199.   inherited;
  3200.   if FDown then UpDateScrollRange;
  3201. end;
  3202. procedure TspSkinMemo2.SetVScrollBar;
  3203. begin
  3204.   FVScrollBar := Value;
  3205.   FVScrollBar.Min := 0;
  3206.   FVScrollBar.Max := 0;
  3207.   FVScrollBar.Position := 0;
  3208.   if FVScrollBar <> nil then FVScrollBar.OnChange := OnVScrollBarChange;
  3209.   UpDateScrollRange;
  3210. end;
  3211. procedure TspSkinMemo2.OnVScrollBarChange(Sender: TObject);
  3212. begin
  3213.   SendMessage(Handle, WM_VSCROLL,
  3214.     MakeWParam(SB_THUMBPOSITION, FVScrollBar.Position), 0);
  3215.   Invalidate;
  3216. end;
  3217. procedure TspSkinMemo2.SetHScrollBar;
  3218. begin
  3219.   FHScrollBar := Value;
  3220.   FHScrollBar.Min := 0;
  3221.   FHScrollBar.Max := 0;
  3222.   FHScrollBar.Position := 0;
  3223.   if FHScrollBar <> nil then FHScrollBar.OnChange := OnHScrollBarChange;
  3224.   UpDateScrollRange;
  3225. end;
  3226. procedure TspSkinMemo2.OnHScrollBarChange(Sender: TObject);
  3227. begin
  3228.   SendMessage(Handle, WM_HSCROLL,
  3229.     MakeWParam(SB_THUMBPOSITION, FHScrollBar.Position), 0);
  3230.   Invalidate;
  3231. end;
  3232. procedure TspSkinMemo2.UpDateScrollRange;
  3233. function GetVisibleLines: Integer;
  3234. var
  3235.   R: TRect;
  3236.   C: TCanvas;
  3237.   DC: HDC;
  3238.   LineHeight: Integer;
  3239. begin
  3240.   C := TCanvas.Create;
  3241.   C.Font.Assign(Font);
  3242.   DC := GetDC(0);
  3243.   C.Handle := DC;
  3244.   R := GetClientRect;
  3245.   LineHeight := C.TextHeight('Wq');
  3246.   if LineHeight <> 0
  3247.   then
  3248.     Result := RectHeight(R) div LineHeight
  3249.   else
  3250.     Result := 1;
  3251.   ReleaseDC(0, DC);
  3252.   C.Free;
  3253. end;
  3254. var
  3255.   SMin, SMax, SPos, SPage: Integer;
  3256. begin
  3257.   if FVScrollBar <> nil
  3258.   then
  3259.   if not Enabled
  3260.   then
  3261.     FVScrollBar.Enabled := False
  3262.   else
  3263.   with FVScrollBar do
  3264.   begin
  3265.     SPage := GetVisibleLines;
  3266.     SPos := GetScrollPos(Self.Handle, SB_VERT);
  3267.     GetScrollRange(Self.Handle, SB_VERT, SMin, SMax);
  3268.     if SMax > SPage
  3269.     then
  3270.       begin
  3271.         SetRange(0, SMax, SPos, SPage + 1);
  3272.         if not Enabled then Enabled := True;
  3273.       end
  3274.     else
  3275.       begin
  3276.         SetRange(0, 0, 0, 0);
  3277.         if Enabled then Enabled := False;
  3278.       end;
  3279.   end;
  3280.   if FHScrollBar <> nil
  3281.   then
  3282.   if not Enabled
  3283.   then
  3284.     FHScrollBar.Enabled := False
  3285.   else
  3286.   with FHScrollBar do
  3287.   begin
  3288.     SPage := Width;
  3289.     SPos := GetScrollPos(Self.Handle, SB_HORZ);
  3290.     GetScrollRange(Self.Handle, SB_HORZ, SMin, SMax);
  3291.     if SMax > SPage
  3292.     then
  3293.       begin
  3294.         SetRange(0, SMax, SPos, SPage + 1);
  3295.         if not Enabled then Enabled := True;
  3296.       end
  3297.     else
  3298.       begin
  3299.         SetRange(0, 0, 0, 0);
  3300.         if Enabled then Enabled := False;
  3301.       end;
  3302.   end;
  3303. end;
  3304. procedure TspSkinMemo2.WMMove;
  3305. begin
  3306.   inherited;
  3307. end;
  3308. procedure TspSkinMemo2.WMCut(var Message: TMessage);
  3309. begin
  3310.   inherited;
  3311.   UpDateScrollRange;
  3312. end;
  3313. procedure TspSkinMemo2.WMPaste(var Message: TMessage);
  3314. begin
  3315.   inherited;
  3316.   UpDateScrollRange;
  3317. end;
  3318. procedure TspSkinMemo2.WMClear(var Message: TMessage);
  3319. begin
  3320.   inherited;
  3321.   UpDateScrollRange;
  3322. end;
  3323. procedure TspSkinMemo2.WMUndo(var Message: TMessage);
  3324. begin
  3325.   inherited;
  3326.   UpDateScrollRange;
  3327. end;
  3328. procedure TspSkinMemo2.WMSetText(var Message:TWMSetText);
  3329. begin
  3330.   inherited;
  3331.   UpDateScrollRange;
  3332. end;
  3333. procedure TspSkinMemo2.WMMOUSEWHEEL;
  3334. var
  3335.   LParam, WParam: Integer;
  3336. begin
  3337.   LParam := 0;
  3338.   if Message.WParam > 0
  3339.   then
  3340.     WParam := MakeWParam(SB_LINEUP, 0)
  3341.   else
  3342.     WParam := MakeWParam(SB_LINEDOWN, 0);
  3343.   SendMessage(Handle, WM_VSCROLL, WParam, LParam);
  3344. end;
  3345. procedure TspSkinMemo2.WMCHAR(var Message:TMessage);
  3346. begin
  3347.   inherited;
  3348.   UpDateScrollRange;
  3349. end;
  3350. procedure TspSkinMemo2.WMKeyDown(var Message: TWMKeyDown);
  3351. begin
  3352.   inherited;
  3353.   UpDateScrollRange;
  3354. end;
  3355. procedure TspSkinMemo2.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  3356. begin
  3357.   inherited;
  3358. end;
  3359. procedure TspSkinMemo2.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
  3360. begin
  3361.   inherited;
  3362. end;
  3363. procedure TspSkinMemo2.WMNCCALCSIZE;
  3364. begin
  3365.  
  3366. end;
  3367. procedure TspSkinMemo2.CreateParams(var Params: TCreateParams);
  3368. begin
  3369.   inherited CreateParams(Params);
  3370.   with Params do
  3371.   begin
  3372.     ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
  3373.     Style := Style and not WS_BORDER;
  3374.     WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  3375.   end;
  3376. end;
  3377. destructor TspSkinMemo2.Destroy;
  3378. begin
  3379.   FDefaultFont.Free;
  3380.   if FSysPopupMenu <> nil then FSysPopupMenu.Free;
  3381.   inherited;
  3382. end;
  3383. procedure TspSkinMemo2.WMSETFOCUS;
  3384. begin
  3385.   inherited;
  3386.   if not FMouseIn and (FIndex <> -1)
  3387.   then
  3388.     begin
  3389.       Font.Color := ActiveFontColor;
  3390.       Color := ActiveBGColor;
  3391.     end;
  3392. end;
  3393. procedure TspSkinMemo2.WMKILLFOCUS;
  3394. begin
  3395.   inherited;
  3396.   if not FMouseIn and (FIndex <> -1)
  3397.   then
  3398.     begin
  3399.       Font.Color := FontColor;
  3400.       Color := BGColor;
  3401.     end;
  3402. end;
  3403. procedure TspSkinMemo2.CMMouseEnter;
  3404. begin
  3405.   inherited;
  3406.   FMouseIn := True;
  3407.   if not Focused and (FIndex <> -1)
  3408.   then
  3409.     begin
  3410.       Font.Color := ActiveFontColor;
  3411.       Color := ActiveBGColor;
  3412.     end;
  3413. end;
  3414. procedure TspSkinMemo2.CMMouseLeave;
  3415. begin
  3416.   inherited;
  3417.   FMouseIn := False;
  3418.   if not Focused and (FIndex <> -1)
  3419.   then
  3420.     begin
  3421.       Font.Color := FontColor;
  3422.       Color := BGColor;
  3423.     end;
  3424. end;
  3425. procedure TspSkinMemo2.GetSkinData;
  3426. begin
  3427.   if FSD = nil
  3428.   then
  3429.     begin
  3430.       FIndex := -1;
  3431.       Exit;
  3432.     end;
  3433.   if FSD.Empty
  3434.   then
  3435.     FIndex := -1
  3436.   else
  3437.     FIndex := FSD.GetControlIndex(FSkinDataName);
  3438.   if FIndex <> -1
  3439.   then
  3440.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinMemoControl
  3441.     then
  3442.       with TspDataSkinMemoControl(FSD.CtrlList.Items[FIndex]) do
  3443.       begin
  3444.         Self.FontName := FontName;
  3445.         Self.FontStyle := FontStyle;
  3446.         Self.FontHeight := FontHeight;
  3447.         Self.FontColor := FontColor;
  3448.         Self.ActiveFontColor := ActiveFontColor;
  3449.         Self.BGColor := BGColor;
  3450.         Self.ActiveBGColor := ActiveBGColor;
  3451.       end;
  3452. end;
  3453. procedure TspSkinMemo2.SetSkinData;
  3454. begin
  3455.   FSD := Value;
  3456.   if (FSD <> nil) then
  3457.   if not FSD.Empty and not (csDesigning in ComponentState)
  3458.   then
  3459.     ChangeSkinData;
  3460. end;
  3461. procedure TspSkinMemo2.Notification;
  3462. begin
  3463.   inherited Notification(AComponent, Operation);
  3464.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  3465.   if (Operation = opRemove) and (AComponent = FVScrollBar)
  3466.   then FVScrollBar := nil;
  3467.   if (Operation = opRemove) and (AComponent = FHScrollBar)
  3468.   then FHScrollBar := nil;
  3469. end;
  3470. procedure TspSkinMemo2.ChangeSkinData;
  3471. begin
  3472.   GetSkinData;
  3473.   //
  3474.   if FIndex <> -1
  3475.   then
  3476.     begin
  3477.       if FUseSkinFont
  3478.       then
  3479.         begin
  3480.           Font.Name := FontName;
  3481.           Font.Style := FontStyle;
  3482.           Font.Height := FontHeight;
  3483.           if Focused
  3484.           then
  3485.             Font.Color := ActiveFontColor
  3486.           else
  3487.             Font.Color := FontColor;
  3488.           Font.CharSet := FDefaultFont.CharSet;  
  3489.         end
  3490.       else
  3491.         begin
  3492.           Font.Assign(FDefaultFont);
  3493.           if Focused
  3494.           then
  3495.             Font.Color := ActiveFontColor
  3496.           else
  3497.             Font.Color := FontColor;
  3498.         end;
  3499.       Color := BGColor;
  3500.     end
  3501.   else
  3502.     Font.Assign(FDefaultFont);
  3503.   //
  3504.   UpDateScrollRange;
  3505.   ReCreateWnd;
  3506.   if FVScrollBar <> nil then FVScrollBar.Align := FVScrollBar.Align;
  3507. end;
  3508. constructor TspSkinPasswordEdit.Create(AOwner: TComponent); 
  3509. begin
  3510.   inherited;
  3511.   Text := '';
  3512.   FMouseIn := False;
  3513.   SkinDataName := 'edit';
  3514.   Width := 121;
  3515.   DefaultHeight := 21;
  3516.   TabStop := True;
  3517.   Color := clWindow;
  3518.   FTextAlignment := taLeftJustify;
  3519.   FAutoSelect := True;
  3520.   FCharCase := ecNormal;
  3521.   FHideSelection := True;
  3522.   FMaxLength := 0;
  3523.   FReadOnly := False;
  3524.   FLMouseSelecting := False;
  3525.   FCaretPosition := 0;
  3526.   FSelStart := 0;
  3527.   FSelLength := 0;
  3528.   FFirstVisibleChar := 1;
  3529.   ControlStyle := ControlStyle + [csCaptureMouse] - [csSetCaption];
  3530.   Cursor := Cursor;
  3531. end;
  3532. destructor TspSkinPasswordEdit.Destroy;
  3533. begin
  3534.   inherited;
  3535. end;
  3536. procedure TspSkinPasswordEdit.PasteFromClipboard;
  3537. var
  3538.   Data: THandle;
  3539.   Insertion: WideString;
  3540. begin
  3541.   if ReadOnly then Exit;
  3542.   if Clipboard.HasFormat(CF_UNICODETEXT)
  3543.   then
  3544.     begin
  3545.       Data := Clipboard.GetAsHandle(CF_UNICODETEXT);
  3546.       try
  3547.         if Data <> 0
  3548.         then
  3549.           Insertion := PWideChar(GlobalLock(Data));
  3550.       finally
  3551.         if Data <> 0 then GlobalUnlock(Data);
  3552.       end;
  3553.     end
  3554.   else
  3555.     Insertion := Clipboard.AsText;
  3556.   InsertText(Insertion);
  3557. end;
  3558. procedure TspSkinPasswordEdit.GetSkinData;
  3559. begin
  3560.   inherited;
  3561.   if FIndex <> -1
  3562.   then
  3563.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinEditControl
  3564.     then
  3565.       with TspDataSkinEditControl(FSD.CtrlList.Items[FIndex]) do
  3566.       begin
  3567.         Self.SkinRect := SkinRect;
  3568.         Self.ActiveSkinRect := ActiveSkinRect;
  3569.         if IsNullRect(ActiveSkinRect)
  3570.         then
  3571.           Self.ActiveSkinRect := SkinRect;
  3572.         LOffset := LTPoint.X;
  3573.         ROffset := RectWidth(SkinRect) - RTPoint.X;
  3574.         CharColor := FontColor;
  3575.         CharDisabledColor := DisabledFontColor;
  3576.         CharActiveColor := ActiveFontColor;
  3577.       end;
  3578. end;
  3579. procedure TspSkinPasswordEdit.CreateControlSkinImage(B: TBitMap);
  3580. begin
  3581.   if FMouseIn or Focused
  3582.   then
  3583.     CreateHSkinImage(LOffset, ROffset, B, Picture, ActiveSkinRect, Width,
  3584.           RectHeight(ActiveSkinRect))
  3585.   else
  3586.     CreateHSkinImage(LOffset, ROffset, B, Picture, SkinRect, Width,
  3587.                            RectHeight(SkinRect));
  3588.                            
  3589.   if Focused or not HideSelection
  3590.   then
  3591.     with B.Canvas do
  3592.     begin
  3593.       Brush.Color := clHighlight;
  3594.       FillRect(GetSelRect);
  3595.     end;
  3596.   PaintText(B.Canvas);
  3597.   if Focused or not HideSelection
  3598.   then
  3599.     PaintSelectedText(B.Canvas);
  3600. end;
  3601. procedure TspSkinPasswordEdit.CreateControlDefaultImage(B: TBitMap);
  3602. var
  3603.   R: TRect;
  3604. begin
  3605.   R := Rect(0, 0, Width, Height);
  3606.   with B.Canvas do
  3607.   begin
  3608.     Brush.Color := clWindow;
  3609.     FillRect(R);
  3610.     Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  3611.     Frame3D(B.Canvas, R, clBtnFace, clBtnFace, 1);
  3612.   end;
  3613.   if Focused or not HideSelection
  3614.   then
  3615.     with B.Canvas do
  3616.     begin
  3617.       Brush.Color := clHighlight;
  3618.       FillRect(GetSelRect);
  3619.     end;
  3620.   PaintText(B.Canvas);
  3621.   if Focused or not HideSelection
  3622.   then
  3623.     PaintSelectedText(B.Canvas);
  3624. end;
  3625. procedure TspSkinPasswordEdit.Loaded;
  3626. begin
  3627.   inherited;
  3628. end;
  3629. procedure TspSkinPasswordEdit.WMSETFOCUS(var Message: TWMSETFOCUS);
  3630. begin
  3631.   inherited;
  3632.   HAsFocus;
  3633. end;
  3634. procedure TspSkinPasswordEdit.WMKILLFOCUS(var Message: TWMKILLFOCUS);
  3635. begin
  3636.   inherited;
  3637.   KillFocus;
  3638. end;
  3639. procedure TspSkinPasswordEdit.HasFocus;
  3640. begin
  3641.   inherited;
  3642.   UpdateCarete;
  3643.   CaretPosition := 0;
  3644.   if AutoSelect then SelectAll;
  3645. end;
  3646. procedure TspSkinPasswordEdit.KillFocus;
  3647. begin
  3648.   inherited;
  3649.   DestroyCaret;
  3650.   Invalidate;
  3651. end;
  3652. function TspSkinPasswordEdit.GetCharX(a: integer): integer;
  3653. var
  3654.   WholeTextWidth : integer;
  3655.   EditRectWidth : integer;
  3656. begin
  3657.   Result := GetEditRect.Left;
  3658.   WholeTextWidth := Length(Text) * GetPasswordCharWidth;
  3659.   if a > 0 then
  3660.   begin
  3661.     if a <= Length(Text)
  3662.     then
  3663.       Result := Result + (a - FFirstVisibleChar + 1) * GetPasswordCharWidth
  3664.     else
  3665.       Result := Result + (Length(Text) - FFirstVisibleChar + 1) * GetPasswordCharWidth;
  3666.   end;
  3667.   EditRectWidth := GetEditRect.Right - GetEditRect.Left;
  3668.   if WholeTextWidth < EditRectWidth then
  3669.     case TextAlignment of
  3670.       taRightJustify : Result := Result + (EditRectWidth - WholeTextWidth);
  3671.       taCenter : Result := Result + ((EditRectWidth - WholeTextWidth) div 2);
  3672.     end;
  3673. end;
  3674. function TspSkinPasswordEdit.GetCoordinatePosition(x: integer): integer;
  3675. var
  3676.   TmpX,
  3677.   WholeTextWidth,
  3678.   EditRectWidth : integer;
  3679. begin
  3680.   Result := FFirstVisibleChar - 1;
  3681.   if Length(Text) = 0 then  Exit;
  3682.   WholeTextWidth := Length(Text) * GetPasswordCharWidth;
  3683.   EditRectWidth := GetEditRect.Right - GetEditRect.Left;
  3684.   TmpX := x;
  3685.   if WholeTextWidth < EditRectWidth
  3686.   then
  3687.     case TextAlignment of
  3688.       taRightJustify : TmpX := x - (EditRectWidth - WholeTextWidth);
  3689.       taCenter : TmpX := x - ((EditRectWidth - WholeTextWidth) div 2);
  3690.     end;
  3691.   Result := Result + (TmpX - GetEditRect.Left) div GetPasswordCharWidth;
  3692.   if Result < 0
  3693.   then
  3694.     Result := 0
  3695.   else
  3696.     if Result > Length(Text)
  3697.     then
  3698.       Result := Length(Text);
  3699. end;
  3700. function TspSkinPasswordEdit.GetEditRect: TRect;
  3701. begin
  3702.   with Result do
  3703.   begin
  3704.     if FIndex = -1
  3705.     then
  3706.       Result := Rect(2, 2, Width - 2, Height - 2)
  3707.     else
  3708.       Result := NewClRect;
  3709.   end;
  3710. end;
  3711. function TspSkinPasswordEdit.GetAlignmentFlags: integer;
  3712. begin
  3713.   case FTextAlignment of
  3714.     taCenter: Result := DT_CENTER;
  3715.     taRightJustify: Result := DT_RIGHT;
  3716.   else
  3717.     Result := DT_LEFT;
  3718.   end;
  3719. end;
  3720. procedure TspSkinPasswordEdit.KeyDown(var Key: word; Shift: TShiftState);
  3721. var
  3722.   TmpS: String;
  3723.   OldCaretPosition: integer;
  3724. begin
  3725.   inherited KeyDown(Key, Shift);
  3726.   OldCaretPosition := CaretPosition;
  3727.   case Key of
  3728.     Ord('v'), Ord('V'):
  3729.       if Shift = [ssCtrl] then PasteFromClipboard;
  3730.     VK_INSERT:
  3731.       if Shift = [ssShift] then PasteFromClipboard;
  3732.     VK_END: CaretPosition := Length(Text);
  3733.     VK_HOME: CaretPosition := 0;
  3734.     VK_LEFT:
  3735.       if ssCtrl in Shift then
  3736.         CaretPosition := GetPrivWordBeging(CaretPosition)
  3737.       else
  3738.         CaretPosition := CaretPosition - 1;
  3739.     VK_RIGHT:
  3740.       if ssCtrl in Shift then
  3741.         CaretPosition := GetNextWordBeging(CaretPosition)
  3742.       else
  3743.         CaretPosition := CaretPosition + 1;
  3744.     VK_DELETE, 8:
  3745.       if not ReadOnly then
  3746.       begin
  3747.         if SelLength <> 0 then
  3748.         begin
  3749.           ClearSelection;
  3750.         end
  3751.         else
  3752.         begin
  3753.           TmpS := Text;
  3754.           if TmpS <> '' then
  3755.             if Key = VK_DELETE then
  3756.             begin
  3757.               Delete(TmpS, CaretPosition + 1, 1);
  3758.             end
  3759.             else
  3760.             begin
  3761.               Delete(TmpS, CaretPosition, 1);
  3762.               CaretPosition := CaretPosition - 1;
  3763.             end;
  3764.           Text := TmpS;
  3765.         end;
  3766.       end;
  3767.   end;
  3768.   if Key in [VK_END, VK_HOME, VK_LEFT, VK_RIGHT] then
  3769.   begin
  3770.     if ssShift in Shift then
  3771.     begin
  3772.       if SelLength = 0 then
  3773.         FSelStart := OldCaretPosition;
  3774.       FSelStart := CaretPosition;
  3775.       FSelLength := FSelLength - (CaretPosition - OldCaretPosition);
  3776.     end
  3777.     else
  3778.       FSelLength := 0;
  3779.     Invalidate;
  3780.   end;
  3781.   UpdateCaretePosition;
  3782.   
  3783. end;
  3784. procedure TspSkinPasswordEdit.KeyPress(var Key: Char);
  3785. begin
  3786.   inherited KeyPress(Key);
  3787.   if (Ord(Key) >= 32) and not ReadOnly then InsertChar(Key);
  3788. end;
  3789. procedure TspSkinPasswordEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
  3790.   x, y: integer);
  3791. begin
  3792.   inherited;
  3793.   if Button = mbLeft then FLMouseSelecting := true;
  3794.   SetFocus;
  3795.   if Button = mbLeft
  3796.   then
  3797.     begin
  3798.       CaretPosition := GetCoordinatePosition(x);
  3799.       SelLength := 0;
  3800.     end;
  3801. end;
  3802. procedure TspSkinPasswordEdit.PaintText;
  3803. var
  3804.   TmpRect: TRect;
  3805.   CurChar: integer;
  3806.   LPWCharWidth: integer;
  3807. begin
  3808.   TmpRect := GetEditRect;
  3809.   LPWCharWidth := GetPasswordCharWidth;
  3810.   for CurChar := 0 to Length(Text) - FFirstVisibleChar + 1 - 1 do
  3811.     DrawPasswordChar(Rect(CurChar * LPWCharWidth + GetCharX(0), TmpRect.Top,
  3812.       (CurChar + 1) * LPWCharWidth + GetCharX(0), TmpRect.Bottom), False, Cnv);
  3813. end;
  3814. procedure TspSkinPasswordEdit.UpdateFirstVisibleChar;
  3815. var
  3816.   LEditRect: TRect;
  3817. begin
  3818.   if FFirstVisibleChar >= (FCaretPosition + 1)
  3819.   then
  3820.     begin
  3821.       FFirstVisibleChar := FCaretPosition;
  3822.       if FFirstVisibleChar < 1 then FFirstVisibleChar := 1;
  3823.     end
  3824.   else
  3825.     begin
  3826.       LEditRect := GetEditRect;
  3827.       while ((FCaretPosition - FFirstVisibleChar + 1) * GetPasswordCharWidth >
  3828.         LEditRect.Right - LEditRect.Left) and (FFirstVisibleChar < Length(Text)) do
  3829.         Inc(FFirstVisibleChar)
  3830.       end;
  3831.   Invalidate;
  3832. end;
  3833. procedure TspSkinPasswordEdit.MouseMove(Shift: TShiftState; x, y: integer);
  3834. var
  3835.   OldCaretPosition: integer;
  3836.   TmpNewPosition : integer;
  3837. begin
  3838.   inherited;
  3839.   if FLMouseSelecting then
  3840.   begin
  3841.     TmpNewPosition := GetCoordinatePosition(x);
  3842.     OldCaretPosition := CaretPosition;
  3843.     if (x > GetEditRect.Right) then
  3844.       CaretPosition := TmpNewPosition +1
  3845.     else
  3846.       CaretPosition := TmpNewPosition;
  3847.     if SelLength = 0 then
  3848.       FSelStart := OldCaretPosition;
  3849.     FSelStart := CaretPosition;
  3850.     FSelLength := FSelLength - (CaretPosition - OldCaretPosition);
  3851.   end;
  3852. end;
  3853. procedure TspSkinPasswordEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
  3854.   x, y: integer);
  3855. begin
  3856.   inherited;
  3857.   FLMouseSelecting := false;
  3858. end;
  3859. procedure TspSkinPasswordEdit.PaintSelectedText;
  3860. var
  3861.   TmpRect: TRect;
  3862.   CurChar: integer;
  3863.   LPWCharWidth: integer;
  3864. begin
  3865.   TmpRect := GetSelRect;
  3866.   LPWCharWidth := GetPasswordCharWidth;
  3867.   for CurChar := 0 to Length(GetVisibleSelText) - 1 do
  3868.       DrawPasswordChar(Rect(CurChar * LPWCharWidth + TmpRect.Left,
  3869.        TmpRect.Top,
  3870.        (CurChar + 1) * LPWCharWidth + TmpRect.Left,
  3871.        TmpRect.Bottom),
  3872.        true, Cnv);
  3873. end;
  3874. function TspSkinPasswordEdit.GetVisibleSelText: String;
  3875. begin
  3876.   if SelStart + 1 >= FFirstVisibleChar then
  3877.     Result := SelText
  3878.   else
  3879.     Result := Copy(SelText, FFirstVisibleChar - SelStart, Length(SelText) - (FFirstVisibleChar - SelStart) + 1);
  3880. end;
  3881. function TspSkinPasswordEdit.GetNextWordBeging(StartPosition: integer): integer;
  3882. var
  3883.   SpaceFound,
  3884.     WordFound: boolean;
  3885. begin
  3886.   Result := StartPosition;
  3887.   SpaceFound := false;
  3888.   WordFound := false;
  3889.   while (Result + 2 <= Length(Text)) and
  3890.     ((not ((Text[Result + 1] <> ' ') and SpaceFound))
  3891.     or not WordFound) do
  3892.   begin
  3893.     if Text[Result + 1] = ' ' then
  3894.       SpaceFound := true;
  3895.     if Text[Result + 1] <> ' ' then begin
  3896.       WordFound := true;
  3897.       SpaceFound := false;
  3898.     end;
  3899.     Result := Result + 1;
  3900.   end;
  3901.   if not SpaceFound then
  3902.     Result := Result + 1;
  3903. end;
  3904. function TspSkinPasswordEdit.GetPrivWordBeging(StartPosition: integer): integer;
  3905. var
  3906.   WordFound: boolean;
  3907. begin
  3908.   Result := StartPosition;
  3909.   WordFound := false;
  3910.   while (Result > 0) and
  3911.     ((Text[Result] <> ' ') or not WordFound) do
  3912.   begin
  3913.     if Text[Result] <> ' ' then
  3914.       WordFound := true;
  3915.     Result := Result - 1;
  3916.   end;
  3917. end;
  3918. procedure TspSkinPasswordEdit.ClearSelection;
  3919. var
  3920.   TmpS: String;
  3921. begin
  3922.   if ReadOnly then Exit;
  3923.   TmpS := Text;
  3924.   Delete(TmpS, SelStart + 1, SelLength);
  3925.   Text := TmpS;
  3926.   CaretPosition := SelStart;
  3927.   SelLength := 0;
  3928. end;
  3929. procedure TspSkinPasswordEdit.SelectAll;
  3930. begin
  3931.   SetCaretPosition(Length(Text));
  3932.   SelStart := 0;
  3933.   SelLength := Length(Text);
  3934.   Invalidate;
  3935. end;
  3936. procedure TspSkinPasswordEdit.DrawPasswordChar(SymbolRect: TRect; Selected: boolean; Cnv: TCanvas);
  3937. var
  3938.   R: TRect;
  3939.   C: TColor;
  3940. begin
  3941.   if not Enabled
  3942.   then
  3943.     begin
  3944.       if FIndex = -1
  3945.       then C := clGrayText
  3946.       else C := CharDisabledColor; 
  3947.     end
  3948.   else
  3949.   if Selected
  3950.   then
  3951.     C := clHighlightText
  3952.   else
  3953.     if FIndex = -1
  3954.     then
  3955.       C := clWindowText
  3956.     else
  3957.       begin
  3958.         if FMouseIn or Focused
  3959.         then
  3960.           C := CharActiveColor
  3961.         else
  3962.           C := CharColor;
  3963.       end;
  3964.   R := SymbolRect;
  3965.   InflateRect(R, -2, - (RectHeight(R) - RectWidth(R)) div 2 - 2);
  3966.   with Cnv do
  3967.   case FPasswordKind of
  3968.     pkRect:
  3969.       begin
  3970.         Brush.Color := C;
  3971.         FillRect(R);
  3972.       end;
  3973.     pkRoundRect:
  3974.       begin
  3975.         Brush.Color := C;
  3976.         Pen.Color := C;
  3977.         RoundRect(R.Left, R.Top, R.Right, R.Bottom, RectWidth(R) div 2, Font.Color);
  3978.       end;
  3979.     pkTriangle:
  3980.       begin
  3981.         R := Rect(0, 0, RectWidth(R), RectWidth(R));
  3982.         if not Odd(RectWidth(R)) then R.Right := R.Right + 1;
  3983.         RectToCenter(R, SymbolRect);
  3984.         Pen.Color := C;
  3985.         Brush.Color := C;
  3986.         Polygon([
  3987.           Point(R.Left + RectWidth(R) div 2 + 1, R.Top),
  3988.           Point(R.Right, R.Bottom),
  3989.           Point(R.Left, R.Bottom)]);
  3990.       end;
  3991.     end;
  3992. end;
  3993. procedure TspSkinPasswordEdit.SelectWord;
  3994. begin
  3995.   SelStart := GetPrivWordBeging(CaretPosition);
  3996.   SelLength := GetNextWordBeging(SelStart) - SelStart;
  3997.   CaretPosition := SelStart + SelLength;
  3998. end;
  3999. procedure TspSkinPasswordEdit.UpdateCarete;
  4000. begin
  4001.   GetSkinData;
  4002.   if FIndex = -1
  4003.   then
  4004.     CreateCaret(Handle, 0, 0, Height - 4)
  4005.   else
  4006.     CreateCaret(Handle, 0, 0, RectHeight(NewClRect));
  4007.   CaretPosition := FCaretPosition;
  4008.   ShowCaret;
  4009. end;
  4010. procedure TspSkinPasswordEdit.HideCaret;
  4011. begin
  4012.   Windows.HideCaret(Handle);
  4013. end;
  4014. procedure TspSkinPasswordEdit.ShowCaret;
  4015. begin
  4016.   Windows.ShowCaret(Handle);
  4017. end;
  4018. function TspSkinPasswordEdit.GetPasswordCharWidth: integer;
  4019. begin
  4020.   Result := RectHeight(GetEditRect) div 2 + 3;
  4021. end;
  4022. procedure TspSkinPasswordEdit.Change;
  4023. begin
  4024.   inherited Changed;
  4025.   if Enabled and HandleAllocated then SetCaretPosition(CaretPosition);
  4026.   if Assigned(FOnChange) then  FOnChange(Self);
  4027. end;
  4028. procedure TspSkinPasswordEdit.WMGetDlgCode(var Msg: TWMGetDlgCode);
  4029. begin
  4030.   inherited;
  4031.   Msg.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
  4032. end;
  4033. procedure TspSkinPasswordEdit.WMLButtonDblClk(var Message: TWMLButtonDblClk);
  4034. begin
  4035.   inherited;
  4036.   FLMouseSelecting := false;
  4037.   SelectWord;
  4038. end;
  4039. procedure TspSkinPasswordEdit.CMFontChanged(var Message: TMessage);
  4040. begin
  4041.   inherited;
  4042.   Font.Assign(Font);
  4043.   UpdateCarete;
  4044. end;
  4045. function TspSkinPasswordEdit.GetText: String;
  4046. begin
  4047.   Result := FText;
  4048. end;
  4049. procedure TspSkinPasswordEdit.SetText(const Value: String);
  4050. var
  4051.   TmpS: String;
  4052.   LOldText: String;
  4053. begin
  4054.   if not ValidText(Value) then
  4055.     Exit;
  4056.   TmpS := Value;
  4057.   LOldText := Text;
  4058.   if (Value <> '') and (CharCase <> ecNormal) then
  4059.     case CharCase of
  4060.       ecUpperCase: FText := AnsiUpperCase(TmpS);
  4061.       ecLowerCase: FText := AnsiLowerCase(TmpS);
  4062.     end
  4063.   else
  4064.     FText := TmpS;
  4065.   Invalidate;
  4066.   if Text <> LOldText then
  4067.     Change;
  4068. end;
  4069. procedure TspSkinPasswordEdit.SetCaretPosition(const Value: integer);
  4070. begin
  4071.   if Value < 0 then
  4072.     FCaretPosition := 0
  4073.   else
  4074.     if Value > Length(Text) then
  4075.       FCaretPosition := Length(Text)
  4076.     else
  4077.       FCaretPosition := Value;
  4078.   UpdateFirstVisibleChar;
  4079.   if SelLength <= 0 then
  4080.     FSelStart := Value;
  4081.   if Focused then
  4082.     SetCaretPos(GetCharX(FCaretPosition), GetEditRect.Top);
  4083. end;
  4084. procedure TspSkinPasswordEdit.SetSelLength(const Value: integer);
  4085. begin
  4086.   if FSelLength <> Value then
  4087.   begin
  4088.     FSelLength := Value;
  4089.     Invalidate;
  4090.   end;
  4091. end;
  4092. procedure TspSkinPasswordEdit.SetSelStart(const Value: integer);
  4093. begin
  4094.   if FSelStart <> Value then
  4095.   begin
  4096.     SelLength := 0;
  4097.     FSelStart := Value;
  4098.     CaretPosition := FSelStart;
  4099.     Invalidate;
  4100.   end;
  4101. end;
  4102. procedure TspSkinPasswordEdit.SetAutoSelect(const Value: boolean);
  4103. begin
  4104.   if FAutoSelect <> Value then
  4105.     FAutoSelect := Value;
  4106. end;
  4107. function TspSkinPasswordEdit.GetSelStart: integer;
  4108. begin
  4109.   if FSelLength > 0 then
  4110.     Result := FSelStart
  4111.   else
  4112.     if FSelLength < 0 then
  4113.       Result := FSelStart + FSelLength
  4114.     else
  4115.       Result := CaretPosition;
  4116. end;
  4117. function TspSkinPasswordEdit.GetSelRect: TRect;
  4118. begin
  4119.   Result := GetEditRect;
  4120.   Result.Left := GetCharX(SelStart);
  4121.   Result.Right := GetCharX(SelStart + SelLength);
  4122.   IntersectRect(Result, Result, GetEditRect);
  4123. end;
  4124. function TspSkinPasswordEdit.GetSelLength: integer;
  4125. begin
  4126.   Result := Abs(FSelLength);
  4127. end;
  4128. function TspSkinPasswordEdit.GetSelText: String;
  4129. begin
  4130.   Result := Copy(Text, SelStart + 1, SelLength);
  4131. end;
  4132. procedure TspSkinPasswordEdit.SetCharCase(const Value: TEditCharCase);
  4133. var
  4134.   TmpS: String;
  4135. begin
  4136.   if FCharCase <> Value then
  4137.   begin
  4138.     FCharCase := Value;
  4139.     if Text <> '' then
  4140.     begin
  4141.       TmpS := Text;
  4142.       case Value of
  4143.         ecUpperCase: Text := AnsiUpperCase(TmpS);
  4144.         ecLowerCase: Text := AnsiLowerCase(TmpS);
  4145.       end;
  4146.     end;
  4147.   end;
  4148. end;
  4149. procedure TspSkinPasswordEdit.SetHideSelection(const Value: Boolean);
  4150. begin
  4151.   if FHideSelection <> Value then
  4152.   begin
  4153.     FHideSelection := Value;
  4154.     Invalidate;
  4155.   end;
  4156. end;
  4157. procedure TspSkinPasswordEdit.SetMaxLength(const Value: Integer);
  4158. begin
  4159.   if FMaxLength <> Value then
  4160.   begin
  4161.     FMaxLength := Value;
  4162.   end;
  4163. end;
  4164. procedure TspSkinPasswordEdit.SetCursor(const Value: TCursor);
  4165. begin
  4166.   if Value = crDefault then
  4167.     inherited Cursor := crIBeam
  4168.   else
  4169.     inherited Cursor := Value;
  4170. end;
  4171. function TspSkinPasswordEdit.ValidText(NewText: String): boolean;
  4172. begin
  4173.   Result := true;
  4174. end;
  4175. procedure TspSkinPasswordEdit.SetTextAlignment(const Value: TAlignment);
  4176. begin
  4177.   if FTextAlignment <> Value then begin
  4178.     FTextAlignment := Value;
  4179.     Invalidate;
  4180.   end;
  4181. end;
  4182. procedure TspSkinPasswordEdit.UpdateCaretePosition;
  4183. begin
  4184.   SetCaretPosition(CaretPosition);
  4185. end;
  4186. procedure TspSkinPasswordEdit.InsertText(AText: String);
  4187. var
  4188.   TmpS: String;
  4189. begin
  4190.   if ReadOnly then Exit;
  4191.   TmpS := Text;
  4192.   Delete(TmpS, SelStart + 1, SelLength);
  4193.   Insert(AText, TmpS, SelStart + 1);
  4194.   if (MaxLength <= 0) or (Length(TmpS) <= MaxLength) then
  4195.   begin
  4196.     Text := TmpS;
  4197.     CaretPosition := SelStart + Length(AText);
  4198.   end;
  4199.   SelLength := 0;
  4200. end;
  4201. procedure TspSkinPasswordEdit.InsertChar(Ch: Char);
  4202. begin
  4203.   if ReadOnly then Exit;
  4204.   InsertText(Ch);
  4205. end;
  4206. procedure TspSkinPasswordEdit.InsertAfter(Position: integer; S: String;
  4207.   Selected: boolean);
  4208. var
  4209.   TmpS : String;
  4210.   Insertion : String;
  4211. begin
  4212.   TmpS := Text;
  4213.   Insertion := S;
  4214.   if MaxLength > 0 then
  4215.     Insertion := Copy(Insertion, 1, MaxLength - Length(TmpS));
  4216.   Insert(Insertion, TmpS, Position+1);
  4217.   Text := TmpS;
  4218.   if Selected then begin
  4219.     SelStart := Position;
  4220.     SelLength := Length(Insertion);
  4221.     CaretPosition := SelStart + SelLength;
  4222.   end;
  4223. end;
  4224. procedure TspSkinPasswordEdit.DeleteFrom(Position, Length: integer; MoveCaret : boolean);
  4225. var
  4226.   TmpS: String;
  4227. begin
  4228.   TmpS := Text;
  4229.   Delete(TmpS,Position,Length);
  4230.   Text := TmpS;
  4231.   if MoveCaret
  4232.   then
  4233.     begin
  4234.       SelLength := 0;
  4235.       SelStart := Position-1;
  4236.     end;
  4237. end;
  4238. procedure TspSkinPasswordEdit.SetPasswordKind(const Value: TspPasswordKind);
  4239. begin
  4240.   if FPasswordKind <> Value
  4241.   then
  4242.     begin
  4243.       FPasswordKind := Value;
  4244.       Invalidate;
  4245.     end;
  4246. end;
  4247. procedure TspSkinPasswordEdit.CMTextChanged(var Msg: TMessage);
  4248. begin
  4249.   inherited;
  4250.   FText := inherited Text;
  4251.   SelLength := 0;
  4252.   Invalidate;
  4253. end;
  4254. procedure TspSkinPasswordEdit.Clear;
  4255. begin
  4256.   Text := '';
  4257. end;
  4258. procedure TspSkinPasswordEdit.CMEnabledChanged(var Msg: TMessage);
  4259. begin
  4260.   inherited;
  4261.   if HandleAllocated then Invalidate;
  4262. end;
  4263. procedure TspSkinPasswordEdit.CMMouseEnter;
  4264. begin
  4265.   inherited;
  4266.   FMouseIn := True;
  4267.   if (not Focused) then Invalidate;
  4268. end;
  4269. procedure TspSkinPasswordEdit.CMMouseLeave;
  4270. begin
  4271.   inherited;
  4272.   FMouseIn := False;
  4273.   if not Focused then Invalidate;
  4274. end;
  4275. // TspSkinNumericEdit
  4276. constructor TspSkinNumericEdit.Create(AOwner: TComponent);
  4277. begin
  4278.   inherited;
  4279.   FMinValue := 0;
  4280.   FMaxValue := 0;
  4281.   FValue := 0;
  4282.   StopCheck := True;
  4283.   FromEdit := False;
  4284.   Text := '0';
  4285.   StopCheck := False;
  4286.   Width := 120;
  4287.   Height := 20;
  4288.   FDecimal := 2;
  4289.   FSkinDataName := 'edit';
  4290. end;
  4291. destructor TspSkinNumericEdit.Destroy;
  4292. begin
  4293.   inherited;
  4294. end;
  4295. procedure TspSkinNumericEdit.SetValueType(NewType: TspValueType);
  4296. begin
  4297.   if FValueType <> NewType
  4298.   then
  4299.     begin
  4300.       FValueType := NewType;
  4301.     end;
  4302. end;
  4303. procedure TspSkinNumericEdit.SetDecimal(NewValue: Byte);
  4304. begin
  4305.   if FDecimal <> NewValue then begin
  4306.     FDecimal := NewValue;
  4307.   end;
  4308. end;
  4309. function TspSkinNumericEdit.CheckValue;
  4310. begin
  4311.   Result := NewValue;
  4312.   if (FMaxValue <> FMinValue)
  4313.   then
  4314.     begin
  4315.       if NewValue < FMinValue then
  4316.       Result := FMinValue
  4317.       else if NewValue > FMaxValue then
  4318.       Result := FMaxValue;
  4319.     end;
  4320. end;
  4321. procedure TspSkinNumericEdit.SetMinValue;
  4322. begin
  4323.   FMinValue := AValue;
  4324. end;
  4325. procedure TspSkinNumericEdit.SetMaxValue;
  4326. begin
  4327.   FMaxValue := AValue;
  4328. end;
  4329. function TspSkinNumericEdit.IsNumText;
  4330. function GetMinus: Boolean;
  4331. var
  4332.   i: Integer;
  4333.   S: String;
  4334. begin
  4335.   S := AText;
  4336.   i := Pos('-', S);
  4337.   if i > 1
  4338.   then
  4339.     Result := False
  4340.   else
  4341.     begin
  4342.       Delete(S, i, 1);
  4343.       Result := Pos('-', S) = 0;
  4344.     end;
  4345. end;
  4346. function GetP: Boolean;
  4347. var
  4348.   i: Integer;
  4349.   S: String;
  4350. begin
  4351.   S := AText;
  4352.   i := Pos(DecimalSeparator, S);
  4353.   if i = 1
  4354.   then
  4355.     Result := False
  4356.   else
  4357.     begin
  4358.       Delete(S, i, 1);
  4359.       Result := Pos(DecimalSeparator, S) = 0;
  4360.     end;
  4361. end;
  4362. const
  4363.   EditChars = '01234567890-';
  4364. var
  4365.   i: Integer;
  4366.   S: String;
  4367. begin
  4368.   S := EditChars;
  4369.   Result := True;
  4370.   if ValueType = vtFloat
  4371.   then
  4372.     S := S + DecimalSeparator;
  4373.   if (Text = '') or (Text = '-')
  4374.   then
  4375.     begin
  4376.       Result := False;
  4377.       Exit;
  4378.     end;
  4379.   for i := 1 to Length(Text) do
  4380.   begin
  4381.     if Pos(Text[i], S) = 0
  4382.     then
  4383.       begin
  4384.         Result := False;
  4385.         Break;
  4386.       end;
  4387.   end;
  4388.   Result := Result and GetMinus;
  4389.   if ValueType = vtFloat
  4390.   then
  4391.     Result := Result and GetP;
  4392. end;
  4393. procedure TspSkinNumericEdit.Change;
  4394. var
  4395.   NewValue, TmpValue: Double;
  4396. begin
  4397.   if FromEdit then Exit;
  4398.   if not StopCheck and IsNumText(Text)
  4399.   then
  4400.     begin
  4401.       if ValueType = vtFloat
  4402.       then TmpValue := StrToFloat(Text)
  4403.       else TmpValue := StrToInt(Text);
  4404.       NewValue := CheckValue(TmpValue);
  4405.       if NewValue <> FValue
  4406.       then
  4407.         begin
  4408.           FValue := NewValue;
  4409.         end;
  4410.       if NewValue <> TmpValue 
  4411.       then
  4412.         begin
  4413.           FromEdit := True;
  4414.           if ValueType = vtFloat
  4415.           then Text := FloatToStrF(NewValue, ffFixed, 15, FDecimal)
  4416.           else Text := IntToStr(Round(FValue));
  4417.           FromEdit := False;
  4418.         end;
  4419.     end;
  4420.   inherited;   
  4421. end;
  4422. procedure TspSkinNumericEdit.SetValue;
  4423. begin
  4424.   FValue := CheckValue(AValue);
  4425.   StopCheck := True;
  4426.   if ValueType = vtFloat
  4427.   then
  4428.     Text := FloatToStrF(CheckValue(AValue), ffFixed, 15, FDecimal)
  4429.   else
  4430.     Text := IntToStr(Round(CheckValue(AValue)));
  4431.   StopCheck := False;
  4432. end;
  4433. procedure TspSkinNumericEdit.KeyPress(var Key: Char);
  4434. begin
  4435.   if not IsValidChar(Key)
  4436.   then
  4437.     begin
  4438.       Key := #0;
  4439.       MessageBeep(0)
  4440.     end;
  4441.   inherited KeyPress(Key);
  4442. end;
  4443. function TspSkinNumericEdit.IsValidChar(Key: Char): Boolean;
  4444. begin
  4445.   if ValueType = vtFloat 
  4446.   then
  4447.     Result := (Key in [DecimalSeparator, '-', '0'..'9']) or
  4448.     ((Key < #32) and (Key <> Chr(VK_RETURN)))
  4449.   else
  4450.     Result := (Key in ['-', '0'..'9']) or
  4451.      ((Key < #32) and (Key <> Chr(VK_RETURN)));
  4452.   
  4453.  if (Key = DecimalSeparator) and (Pos(DecimalSeparator, Text) <> 0)
  4454.   then
  4455.     Result := False
  4456.   else
  4457.   if (Key = '-') and (Pos('-', Text) <> 0)
  4458.   then
  4459.     Result := False;
  4460.   if ReadOnly and Result and ((Key >= #32) or
  4461.      (Key = Char(VK_BACK)) or (Key = Char(VK_DELETE)))
  4462.   then
  4463.     Result := False;
  4464. end;
  4465. end.