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

Delphi控件源码

开发平台:

Delphi

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