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

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************************}
  2. {                                                                   }
  3. {       Almediadev Visual Component Library                         }
  4. {       BusinessSkinForm                                            }
  5. {       Version 1.98                                                }
  6. {                                                                   }
  7. {       Copyright (c) 2000-2003 Almediadev                          }
  8. {       ALL RIGHTS RESERVED                                         }
  9. {                                                                   }
  10. {       Home:  http://www.almdev.com                                }
  11. {       Support: support@almdev.com                                 }
  12. {                                                                   }
  13. {*******************************************************************}
  14. unit bsSkinTabs;
  15. {$P+,S-,W-,R-}
  16. {$WARNINGS OFF}
  17. {$HINTS OFF}
  18. interface
  19. uses SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, StdCtrls,
  20.      CommCtrl, ComCtrls, ExtCtrls, bsSkinData, bsSkinBoxCtrls;
  21. type
  22.   TbsSkinCustomTabSheet = class(TTabSheet)
  23.   protected
  24.     procedure WMSize(var Msg: TWMSize); message WM_SIZE;
  25.     procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd); message WM_ERASEBKGND;
  26.   public
  27.     procedure PaintBG(DC: HDC);
  28.     constructor Create(AOwner: TComponent); override;
  29.     destructor Destroy; override;
  30.   end;
  31.   TbsSkinTabSheet = class(TbsSkinCustomTabSheet)
  32.   protected
  33.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  34.   public
  35.     constructor Create(AOwner : TComponent); override;
  36.     destructor Destroy; override;
  37.   end;
  38.   TbsSkinPageControl = class(TPageControl)
  39.   private
  40.     FActiveTab, FOldActiveTab: Integer;
  41.     FActiveTabIndex, FOldActiveTabIndex: Integer;
  42.     function GetPosition: Integer;
  43.     function  GetInVisibleItemCount: Integer;
  44.     procedure OnUpDownChange(Sender: TObject);
  45.     procedure DrawTabs(Cnvs: TCanvas);
  46.     procedure DrawTab(TI: Integer; const Rct: TRect; Active, MouseIn: Boolean; Cnvs: TCanvas);
  47.     function GetItemRect(index: integer): TRect;
  48.     procedure SetItemSize(AWidth, AHeight: integer);
  49.     procedure CheckScroll;
  50.     procedure ShowSkinUpDown;
  51.     procedure HideSkinUpDown;
  52.     procedure TestActive(X, Y: Integer);
  53.   protected
  54.     //
  55.     FSD: TbsSkinData;
  56.     FSkinDataName: String;
  57.     FIndex: Integer;
  58.     FSkinUpDown: TbsSkinUpDown;
  59.     FDefaultFont: TFont;
  60.     FUseSkinFont: Boolean;
  61.     FDefaultItemHeight: Integer;
  62.     procedure SetDefaultItemHeight(Value: Integer);
  63.     procedure SetDefaultFont(Value: TFont);
  64.     procedure Change; override;
  65.     procedure GetSkinData;
  66.     //
  67.     procedure Notification(AComponent: TComponent;
  68.       Operation: TOperation); override;
  69.     procedure SetSkinData(Value: TbsSkinData);
  70.     procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd); message WM_ERASEBKGND;
  71.     procedure WMHSCROLL(var Msg: TWMEraseBkGnd); message WM_HSCROLL;
  72.     procedure WMSize(var Msg: TWMSize); message WM_SIZE;
  73.     procedure PaintDefaultWindow(Cnvs: TCanvas);
  74.     procedure PaintSkinWindow(Cnvs: TCanvas);
  75.     procedure PaintWindow(DC: HDC); override;
  76.     procedure WndProc(var Message:TMessage); override;
  77.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  78.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  79.                         X, Y: Integer); override;
  80.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  81.   public
  82.     //
  83.     Picture: TBitMap;
  84.     SkinRect, ClRect, TabRect,
  85.     ActiveTabRect, FocusTabRect, MouseInTabRect: TRect;
  86.     TabsBGRect: TRect;
  87.     LTPoint, RTPoint, LBPoint, RBPoint: TPoint;
  88.     TabLeftOffset, TabRightOffset: Integer;
  89.     FontName: String;
  90.     FontStyle: TFontStyles;
  91.     FontHeight: Integer;
  92.     FontColor, ActiveFontColor, FocusFontColor, MouseInFontColor: TColor;
  93.     UpDown: String;
  94.     BGPictureIndex: Integer;
  95.     //
  96.     constructor Create(AOwner: TComponent); override;
  97.     destructor Destroy; override;
  98.     procedure ChangeSkinData;
  99.     procedure Loaded; override;
  100.     procedure UpDateTabs;
  101.   published
  102.     property DefaultFont: TFont read FDefaultFont write SetDefaultFont;
  103.     property UseSkinFont: Boolean read FUseSkinFont write FUseSkinFont;
  104.     property DefaultItemHeight: Integer read FDefaultItemHeight write SetDefaultItemHeight;
  105.     property SkinData: TbsSkinData read FSD write SetSkinData;
  106.     property SkinDataName: String read FSkinDataName write FSkinDataName;
  107.     property Color;
  108.     property ActivePage;
  109.     property Align;
  110.     property Anchors;
  111.     property BiDiMode;
  112.     property Constraints;
  113.     property DockSite;
  114.     property DragCursor;
  115.     property DragKind;
  116.     property DragMode;
  117.     property Enabled;
  118.     property Font;
  119.     property HotTrack;
  120.     property Images;
  121.     property OwnerDraw;
  122.     property ParentBiDiMode;
  123.     property ParentFont;
  124.     property ParentShowHint;
  125.     property PopupMenu;
  126.     property RaggedRight;
  127.     property ScrollOpposite;
  128.     property ShowHint;
  129.     property TabHeight;
  130.     property TabOrder;
  131.     property TabPosition;
  132.     property TabStop;
  133.     property TabWidth;
  134.     property Visible;
  135.     property OnChange;
  136.     property OnChanging;
  137.     property OnDockDrop;
  138.     property OnDockOver;
  139.     property OnDragDrop;
  140.     property OnDragOver;
  141.     property OnDrawTab;
  142.     property OnEndDock;
  143.     property OnEndDrag;
  144.     property OnEnter;
  145.     property OnExit;
  146.     property OnGetImageIndex;
  147.     property OnGetSiteInfo;
  148.     property OnMouseDown;
  149.     property OnMouseMove;
  150.     property OnMouseUp;
  151.     property OnResize;
  152.     property OnStartDock;
  153.     property OnStartDrag;
  154.     property OnUnDock;
  155.   end;
  156.   TbsSkinTabControl = class(TTabControl)
  157.   private
  158.     FOldTop, FOldBottom: Integer;
  159.     FActiveTab, FOldActiveTab: Integer;
  160.     function GetPosition: Integer;
  161.     function  GetInVisibleItemCount: Integer;
  162.     procedure OnUpDownChange(Sender: TObject);
  163.     procedure DrawTabs(Cnvs: TCanvas);
  164.     procedure DrawTab(TI: Integer; const Rct: TRect; Active, MouseIn: Boolean; Cnvs: TCanvas);
  165.     function GetItemRect(index: integer): TRect;
  166.     procedure SetItemSize(AWidth, AHeight: integer);
  167.     procedure CheckScroll;
  168.     procedure ShowSkinUpDown;
  169.     procedure HideSkinUpDown;
  170.     procedure TestActive(X, Y: Integer);
  171.   protected
  172.     //
  173.     FSD: TbsSkinData;
  174.     FSkinDataName: String;
  175.     FIndex: Integer;
  176.     FSkinUpDown: TbsSkinUpDown;
  177.     FDefaultFont: TFont;
  178.     FUseSkinFont: Boolean;
  179.     FDefaultItemHeight: Integer;
  180.     procedure SetDefaultItemHeight(Value: Integer);
  181.     procedure SetDefaultFont(Value: TFont);
  182.     procedure WMSize(var Msg: TWMSize); message WM_SIZE;
  183.     procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
  184.     procedure GetSkinData;
  185.     //
  186.     procedure Notification(AComponent: TComponent;
  187.       Operation: TOperation); override;
  188.     procedure SetSkinData(Value: TbsSkinData);
  189.     procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd); message WM_ERASEBKGND;
  190.     procedure WMHSCROLL(var Msg: TWMEraseBkGnd); message WM_HSCROLL;
  191.     procedure PaintDefaultWindow(Cnvs: TCanvas);
  192.     procedure PaintSkinWindow(Cnvs: TCanvas);
  193.     procedure PaintWindow(DC: HDC); override;
  194.     procedure WndProc(var Message:TMessage); override;
  195.     procedure Change; override;
  196.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  197.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  198.       X, Y: Integer); override;
  199.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  200.   public
  201.     //
  202.     Picture: TBitMap;
  203.     SkinRect, ClRect, TabRect,
  204.     ActiveTabRect, FocusTabRect, MouseInTabRect: TRect;
  205.     TabsBGRect: TRect;
  206.     LTPoint, RTPoint, LBPoint, RBPoint: TPoint;
  207.     TabLeftOffset, TabRightOffset: Integer;
  208.     FontName: String;
  209.     FontStyle: TFontStyles;
  210.     FontHeight: Integer;
  211.     FontColor, ActiveFontColor, FocusFontColor, MouseInFontColor: TColor;
  212.     UpDown: String;
  213.     BGPictureIndex: Integer;
  214.     //
  215.     constructor Create(AOwner: TComponent); override;
  216.     destructor Destroy; override;
  217.     procedure ChangeSkinData;
  218.     procedure Loaded; override;
  219.     procedure UpDateTabs; 
  220.   published
  221.     property DefaultFont: TFont read FDefaultFont write SetDefaultFont;
  222.     property UseSkinFont: Boolean read FUseSkinFont write FUseSkinFont;
  223.     property DefaultItemHeight: Integer read FDefaultItemHeight write SetDefaultItemHeight;
  224.     property SkinData: TbsSkinData read FSD write SetSkinData;
  225.     property SkinDataName: String read FSkinDataName write FSkinDataName;
  226.     property Color;
  227.     property Align;
  228.     property Anchors;
  229.     property BiDiMode;
  230.     property Constraints;
  231.     property DockSite;
  232.     property DragCursor;
  233.     property DragKind;
  234.     property DragMode;
  235.     property Enabled;
  236.     property Font;
  237.     property HotTrack;
  238.     property Images;
  239.     property OwnerDraw;
  240.     property ParentBiDiMode;
  241.     property ParentFont;
  242.     property ParentShowHint;
  243.     property PopupMenu;
  244.     property RaggedRight;
  245.     property ScrollOpposite;
  246.     property ShowHint;
  247.     property TabHeight;
  248.     property TabOrder;
  249.     property TabPosition;
  250.     property TabStop;
  251.     property TabWidth;
  252.     property Visible;
  253.     property OnChange;
  254.     property OnChanging;
  255.     property OnDockDrop;
  256.     property OnDockOver;
  257.     property OnDragDrop;
  258.     property OnDragOver;
  259.     property OnDrawTab;
  260.     property OnEndDock;
  261.     property OnEndDrag;
  262.     property OnEnter;
  263.     property OnExit;
  264.     property OnGetImageIndex;
  265.     property OnGetSiteInfo;
  266.     property OnMouseDown;
  267.     property OnMouseMove;
  268.     property OnMouseUp;
  269.     property OnResize;
  270.     property OnStartDock;
  271.     property OnStartDrag;
  272.     property OnUnDock;
  273.   end;
  274. implementation
  275. uses Consts, ComStrs, bsUtils, ImgList, BusinessSkinForm, bsEffects;
  276. procedure DrawRotate90_1(Cnvs: TCanvas; B: TBitMap; X, Y: Integer);
  277. var
  278.   B1, B2: TbsEffectBmp;
  279. begin
  280.   B1 := TbsEffectBmp.CreateFromhWnd(B.Handle);
  281.   B2 := TbsEffectBmp.Create(B1.Height, B1.Width);
  282.   B1.Rotate90_1(B2);
  283.   B2.Draw(Cnvs.Handle, X, Y);
  284.   B1.Free;
  285.   B2.Free;
  286. end;
  287. procedure DrawRotate90_2(Cnvs: TCanvas; B: TBitMap; X, Y: Integer);
  288. var
  289.   B1, B2: TbsEffectBmp;
  290. begin
  291.   B1 := TbsEffectBmp.CreateFromhWnd(B.Handle);
  292.   B2 := TbsEffectBmp.Create(B1.Height, B1.Width);
  293.   B1.Rotate90_2(B2);
  294.   B2.Draw(Cnvs.Handle, X, Y);
  295.   B1.Free;
  296.   B2.Free;
  297. end;
  298. procedure DrawTabGlyphAndText(Cnvs: TCanvas; W, H: Integer; S: String;
  299.                               IM: TCustomImageList; IMIndex: Integer;
  300.                               AEnabled: Boolean);
  301. var
  302.   R, TR: TRect;
  303.   GX, GY, GW, GH, TW, TH: Integer;
  304. begin
  305.   R := Rect(0, 0, 0, 0);
  306.   DrawText(Cnvs.Handle, PChar(S), Length(S), R, DT_CALCRECT);
  307.   TW := RectWidth(R) + 2;
  308.   TH := RectHeight(R);
  309.   GW := IM.Width;
  310.   GH := IM.Height;
  311.   GX := W div 2 - (GW + TW + 2) div 2;
  312.   GY := H div 2 - GH div 2;
  313.   TR.Left := GX + GW + 2;
  314.   TR.Top := H div 2 - TH div 2;
  315.   TR.Right := TR.Left + TW;
  316.   TR.Bottom := TR.Top + TH;
  317.   DrawText(Cnvs.Handle, PChar(S), Length(S), TR, DT_CENTER);
  318.   IM.Draw(Cnvs, GX, GY, IMIndex, AEnabled);
  319. end;
  320. constructor TbsSkinCustomTabSheet.Create(AOwner: TComponent);
  321. begin
  322.   inherited Create(AOwner);
  323.   Align := alClient;
  324.   ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];
  325.   Visible := False;
  326. end;
  327. destructor TbsSkinCustomTabSheet.Destroy;
  328. begin
  329.   inherited Destroy;
  330. end;
  331. procedure TbsSkinCustomTabSheet.WMEraseBkGnd;
  332. begin
  333.   PaintBG(Msg.DC);
  334. end;
  335. procedure TbsSkinCustomTabSheet.WMSize;
  336. begin
  337.   inherited;
  338.   RePaint;
  339. end;
  340. procedure TbsSkinCustomTabSheet.PaintBG;
  341. var
  342.   C: TCanvas;
  343.   TabSheetBG: TBitMap;
  344.   PC: TbsSkinPageControl;
  345.   X, Y, XCnt, YCnt, XO, YO, w, h, w1, h1: Integer;
  346. begin
  347.   if (Width <= 0) or (Height <=0) then Exit;
  348.   PC := TbsSkinPageControl(Parent);
  349.   if PC = nil then Exit;
  350.   PC.GetSkinData;
  351.   C := TCanvas.Create;
  352.   C.Handle := DC;
  353.   if (PC.FSD <> nil) and (not PC.FSD.Empty) and
  354.      (PC.FIndex <> -1) and (PC.BGPictureIndex <> -1)
  355.   then
  356.     begin
  357.       TabSheetBG := TBitMap(PC.FSD.FActivePictures.Items[PC.BGPictureIndex]);
  358.       if (Width > 0) and (Height > 0)
  359.       then
  360.         begin
  361.           XCnt := Width div TabSheetBG.Width;
  362.           YCnt := Height div TabSheetBG.Height;
  363.           for X := 0 to XCnt do
  364.           for Y := 0 to YCnt do
  365.           C.Draw(X * TabSheetBG.Width, Y * TabSheetBG.Height, TabSheetBG);
  366.         end;
  367.       C.Free;
  368.       Exit;
  369.     end;
  370.   w1 := Width;
  371.   h1 := Height;
  372.   TabSheetBG := TBitMap.Create;
  373.   TabSheetBG.Width := w1;
  374.   TabSheetBG.Height := h1;
  375.   if PC.FIndex <> -1
  376.   then
  377.   with TabSheetBG.Canvas, PC do
  378.   begin
  379.       w := RectWidth(ClRect);
  380.       h := RectHeight(ClRect);
  381.       XCnt := w1 div w;
  382.       YCnt := h1 div h;
  383.       for X := 0 to XCnt do
  384.       for Y := 0 to YCnt do
  385.       begin
  386.         if X * w + w > w1 then XO := X * w + w - w1 else XO := 0;
  387.         if Y * h + h > h1 then YO := Y * h + h - h1 else YO := 0;
  388.         CopyRect(Rect(X * w, Y * h, X * w + w - XO, Y * h + h - YO),
  389.                  Picture.Canvas,
  390.                  Rect(SkinRect.Left + ClRect.Left, SkinRect.Top + ClRect.Top,
  391.                  SkinRect.Left + ClRect.Right - XO,
  392.                  SkinRect.Top + ClRect.Bottom - YO));
  393.       end;
  394.   end
  395.   else
  396.   with TabSheetBG.Canvas do
  397.   begin
  398.     Brush.Color := clbtnface;
  399.     FillRect(Rect(0, 0, w1, h1));
  400.   end;
  401.   C.Draw(0, 0, TabSheetBG);
  402.   TabSheetBG.Free;
  403.   C.Free;
  404. end;
  405. {TTabSheetes}
  406. constructor TbsSkinTabSheet.Create(AOwner : TComponent);
  407. begin
  408.   inherited Create(AOwner);
  409. end;
  410. destructor TbsSkinTabSheet.Destroy;
  411. begin
  412.   inherited Destroy;
  413. end;
  414. procedure TbsSkinTabSheet.Notification(AComponent: TComponent; Operation: TOperation);
  415. begin
  416.   inherited Notification(AComponent, Operation);
  417. end;
  418. { TbsSkinPageControl }
  419. constructor TbsSkinPageControl.Create(AOwner: TComponent);
  420. begin
  421.   inherited Create(AOwner);
  422.   Ctl3D := False;
  423.   FIndex := -1;
  424.   Picture := nil;
  425.   Font.Name := 'Arial';
  426.   Font.Style := [];
  427.   Font.Color := clBtnText;
  428.   Font.Height := 14;
  429.   FSkinUpDown := nil;
  430.   FSkinDataName := 'tab';
  431.   FDefaultFont := TFont.Create;
  432.   FDefaultFont.Name := 'Arial';
  433.   FDefaultFont.Style := [];
  434.   FDefaultFont.Color := clBtnText;
  435.   FDefaultFont.Height := 14;
  436.   FDefaultItemHeight := 20;
  437.   FActiveTab := -1;
  438.   FOldActiveTab := -1;
  439.   FActiveTabIndex := -1;
  440.   FOldActiveTabIndex := -1;
  441.   FUseSkinFont := True;
  442. end;
  443. destructor TbsSkinPageControl.Destroy;
  444. begin
  445.   FDefaultFont.Free;
  446.   inherited Destroy;
  447. end;
  448. procedure TbsSkinPageControl.UpDateTabs;
  449. begin
  450.   if FIndex <> -1
  451.   then
  452.     SetItemSize(0, RectHeight(TabRect))
  453.   else
  454.     SetItemSize(0, FDefaultItemHeight);
  455.   if MultiLine and (FSkinUpDown <> nil)
  456.   then
  457.     HideSkinUpDown;
  458.   ReAlign;
  459. end;
  460. procedure TbsSkinPageControl.CMMouseLeave;
  461. var
  462.   R: TRect;
  463. begin
  464.   if (FOldActiveTabIndex <> - 1) and (FOldActiveTabIndex <> TabIndex) and
  465.      (FOldActiveTabIndex < PageCount)
  466.   then
  467.     begin
  468.       R := GetItemRect(FOldActiveTabIndex);
  469.       DrawTab(FOldActiveTab, R, False, False, Canvas);
  470.       FOldActiveTabIndex := -1;
  471.       FOldActiveTab := -1;
  472.     end;
  473.   if (FActiveTabIndex <> - 1) and (FActiveTabIndex <> TabIndex) and
  474.      (FActiveTabIndex < PageCount)
  475.   then
  476.     begin
  477.       R := GetItemRect(FActiveTabIndex);
  478.       DrawTab(FActiveTab, R, False, False, Canvas);
  479.       FActiveTabIndex := -1;
  480.       FActiveTab := -1;
  481.     end;
  482. end;
  483. procedure TbsSkinPageControl.MouseDown;
  484. begin
  485.   inherited;
  486.   if (Button = mbLeft) and not (csDesigning in ComponentState)
  487.   then
  488.     TestActive(X, Y);
  489. end;
  490. procedure TbsSkinPageControl.MouseMove;
  491. begin
  492.  inherited;
  493.  if  not (csDesigning in ComponentState)
  494.  then
  495.    TestActive(X, Y);
  496. end;
  497. procedure TbsSkinPageControl.SetDefaultItemHeight;
  498. begin
  499.   FDefaultItemHeight := Value;
  500.   if FIndex = -1
  501.   then
  502.     begin
  503.       SetItemSize(0, FDefaultItemHeight);
  504.       Change;
  505.       ReAlign;
  506.     end;
  507. end;
  508. procedure TbsSkinPageControl.SetDefaultFont;
  509. begin
  510.   FDefaultFont.Assign(Value);
  511. end;
  512. procedure TbsSkinPageControl.OnUpDownChange(Sender: TObject);
  513. begin
  514.   FSkinUpDown.Max := GetInVisibleItemCount;
  515.   SendMessage(Handle, WM_HSCROLL,
  516.     MakeWParam(SB_THUMBPOSITION, FSkinUpDown.Position), 0);
  517. end;
  518. function TbsSkinPageControl.GetPosition: Integer;
  519. var
  520.   i, j: Integer;
  521.   R: TRect;
  522. begin
  523.   j := 0;
  524.   for i := 0 to PageCount - 1 do
  525.   begin
  526.     R := GetItemRect(i);
  527.     if R.Right <= 0 then inc(j);
  528.   end;
  529.   Result := j;
  530. end;
  531. function TbsSkinPageControl.GetInVisibleItemCount;
  532. var
  533.   i, j, k: Integer;
  534.   R: TRect;
  535.   Limit: Integer;
  536. begin
  537.   if FSkinUpDown = nil
  538.   then
  539.     Limit := Width - 3
  540.   else
  541.     Limit := Width - FSkinUpDown.Width - 3;
  542.   j := 0;
  543.   k := -1;
  544.   for i := 0 to PageCount - 1 do
  545.   if Pages[i].TabVisible
  546.   then
  547.   begin
  548.     inc(k);
  549.     R := GetItemRect(k);
  550.     if (R.Right > Limit) or (R.Right <= 0)
  551.     then inc(j);
  552.   end;
  553.   Result := j;
  554. end;
  555. procedure TbsSkinPageControl.CheckScroll;
  556. var
  557.   Wnd: HWND;
  558.   InVCount: Integer;
  559. begin
  560.   Wnd := FindWindowEx(Handle, 0, 'msctls_updown32', nil);
  561.   if Wnd <> 0 then DestroyWindow(Wnd);
  562.   InVCount := GetInVisibleItemCount;
  563.   if ((InVCount = 0) or MultiLine) and (FSkinUpDown <> nil)
  564.   then
  565.     HideSkinUpDown
  566.   else
  567.   if (InVCount > 0) and (FSkinUpDown = nil)
  568.   then
  569.     ShowSkinUpDown;
  570.   if FSkinUpDown <> nil
  571.   then
  572.     begin
  573.       FSkinUpDown.Max := InVCount;
  574.       FSkinUpDown.Left := Width - FSkinUpDown.Width;
  575.       if TabPosition = tpTop
  576.       then
  577.         FSkinUpDown.Top := 0
  578.       else
  579.        FSkinUpDown.Top := Height - FSkinUpDown.Height;
  580.     end;
  581. end;
  582. procedure TbsSkinPageControl.ShowSkinUpDown;
  583. begin
  584.   FSkinUpDown := TbsSkinUpDown.Create(Self);
  585.   FSkinUpDown.Parent := Self;
  586.   FSkinUpDown.Width := FDefaultItemHeight * 2;
  587.   FSkinUpDown.Height := FDefaultItemHeight;
  588.   FSkinUpDown.Min := 0;
  589.   FSkinUpDown.Max := GetInVisibleItemCount;
  590.   FSkinUpDown.Position := GetPosition;
  591.   FSkinUpDown.Increment := 1;
  592.   FSkinUpDown.OnChange := OnUpDownChange;
  593.   FSkinUpDown.Left := Width - FSkinUpDown.Width;
  594.   if TabPosition = tpTop
  595.   then
  596.     FSkinUpDown.Top := 0
  597.   else
  598.     FSkinUpDown.Top := Height - FSkinUpDown.Height;
  599.   FSkinUpDown.SkinDataName := UpDown;
  600.   FSkinUpDown.SkinData := SkinData;
  601.   FSkinUpDown.Visible := True;
  602. end;
  603. procedure TbsSkinPageControl.HideSkinUpDown;
  604. begin
  605.   FSkinUpDown.Free;
  606.   FSkinUpDown := nil;
  607. end;
  608. procedure TbsSkinPageControl.WMHSCROLL;
  609. begin
  610.   inherited;
  611.   RePaint;
  612. end;
  613. procedure TbsSkinPageControl.WMSize;
  614. begin
  615.   GetSkinData;
  616.   inherited;
  617. end;
  618. procedure TbsSkinPageControl.Change;
  619. begin
  620.   if FSkinUpDown <> nil
  621.   then FSkinUpDown.Position := GetPosition;
  622.   inherited;
  623.   Invalidate;
  624. end;
  625. procedure TbsSkinPageControl.GetSkinData;
  626. begin
  627.   BGPictureIndex := -1;
  628.   if FSD = nil
  629.   then
  630.     begin
  631.       FIndex := -1;
  632.       Exit;
  633.     end;
  634.   if FSD.Empty
  635.   then
  636.     FIndex := -1
  637.   else
  638.     FIndex := FSD.GetControlIndex(FSkinDataName);
  639.   //
  640.   if FIndex <> -1
  641.   then
  642.     if TbsDataSkinControl(FSD.CtrlList.Items[FIndex]) is TbsDataSkinTabControl
  643.     then
  644.       with TbsDataSkinTabControl(FSD.CtrlList.Items[FIndex]) do
  645.       begin
  646.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  647.         then
  648.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  649.         else
  650.           Picture := nil;
  651.         Self.SkinRect := SkinRect;
  652.         Self.ClRect := ClRect;
  653.         Self.TabRect := TabRect;
  654.         if IsNullRect(ActiveTabRect)
  655.         then
  656.           Self.ActiveTabRect := TabRect
  657.         else
  658.           Self.ActiveTabRect := ActiveTabRect;
  659.         if IsNullRect(FocusTabRect)
  660.         then
  661.           Self.FocusTabRect := ActiveTabRect
  662.         else
  663.           Self.FocusTabRect := FocusTabRect;
  664.         //
  665.         Self.TabsBGRect := TabsBGRect;
  666.         Self.LTPoint := LTPoint;
  667.         Self.RTPoint := RTPoint;
  668.         Self.LBPoint := LBPoint;
  669.         Self.RBPoint := RBPoint;
  670.         Self.TabLeftOffset := TabLeftOffset;
  671.         Self.TabRightOffset := TabRightOffset;
  672.         //
  673.         Self.FontName := FontName;
  674.         Self.FontColor := FontColor;
  675.         Self.ActiveFontColor := ActiveFontColor;
  676.         Self.FocusFontColor := FocusFontColor;
  677.         Self.FontStyle := FontStyle;
  678.         Self.FontHeight := FontHeight;
  679.         Self.UpDown := UpDown;
  680.         Self.BGPictureIndex := BGPictureIndex;
  681.         Self.MouseInTabRect := MouseInTabRect;
  682.         Self.MouseInFontColor := MouseInFontColor;
  683.       end;
  684. end;
  685. procedure TbsSkinPageControl.ChangeSkinData;
  686. begin
  687.   GetSkinData;
  688.   //
  689.   if FIndex <> -1
  690.   then
  691.     begin
  692.       if FUseSkinFont
  693.       then
  694.         begin
  695.           Font.Name := FontName;
  696.           Font.Height := FontHeight;
  697.           Font.Style := FontStyle;
  698.           Font.CharSet := DefaultFont.CharSet;
  699.         end
  700.       else
  701.         Font.Assign(FDefaultFont);
  702.       Font.Color := FontColor;
  703.       SetItemSize(0, RectHeight(TabRect));
  704.     end
  705.   else
  706.     begin
  707.       Font.Assign(FDefaultFont);
  708.       SetItemSize(0, FDefaultItemHeight);
  709.     end;
  710.   //
  711.   Change;
  712.   ReAlign;
  713.   if FSkinUpDown <> nil
  714.   then
  715.     begin
  716.       HideSkinUpDown;
  717.       CheckScroll;
  718.     end;
  719. end;
  720. procedure TbsSkinPageControl.SetSkinData;
  721. begin
  722.   FSD := Value;
  723.   if (FSD <> nil) then
  724.   if not FSD.Empty and not (csDesigning in ComponentState)
  725.   then
  726.     ChangeSkinData;
  727. end;
  728. procedure TbsSkinPageControl.Notification;
  729. begin
  730.   inherited Notification(AComponent, Operation);
  731.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  732. end;
  733. procedure TbsSkinPageControl.PaintDefaultWindow;
  734. var
  735.   R: TRect;
  736. begin
  737.   with Cnvs do
  738.   begin
  739.     Brush.Color := clBtnFace;
  740.     FillRect(ClientRect);
  741.     R := Self.DisplayRect;
  742.     InflateRect(R, 1, 1);
  743.     Frame3D(Cnvs, R, clBtnShadow, clBtnShadow, 1);
  744.   end;
  745. end;
  746. procedure TbsSkinPageControl.PaintSkinWindow;
  747. var
  748.   TOff, LOff, Roff, BOff: Integer;
  749.   DR, R: TRect;
  750.   TBGOffX, TBGOffY, X, Y, XCnt, YCnt, w, h, rw, rh, XO, YO: Integer;
  751.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  752. begin
  753.   TOff := ClRect.Top;
  754.   LOff := ClRect.Left;
  755.   ROff := RectWidth(SkinRect) - ClRect.Right;
  756.   BOff := RectHeight(SkinRect) - ClRect.Bottom;
  757.   DR := DisplayRect;
  758.   R := Rect(DR.Left - LOff, DR.Top - TOff, DR.Right + ROff, DR.Bottom + BOff);
  759.   XO := RectWidth(R) - RectWidth(SkinRect);
  760.   YO := RectHeight(R) - RectHeight(SkinRect);
  761.   NewLTPoint := LTPoint;
  762.   NewRTPoint := Point(RTPoint.X + XO, RTPoint.Y);
  763.   NewLBPoint := Point(LBPoint.X, LBPoint.Y + YO);
  764.   NewRBPoint := Point(RBPoint.X + XO, RBPoint.Y + YO);
  765.   // Draw tabs BG
  766.   if not IsNullRect(TabsBGRect)
  767.   then
  768.     begin
  769.       if TabPosition = tpLeft
  770.       then
  771.         begin
  772.           TBGOffY := 0;
  773.           TBGOffX := 0;
  774.           rw := R.Left;
  775.           rh := Height;
  776.         end
  777.       else
  778.       if TabPosition = tpRight
  779.       then
  780.         begin
  781.           TBGOffY := 0;
  782.           TBGOffX := R.Right;
  783.           rw := Width - R.Right;
  784.           rh := Height;
  785.         end
  786.       else
  787.       if TabPosition = tpTop
  788.       then
  789.         begin
  790.           TBGOffX := 0;
  791.           TBGOffY := 0;
  792.           rh := R.Top;
  793.           rw := Width;
  794.         end
  795.       else
  796.         begin
  797.           TBGOffX := 0;
  798.           TBGOffY := R.Bottom;
  799.           rh := Height - R.Bottom;
  800.           rw := Width;
  801.         end;
  802.       w := RectWidth(TabsBGRect);
  803.       h := RectHeight(TabsBGRect);
  804.       XCnt := rw div w;
  805.       YCnt := rh div h;
  806.       for X := 0 to XCnt do
  807.       for Y := 0 to YCnt do
  808.       begin
  809.         if X * w + w > rw then XO := X * w + w - rw else XO := 0;
  810.         if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  811.         Cnvs.CopyRect(Rect(TBGOffX + X * w, TBGOffY + Y * h,
  812.                            TBGOffX + X * w + w - XO, TBGOffY + Y * h + h - YO),
  813.                       Picture.Canvas,
  814.                       Rect(TabsBGRect.Left, TabsBGRect.Top,
  815.                            TabsBGRect.Right - XO, TabsBGRect.Bottom - YO));
  816.       end;
  817.     end;  
  818.   // Draw frame around displayrect
  819.     // draw lines
  820.   w := RTPoint.X - LTPoint.X;
  821.   XCnt := (NewRTPoint.X - NewLTPoint.X) div w;
  822.   for X := 0 to XCnt do
  823.   begin
  824.     if NewLTPoint.X + X * w + w > NewRTPoint.X
  825.     then XO := NewLTPoint.X + X * w + w - NewRTPoint.X else XO := 0;
  826.     Cnvs.CopyRect(Rect(R.Left + NewLTPoint.X + X * w, R.Top,
  827.                   R.Left + NewLTPoint.X + X * w + w - XO, R.Top + TOff),
  828.              Picture.Canvas,
  829.              Rect(SkinRect.Left + LTPoint.X, SkinRect.Top,
  830.                   SkinRect.Left + RTPoint.X - XO, SkinRect.Top + TOff));
  831.   end;
  832.   w := RBPoint.X - LBPoint.X;
  833.   XCnt := (NewRBPoint.X - NewLBPoint.X) div w;
  834.   for X := 0 to XCnt do
  835.   begin
  836.     if NewLBPoint.X + X * w + w > NewRBPoint.X
  837.     then XO := NewLBPoint.X + X * w + w - NewRBPoint.X else XO := 0;
  838.     Cnvs.CopyRect(Rect(R.Left + NewLBPoint.X + X * w, R.Bottom - BOff,
  839.                   R.Left + NewLBPoint.X + X * w + w - XO, R.Bottom),
  840.              Picture.Canvas,
  841.              Rect(SkinRect.Left + LBPoint.X, SkinRect.Bottom - BOff,
  842.                   SkinRect.Left + RBPoint.X - XO, SkinRect.Bottom));
  843.   end;
  844.   w := LOff;
  845.   h := LBPoint.Y - LTPoint.Y;
  846.   YCnt := (NewLBPoint.Y - NewLTPoint.Y) div h;
  847.   for Y := 0 to YCnt do
  848.   begin
  849.     if NewLTPoint.Y + Y * h + h > NewLBPoint.Y
  850.     then YO := NewLTPoint.Y + Y * h + h - NewLBPoint.Y else YO := 0;
  851.     Cnvs.CopyRect(Rect(R.Left, R.Top + NewLTPoint.Y + Y * h,
  852.                        R.Left + w, R.Top + NewLTPoint.Y + Y * h + h - YO),
  853.                   Picture.Canvas,
  854.                   Rect(SkinRect.Left, SkinRect.Top + LTPoint.Y,
  855.                        SkinRect.Left + w, SkinRect.Top + LBPoint.Y - YO));
  856.   end;
  857.   w := ROff;
  858.   h := RBPoint.Y - RTPoint.Y;
  859.   YCnt := (NewRBPoint.Y - NewRTPoint.Y) div h;
  860.   for Y := 0 to YCnt do
  861.   begin
  862.     if NewRTPoint.Y + Y * h + h > NewRBPoint.Y
  863.     then YO := NewRTPoint.Y + Y * h + h - NewRBPoint.Y else YO := 0;
  864.     Cnvs.CopyRect(Rect(R.Right - w, R.Top + NewRTPoint.Y + Y * h,
  865.                        R.Right, R.Top + NewRTPoint.Y + Y * h + h - YO),
  866.                   Picture.Canvas,
  867.                   Rect(SkinRect.Right - w, SkinRect.Top + RTPoint.Y,
  868.                        SkinRect.Right, SkinRect.Top + RBPoint.Y - YO));
  869.   end;
  870.     // draw corners
  871.   Cnvs.CopyRect(Rect(R.Left, R.Top, R.Left + LTPoint.X, R.Top + LTPoint.Y),
  872.                 Picture.Canvas,
  873.                 Rect(SkinRect.Left, SkinRect.Top,
  874.                      SkinRect.Left + NewLTPoint.X, SkinRect.Top + NewLTPoint.Y));
  875.   Cnvs.CopyRect(Rect(R.Left + NewRTPoint.X, R.Top,
  876.                      R.Right, R.Top + NewRTPoint.Y),
  877.                 Picture.Canvas,
  878.                 Rect(SkinRect.Left + RTPoint.X, SkinRect.Top,
  879.                      SkinRect.Right, SkinRect.Top + RTPoint.Y));
  880.   Cnvs.CopyRect(Rect(R.Left, R.Top + NewLBPoint.Y,
  881.                      R.Left + NewLBPoint.X, R.Bottom),
  882.                 Picture.Canvas,
  883.                 Rect(SkinRect.Left, SkinRect.Top + LBPoint.Y,
  884.                      SkinRect.Left + LBPoint.X, SkinRect.Bottom));
  885.   Cnvs.CopyRect(Rect(R.Left + NewRBPoint.X, R.Top + NewRBPoint.Y,
  886.                      R.Right, R.Bottom),
  887.                 Picture.Canvas,
  888.                 Rect(SkinRect.Left + RBPoint.X, SkinRect.Top + RBPoint.Y,
  889.                      SkinRect.Right, SkinRect.Bottom));
  890. end;
  891. procedure TbsSkinPageControl.Loaded;
  892. begin
  893.   inherited Loaded;
  894.   if FIndex = -1
  895.   then
  896.     begin
  897.       SetItemSize(0, FDefaultItemHeight);
  898.       Change;
  899.       ReAlign;
  900.     end;
  901. end;
  902. procedure TbsSkinPageControl.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
  903. begin
  904.   if Self.PageCount = 0
  905.   then
  906.     inherited
  907.   else
  908.     Msg.Result := 1;
  909. end;
  910. procedure TbsSkinPageControl.WndProc(var Message:TMessage);
  911. var
  912.   TOff, LOff, Roff, BOff: Integer;
  913. begin
  914.   if Message.Msg = TCM_ADJUSTRECT
  915.   then
  916.     begin
  917.       inherited WndProc(Message);
  918.       if FIndex <> -1
  919.       then
  920.         begin
  921.           TOff := ClRect.Top;
  922.           LOff := ClRect.Left;
  923.           ROff := RectWidth(SkinRect) - ClRect.Right;
  924.           BOff := RectHeight(SkinRect) - ClRect.Bottom;
  925.         end;
  926.       case TabPosition of
  927.         tpLeft:
  928.            if FIndex <> -1
  929.            then
  930.              begin
  931.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + LOff - 4;
  932.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  933.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  934.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  935.              end
  936.            else
  937.              begin
  938.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  939.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  940.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  941.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  942.              end;
  943.         tpRight:
  944.            if FIndex <> -1
  945.            then
  946.              begin
  947.                PRect(Message.LParam)^.Left := LOff;
  948.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - ROff + 4;
  949.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  950.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  951.              end
  952.            else
  953.              begin
  954.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  955.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 3;
  956.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  957.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  958.              end;
  959.         tpTop:
  960.            if FIndex <> -1
  961.            then
  962.              begin
  963.                PRect(Message.LParam)^.Left := LOff;
  964.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  965.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  966.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  967.              end
  968.            else
  969.              begin
  970.                PRect(Message.LParam)^.Left := 1;
  971.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  972.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  973.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  974.              end;
  975.         tpBottom:
  976.           if FIndex <> -1
  977.           then
  978.             begin
  979.               PRect(Message.LParam)^.Left := LOff;
  980.               PRect(Message.LParam)^.Right := ClientWidth - ROff;
  981.               PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  982.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 4 - BOff;
  983.             end
  984.           else
  985.             begin
  986.               PRect(Message.LParam)^.Left := 1;
  987.               PRect(Message.LParam)^.Right := ClientWidth - 1;
  988.               PRect(Message.LParam)^.Top := 1;
  989.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 3;
  990.             end;
  991.       end;
  992.     end
  993.   else
  994.     if Message.Msg = TCM_GETITEMRECT
  995.     then
  996.       begin
  997.         inherited WndProc(Message);
  998.         if Style = tsTabs
  999.         then
  1000.           case TabPosition of
  1001.             tpLeft:
  1002.                 begin
  1003.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1004.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1005.                 end;
  1006.             tpRight:
  1007.                 begin
  1008.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + 2;
  1009.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 2;
  1010.                 end;
  1011.             tpTop:
  1012.                 begin
  1013.                   if not MultiLine
  1014.                   then
  1015.                     begin
  1016.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1017.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1018.                     end;
  1019.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 2;
  1020.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom - 2;
  1021.                 end;
  1022.             tpBottom:
  1023.                 begin
  1024.                   if not MultiLine
  1025.                   then
  1026.                     begin
  1027.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1028.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1029.                     end;
  1030.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top + 2;
  1031.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 2;
  1032.                 end;
  1033.           end;
  1034.       end
  1035.   else
  1036.   inherited WndProc(Message);
  1037.   if (Message.Msg = WM_SIZE) and (not MultiLine) and
  1038.      not (csDesigning in ComponentState)
  1039.   then
  1040.     begin
  1041.       CheckScroll;
  1042.     end;
  1043. end;
  1044. function TbsSkinPageControl.GetItemRect(index: integer): TRect;
  1045. var
  1046.   R: TRect;
  1047. begin
  1048.   SendMessage(Handle, TCM_GETITEMRECT, index, Integer(@R));
  1049.   Result := R;
  1050. end;
  1051. procedure TbsSkinPageControl.SetItemSize;
  1052. begin
  1053.   SendMessage(Handle, TCM_SETITEMSIZE, 0, MakeLParam(AWidth, AHeight));
  1054. end;
  1055. procedure TbsSkinPageControl.PaintWindow(DC: HDC);
  1056. var
  1057.   SaveIndex: Integer;
  1058.   B: TBitMap;
  1059. begin
  1060.   if (Width <= 0) or (Height <=0) then Exit;
  1061.   GetSkinData;
  1062.   SaveIndex := SaveDC(DC);
  1063.   try
  1064.     Canvas.Handle := DC;
  1065.     B := TBitMap.Create;
  1066.     B.Width := Width;
  1067.     B.Height := Height;
  1068.     if FIndex = -1
  1069.     then
  1070.       PaintDefaultWindow(B.Canvas)
  1071.     else
  1072.       PaintSkinWindow(B.Canvas);
  1073.     DrawTabs(B.Canvas);
  1074.     Canvas.Draw(0, 0, B);
  1075.     B.Free;
  1076.     Canvas.Handle := 0;
  1077.   finally
  1078.     RestoreDC(DC, SaveIndex);
  1079.   end;
  1080. end;
  1081. procedure TbsSkinPageControl.TestActive(X, Y: Integer);
  1082. var
  1083.   i, j, k: Integer;
  1084.   R: TRect;
  1085. begin
  1086.   FOldActiveTab := FActiveTab;
  1087.   FOldActiveTabIndex := FActiveTabIndex;
  1088.   k := -1;
  1089.   j := -1;
  1090.   for i := 0 to PageCount - 1 do
  1091.   if Pages[i].TabVisible then
  1092.   begin
  1093.     Inc(k);
  1094.     R := GetItemRect(k);
  1095.     if PtInRect(R, Point(X, Y))
  1096.     then
  1097.       begin
  1098.         j := k;
  1099.         Break;
  1100.       end;
  1101.   end;
  1102.   FActiveTab := i;
  1103.   FActiveTabIndex := j;
  1104.   if (FOldActiveTabIndex <> FActiveTabIndex)
  1105.   then
  1106.     begin
  1107.       if (FOldActiveTabIndex <> - 1) and (FOldActiveTabIndex <> TabIndex) and
  1108.          (FOldActiveTabIndex < PageCount)
  1109.       then
  1110.         begin
  1111.           R := GetItemRect(FOldActiveTabIndex);
  1112.           DrawTab(FOldActiveTab, R, False, False, Canvas);
  1113.         end;
  1114.       if (FActiveTabIndex <> -1) and (FActiveTabIndex <> TabIndex) and
  1115.          (FActiveTabIndex < PageCount)
  1116.       then
  1117.         begin
  1118.           R := GetItemRect(FActiveTabIndex);
  1119.           DrawTab(FActiveTab, R, False, True, Canvas );
  1120.         end;
  1121.     end;
  1122. end;
  1123. procedure TbsSkinPageControl.DrawTabs;
  1124. var
  1125.   i, j: integer;
  1126.   R: TRect;
  1127. begin
  1128.   j := -1;
  1129.   for i := 0 to PageCount-1 do
  1130.   if Pages[i].TabVisible then
  1131.   begin
  1132.     inc(j);
  1133.     R := GetItemRect(j);
  1134.     DrawTab(i, R, (j = TabIndex), j = FActiveTabIndex, Cnvs);
  1135.   end;
  1136. end;
  1137. procedure TbsSkinPageControl.DrawTab;
  1138. var
  1139.   R: TRect;
  1140.   S: String;
  1141.   TB: TBitMap;
  1142.   DrawGlyph: Boolean;
  1143.   W, H: Integer;
  1144. begin
  1145.   DrawGlyph := (Images <> nil) and (TI < Images.Count);
  1146.   S := Pages[TI].Caption;
  1147.   TB := TBitMap.Create;
  1148.   if (TabPosition = tpTop) or (TabPosition = tpBottom)
  1149.   then
  1150.     begin
  1151.       W := RectWidth(Rct);
  1152.       H := RectHeight(Rct);
  1153.     end
  1154.   else
  1155.     begin
  1156.       H := RectWidth(Rct);
  1157.       W := RectHeight(Rct);
  1158.     end;
  1159.   R := Rect(0, 0, W, H);  
  1160.   if FIndex <> -1
  1161.   then
  1162.     begin
  1163.       if MouseIn and not Active and not IsNullRect(MouseInTabRect)
  1164.       then
  1165.         CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1166.           TB, Picture, MouseInTabRect, W, H)
  1167.       else
  1168.       if Active and Focused
  1169.       then
  1170.         CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1171.           TB, Picture, FocusTabRect, W, H)
  1172.       else
  1173.       if Active
  1174.       then
  1175.          CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1176.           TB, Picture, ActiveTabRect, W, H)
  1177.       else
  1178.         CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1179.           TB, Picture, TabRect, W, H);
  1180.       with TB.Canvas do
  1181.       begin
  1182.         Brush.Style := bsClear;
  1183.         if FUseSkinFont
  1184.         then
  1185.           begin
  1186.             Font.Name := FontName;
  1187.             Font.Style := FontStyle;
  1188.             Font.Height := FontHeight;
  1189.             Font.CharSet := Self.Font.CharSet;
  1190.           end
  1191.         else
  1192.            Font.Assign(Self.Font);
  1193.         if MouseIn and not Active
  1194.         then
  1195.           Font.Color := MouseInFontColor
  1196.         else
  1197.         if Active and Focused
  1198.         then
  1199.           Font.Color := FocusFontColor
  1200.         else
  1201.           if Active
  1202.           then Font.Color := ActiveFontColor
  1203.           else Font.Color := FontColor;
  1204.       end;
  1205.     end
  1206.   else
  1207.     begin
  1208.       TB.Width := W;
  1209.       TB.Height := H;
  1210.       if MouseIn and not Active
  1211.       then
  1212.         begin
  1213.           TB.Canvas.Brush.Color := BS_XP_BTNACTIVECOLOR;
  1214.           TB.Canvas.FillRect(R);
  1215.         end
  1216.       else
  1217.       if Active and Focused
  1218.       then
  1219.         begin
  1220.           Frame3D(TB.Canvas, R, BS_XP_BTNFRAMECOLOR, BS_XP_BTNFRAMECOLOR, 1);
  1221.           TB.Canvas.Brush.Color := BS_XP_BTNDOWNCOLOR;
  1222.           TB.Canvas.FillRect(R);
  1223.         end
  1224.       else
  1225.       if Active
  1226.       then
  1227.         begin
  1228.           Frame3D(TB.Canvas, R, BS_XP_BTNFRAMECOLOR, BS_XP_BTNFRAMECOLOR, 1);
  1229.           TB.Canvas.Brush.Color := BS_XP_BTNACTIVECOLOR;
  1230.           TB.Canvas.FillRect(R);
  1231.         end
  1232.       else
  1233.         begin
  1234.           TB.Canvas.Brush.Color := clBtnFace;
  1235.           TB.Canvas.FillRect(R);
  1236.         end;
  1237.       with TB.Canvas do
  1238.       begin
  1239.         Brush.Style := bsClear;
  1240.         Font.Assign(Self.Font);
  1241.       end;
  1242.     end;
  1243.   //
  1244.   if DrawGlyph
  1245.   then
  1246.     DrawTabGlyphAndText(TB.Canvas, TB.Width, TB.Height, S,
  1247.                         Images, TI, Pages[TI].Enabled)
  1248.   else
  1249.     DrawText(TB.Canvas.Handle, PChar(S), Length(S), R, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  1250.   if TabPosition = tpLeft
  1251.   then
  1252.     DrawRotate90_1(Cnvs, TB, Rct.Left, Rct.Top)
  1253.   else
  1254.   if TabPosition = tpRight
  1255.   then
  1256.     DrawRotate90_2(Cnvs, TB, Rct.Left, Rct.Top)
  1257.   else
  1258.     Cnvs.Draw(Rct.Left, Rct.Top, TB);
  1259.   TB.Free;
  1260. end;
  1261. { TbsSkinTabControl }
  1262. constructor TbsSkinTabControl.Create(AOwner: TComponent);
  1263. begin
  1264.   inherited Create(AOwner);
  1265.   Ctl3D := False;
  1266.   FIndex := -1;
  1267.   Picture := nil;
  1268.   Font.Name := 'Arial';
  1269.   Font.Style := [];
  1270.   Font.Color := clBtnText;
  1271.   Font.Height := 14;
  1272.   FOldTop := 0;
  1273.   FOldBottom := 0;
  1274.   FSkinUpDown := nil;
  1275.   FSkinDataName := 'tab';
  1276.   FDefaultFont := TFont.Create;
  1277.   FDefaultFont.Name := 'Arial';
  1278.   FDefaultFont.Style := [];
  1279.   FDefaultFont.Color := clBtnText;
  1280.   FDefaultFont.Height := 14;
  1281.   FDefaultItemHeight := 20;
  1282.   FUseSkinFont := True;
  1283. end;
  1284. procedure TbsSkinTabControl.MouseMove;
  1285. begin
  1286.  inherited;
  1287.  if not (csDesigning in ComponentState)
  1288.  then
  1289.    TestActive(X, Y);
  1290. end;
  1291. procedure TbsSkinTabControl.MouseDown;
  1292. begin
  1293.   inherited;
  1294.   if (Button = mbLeft) and not (csDesigning in ComponentState)
  1295.   then
  1296.     TestActive(X, Y);
  1297. end;
  1298. procedure TbsSkinTabControl.CMMouseLeave;
  1299. var
  1300.   R: TRect;
  1301. begin
  1302.   if (FOldActiveTab <> - 1) and (FOldActiveTab <> TabIndex) and
  1303.      (FOldActiveTab < Self.Tabs.Count)
  1304.   then
  1305.     begin
  1306.       R := GetItemRect(FOldActiveTab);
  1307.       DrawTab(FOldActiveTab, R, False, False, Canvas);
  1308.       FOldActiveTab := -1;
  1309.     end;
  1310.   if (FActiveTab <> - 1) and (FActiveTab <> TabIndex) and
  1311.      (FActiveTab < Self.Tabs.Count)
  1312.   then
  1313.     begin
  1314.       R := GetItemRect(FActiveTab);
  1315.       DrawTab(FActiveTab, R, False, False, Canvas);
  1316.       FActiveTab := -1;
  1317.     end;
  1318. end;
  1319. procedure TbsSkinTabControl.TestActive(X, Y: Integer);
  1320. var
  1321.   i, j: Integer;
  1322.   R: TRect;
  1323. begin
  1324.   FOldActiveTab := FActiveTab;
  1325.   j := -1;
  1326.   for i := 0 to Tabs.Count-1 do
  1327.   begin
  1328.     R := GetItemRect(i);
  1329.     if PtInRect(R, Point(X, Y))
  1330.     then
  1331.       begin
  1332.         j := i;
  1333.         Break;
  1334.       end;
  1335.   end;
  1336.   FActiveTab := j;
  1337.   if (FOldActiveTab <> FActiveTab)
  1338.   then
  1339.     begin
  1340.       if (FOldActiveTab <> - 1) and (FOldActiveTab <> TabIndex) and
  1341.          (FOldActiveTab < Self.Tabs.Count)
  1342.       then
  1343.         begin
  1344.           R := GetItemRect(FOldActiveTab);
  1345.           DrawTab(FOldActiveTab, R, False, False, Canvas);
  1346.         end;
  1347.       if (FActiveTab <> -1) and (FActiveTab <> TabIndex) and
  1348.          (FActiveTab < Self.Tabs.Count)
  1349.       then
  1350.         begin
  1351.           R := GetItemRect(FActiveTab);
  1352.           DrawTab(FActiveTab, R, False, True, Canvas );
  1353.         end;
  1354.     end;
  1355. end;
  1356. procedure TbsSkinTabControl.SetDefaultItemHeight;
  1357. begin
  1358.   FDefaultItemHeight := Value;
  1359.   if FIndex = -1
  1360.   then
  1361.     begin
  1362.       SetitemSize(0, FDefaultItemHeight);
  1363.       Change;
  1364.       ReAlign;
  1365.     end;
  1366. end;
  1367. procedure TbsSkinTabControl.SetDefaultFont;
  1368. begin
  1369.   FDefaultFont.Assign(Value);
  1370. end;
  1371. procedure TbsSkinTabControl.OnUpDownChange(Sender: TObject);
  1372. begin
  1373.   FSkinUpDown.Max := GetInVisibleItemCount;
  1374.   SendMessage(Handle, WM_HSCROLL,
  1375.     MakeWParam(SB_THUMBPOSITION, FSkinUpDown.Position), 0);
  1376. end;
  1377. function TbsSkinTabControl.GetPosition: Integer;
  1378. var
  1379.   i, j: Integer;
  1380.   R: TRect;
  1381. begin
  1382.   j := 0;
  1383.   for i := 0 to Tabs.Count - 1 do
  1384.   begin
  1385.     R := GetItemRect(i);
  1386.     if R.Right <= 0 then inc(j);
  1387.   end;
  1388.   Result := j;
  1389. end;
  1390. function TbsSkinTabControl.GetInVisibleItemCount;
  1391. var
  1392.   i, j: Integer;
  1393.   R: TRect;
  1394.   Limit: Integer;
  1395. begin
  1396.   if FSkinUpDown = nil
  1397.   then
  1398.     Limit := Width - 3
  1399.   else
  1400.     Limit := Width - FSkinUpDown.Width - 3;
  1401.   j := 0;
  1402.   for i := 0 to Tabs.Count - 1 do
  1403.   begin
  1404.     R := GetItemRect(i);
  1405.     if (R.Right > Limit) or (R.Right <= 0)
  1406.     then inc(j);
  1407.   end;
  1408.   Result := j;
  1409. end;
  1410. procedure TbsSkinTabControl.CheckScroll;
  1411. var
  1412.   Wnd: HWND;
  1413.   InVCount: Integer;
  1414. begin
  1415.   Wnd := FindWindowEx(Handle, 0, 'msctls_updown32', nil);
  1416.   if Wnd <> 0 then DestroyWindow(Wnd);
  1417.   InVCount := GetInVisibleItemCount;
  1418.   if (InVCount = 0) and (FSkinUpDown <> nil)
  1419.   then
  1420.     HideSkinUpDown
  1421.   else
  1422.   if (InVCount > 0) and (FSkinUpDown = nil)
  1423.   then
  1424.     ShowSkinUpDown;
  1425.   if FSkinUpDown <> nil
  1426.   then
  1427.     begin
  1428.       FSkinUpDown.Max := InVCount;
  1429.       FSkinUpDown.Left := Width - FSkinUpDown.Width;
  1430.       if TabPosition = tpTop
  1431.       then
  1432.         FSkinUpDown.Top := 0
  1433.       else
  1434.        FSkinUpDown.Top := Height - FSkinUpDown.Height;
  1435.     end;
  1436. end;
  1437. procedure TbsSkinTabControl.ShowSkinUpDown;
  1438. begin
  1439.   FSkinUpDown := TbsSkinUpDown.Create(Self);
  1440.   FSkinUpDown.Parent := Self;
  1441.   FSkinUpDown.Width := 36;
  1442.   FSkinUpDown.Height := 18;
  1443.   FSkinUpDown.Min := 0;
  1444.   FSkinUpDown.Max := GetInVisibleItemCount;
  1445.   FSkinUpDown.Position := GetPosition;
  1446.   FSkinUpDown.Increment := 1;
  1447.   FSkinUpDown.OnChange := OnUpDownChange;
  1448.   FSkinUpDown.Left := Width - FSkinUpDown.Width;
  1449.   if TabPosition = tpTop
  1450.   then
  1451.     FSkinUpDown.Top := 0
  1452.   else
  1453.     FSkinUpDown.Top := Height - FSkinUpDown.Height;
  1454.   FSkinUpDown.SkinDataName := UpDown;
  1455.   FSkinUpDown.SkinData := SkinData;
  1456.   FSkinUpDown.Visible := True;
  1457. end;
  1458. procedure TbsSkinTabControl.HideSkinUpDown;
  1459. begin
  1460.   FSkinUpDown.Free;
  1461.   FSkinUpDown := nil;
  1462. end;
  1463. procedure TbsSkinTabControl.WMPaint;
  1464. begin
  1465.   if ControlCount = 0
  1466.   then
  1467.     PaintHandler(Msg)
  1468.   else
  1469.     inherited;
  1470. end;
  1471. procedure TbsSkinTabControl.WMHSCROLL;
  1472. begin
  1473.   inherited;
  1474.   RePaint;
  1475. end;
  1476. procedure TbsSkinTabControl.WMSize;
  1477. begin
  1478.   inherited;
  1479. end;
  1480. destructor TbsSkinTabControl.Destroy;
  1481. begin
  1482.   FDefaultFont.Free;
  1483.   inherited Destroy;
  1484. end;
  1485. procedure TbsSkinTabControl.Change;
  1486. begin
  1487.   if FSkinUpDown <> nil
  1488.   then FSkinUpDown.Position := GetPosition;
  1489.   inherited;
  1490.   Invalidate;
  1491. end;
  1492. procedure TbsSkinTabControl.GetSkinData;
  1493. begin
  1494.   BGPictureIndex := -1;
  1495.   if FSD = nil
  1496.   then
  1497.     begin
  1498.       FIndex := -1;
  1499.       Exit;
  1500.     end;
  1501.   if FSD.Empty
  1502.   then
  1503.     FIndex := -1
  1504.   else
  1505.     FIndex := FSD.GetControlIndex(FSkinDataName);
  1506.   //
  1507.   if FIndex <> -1
  1508.   then
  1509.     if TbsDataSkinControl(FSD.CtrlList.Items[FIndex]) is TbsDataSkinTabControl
  1510.     then
  1511.       with TbsDataSkinTabControl(FSD.CtrlList.Items[FIndex]) do
  1512.       begin
  1513.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  1514.         then
  1515.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  1516.         else
  1517.           Picture := nil;
  1518.         Self.SkinRect := SkinRect;
  1519.         Self.ClRect := ClRect;
  1520.         Self.TabRect := TabRect;
  1521.         if IsNullRect(ActiveTabRect)
  1522.         then
  1523.           Self.ActiveTabRect := TabRect
  1524.         else
  1525.           Self.ActiveTabRect := ActiveTabRect;
  1526.         if IsNullRect(FocusTabRect)
  1527.         then
  1528.           Self.FocusTabRect := ActiveTabRect
  1529.         else
  1530.           Self.FocusTabRect := FocusTabRect;
  1531.         //
  1532.         Self.TabsBGRect := TabsBGRect; 
  1533.         Self.LTPoint := LTPoint;
  1534.         Self.RTPoint := RTPoint;
  1535.         Self.LBPoint := LBPoint;
  1536.         Self.RBPoint := RBPoint;
  1537.         Self.TabLeftOffset := TabLeftOffset;
  1538.         Self.TabRightOffset := TabRightOffset;
  1539.         //
  1540.         Self.FontName := FontName;
  1541.         Self.FontColor := FontColor;
  1542.         Self.ActiveFontColor := ActiveFontColor;
  1543.         Self.FocusFontColor := FocusFontColor;
  1544.         Self.FontStyle := FontStyle;
  1545.         Self.FontHeight := FontHeight;
  1546.         Self.UpDown := UpDown;
  1547.         Self.BGPictureIndex := BGPictureIndex;
  1548.         Self.MouseInFontColor := MouseInFontColor;
  1549.         Self.MouseInTabRect := MouseInTabRect;
  1550.       end;
  1551. end;
  1552. procedure TbsSkinTabControl.ChangeSkinData;
  1553. begin
  1554.   GetSkinData;
  1555.   //
  1556.   if FIndex <> -1
  1557.   then
  1558.     begin
  1559.       Font.Color := FontColor;
  1560.       if FUseSkinFont
  1561.       then
  1562.         begin
  1563.           Font.Name := FontName;
  1564.           Font.Height := FontHeight;
  1565.           Font.Style := FontStyle;
  1566.           Font.CharSet := DefaultFont.CharSet;
  1567.         end
  1568.       else
  1569.         Font.Assign(FDefaultFont);
  1570.       SetItemSize(0, RectHeight(TabRect));
  1571.     end
  1572.   else
  1573.     begin
  1574.       Font.Assign(FDefaultFont);
  1575.       SetItemSize(0, FDefaultItemHeight);
  1576.     end;
  1577.   //
  1578.   Change;
  1579.   ReAlign;
  1580.   RePaint;
  1581.   if FSkinUpDown <> nil
  1582.   then
  1583.     begin
  1584.       HideSkinUpDown;
  1585.       CheckScroll;
  1586.     end;
  1587. end;
  1588. procedure TbsSkinTabControl.SetSkinData;
  1589. begin
  1590.   FSD := Value;
  1591.   if (FSD <> nil) then
  1592.   if not FSD.Empty and not (csDesigning in ComponentState)
  1593.   then
  1594.     ChangeSkinData;
  1595. end;
  1596. procedure TbsSkinTabControl.Notification;
  1597. begin
  1598.   inherited Notification(AComponent, Operation);
  1599.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  1600. end;
  1601. procedure TbsSkinTabControl.PaintDefaultWindow;
  1602. var
  1603.   R: TRect;
  1604. begin
  1605.   with Cnvs do
  1606.   begin
  1607.     Brush.Color := clBtnFace;
  1608.     FillRect(ClientRect);
  1609.     R := Self.DisplayRect;
  1610.     InflateRect(R, 1, 1);
  1611.     Frame3D(Cnvs, R, clBtnShadow, clBtnShadow, 1);
  1612.   end;
  1613. end;
  1614. procedure TbsSkinTabControl.PaintSkinWindow;
  1615. var
  1616.   TOff, LOff, Roff, BOff: Integer;
  1617.   DR, R: TRect;
  1618.   TBGOffX, TBGOffY, X, Y, XCnt, YCnt, w, h, w1, h1, rw, rh, XO, YO: Integer;
  1619.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  1620.   B: TBitMap;
  1621. begin
  1622.   TOff := ClRect.Top;
  1623.   LOff := ClRect.Left;
  1624.   ROff := RectWidth(SkinRect) - ClRect.Right;
  1625.   BOff := RectHeight(SkinRect) - ClRect.Bottom;
  1626.   DR := DisplayRect;
  1627.   R := Rect(DR.Left - LOff, DR.Top - TOff, DR.Right + ROff, DR.Bottom + BOff);
  1628.   XO := RectWidth(R) - RectWidth(SkinRect);
  1629.   YO := RectHeight(R) - RectHeight(SkinRect);
  1630.   NewLTPoint := LTPoint;
  1631.   NewRTPoint := Point(RTPoint.X + XO, RTPoint.Y);
  1632.   NewLBPoint := Point(LBPoint.X, LBPoint.Y + YO);
  1633.   NewRBPoint := Point(RBPoint.X + XO, RBPoint.Y + YO);
  1634.   // DrawBG
  1635.   if BGPictureIndex <> -1
  1636.   then
  1637.     begin
  1638.       B := TBitMap(FSD.FActivePictures.Items[BGPictureIndex]);
  1639.       if (Width > 0) and (Height > 0)
  1640.       then
  1641.         begin
  1642.           XCnt := Width div B.Width;
  1643.           YCnt := Height div B.Height;
  1644.           for X := 0 to XCnt do
  1645.           for Y := 0 to YCnt do
  1646.           Cnvs.Draw(X * B.Width, Y * B.Height, B);
  1647.         end;
  1648.       Exit;
  1649.     end;
  1650.   w := RectWidth(ClRect);
  1651.   h := RectHeight(ClRect);
  1652.   w1 := RectWidth(R);
  1653.   h1 := RectHeight(R);
  1654.   XCnt := w1 div w;
  1655.   YCnt := h1 div h;
  1656.   for X := 0 to XCnt do
  1657.   for Y := 0 to YCnt do
  1658.   begin
  1659.     if X * w + w > w1 then XO := X * w + w - w1 else XO := 0;
  1660.     if Y * h + h > h1 then YO := Y * h + h - h1 else YO := 0;
  1661.      Cnvs.CopyRect(Rect(R.Left + X * w, R.Top + Y * h,
  1662.                         R.Left + X * w + w - XO, R.Top + Y * h + h - YO),
  1663.               Picture.Canvas,
  1664.               Rect(SkinRect.Left + ClRect.Left, SkinRect.Top + ClRect.Top,
  1665.                    SkinRect.Left + ClRect.Right - XO,
  1666.                    SkinRect.Top + ClRect.Bottom - YO));
  1667.   end;            
  1668.   // Draw tabs BG
  1669.   if not IsNullRect(TabsBGRect)
  1670.   then
  1671.     begin
  1672.       if TabPosition = tpLeft
  1673.       then
  1674.         begin
  1675.           TBGOffY := 0;
  1676.           TBGOffX := 0;
  1677.           rw := R.Left;
  1678.           rh := Height;
  1679.         end
  1680.       else
  1681.       if TabPosition = tpRight
  1682.       then
  1683.         begin
  1684.           TBGOffY := 0;
  1685.           TBGOffX := R.Right;
  1686.           rw := Width - R.Right;
  1687.           rh := Height;
  1688.         end
  1689.       else
  1690.       if TabPosition = tpTop
  1691.       then
  1692.         begin
  1693.           TBGOffX := 0;
  1694.           TBGOffY := 0;
  1695.           rh := R.Top;
  1696.           rw := Width;
  1697.         end
  1698.       else
  1699.         begin
  1700.           TBGOffX := 0;
  1701.           TBGOffY := R.Bottom;
  1702.           rh := Height - R.Bottom;
  1703.           rw := Width;
  1704.         end;
  1705.       w := RectWidth(TabsBGRect);
  1706.       h := RectHeight(TabsBGRect);
  1707.       XCnt := rw div w;
  1708.       YCnt := rh div h;
  1709.       for X := 0 to XCnt do
  1710.       for Y := 0 to YCnt do
  1711.       begin
  1712.         if X * w + w > rw then XO := X * w + w - rw else XO := 0;
  1713.         if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  1714.         Cnvs.CopyRect(Rect(TBGOffX + X * w, TBGOffY + Y * h,
  1715.                            TBGOffX + X * w + w - XO, TBGOffY + Y * h + h - YO),
  1716.                       Picture.Canvas,
  1717.                       Rect(TabsBGRect.Left, TabsBGRect.Top,
  1718.                            TabsBGRect.Right - XO, TabsBGRect.Bottom - YO));
  1719.       end;
  1720.     end;
  1721.   // Draw frame around displayrect
  1722.     // draw lines
  1723.   w := RTPoint.X - LTPoint.X;
  1724.   XCnt := (NewRTPoint.X - NewLTPoint.X) div w;
  1725.   for X := 0 to XCnt do
  1726.   begin
  1727.     if NewLTPoint.X + X * w + w > NewRTPoint.X
  1728.     then XO := NewLTPoint.X + X * w + w - NewRTPoint.X else XO := 0;
  1729.     Cnvs.CopyRect(Rect(R.Left + NewLTPoint.X + X * w, R.Top,
  1730.                   R.Left + NewLTPoint.X + X * w + w - XO, R.Top + TOff),
  1731.              Picture.Canvas,
  1732.              Rect(SkinRect.Left + LTPoint.X, SkinRect.Top,
  1733.                   SkinRect.Left + RTPoint.X - XO, SkinRect.Top + TOff));
  1734.   end;
  1735.   w := RBPoint.X - LBPoint.X;
  1736.   XCnt := (NewRBPoint.X - NewLBPoint.X) div w;
  1737.   for X := 0 to XCnt do
  1738.   begin
  1739.     if NewLBPoint.X + X * w + w > NewRBPoint.X
  1740.     then XO := NewLBPoint.X + X * w + w - NewRBPoint.X else XO := 0;
  1741.     Cnvs.CopyRect(Rect(R.Left + NewLBPoint.X + X * w, R.Bottom - BOff,
  1742.                   R.Left + NewLBPoint.X + X * w + w - XO, R.Bottom),
  1743.              Picture.Canvas,
  1744.              Rect(SkinRect.Left + LBPoint.X, SkinRect.Bottom - BOff,
  1745.                   SkinRect.Left + RBPoint.X - XO, SkinRect.Bottom));
  1746.   end;
  1747.   w := LOff;
  1748.   h := LBPoint.Y - LTPoint.Y;
  1749.   YCnt := (NewLBPoint.Y - NewLTPoint.Y) div h;
  1750.   for Y := 0 to YCnt do
  1751.   begin
  1752.     if NewLTPoint.Y + Y * h + h > NewLBPoint.Y
  1753.     then YO := NewLTPoint.Y + Y * h + h - NewLBPoint.Y else YO := 0;
  1754.     Cnvs.CopyRect(Rect(R.Left, R.Top + NewLTPoint.Y + Y * h,
  1755.                        R.Left + w, R.Top + NewLTPoint.Y + Y * h + h - YO),
  1756.                   Picture.Canvas,
  1757.                   Rect(SkinRect.Left, SkinRect.Top + LTPoint.Y,
  1758.                        SkinRect.Left + w, SkinRect.Top + LBPoint.Y - YO));
  1759.   end;
  1760.   w := ROff;
  1761.   h := RBPoint.Y - RTPoint.Y;
  1762.   YCnt := (NewRBPoint.Y - NewRTPoint.Y) div h;
  1763.   for Y := 0 to YCnt do
  1764.   begin
  1765.     if NewRTPoint.Y + Y * h + h > NewRBPoint.Y
  1766.     then YO := NewRTPoint.Y + Y * h + h - NewRBPoint.Y else YO := 0;
  1767.     Cnvs.CopyRect(Rect(R.Right - w, R.Top + NewRTPoint.Y + Y * h,
  1768.                        R.Right, R.Top + NewRTPoint.Y + Y * h + h - YO),
  1769.                   Picture.Canvas,
  1770.                   Rect(SkinRect.Right - w, SkinRect.Top + RTPoint.Y,
  1771.                        SkinRect.Right, SkinRect.Top + RBPoint.Y - YO));
  1772.   end;
  1773.     // draw corners
  1774.   Cnvs.CopyRect(Rect(R.Left, R.Top, R.Left + LTPoint.X, R.Top + LTPoint.Y),
  1775.                 Picture.Canvas,
  1776.                 Rect(SkinRect.Left, SkinRect.Top,
  1777.                      SkinRect.Left + NewLTPoint.X, SkinRect.Top + NewLTPoint.Y));
  1778.   Cnvs.CopyRect(Rect(R.Left + NewRTPoint.X, R.Top,
  1779.                      R.Right, R.Top + NewRTPoint.Y),
  1780.                 Picture.Canvas,
  1781.                 Rect(SkinRect.Left + RTPoint.X, SkinRect.Top,
  1782.                      SkinRect.Right, SkinRect.Top + RTPoint.Y));
  1783.   Cnvs.CopyRect(Rect(R.Left, R.Top + NewLBPoint.Y,
  1784.                      R.Left + NewLBPoint.X, R.Bottom),
  1785.                 Picture.Canvas,
  1786.                 Rect(SkinRect.Left, SkinRect.Top + LBPoint.Y,
  1787.                      SkinRect.Left + LBPoint.X, SkinRect.Bottom));
  1788.   Cnvs.CopyRect(Rect(R.Left + NewRBPoint.X, R.Top + NewRBPoint.Y,
  1789.                      R.Right, R.Bottom),
  1790.                 Picture.Canvas,
  1791.                 Rect(SkinRect.Left + RBPoint.X, SkinRect.Top + RBPoint.Y,
  1792.                      SkinRect.Right, SkinRect.Bottom));
  1793. end;
  1794. procedure TbsSkinTabControl.Loaded;
  1795. begin
  1796.   inherited Loaded;
  1797.   if FIndex = -1
  1798.   then
  1799.     begin
  1800.       SetItemSize(0, FDefaultItemHeight);
  1801.       Change;
  1802.       ReAlign;
  1803.     end;
  1804. end;
  1805. procedure TbsSkinTabControl.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
  1806. begin
  1807.   Msg.Result := 1;
  1808. end;
  1809. procedure TbsSkinTabControl.WndProc(var Message:TMessage);
  1810. var
  1811.   TOff, LOff, Roff, BOff: Integer;
  1812. begin
  1813.   if Message.Msg = TCM_ADJUSTRECT
  1814.   then
  1815.     begin
  1816.       inherited WndProc(Message);
  1817.       TOff := 0;
  1818.       LOff := 0;
  1819.       ROff := 0;
  1820.       BOff := 0;
  1821.       if (FIndex <> -1) and (BGPictureIndex = -1)
  1822.       then
  1823.         begin
  1824.           TOff := ClRect.Top;
  1825.           LOff := ClRect.Left;
  1826.           ROff := RectWidth(SkinRect) - ClRect.Right;
  1827.           BOff := RectHeight(SkinRect) - ClRect.Bottom;
  1828.         end;
  1829.       case TabPosition of
  1830.         tpLeft:
  1831.            if FIndex <> -1
  1832.            then
  1833.              begin
  1834.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + LOff - 4;
  1835.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1836.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1837.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  1838.              end
  1839.            else
  1840.              begin
  1841.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  1842.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  1843.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  1844.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  1845.              end;
  1846.         tpRight:
  1847.            if FIndex <> -1
  1848.            then
  1849.              begin
  1850.                PRect(Message.LParam)^.Left := LOff;
  1851.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - ROff + 4;
  1852.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1853.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  1854.              end
  1855.            else
  1856.              begin
  1857.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  1858.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 3;
  1859.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  1860.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  1861.              end;
  1862.         tpTop:
  1863.            if FIndex <> -1
  1864.            then
  1865.              begin
  1866.                PRect(Message.LParam)^.Left := LOff;
  1867.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1868.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1869.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  1870.              end
  1871.            else
  1872.              begin
  1873.                PRect(Message.LParam)^.Left := 1;
  1874.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  1875.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  1876.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  1877.              end;
  1878.         tpBottom:
  1879.           if FIndex <> -1
  1880.           then
  1881.             begin
  1882.               PRect(Message.LParam)^.Left := LOff;
  1883.               PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1884.               PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1885.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 4 - BOff;
  1886.             end
  1887.           else
  1888.             begin
  1889.               PRect(Message.LParam)^.Left := 1;
  1890.               PRect(Message.LParam)^.Right := ClientWidth - 1;
  1891.               PRect(Message.LParam)^.Top := 1;
  1892.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 3;
  1893.             end;
  1894.       end;
  1895.     end
  1896.   else
  1897.     if Message.Msg = TCM_GETITEMRECT
  1898.     then
  1899.       begin
  1900.         inherited WndProc(Message);
  1901.         if Style = tsTabs
  1902.         then
  1903.           case TabPosition of
  1904.             tpLeft:
  1905.                 begin
  1906.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1907.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1908.                 end;
  1909.             tpRight:
  1910.                 begin
  1911.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + 2;
  1912.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 2;
  1913.                 end;
  1914.             tpTop:
  1915.                 begin
  1916.                   if not MultiLine
  1917.                   then
  1918.                     begin
  1919.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1920.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1921.                     end;
  1922.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 2;
  1923.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom - 2;
  1924.                 end;
  1925.             tpBottom:
  1926.                 begin
  1927.                   if not MultiLine
  1928.                   then
  1929.                     begin
  1930.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1931.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1932.                     end;
  1933.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top + 2;
  1934.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 2;
  1935.                 end;
  1936.           end;
  1937.       end
  1938.   else
  1939.   inherited WndProc(Message);
  1940.   if (Message.Msg = WM_SIZE) and (not MultiLine)
  1941.   then
  1942.     begin
  1943.       CheckScroll;
  1944.     end;
  1945. end;
  1946. function TbsSkinTabControl.GetItemRect(index: integer): TRect;
  1947. var
  1948.   R: TRect;
  1949. begin
  1950.   SendMessage(Handle, TCM_GETITEMRECT, index, Integer(@R));
  1951.   Result := R;
  1952. end;
  1953. procedure TbsSkinTabControl.SetItemSize;
  1954. begin
  1955.   SendMessage(Handle, TCM_SETITEMSIZE, 0, MakeLParam(AWidth, AHeight));
  1956. end;
  1957. procedure TbsSkinTabControl.PaintWindow(DC: HDC);
  1958. var
  1959.   SaveIndex: Integer;
  1960.   RealPicture: TBitMap;
  1961. begin
  1962.   GetSkinData;
  1963.   SaveIndex := SaveDC(DC);
  1964.   try
  1965.     RealPicture := TBitMap.Create;
  1966.     Canvas.Handle := DC;
  1967.     RealPicture.Width := Width;
  1968.     RealPicture.Height := Height;
  1969.     if FIndex = -1
  1970.     then
  1971.       PaintDefaultWindow(RealPicture.Canvas)
  1972.     else
  1973.       PaintSkinWindow(RealPicture.Canvas);
  1974.     DrawTabs(RealPicture.Canvas);
  1975.     Canvas.Draw(0, 0, RealPicture);
  1976.     Canvas.Handle := 0;
  1977.     RealPicture.Free;
  1978.   finally
  1979.     RestoreDC(DC, SaveIndex);
  1980.   end;
  1981. end;
  1982. procedure TbsSkinTabControl.DrawTabs;
  1983. var
  1984.   i: integer;
  1985.   R: TRect;
  1986. begin
  1987.   for i := 0 to Tabs.Count-1 do
  1988.   begin
  1989.     R := GetItemRect(i);
  1990.     DrawTab(i, R, i = TabIndex, i = FActiveTab, Cnvs);
  1991.   end;
  1992. end;
  1993. procedure TbsSkinTabControl.UpDateTabs;
  1994. begin
  1995.   if FIndex <> -1
  1996.   then
  1997.     SetItemSize(0, RectHeight(TabRect))
  1998.   else
  1999.     SetItemSize(0, FDefaultItemHeight);
  2000.   if MultiLine and (FSkinUpDown <> nil)
  2001.   then
  2002.     HideSkinUpDown;
  2003.   ReAlign;
  2004. end;
  2005. procedure TbsSkinTabControl.DrawTab;
  2006. var
  2007.   R: TRect;
  2008.   S: String;
  2009.   TB: TBitMap;
  2010.   DrawGlyph: Boolean;
  2011.   W, H: Integer;
  2012. begin
  2013.   DrawGlyph := (Images <> nil) and (TI < Images.Count);
  2014.   S := Tabs[TI];
  2015.   TB := TBitMap.Create;
  2016.   if (TabPosition = tpTop) or (TabPosition = tpBottom)
  2017.   then
  2018.     begin
  2019.       W := RectWidth(Rct);
  2020.       H := RectHeight(Rct);
  2021.     end
  2022.   else
  2023.     begin
  2024.       H := RectWidth(Rct);
  2025.       W := RectHeight(Rct);
  2026.     end;
  2027.   R := Rect(0, 0, W, H);  
  2028.   if FIndex <> -1
  2029.   then
  2030.     begin
  2031.       if MouseIn and not Active and not IsNullRect(MouseInTabRect)
  2032.       then
  2033.         CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2034.           TB, Picture, MouseInTabRect, W, H)
  2035.       else
  2036.       if Active and Focused
  2037.       then
  2038.         CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2039.           TB, Picture, FocusTabRect, W, H)
  2040.       else
  2041.       if Active
  2042.       then
  2043.          CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2044.           TB, Picture, ActiveTabRect, W, H)
  2045.       else
  2046.         CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2047.           TB, Picture, TabRect, W, H);
  2048.       with TB.Canvas do
  2049.       begin
  2050.         Brush.Style := bsClear;
  2051.         if FUseSkinFont
  2052.         then
  2053.           begin
  2054.             Font.Name := FontName;
  2055.             Font.Style := FontStyle;
  2056.             Font.Height := FontHeight;
  2057.             Font.CharSet := Self.Font.CharSet;
  2058.           end
  2059.         else
  2060.            Font.Assign(Self.Font);
  2061.         if MouseIn and not Active
  2062.         then
  2063.           Font.Color := MouseInFontColor
  2064.         else
  2065.         if Active and Focused
  2066.         then
  2067.           Font.Color := FocusFontColor
  2068.         else
  2069.           if Active
  2070.           then Font.Color := ActiveFontColor
  2071.           else Font.Color := FontColor;
  2072.       end;
  2073.     end
  2074.   else
  2075.     begin
  2076.       TB.Width := W;
  2077.       TB.Height := H;
  2078.       if MouseIn and not Active
  2079.       then
  2080.         begin
  2081.           TB.Canvas.Brush.Color := BS_XP_BTNACTIVECOLOR;
  2082.           TB.Canvas.FillRect(R);
  2083.         end
  2084.       else
  2085.       if Active and Focused
  2086.       then
  2087.         begin
  2088.           Frame3D(TB.Canvas, R, BS_XP_BTNFRAMECOLOR, BS_XP_BTNFRAMECOLOR, 1);
  2089.           TB.Canvas.Brush.Color := BS_XP_BTNDOWNCOLOR;
  2090.           TB.Canvas.FillRect(R);
  2091.         end
  2092.       else
  2093.       if Active
  2094.       then
  2095.         begin
  2096.           Frame3D(TB.Canvas, R, BS_XP_BTNFRAMECOLOR, BS_XP_BTNFRAMECOLOR, 1);
  2097.           TB.Canvas.Brush.Color := BS_XP_BTNACTIVECOLOR;
  2098.           TB.Canvas.FillRect(R);
  2099.         end
  2100.       else
  2101.         begin
  2102.           TB.Canvas.Brush.Color := clBtnFace;
  2103.           TB.Canvas.FillRect(R);
  2104.         end;
  2105.       with TB.Canvas do
  2106.       begin
  2107.         Brush.Style := bsClear;
  2108.         Font.Assign(Self.Font);
  2109.       end;
  2110.     end;
  2111.   //
  2112.   if DrawGlyph
  2113.   then
  2114.     DrawTabGlyphAndText(TB.Canvas, TB.Width, TB.Height, S,
  2115.                         Images, TI, True)
  2116.   else
  2117.     DrawText(TB.Canvas.Handle, PChar(S), Length(S), R, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  2118.   if TabPosition = tpLeft
  2119.   then
  2120.     DrawRotate90_1(Cnvs, TB, Rct.Left, Rct.Top)
  2121.   else
  2122.   if TabPosition = tpRight
  2123.   then
  2124.     DrawRotate90_2(Cnvs, TB, Rct.Left, Rct.Top)
  2125.   else
  2126.     Cnvs.Draw(Rct.Left, Rct.Top, TB);
  2127.   TB.Free;
  2128. end;
  2129. end.