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

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************************}
  2. {                                                                   }
  3. {       Almediadev Visual Component Library                         }
  4. {       DynamicSkinForm                                             }
  5. {       Version 5.60                                                }
  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 SkinTabs;
  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, SkinData, SkinCtrls, SkinBoxCtrls;
  21. type
  22.   TspSkinCustomTabSheet = 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.   TspSkinTabSheet = class(TspSkinCustomTabSheet)
  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.   TspSkinPageControl = class(TPageControl)
  39.   private
  40.     FActiveTab, FOldActiveTab: Integer;
  41.     FActiveTabIndex, FOldActiveTabIndex: Integer;
  42.     FUseSkinFont: Boolean;
  43.     function GetPosition: Integer;
  44.     function  GetInVisibleItemCount: Integer;
  45.     procedure OnUpDownChange(Sender: TObject);
  46.     procedure DrawTabs(Cnvs: TCanvas);
  47.     procedure DrawTab(TI: Integer; const Rct: TRect; Active, MouseIn: Boolean; Cnvs: TCanvas);
  48.     function GetItemRect(index: integer): TRect;
  49.     procedure SetItemSize(AWidth, AHeight: integer);
  50.     procedure CheckScroll;
  51.     procedure ShowSkinUpDown;
  52.     procedure HideSkinUpDown;
  53.     procedure TestActive(X, Y: Integer);
  54.   protected
  55.     //
  56.     FSD: TspSkinData;
  57.     FSkinDataName: String;
  58.     FIndex: Integer;
  59.     FSkinUpDown: TspSkinUpDown;
  60.     FDefaultFont: TFont;
  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: TspSkinData);
  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 UseSkinFont: Boolean read FUseSkinFont write FUseSkinFont;
  103.     property DefaultFont: TFont read FDefaultFont write SetDefaultFont;
  104.     property DefaultItemHeight: Integer read FDefaultItemHeight write SetDefaultItemHeight;
  105.     property SkinData: TspSkinData 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.   TspSkinTabControl = class(TTabControl)
  157.   private
  158.     FOldTop, FOldBottom: Integer;
  159.     FActiveTab, FOldActiveTab: Integer;
  160.     FUseSkinFont: Boolean;
  161.     function GetPosition: Integer;
  162.     function  GetInVisibleItemCount: Integer;
  163.     procedure OnUpDownChange(Sender: TObject);
  164.     procedure DrawTabs(Cnvs: TCanvas);
  165.     procedure DrawTab(TI: Integer; const Rct: TRect; Active, MouseIn: Boolean; Cnvs: TCanvas);
  166.     function GetItemRect(index: integer): TRect;
  167.     procedure SetItemSize(AWidth, AHeight: integer);
  168.     procedure CheckScroll;
  169.     procedure ShowSkinUpDown;
  170.     procedure HideSkinUpDown;
  171.     procedure TestActive(X, Y: Integer);
  172.   protected
  173.     //
  174.     FSD: TspSkinData;
  175.     FSkinDataName: String;
  176.     FIndex: Integer;
  177.     FSkinUpDown: TspSkinUpDown;
  178.     FDefaultFont: TFont;
  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: TspSkinData);
  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: TspSkinData 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, spUtils, ImgList, DynamicSkinForm, spEffBmp;
  276. procedure DrawRotate90_1(Cnvs: TCanvas; B: TBitMap; X, Y: Integer);
  277. var
  278.   B1, B2: TspEffectBmp;
  279. begin
  280.   B1 := TspEffectBmp.CreateFromhWnd(B.Handle);
  281.   B2 := TspEffectBmp.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: TspEffectBmp;
  290. begin
  291.   B1 := TspEffectBmp.CreateFromhWnd(B.Handle);
  292.   B2 := TspEffectBmp.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 TspSkinCustomTabSheet.Create(AOwner: TComponent);
  321. begin
  322.   inherited Create(AOwner);
  323.   Align := alClient;
  324.   ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];
  325.   Visible := False;
  326. end;
  327. destructor TspSkinCustomTabSheet.Destroy;
  328. begin
  329.   inherited Destroy;
  330. end;
  331. procedure TspSkinCustomTabSheet.WMEraseBkGnd;
  332. begin
  333.   PaintBG(Msg.DC);
  334. end;
  335. procedure TspSkinCustomTabSheet.WMSize;
  336. begin
  337.   inherited;
  338.   RePaint;
  339. end;
  340. procedure TspSkinCustomTabSheet.PaintBG;
  341. var
  342.   C: TCanvas;
  343.   TabSheetBG: TBitMap;
  344.   PC: TspSkinPageControl;
  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 := TspSkinPageControl(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 TspSkinTabSheet.Create(AOwner : TComponent);
  407. begin
  408.   inherited Create(AOwner);
  409. end;
  410. destructor TspSkinTabSheet.Destroy;
  411. begin
  412.   inherited Destroy;
  413. end;
  414. procedure TspSkinTabSheet.Notification(AComponent: TComponent; Operation: TOperation);
  415. begin
  416.   inherited Notification(AComponent, Operation);
  417. end;
  418. { TspSkinPageControl }
  419. constructor TspSkinPageControl.Create(AOwner: TComponent);
  420. begin
  421.   inherited Create(AOwner);
  422.   Ctl3D := False;
  423.   FIndex := -1;
  424.   Picture := nil;
  425.   FUseSkinFont := True;
  426.   Font.Name := 'Arial';
  427.   Font.Style := [];
  428.   Font.Color := clBtnText;
  429.   Font.Height := 14;
  430.   FSkinUpDown := nil;
  431.   FSkinDataName := 'tab';
  432.   FDefaultFont := TFont.Create;
  433.   FDefaultFont.Name := 'Arial';
  434.   FDefaultFont.Style := [];
  435.   FDefaultFont.Color := clBtnText;
  436.   FDefaultFont.Height := 14;
  437.   FDefaultItemHeight := 20;
  438.   FActiveTab := -1;
  439.   FOldActiveTab := -1;
  440.   FActiveTabIndex := -1;
  441.   FOldActiveTabIndex := -1;
  442. end;
  443. destructor TspSkinPageControl.Destroy;
  444. begin
  445.   FDefaultFont.Free;
  446.   inherited Destroy;
  447. end;
  448. procedure TspSkinPageControl.UpDateTabs;
  449. begin
  450.   if FIndex <> -1
  451.   then
  452.     begin
  453.       if TabHeight <= 0
  454.       then
  455.         SetItemSize(TabWidth, RectHeight(TabRect))
  456.       else
  457.         SetItemSize(TabWidth, TabHeight);
  458.     end
  459.   else
  460.     begin
  461.       if TabHeight <= 0
  462.       then
  463.         SetItemSize(TabWidth, FDefaultItemHeight)
  464.       else
  465.         SetItemSize(TabWidth, TabHeight);
  466.     end;
  467.   if MultiLine and (FSkinUpDown <> nil)
  468.   then
  469.     HideSkinUpDown;
  470.   ReAlign;
  471. end;
  472. procedure TspSkinPageControl.CMMouseLeave;
  473. var
  474.   R: TRect;
  475. begin
  476.   if (FOldActiveTabIndex <> - 1) and (FOldActiveTabIndex <> TabIndex) and
  477.      (FOldActiveTabIndex < PageCount)
  478.   then
  479.     begin
  480.       R := GetItemRect(FOldActiveTabIndex);
  481.       DrawTab(FOldActiveTab, R, False, False, Canvas);
  482.       FOldActiveTabIndex := -1;
  483.       FOldActiveTab := -1;
  484.     end;
  485.   if (FActiveTabIndex <> - 1) and (FActiveTabIndex <> TabIndex) and
  486.      (FActiveTabIndex < PageCount)
  487.   then
  488.     begin
  489.       R := GetItemRect(FActiveTabIndex);
  490.       DrawTab(FActiveTab, R, False, False, Canvas);
  491.       FActiveTabIndex := -1;
  492.       FActiveTab := -1;
  493.     end;
  494. end;
  495. procedure TspSkinPageControl.MouseDown;
  496. begin
  497.   inherited;
  498.   if (Button = mbLeft) and not (csDesigning in ComponentState)
  499.   then
  500.     TestActive(X, Y);
  501. end;
  502. procedure TspSkinPageControl.MouseMove;
  503. begin
  504.  inherited;
  505.  if  not (csDesigning in ComponentState)
  506.  then
  507.    TestActive(X, Y);
  508. end;
  509. procedure TspSkinPageControl.SetDefaultItemHeight;
  510. begin
  511.   FDefaultItemHeight := Value;
  512.   if FIndex = -1
  513.   then
  514.     begin
  515.       SetItemSize(TabWidth, FDefaultItemHeight);
  516.       Change;
  517.       ReAlign;
  518.     end;
  519. end;
  520. procedure TspSkinPageControl.SetDefaultFont;
  521. begin
  522.   FDefaultFont.Assign(Value);
  523. end;
  524. procedure TspSkinPageControl.OnUpDownChange(Sender: TObject);
  525. begin
  526.   FSkinUpDown.Max := GetInVisibleItemCount;
  527.   SendMessage(Handle, WM_HSCROLL,
  528.     MakeWParam(SB_THUMBPOSITION, FSkinUpDown.Position), 0);
  529. end;
  530. function TspSkinPageControl.GetPosition: Integer;
  531. var
  532.   i, j: Integer;
  533.   R: TRect;
  534. begin
  535.   j := 0;
  536.   for i := 0 to PageCount - 1 do
  537.   begin
  538.     R := GetItemRect(i);
  539.     if R.Right <= 0 then inc(j);
  540.   end;
  541.   Result := j;
  542. end;
  543. function TspSkinPageControl.GetInVisibleItemCount;
  544. var
  545.   i, j, k: Integer;
  546.   R: TRect;
  547.   Limit: Integer;
  548. begin
  549.   if FSkinUpDown = nil
  550.   then
  551.     Limit := Width - 3
  552.   else
  553.     Limit := Width - FSkinUpDown.Width - 3;
  554.   j := 0;
  555.   k := -1;
  556.   for i := 0 to PageCount - 1 do
  557.   if Pages[i].TabVisible
  558.   then
  559.   begin
  560.     inc(k);
  561.     R := GetItemRect(k);
  562.     if (R.Right > Limit) or (R.Right <= 0)
  563.     then inc(j);
  564.   end;
  565.   Result := j;
  566. end;
  567. procedure TspSkinPageControl.CheckScroll;
  568. var
  569.   Wnd: HWND;
  570.   InVCount: Integer;
  571. begin
  572.   Wnd := FindWindowEx(Handle, 0, 'msctls_updown32', nil);
  573.   if Wnd <> 0 then DestroyWindow(Wnd);
  574.   InVCount := GetInVisibleItemCount;
  575.   if (InVCount = 0) and (FSkinUpDown <> nil)
  576.   then
  577.     HideSkinUpDown
  578.   else
  579.   if (InVCount > 0) and (FSkinUpDown = nil)
  580.   then
  581.     ShowSkinUpDown;
  582.   if FSkinUpDown <> nil
  583.   then
  584.     begin
  585.       FSkinUpDown.Max := InVCount;
  586.       FSkinUpDown.Left := Width - FSkinUpDown.Width;
  587.       if TabPosition = tpTop
  588.       then
  589.         FSkinUpDown.Top := 0
  590.       else
  591.        FSkinUpDown.Top := Height - FSkinUpDown.Height;
  592.     end;
  593. end;
  594. procedure TspSkinPageControl.ShowSkinUpDown;
  595. begin
  596.   FSkinUpDown := TspSkinUpDown.Create(Self);
  597.   FSkinUpDown.Parent := Self;
  598.   FSkinUpDown.Width := FDefaultItemHeight * 2;
  599.   FSkinUpDown.Height := FDefaultItemHeight;
  600.   FSkinUpDown.Min := 0;
  601.   FSkinUpDown.Max := GetInVisibleItemCount;
  602.   FSkinUpDown.Position := GetPosition;
  603.   FSkinUpDown.Increment := 1;
  604.   FSkinUpDown.OnChange := OnUpDownChange;
  605.   FSkinUpDown.Left := Width - FSkinUpDown.Width;
  606.   if TabPosition = tpTop
  607.   then
  608.     FSkinUpDown.Top := 0
  609.   else
  610.     FSkinUpDown.Top := Height - FSkinUpDown.Height;
  611.   FSkinUpDown.SkinDataName := UpDown;
  612.   FSkinUpDown.SkinData := SkinData;
  613.   FSkinUpDown.Visible := True;
  614. end;
  615. procedure TspSkinPageControl.HideSkinUpDown;
  616. begin
  617.   FSkinUpDown.Free;
  618.   FSkinUpDown := nil;
  619. end;
  620. procedure TspSkinPageControl.WMHSCROLL;
  621. begin
  622.   inherited;
  623.   RePaint;
  624. end;
  625. procedure TspSkinPageControl.WMSize;
  626. begin
  627.   GetSkinData;
  628.   inherited;
  629. end;
  630. procedure TspSkinPageControl.Change;
  631. begin
  632.   if FSkinUpDown <> nil
  633.   then FSkinUpDown.Position := GetPosition;
  634.   inherited;
  635.   Invalidate;
  636. end;
  637. procedure TspSkinPageControl.GetSkinData;
  638. begin
  639.   BGPictureIndex := -1;
  640.   if FSD = nil
  641.   then
  642.     begin
  643.       FIndex := -1;
  644.       Exit;
  645.     end;
  646.   if FSD.Empty
  647.   then
  648.     FIndex := -1
  649.   else
  650.     FIndex := FSD.GetControlIndex(FSkinDataName);
  651.   //
  652.   if FIndex <> -1
  653.   then
  654.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinTabControl
  655.     then
  656.       with TspDataSkinTabControl(FSD.CtrlList.Items[FIndex]) do
  657.       begin
  658.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  659.         then
  660.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  661.         else
  662.           Picture := nil;
  663.         Self.SkinRect := SkinRect;
  664.         Self.ClRect := ClRect;
  665.         Self.TabRect := TabRect;
  666.         if IsNullRect(ActiveTabRect)
  667.         then
  668.           Self.ActiveTabRect := TabRect
  669.         else
  670.           Self.ActiveTabRect := ActiveTabRect;
  671.         if IsNullRect(FocusTabRect)
  672.         then
  673.           Self.FocusTabRect := ActiveTabRect
  674.         else
  675.           Self.FocusTabRect := FocusTabRect;
  676.         //
  677.         Self.TabsBGRect := TabsBGRect;
  678.         Self.LTPoint := LTPoint;
  679.         Self.RTPoint := RTPoint;
  680.         Self.LBPoint := LBPoint;
  681.         Self.RBPoint := RBPoint;
  682.         Self.TabLeftOffset := TabLeftOffset;
  683.         Self.TabRightOffset := TabRightOffset;
  684.         //
  685.         Self.FontName := FontName;
  686.         Self.FontColor := FontColor;
  687.         Self.ActiveFontColor := ActiveFontColor;
  688.         Self.FocusFontColor := FocusFontColor;
  689.         Self.FontStyle := FontStyle;
  690.         Self.FontHeight := FontHeight;
  691.         Self.UpDown := UpDown;
  692.         Self.BGPictureIndex := BGPictureIndex;
  693.         Self.MouseInTabRect := MouseInTabRect;
  694.         Self.MouseInFontColor := MouseInFontColor;
  695.       end;
  696. end;
  697. procedure TspSkinPageControl.ChangeSkinData;
  698. begin
  699.   GetSkinData;
  700.   //
  701.   if FIndex <> -1
  702.   then
  703.     begin
  704.       if FUseSkinFont
  705.       then
  706.         begin
  707.           Font.Name := FontName;
  708.           Font.Height := FontHeight;
  709.           Font.Style := FontStyle;
  710.           Font.CharSet := DefaultFont.CharSet;
  711.         end
  712.       else
  713.         Font.Assign(FDefaultFont);
  714.       Font.Color := FontColor;
  715.       if TabHeight <= 0
  716.       then
  717.         SetItemSize(TabWidth, RectHeight(TabRect))
  718.       else
  719.         SetItemSize(TabWidth, TabHeight);
  720.     end
  721.   else
  722.     begin
  723.       Font.Assign(FDefaultFont);
  724.       if TabHeight <= 0
  725.       then
  726.         SetItemSize(TabWidth, FDefaultItemHeight)
  727.       else
  728.         SetItemSize(TabWidth, TabHeight);
  729.     end;
  730.   //
  731.   Change;
  732.   ReAlign;
  733.   if FSkinUpDown <> nil
  734.   then
  735.     begin
  736.       HideSkinUpDown;
  737.       CheckScroll;
  738.     end;
  739. end;
  740. procedure TspSkinPageControl.SetSkinData;
  741. begin
  742.   FSD := Value;
  743.   if (FSD <> nil) then
  744.   if not FSD.Empty and not (csDesigning in ComponentState)
  745.   then
  746.     ChangeSkinData;
  747. end;
  748. procedure TspSkinPageControl.Notification;
  749. begin
  750.   inherited Notification(AComponent, Operation);
  751.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  752. end;
  753. procedure TspSkinPageControl.PaintDefaultWindow;
  754. var
  755.   R: TRect;
  756. begin
  757.   with Cnvs do
  758.   begin
  759.     Brush.Color := clBtnFace;
  760.     FillRect(ClientRect);
  761.     R := Self.DisplayRect;
  762.     InflateRect(R, 1, 1);
  763.     Frame3D(Cnvs, R, clBtnShadow, clBtnShadow, 1);
  764.   end;
  765. end;
  766. procedure TspSkinPageControl.PaintSkinWindow;
  767. var
  768.   TOff, LOff, Roff, BOff: Integer;
  769.   DR, R: TRect;
  770.   TBGOffX, TBGOffY, X, Y, XCnt, YCnt, w, h, rw, rh, XO, YO: Integer;
  771.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  772. begin
  773.   TOff := ClRect.Top;
  774.   LOff := ClRect.Left;
  775.   ROff := RectWidth(SkinRect) - ClRect.Right;
  776.   BOff := RectHeight(SkinRect) - ClRect.Bottom;
  777.   DR := DisplayRect;
  778.   R := Rect(DR.Left - LOff, DR.Top - TOff, DR.Right + ROff, DR.Bottom + BOff);
  779.   XO := RectWidth(R) - RectWidth(SkinRect);
  780.   YO := RectHeight(R) - RectHeight(SkinRect);
  781.   NewLTPoint := LTPoint;
  782.   NewRTPoint := Point(RTPoint.X + XO, RTPoint.Y);
  783.   NewLBPoint := Point(LBPoint.X, LBPoint.Y + YO);
  784.   NewRBPoint := Point(RBPoint.X + XO, RBPoint.Y + YO);
  785.   // Draw tabs BG
  786.   if not IsNullRect(TabsBGRect)
  787.   then
  788.     begin
  789.       if TabPosition = tpLeft
  790.       then
  791.         begin
  792.           TBGOffY := 0;
  793.           TBGOffX := 0;
  794.           rw := R.Left;
  795.           rh := Height;
  796.         end
  797.       else
  798.       if TabPosition = tpRight
  799.       then
  800.         begin
  801.           TBGOffY := 0;
  802.           TBGOffX := R.Right;
  803.           rw := Width - R.Right;
  804.           rh := Height;
  805.         end
  806.       else
  807.       if TabPosition = tpTop
  808.       then
  809.         begin
  810.           TBGOffX := 0;
  811.           TBGOffY := 0;
  812.           rh := R.Top;
  813.           rw := Width;
  814.         end
  815.       else
  816.         begin
  817.           TBGOffX := 0;
  818.           TBGOffY := R.Bottom;
  819.           rh := Height - R.Bottom;
  820.           rw := Width;
  821.         end;
  822.       w := RectWidth(TabsBGRect);
  823.       h := RectHeight(TabsBGRect);
  824.       XCnt := rw div w;
  825.       YCnt := rh div h;
  826.       for X := 0 to XCnt do
  827.       for Y := 0 to YCnt do
  828.       begin
  829.         if X * w + w > rw then XO := X * w + w - rw else XO := 0;
  830.         if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  831.         Cnvs.CopyRect(Rect(TBGOffX + X * w, TBGOffY + Y * h,
  832.                            TBGOffX + X * w + w - XO, TBGOffY + Y * h + h - YO),
  833.                       Picture.Canvas,
  834.                       Rect(TabsBGRect.Left, TabsBGRect.Top,
  835.                            TabsBGRect.Right - XO, TabsBGRect.Bottom - YO));
  836.       end;
  837.     end;  
  838.   // Draw frame around displayrect
  839.     // draw lines
  840.   w := RTPoint.X - LTPoint.X;
  841.   XCnt := (NewRTPoint.X - NewLTPoint.X) div w;
  842.   for X := 0 to XCnt do
  843.   begin
  844.     if NewLTPoint.X + X * w + w > NewRTPoint.X
  845.     then XO := NewLTPoint.X + X * w + w - NewRTPoint.X else XO := 0;
  846.     Cnvs.CopyRect(Rect(R.Left + NewLTPoint.X + X * w, R.Top,
  847.                   R.Left + NewLTPoint.X + X * w + w - XO, R.Top + TOff),
  848.              Picture.Canvas,
  849.              Rect(SkinRect.Left + LTPoint.X, SkinRect.Top,
  850.                   SkinRect.Left + RTPoint.X - XO, SkinRect.Top + TOff));
  851.   end;
  852.   w := RBPoint.X - LBPoint.X;
  853.   XCnt := (NewRBPoint.X - NewLBPoint.X) div w;
  854.   for X := 0 to XCnt do
  855.   begin
  856.     if NewLBPoint.X + X * w + w > NewRBPoint.X
  857.     then XO := NewLBPoint.X + X * w + w - NewRBPoint.X else XO := 0;
  858.     Cnvs.CopyRect(Rect(R.Left + NewLBPoint.X + X * w, R.Bottom - BOff,
  859.                   R.Left + NewLBPoint.X + X * w + w - XO, R.Bottom),
  860.              Picture.Canvas,
  861.              Rect(SkinRect.Left + LBPoint.X, SkinRect.Bottom - BOff,
  862.                   SkinRect.Left + RBPoint.X - XO, SkinRect.Bottom));
  863.   end;
  864.   w := LOff;
  865.   h := LBPoint.Y - LTPoint.Y;
  866.   YCnt := (NewLBPoint.Y - NewLTPoint.Y) div h;
  867.   for Y := 0 to YCnt do
  868.   begin
  869.     if NewLTPoint.Y + Y * h + h > NewLBPoint.Y
  870.     then YO := NewLTPoint.Y + Y * h + h - NewLBPoint.Y else YO := 0;
  871.     Cnvs.CopyRect(Rect(R.Left, R.Top + NewLTPoint.Y + Y * h,
  872.                        R.Left + w, R.Top + NewLTPoint.Y + Y * h + h - YO),
  873.                   Picture.Canvas,
  874.                   Rect(SkinRect.Left, SkinRect.Top + LTPoint.Y,
  875.                        SkinRect.Left + w, SkinRect.Top + LBPoint.Y - YO));
  876.   end;
  877.   w := ROff;
  878.   h := RBPoint.Y - RTPoint.Y;
  879.   YCnt := (NewRBPoint.Y - NewRTPoint.Y) div h;
  880.   for Y := 0 to YCnt do
  881.   begin
  882.     if NewRTPoint.Y + Y * h + h > NewRBPoint.Y
  883.     then YO := NewRTPoint.Y + Y * h + h - NewRBPoint.Y else YO := 0;
  884.     Cnvs.CopyRect(Rect(R.Right - w, R.Top + NewRTPoint.Y + Y * h,
  885.                        R.Right, R.Top + NewRTPoint.Y + Y * h + h - YO),
  886.                   Picture.Canvas,
  887.                   Rect(SkinRect.Right - w, SkinRect.Top + RTPoint.Y,
  888.                        SkinRect.Right, SkinRect.Top + RBPoint.Y - YO));
  889.   end;
  890.     // draw corners
  891.   Cnvs.CopyRect(Rect(R.Left, R.Top, R.Left + LTPoint.X, R.Top + LTPoint.Y),
  892.                 Picture.Canvas,
  893.                 Rect(SkinRect.Left, SkinRect.Top,
  894.                      SkinRect.Left + NewLTPoint.X, SkinRect.Top + NewLTPoint.Y));
  895.   Cnvs.CopyRect(Rect(R.Left + NewRTPoint.X, R.Top,
  896.                      R.Right, R.Top + NewRTPoint.Y),
  897.                 Picture.Canvas,
  898.                 Rect(SkinRect.Left + RTPoint.X, SkinRect.Top,
  899.                      SkinRect.Right, SkinRect.Top + RTPoint.Y));
  900.   Cnvs.CopyRect(Rect(R.Left, R.Top + NewLBPoint.Y,
  901.                      R.Left + NewLBPoint.X, R.Bottom),
  902.                 Picture.Canvas,
  903.                 Rect(SkinRect.Left, SkinRect.Top + LBPoint.Y,
  904.                      SkinRect.Left + LBPoint.X, SkinRect.Bottom));
  905.   Cnvs.CopyRect(Rect(R.Left + NewRBPoint.X, R.Top + NewRBPoint.Y,
  906.                      R.Right, R.Bottom),
  907.                 Picture.Canvas,
  908.                 Rect(SkinRect.Left + RBPoint.X, SkinRect.Top + RBPoint.Y,
  909.                      SkinRect.Right, SkinRect.Bottom));
  910. end;
  911. procedure TspSkinPageControl.Loaded;
  912. begin
  913.   inherited Loaded;
  914.   if FIndex = -1
  915.   then
  916.     begin
  917.       if TabHeight <= 0
  918.       then
  919.         SetItemSize(TabWidth, FDefaultItemHeight)
  920.       else
  921.         SetItemSize(TabWidth, TabHeight);
  922.       Change;
  923.       ReAlign;
  924.     end;
  925. end;
  926. procedure TspSkinPageControl.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
  927. begin
  928.   if Self.PageCount = 0
  929.   then
  930.     inherited
  931.   else
  932.     Msg.Result := 1;
  933. end;
  934. procedure TspSkinPageControl.WndProc(var Message:TMessage);
  935. var
  936.   TOff, LOff, Roff, BOff: Integer;
  937. begin
  938.   if Message.Msg = TCM_ADJUSTRECT
  939.   then
  940.     begin
  941.       inherited WndProc(Message);
  942.       if FIndex <> -1
  943.       then
  944.         begin
  945.           TOff := ClRect.Top;
  946.           LOff := ClRect.Left;
  947.           ROff := RectWidth(SkinRect) - ClRect.Right;
  948.           BOff := RectHeight(SkinRect) - ClRect.Bottom;
  949.         end;
  950.       case TabPosition of
  951.         tpLeft:
  952.            if FIndex <> -1
  953.            then
  954.              begin
  955.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + LOff - 4;
  956.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  957.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  958.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  959.              end
  960.            else
  961.              begin
  962.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  963.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  964.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  965.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  966.              end;
  967.         tpRight:
  968.            if FIndex <> -1
  969.            then
  970.              begin
  971.                PRect(Message.LParam)^.Left := LOff;
  972.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - ROff + 4;
  973.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  974.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  975.              end
  976.            else
  977.              begin
  978.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  979.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 3;
  980.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  981.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  982.              end;
  983.         tpTop:
  984.            if FIndex <> -1
  985.            then
  986.              begin
  987.                PRect(Message.LParam)^.Left := LOff;
  988.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  989.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  990.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  991.              end
  992.            else
  993.              begin
  994.                PRect(Message.LParam)^.Left := 1;
  995.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  996.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  997.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  998.              end;
  999.         tpBottom:
  1000.           if FIndex <> -1
  1001.           then
  1002.             begin
  1003.               PRect(Message.LParam)^.Left := LOff;
  1004.               PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1005.               PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1006.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 4 - BOff;
  1007.             end
  1008.           else
  1009.             begin
  1010.               PRect(Message.LParam)^.Left := 1;
  1011.               PRect(Message.LParam)^.Right := ClientWidth - 1;
  1012.               PRect(Message.LParam)^.Top := 1;
  1013.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 3;
  1014.             end;
  1015.       end;
  1016.     end
  1017.   else
  1018.     if Message.Msg = TCM_GETITEMRECT
  1019.     then
  1020.       begin
  1021.         inherited WndProc(Message);
  1022.         if Style = tsTabs
  1023.         then
  1024.           case TabPosition of
  1025.             tpLeft:
  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.             tpRight:
  1031.                 begin
  1032.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + 2;
  1033.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 2;
  1034.                 end;
  1035.             tpTop:
  1036.                 begin
  1037.                   if not MultiLine
  1038.                   then
  1039.                     begin
  1040.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1041.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1042.                     end;
  1043.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 2;
  1044.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom - 2;
  1045.                 end;
  1046.             tpBottom:
  1047.                 begin
  1048.                   if not MultiLine
  1049.                   then
  1050.                     begin
  1051.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1052.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1053.                     end;
  1054.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top + 2;
  1055.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 2;
  1056.                 end;
  1057.           end;
  1058.       end
  1059.   else
  1060.   inherited WndProc(Message);
  1061.   if (Message.Msg = WM_SIZE) and (not MultiLine) and
  1062.      not (csDesigning in ComponentState)
  1063.   then
  1064.     begin
  1065.       CheckScroll;
  1066.     end;
  1067. end;
  1068. function TspSkinPageControl.GetItemRect(index: integer): TRect;
  1069. var
  1070.   R: TRect;
  1071. begin
  1072.   SendMessage(Handle, TCM_GETITEMRECT, index, Integer(@R));
  1073.   Result := R;
  1074. end;
  1075. procedure TspSkinPageControl.SetItemSize;
  1076. begin
  1077.   SendMessage(Handle, TCM_SETITEMSIZE, 0, MakeLParam(AWidth, AHeight));
  1078. end;
  1079. procedure TspSkinPageControl.PaintWindow(DC: HDC);
  1080. var
  1081.   SaveIndex: Integer;
  1082.   B: TBitMap;
  1083. begin
  1084.   if (Width <= 0) or (Height <=0) then Exit;
  1085.   GetSkinData;
  1086.   SaveIndex := SaveDC(DC);
  1087.   try
  1088.     Canvas.Handle := DC;
  1089.     B := TBitMap.Create;
  1090.     B.Width := Width;
  1091.     B.Height := Height;
  1092.     if FIndex = -1
  1093.     then
  1094.       PaintDefaultWindow(B.Canvas)
  1095.     else
  1096.       PaintSkinWindow(B.Canvas);
  1097.     DrawTabs(B.Canvas);
  1098.     Canvas.Draw(0, 0, B);
  1099.     B.Free;
  1100.     Canvas.Handle := 0;
  1101.   finally
  1102.     RestoreDC(DC, SaveIndex);
  1103.   end;
  1104. end;
  1105. procedure TspSkinPageControl.TestActive(X, Y: Integer);
  1106. var
  1107.   i, j, k: Integer;
  1108.   R: TRect;
  1109. begin
  1110.   FOldActiveTab := FActiveTab;
  1111.   FOldActiveTabIndex := FActiveTabIndex;
  1112.   k := -1;
  1113.   j := -1;
  1114.   for i := 0 to PageCount - 1 do
  1115.   if Pages[i].TabVisible then
  1116.   begin
  1117.     Inc(k);
  1118.     R := GetItemRect(k);
  1119.     if PtInRect(R, Point(X, Y))
  1120.     then
  1121.       begin
  1122.         j := k;
  1123.         Break;
  1124.       end;
  1125.   end;
  1126.   FActiveTab := i;
  1127.   FActiveTabIndex := j;
  1128.   if (FOldActiveTabIndex <> FActiveTabIndex)
  1129.   then
  1130.     begin
  1131.       if (FOldActiveTabIndex <> - 1) and (FOldActiveTabIndex <> TabIndex) and
  1132.          (FOldActiveTabIndex < PageCount)
  1133.       then
  1134.         begin
  1135.           R := GetItemRect(FOldActiveTabIndex);
  1136.           DrawTab(FOldActiveTab, R, False, False, Canvas);
  1137.         end;
  1138.       if (FActiveTabIndex <> -1) and (FActiveTabIndex <> TabIndex) and
  1139.          (FActiveTabIndex < PageCount)
  1140.       then
  1141.         begin
  1142.           R := GetItemRect(FActiveTabIndex);
  1143.           DrawTab(FActiveTab, R, False, True, Canvas );
  1144.         end;
  1145.     end;
  1146. end;
  1147. procedure TspSkinPageControl.DrawTabs;
  1148. var
  1149.   i, j: integer;
  1150.   R: TRect;
  1151. begin
  1152.   j := -1;
  1153.   for i := 0 to PageCount-1 do
  1154.   if Pages[i].TabVisible then
  1155.   begin
  1156.     inc(j);
  1157.     R := GetItemRect(j);
  1158.     DrawTab(i, R, (j = TabIndex), j = FActiveTabIndex, Cnvs);
  1159.   end;
  1160. end;
  1161. procedure TspSkinPageControl.DrawTab;
  1162. var
  1163.   R: TRect;
  1164.   S: String;
  1165.   TB, BufferTB: TBitMap;
  1166.   DrawGlyph: Boolean;
  1167.   W, H: Integer;
  1168. begin
  1169.   DrawGlyph := (Images <> nil) and (TI < Images.Count);
  1170.   S := Pages[TI].Caption;
  1171.   TB := TBitMap.Create;
  1172.   if (TabPosition = tpTop) or (TabPosition = tpBottom)
  1173.   then
  1174.     begin
  1175.       W := RectWidth(Rct);
  1176.       H := RectHeight(Rct);
  1177.     end
  1178.   else
  1179.     begin
  1180.       H := RectWidth(Rct);
  1181.       W := RectHeight(Rct);
  1182.     end;
  1183.   R := Rect(0, 0, W, H);  
  1184.   if FIndex <> -1
  1185.   then
  1186.     begin
  1187.       if TabHeight <= 0
  1188.       then
  1189.         begin
  1190.           if MouseIn and not Active and not IsNullRect(MouseInTabRect)
  1191.           then
  1192.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1193.              TB, Picture, MouseInTabRect, W, H)
  1194.           else
  1195.             if Active and Focused
  1196.           then
  1197.            CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1198.             TB, Picture, FocusTabRect, W, H)
  1199.           else
  1200.           if Active
  1201.           then
  1202.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1203.               TB, Picture, ActiveTabRect, W, H)
  1204.           else
  1205.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1206.              TB, Picture, TabRect, W, H);
  1207.        end
  1208.      else
  1209.        begin
  1210.          BufferTB := TBitMap.Create;
  1211.          BufferTB.Width := W;
  1212.          BufferTB.Height := RectHeight(TabRect);
  1213.          if MouseIn and not Active and not IsNullRect(MouseInTabRect)
  1214.           then
  1215.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1216.              BufferTB, Picture, MouseInTabRect, W, H)
  1217.           else
  1218.             if Active and Focused
  1219.           then
  1220.            CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1221.             BufferTB, Picture, FocusTabRect, W, H)
  1222.           else
  1223.           if Active
  1224.           then
  1225.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1226.               BufferTB, Picture, ActiveTabRect, W, H)
  1227.           else
  1228.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  1229.              BufferTB, Picture, TabRect, W, H);
  1230.          TB.Width := W;
  1231.          TB.Height := H;
  1232.          TB.Canvas.StretchDraw(R, BufferTB);
  1233.          BufferTB.Free;
  1234.        end;
  1235.       with TB.Canvas do
  1236.       begin
  1237.         Brush.Style := bsClear;
  1238.         if FUseSkinFont
  1239.         then
  1240.           begin
  1241.             Font.Name := FontName;
  1242.             Font.Style := FontStyle;
  1243.             Font.Height := FontHeight;
  1244.             Font.CharSet := Self.Font.CharSet;
  1245.           end
  1246.         else
  1247.            Font.Assign(Self.Font);
  1248.         if MouseIn and not Active
  1249.         then
  1250.           Font.Color := MouseInFontColor
  1251.         else
  1252.         if Active and Focused
  1253.         then
  1254.           Font.Color := FocusFontColor
  1255.         else
  1256.           if Active
  1257.           then Font.Color := ActiveFontColor
  1258.           else Font.Color := FontColor;
  1259.       end;
  1260.     end
  1261.   else
  1262.     begin
  1263.       TB.Width := W;
  1264.       TB.Height := H;
  1265.       if MouseIn and not Active
  1266.       then
  1267.         begin
  1268.           TB.Canvas.Brush.Color := SP_XP_BTNACTIVECOLOR;
  1269.           TB.Canvas.FillRect(R);
  1270.         end
  1271.       else
  1272.       if Active and Focused
  1273.       then
  1274.         begin
  1275.           Frame3D(TB.Canvas, R, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  1276.           TB.Canvas.Brush.Color := SP_XP_BTNDOWNCOLOR;
  1277.           TB.Canvas.FillRect(R);
  1278.         end
  1279.       else
  1280.       if Active
  1281.       then
  1282.         begin
  1283.           Frame3D(TB.Canvas, R, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  1284.           TB.Canvas.Brush.Color := SP_XP_BTNACTIVECOLOR;
  1285.           TB.Canvas.FillRect(R);
  1286.         end
  1287.       else
  1288.         begin
  1289.           TB.Canvas.Brush.Color := clBtnFace;
  1290.           TB.Canvas.FillRect(R);
  1291.         end;
  1292.       with TB.Canvas do
  1293.       begin
  1294.         Brush.Style := bsClear;
  1295.         Font.Assign(Self.Font);
  1296.       end;
  1297.     end;
  1298.   //
  1299.   if DrawGlyph
  1300.   then
  1301.     DrawTabGlyphAndText(TB.Canvas, TB.Width, TB.Height, S,
  1302.                         Images, Pages[TI].ImageIndex, Pages[TI].Enabled)
  1303.   else
  1304.     DrawText(TB.Canvas.Handle, PChar(S), Length(S), R, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  1305.   if TabPosition = tpLeft
  1306.   then
  1307.     DrawRotate90_1(Cnvs, TB, Rct.Left, Rct.Top)
  1308.   else
  1309.   if TabPosition = tpRight
  1310.   then
  1311.     DrawRotate90_2(Cnvs, TB, Rct.Left, Rct.Top)
  1312.   else
  1313.     Cnvs.Draw(Rct.Left, Rct.Top, TB);
  1314.   TB.Free;
  1315. end;
  1316. { TspSkinTabControl }
  1317. constructor TspSkinTabControl.Create(AOwner: TComponent);
  1318. begin
  1319.   inherited Create(AOwner);
  1320.   FUseSkinFont := True;
  1321.   Ctl3D := False;
  1322.   FIndex := -1;
  1323.   Picture := nil;
  1324.   Font.Name := 'Arial';
  1325.   Font.Style := [];
  1326.   Font.Color := clBtnText;
  1327.   Font.Height := 14;
  1328.   FOldTop := 0;
  1329.   FOldBottom := 0;
  1330.   FSkinUpDown := nil;
  1331.   FSkinDataName := 'tab';
  1332.   FDefaultFont := TFont.Create;
  1333.   FDefaultFont.Name := 'Arial';
  1334.   FDefaultFont.Style := [];
  1335.   FDefaultFont.Color := clBtnText;
  1336.   FDefaultFont.Height := 14;
  1337.   FDefaultItemHeight := 20;
  1338. end;
  1339. procedure TspSkinTabControl.MouseMove;
  1340. begin
  1341.  inherited;
  1342.  if not (csDesigning in ComponentState)
  1343.  then
  1344.    TestActive(X, Y);
  1345. end;
  1346. procedure TspSkinTabControl.MouseDown;
  1347. begin
  1348.   inherited;
  1349.   if (Button = mbLeft) and not (csDesigning in ComponentState)
  1350.   then
  1351.     TestActive(X, Y);
  1352. end;
  1353. procedure TspSkinTabControl.CMMouseLeave;
  1354. var
  1355.   R: TRect;
  1356. begin
  1357.   if (FOldActiveTab <> - 1) and (FOldActiveTab <> TabIndex)
  1358.   then
  1359.     begin
  1360.       R := GetItemRect(FOldActiveTab);
  1361.       DrawTab(FOldActiveTab, R, False, False, Canvas);
  1362.       FOldActiveTab := -1;
  1363.     end;
  1364.   if (FActiveTab <> - 1) and (FActiveTab <> TabIndex)
  1365.   then
  1366.     begin
  1367.       R := GetItemRect(FActiveTab);
  1368.       DrawTab(FActiveTab, R, False, False, Canvas);
  1369.       FActiveTab := -1;
  1370.     end;
  1371. end;
  1372. procedure TspSkinTabControl.TestActive(X, Y: Integer);
  1373. var
  1374.   i, j: Integer;
  1375.   R: TRect;
  1376. begin
  1377.   FOldActiveTab := FActiveTab;
  1378.   j := -1;
  1379.   for i := 0 to Tabs.Count-1 do
  1380.   begin
  1381.     R := GetItemRect(i);
  1382.     if PtInRect(R, Point(X, Y))
  1383.     then
  1384.       begin
  1385.         j := i;
  1386.         Break;
  1387.       end;
  1388.   end;
  1389.   FActiveTab := j;
  1390.   if (FOldActiveTab <> FActiveTab)
  1391.   then
  1392.     begin
  1393.       if (FOldActiveTab <> - 1) and (FOldActiveTab <> TabIndex)
  1394.       then
  1395.         begin
  1396.           R := GetItemRect(FOldActiveTab);
  1397.           DrawTab(FOldActiveTab, R, False, False, Canvas);
  1398.         end;
  1399.       if (FActiveTab <> -1) and (FActiveTab <> TabIndex)
  1400.       then
  1401.         begin
  1402.           R := GetItemRect(FActiveTab);
  1403.           DrawTab(FActiveTab, R, False, True, Canvas );
  1404.         end;
  1405.     end;
  1406. end;
  1407. procedure TspSkinTabControl.SetDefaultItemHeight;
  1408. begin
  1409.   FDefaultItemHeight := Value;
  1410.   if FIndex = -1
  1411.   then
  1412.     begin
  1413.       SetitemSize(TabWidth, FDefaultItemHeight);
  1414.       Change;
  1415.       ReAlign;
  1416.     end;
  1417. end;
  1418. procedure TspSkinTabControl.SetDefaultFont;
  1419. begin
  1420.   FDefaultFont.Assign(Value);
  1421. end;
  1422. procedure TspSkinTabControl.OnUpDownChange(Sender: TObject);
  1423. begin
  1424.   FSkinUpDown.Max := GetInVisibleItemCount;
  1425.   SendMessage(Handle, WM_HSCROLL,
  1426.     MakeWParam(SB_THUMBPOSITION, FSkinUpDown.Position), 0);
  1427. end;
  1428. function TspSkinTabControl.GetPosition: Integer;
  1429. var
  1430.   i, j: Integer;
  1431.   R: TRect;
  1432. begin
  1433.   j := 0;
  1434.   for i := 0 to Tabs.Count - 1 do
  1435.   begin
  1436.     R := GetItemRect(i);
  1437.     if R.Right <= 0 then inc(j);
  1438.   end;
  1439.   Result := j;
  1440. end;
  1441. function TspSkinTabControl.GetInVisibleItemCount;
  1442. var
  1443.   i, j: Integer;
  1444.   R: TRect;
  1445.   Limit: Integer;
  1446. begin
  1447.   if FSkinUpDown = nil
  1448.   then
  1449.     Limit := Width - 3
  1450.   else
  1451.     Limit := Width - FSkinUpDown.Width - 3;
  1452.   j := 0;
  1453.   for i := 0 to Tabs.Count - 1 do
  1454.   begin
  1455.     R := GetItemRect(i);
  1456.     if (R.Right > Limit) or (R.Right <= 0)
  1457.     then inc(j);
  1458.   end;
  1459.   Result := j;
  1460. end;
  1461. procedure TspSkinTabControl.CheckScroll;
  1462. var
  1463.   Wnd: HWND;
  1464.   InVCount: Integer;
  1465. begin
  1466.   Wnd := FindWindowEx(Handle, 0, 'msctls_updown32', nil);
  1467.   if Wnd <> 0 then DestroyWindow(Wnd);
  1468.   InVCount := GetInVisibleItemCount;
  1469.   if (InVCount = 0) and (FSkinUpDown <> nil)
  1470.   then
  1471.     HideSkinUpDown
  1472.   else
  1473.   if (InVCount > 0) and (FSkinUpDown = nil)
  1474.   then
  1475.     ShowSkinUpDown;
  1476.   if FSkinUpDown <> nil
  1477.   then
  1478.     begin
  1479.       FSkinUpDown.Max := InVCount;
  1480.       FSkinUpDown.Left := Width - FSkinUpDown.Width;
  1481.       if TabPosition = tpTop
  1482.       then
  1483.         FSkinUpDown.Top := 0
  1484.       else
  1485.        FSkinUpDown.Top := Height - FSkinUpDown.Height;
  1486.     end;
  1487. end;
  1488. procedure TspSkinTabControl.ShowSkinUpDown;
  1489. begin
  1490.   FSkinUpDown := TspSkinUpDown.Create(Self);
  1491.   FSkinUpDown.Parent := Self;
  1492.   FSkinUpDown.Width := 36;
  1493.   FSkinUpDown.Height := 18;
  1494.   FSkinUpDown.Min := 0;
  1495.   FSkinUpDown.Max := GetInVisibleItemCount;
  1496.   FSkinUpDown.Position := GetPosition;
  1497.   FSkinUpDown.Increment := 1;
  1498.   FSkinUpDown.OnChange := OnUpDownChange;
  1499.   FSkinUpDown.Left := Width - FSkinUpDown.Width;
  1500.   if TabPosition = tpTop
  1501.   then
  1502.     FSkinUpDown.Top := 0
  1503.   else
  1504.     FSkinUpDown.Top := Height - FSkinUpDown.Height;
  1505.   FSkinUpDown.SkinDataName := UpDown;
  1506.   FSkinUpDown.SkinData := SkinData;
  1507.   FSkinUpDown.Visible := True;
  1508. end;
  1509. procedure TspSkinTabControl.HideSkinUpDown;
  1510. begin
  1511.   FSkinUpDown.Free;
  1512.   FSkinUpDown := nil;
  1513. end;
  1514. procedure TspSkinTabControl.WMPaint;
  1515. begin
  1516.   if ControlCount = 0
  1517.   then
  1518.     PaintHandler(Msg)
  1519.   else
  1520.     inherited;
  1521. end;
  1522. procedure TspSkinTabControl.WMHSCROLL;
  1523. begin
  1524.   inherited;
  1525.   RePaint;
  1526. end;
  1527. procedure TspSkinTabControl.WMSize;
  1528. begin
  1529.   inherited;
  1530. end;
  1531. destructor TspSkinTabControl.Destroy;
  1532. begin
  1533.   FDefaultFont.Free;
  1534.   inherited Destroy;
  1535. end;
  1536. procedure TspSkinTabControl.Change;
  1537. begin
  1538.   if FSkinUpDown <> nil
  1539.   then FSkinUpDown.Position := GetPosition;
  1540.   inherited;
  1541.   Invalidate;
  1542. end;
  1543. procedure TspSkinTabControl.GetSkinData;
  1544. begin
  1545.   BGPictureIndex := -1;
  1546.   if FSD = nil
  1547.   then
  1548.     begin
  1549.       FIndex := -1;
  1550.       Exit;
  1551.     end;
  1552.   if FSD.Empty
  1553.   then
  1554.     FIndex := -1
  1555.   else
  1556.     FIndex := FSD.GetControlIndex(FSkinDataName);
  1557.   //
  1558.   if FIndex <> -1
  1559.   then
  1560.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinTabControl
  1561.     then
  1562.       with TspDataSkinTabControl(FSD.CtrlList.Items[FIndex]) do
  1563.       begin
  1564.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  1565.         then
  1566.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  1567.         else
  1568.           Picture := nil;
  1569.         Self.SkinRect := SkinRect;
  1570.         Self.ClRect := ClRect;
  1571.         Self.TabRect := TabRect;
  1572.         if IsNullRect(ActiveTabRect)
  1573.         then
  1574.           Self.ActiveTabRect := TabRect
  1575.         else
  1576.           Self.ActiveTabRect := ActiveTabRect;
  1577.         if IsNullRect(FocusTabRect)
  1578.         then
  1579.           Self.FocusTabRect := ActiveTabRect
  1580.         else
  1581.           Self.FocusTabRect := FocusTabRect;
  1582.         //
  1583.         Self.TabsBGRect := TabsBGRect; 
  1584.         Self.LTPoint := LTPoint;
  1585.         Self.RTPoint := RTPoint;
  1586.         Self.LBPoint := LBPoint;
  1587.         Self.RBPoint := RBPoint;
  1588.         Self.TabLeftOffset := TabLeftOffset;
  1589.         Self.TabRightOffset := TabRightOffset;
  1590.         //
  1591.         Self.FontName := FontName;
  1592.         Self.FontColor := FontColor;
  1593.         Self.ActiveFontColor := ActiveFontColor;
  1594.         Self.FocusFontColor := FocusFontColor;
  1595.         Self.FontStyle := FontStyle;
  1596.         Self.FontHeight := FontHeight;
  1597.         Self.UpDown := UpDown;
  1598.         Self.BGPictureIndex := BGPictureIndex;
  1599.         Self.MouseInFontColor := MouseInFontColor;
  1600.         Self.MouseInTabRect := MouseInTabRect;
  1601.       end;
  1602. end;
  1603. procedure TspSkinTabControl.ChangeSkinData;
  1604. begin
  1605.   GetSkinData;
  1606.   //
  1607.   if FIndex <> -1
  1608.   then
  1609.     begin
  1610.       Font.Color := FontColor;
  1611.       if FUseSkinFont
  1612.       then
  1613.         begin
  1614.           Font.Name := FontName;
  1615.           Font.Height := FontHeight;
  1616.           Font.Style := FontStyle;
  1617.           Font.CharSet := DefaultFont.CharSet;
  1618.         end
  1619.       else
  1620.         Font.Assign(FDefaultFont);
  1621.       if TabHeight <= 0
  1622.       then
  1623.         SetItemSize(TabWidth, RectHeight(TabRect))
  1624.       else
  1625.         SetItemSize(TabWidth, TabHeight);
  1626.     end
  1627.   else
  1628.     begin
  1629.       Font.Assign(FDefaultFont);
  1630.       if TabHeight <= 0
  1631.       then
  1632.         SetItemSize(TabWidth, FDefaultItemHeight)
  1633.       else
  1634.         SetItemSize(TabWidth, TabHeight);
  1635.     end;
  1636.   //
  1637.   Change;
  1638.   ReAlign;
  1639.   RePaint;
  1640.   if FSkinUpDown <> nil
  1641.   then
  1642.     begin
  1643.       HideSkinUpDown;
  1644.       CheckScroll;
  1645.     end;
  1646. end;
  1647. procedure TspSkinTabControl.SetSkinData;
  1648. begin
  1649.   FSD := Value;
  1650.   if (FSD <> nil) then
  1651.   if not FSD.Empty and not (csDesigning in ComponentState)
  1652.   then
  1653.     ChangeSkinData;
  1654. end;
  1655. procedure TspSkinTabControl.Notification;
  1656. begin
  1657.   inherited Notification(AComponent, Operation);
  1658.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  1659. end;
  1660. procedure TspSkinTabControl.PaintDefaultWindow;
  1661. var
  1662.   R: TRect;
  1663. begin
  1664.   with Cnvs do
  1665.   begin
  1666.     Brush.Color := clBtnFace;
  1667.     FillRect(ClientRect);
  1668.     R := Self.DisplayRect;
  1669.     InflateRect(R, 1, 1);
  1670.     Frame3D(Cnvs, R, clBtnShadow, clBtnShadow, 1);
  1671.   end;
  1672. end;
  1673. procedure TspSkinTabControl.PaintSkinWindow;
  1674. var
  1675.   TOff, LOff, Roff, BOff: Integer;
  1676.   DR, R: TRect;
  1677.   TBGOffX, TBGOffY, X, Y, XCnt, YCnt, w, h, w1, h1, rw, rh, XO, YO: Integer;
  1678.   NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint: TPoint;
  1679.   B: TBitMap;
  1680. begin
  1681.   TOff := ClRect.Top;
  1682.   LOff := ClRect.Left;
  1683.   ROff := RectWidth(SkinRect) - ClRect.Right;
  1684.   BOff := RectHeight(SkinRect) - ClRect.Bottom;
  1685.   DR := DisplayRect;
  1686.   R := Rect(DR.Left - LOff, DR.Top - TOff, DR.Right + ROff, DR.Bottom + BOff);
  1687.   XO := RectWidth(R) - RectWidth(SkinRect);
  1688.   YO := RectHeight(R) - RectHeight(SkinRect);
  1689.   NewLTPoint := LTPoint;
  1690.   NewRTPoint := Point(RTPoint.X + XO, RTPoint.Y);
  1691.   NewLBPoint := Point(LBPoint.X, LBPoint.Y + YO);
  1692.   NewRBPoint := Point(RBPoint.X + XO, RBPoint.Y + YO);
  1693.   // DrawBG
  1694.   if BGPictureIndex <> -1
  1695.   then
  1696.     begin
  1697.       B := TBitMap(FSD.FActivePictures.Items[BGPictureIndex]);
  1698.       if (Width > 0) and (Height > 0)
  1699.       then
  1700.         begin
  1701.           XCnt := Width div B.Width;
  1702.           YCnt := Height div B.Height;
  1703.           for X := 0 to XCnt do
  1704.           for Y := 0 to YCnt do
  1705.           Cnvs.Draw(X * B.Width, Y * B.Height, B);
  1706.         end;
  1707.       Exit;
  1708.     end;
  1709.   w := RectWidth(ClRect);
  1710.   h := RectHeight(ClRect);
  1711.   w1 := RectWidth(R);
  1712.   h1 := RectHeight(R);
  1713.   XCnt := w1 div w;
  1714.   YCnt := h1 div h;
  1715.   for X := 0 to XCnt do
  1716.   for Y := 0 to YCnt do
  1717.   begin
  1718.     if X * w + w > w1 then XO := X * w + w - w1 else XO := 0;
  1719.     if Y * h + h > h1 then YO := Y * h + h - h1 else YO := 0;
  1720.      Cnvs.CopyRect(Rect(R.Left + X * w, R.Top + Y * h,
  1721.                         R.Left + X * w + w - XO, R.Top + Y * h + h - YO),
  1722.               Picture.Canvas,
  1723.               Rect(SkinRect.Left + ClRect.Left, SkinRect.Top + ClRect.Top,
  1724.                    SkinRect.Left + ClRect.Right - XO,
  1725.                    SkinRect.Top + ClRect.Bottom - YO));
  1726.   end;            
  1727.   // Draw tabs BG
  1728.   if not IsNullRect(TabsBGRect)
  1729.   then
  1730.     begin
  1731.       if TabPosition = tpLeft
  1732.       then
  1733.         begin
  1734.           TBGOffY := 0;
  1735.           TBGOffX := 0;
  1736.           rw := R.Left;
  1737.           rh := Height;
  1738.         end
  1739.       else
  1740.       if TabPosition = tpRight
  1741.       then
  1742.         begin
  1743.           TBGOffY := 0;
  1744.           TBGOffX := R.Right;
  1745.           rw := Width - R.Right;
  1746.           rh := Height;
  1747.         end
  1748.       else
  1749.       if TabPosition = tpTop
  1750.       then
  1751.         begin
  1752.           TBGOffX := 0;
  1753.           TBGOffY := 0;
  1754.           rh := R.Top;
  1755.           rw := Width;
  1756.         end
  1757.       else
  1758.         begin
  1759.           TBGOffX := 0;
  1760.           TBGOffY := R.Bottom;
  1761.           rh := Height - R.Bottom;
  1762.           rw := Width;
  1763.         end;
  1764.       w := RectWidth(TabsBGRect);
  1765.       h := RectHeight(TabsBGRect);
  1766.       XCnt := rw div w;
  1767.       YCnt := rh div h;
  1768.       for X := 0 to XCnt do
  1769.       for Y := 0 to YCnt do
  1770.       begin
  1771.         if X * w + w > rw then XO := X * w + w - rw else XO := 0;
  1772.         if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  1773.         Cnvs.CopyRect(Rect(TBGOffX + X * w, TBGOffY + Y * h,
  1774.                            TBGOffX + X * w + w - XO, TBGOffY + Y * h + h - YO),
  1775.                       Picture.Canvas,
  1776.                       Rect(TabsBGRect.Left, TabsBGRect.Top,
  1777.                            TabsBGRect.Right - XO, TabsBGRect.Bottom - YO));
  1778.       end;
  1779.     end;
  1780.   // Draw frame around displayrect
  1781.     // draw lines
  1782.   w := RTPoint.X - LTPoint.X;
  1783.   XCnt := (NewRTPoint.X - NewLTPoint.X) div w;
  1784.   for X := 0 to XCnt do
  1785.   begin
  1786.     if NewLTPoint.X + X * w + w > NewRTPoint.X
  1787.     then XO := NewLTPoint.X + X * w + w - NewRTPoint.X else XO := 0;
  1788.     Cnvs.CopyRect(Rect(R.Left + NewLTPoint.X + X * w, R.Top,
  1789.                   R.Left + NewLTPoint.X + X * w + w - XO, R.Top + TOff),
  1790.              Picture.Canvas,
  1791.              Rect(SkinRect.Left + LTPoint.X, SkinRect.Top,
  1792.                   SkinRect.Left + RTPoint.X - XO, SkinRect.Top + TOff));
  1793.   end;
  1794.   w := RBPoint.X - LBPoint.X;
  1795.   XCnt := (NewRBPoint.X - NewLBPoint.X) div w;
  1796.   for X := 0 to XCnt do
  1797.   begin
  1798.     if NewLBPoint.X + X * w + w > NewRBPoint.X
  1799.     then XO := NewLBPoint.X + X * w + w - NewRBPoint.X else XO := 0;
  1800.     Cnvs.CopyRect(Rect(R.Left + NewLBPoint.X + X * w, R.Bottom - BOff,
  1801.                   R.Left + NewLBPoint.X + X * w + w - XO, R.Bottom),
  1802.              Picture.Canvas,
  1803.              Rect(SkinRect.Left + LBPoint.X, SkinRect.Bottom - BOff,
  1804.                   SkinRect.Left + RBPoint.X - XO, SkinRect.Bottom));
  1805.   end;
  1806.   w := LOff;
  1807.   h := LBPoint.Y - LTPoint.Y;
  1808.   YCnt := (NewLBPoint.Y - NewLTPoint.Y) div h;
  1809.   for Y := 0 to YCnt do
  1810.   begin
  1811.     if NewLTPoint.Y + Y * h + h > NewLBPoint.Y
  1812.     then YO := NewLTPoint.Y + Y * h + h - NewLBPoint.Y else YO := 0;
  1813.     Cnvs.CopyRect(Rect(R.Left, R.Top + NewLTPoint.Y + Y * h,
  1814.                        R.Left + w, R.Top + NewLTPoint.Y + Y * h + h - YO),
  1815.                   Picture.Canvas,
  1816.                   Rect(SkinRect.Left, SkinRect.Top + LTPoint.Y,
  1817.                        SkinRect.Left + w, SkinRect.Top + LBPoint.Y - YO));
  1818.   end;
  1819.   w := ROff;
  1820.   h := RBPoint.Y - RTPoint.Y;
  1821.   YCnt := (NewRBPoint.Y - NewRTPoint.Y) div h;
  1822.   for Y := 0 to YCnt do
  1823.   begin
  1824.     if NewRTPoint.Y + Y * h + h > NewRBPoint.Y
  1825.     then YO := NewRTPoint.Y + Y * h + h - NewRBPoint.Y else YO := 0;
  1826.     Cnvs.CopyRect(Rect(R.Right - w, R.Top + NewRTPoint.Y + Y * h,
  1827.                        R.Right, R.Top + NewRTPoint.Y + Y * h + h - YO),
  1828.                   Picture.Canvas,
  1829.                   Rect(SkinRect.Right - w, SkinRect.Top + RTPoint.Y,
  1830.                        SkinRect.Right, SkinRect.Top + RBPoint.Y - YO));
  1831.   end;
  1832.     // draw corners
  1833.   Cnvs.CopyRect(Rect(R.Left, R.Top, R.Left + LTPoint.X, R.Top + LTPoint.Y),
  1834.                 Picture.Canvas,
  1835.                 Rect(SkinRect.Left, SkinRect.Top,
  1836.                      SkinRect.Left + NewLTPoint.X, SkinRect.Top + NewLTPoint.Y));
  1837.   Cnvs.CopyRect(Rect(R.Left + NewRTPoint.X, R.Top,
  1838.                      R.Right, R.Top + NewRTPoint.Y),
  1839.                 Picture.Canvas,
  1840.                 Rect(SkinRect.Left + RTPoint.X, SkinRect.Top,
  1841.                      SkinRect.Right, SkinRect.Top + RTPoint.Y));
  1842.   Cnvs.CopyRect(Rect(R.Left, R.Top + NewLBPoint.Y,
  1843.                      R.Left + NewLBPoint.X, R.Bottom),
  1844.                 Picture.Canvas,
  1845.                 Rect(SkinRect.Left, SkinRect.Top + LBPoint.Y,
  1846.                      SkinRect.Left + LBPoint.X, SkinRect.Bottom));
  1847.   Cnvs.CopyRect(Rect(R.Left + NewRBPoint.X, R.Top + NewRBPoint.Y,
  1848.                      R.Right, R.Bottom),
  1849.                 Picture.Canvas,
  1850.                 Rect(SkinRect.Left + RBPoint.X, SkinRect.Top + RBPoint.Y,
  1851.                      SkinRect.Right, SkinRect.Bottom));
  1852. end;
  1853. procedure TspSkinTabControl.Loaded;
  1854. begin
  1855.   inherited Loaded;
  1856.   if FIndex = -1
  1857.   then
  1858.     begin
  1859.       if TabHeight <= 0
  1860.       then
  1861.         SetItemSize(TabWidth, FDefaultItemHeight)
  1862.       else
  1863.         SetItemSize(TabWidth, TabHeight);
  1864.       Change;
  1865.       ReAlign;
  1866.     end;
  1867. end;
  1868. procedure TspSkinTabControl.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
  1869. begin
  1870.   Msg.Result := 1;
  1871. end;
  1872. procedure TspSkinTabControl.WndProc(var Message:TMessage);
  1873. var
  1874.   TOff, LOff, Roff, BOff: Integer;
  1875. begin
  1876.   if Message.Msg = TCM_ADJUSTRECT
  1877.   then
  1878.     begin
  1879.       inherited WndProc(Message);
  1880.       TOff := 0;
  1881.       LOff := 0;
  1882.       ROff := 0;
  1883.       BOff := 0;
  1884.       if (FIndex <> -1) and (BGPictureIndex = -1)
  1885.       then
  1886.         begin
  1887.           TOff := ClRect.Top;
  1888.           LOff := ClRect.Left;
  1889.           ROff := RectWidth(SkinRect) - ClRect.Right;
  1890.           BOff := RectHeight(SkinRect) - ClRect.Bottom;
  1891.         end;
  1892.       case TabPosition of
  1893.         tpLeft:
  1894.            if FIndex <> -1
  1895.            then
  1896.              begin
  1897.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + LOff - 4;
  1898.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1899.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1900.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  1901.              end
  1902.            else
  1903.              begin
  1904.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  1905.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  1906.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  1907.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  1908.              end;
  1909.         tpRight:
  1910.            if FIndex <> -1
  1911.            then
  1912.              begin
  1913.                PRect(Message.LParam)^.Left := LOff;
  1914.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - ROff + 4;
  1915.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1916.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  1917.              end
  1918.            else
  1919.              begin
  1920.                PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 3;
  1921.                PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 3;
  1922.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  1923.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  1924.              end;
  1925.         tpTop:
  1926.            if FIndex <> -1
  1927.            then
  1928.              begin
  1929.                PRect(Message.LParam)^.Left := LOff;
  1930.                PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1931.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1932.                PRect(Message.LParam)^.Bottom := ClientHeight - BOff;
  1933.              end
  1934.            else
  1935.              begin
  1936.                PRect(Message.LParam)^.Left := 1;
  1937.                PRect(Message.LParam)^.Right := ClientWidth - 1;
  1938.                PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 5;
  1939.                PRect(Message.LParam)^.Bottom := ClientHeight - 1;
  1940.              end;
  1941.         tpBottom:
  1942.           if FIndex <> -1
  1943.           then
  1944.             begin
  1945.               PRect(Message.LParam)^.Left := LOff;
  1946.               PRect(Message.LParam)^.Right := ClientWidth - ROff;
  1947.               PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 6 + TOff;
  1948.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 4 - BOff;
  1949.             end
  1950.           else
  1951.             begin
  1952.               PRect(Message.LParam)^.Left := 1;
  1953.               PRect(Message.LParam)^.Right := ClientWidth - 1;
  1954.               PRect(Message.LParam)^.Top := 1;
  1955.               PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 3;
  1956.             end;
  1957.       end;
  1958.     end
  1959.   else
  1960.     if Message.Msg = TCM_GETITEMRECT
  1961.     then
  1962.       begin
  1963.         inherited WndProc(Message);
  1964.         if Style = tsTabs
  1965.         then
  1966.           case TabPosition of
  1967.             tpLeft:
  1968.                 begin
  1969.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1970.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1971.                 end;
  1972.             tpRight:
  1973.                 begin
  1974.                   PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left + 2;
  1975.                   PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right + 2;
  1976.                 end;
  1977.             tpTop:
  1978.                 begin
  1979.                   if not MultiLine
  1980.                   then
  1981.                     begin
  1982.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1983.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1984.                     end;
  1985.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top - 2;
  1986.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom - 2;
  1987.                 end;
  1988.             tpBottom:
  1989.                 begin
  1990.                   if not MultiLine
  1991.                   then
  1992.                     begin
  1993.                       PRect(Message.LParam)^.Left := PRect(Message.LParam)^.Left - 2;
  1994.                       PRect(Message.LParam)^.Right := PRect(Message.LParam)^.Right - 2;
  1995.                     end;
  1996.                   PRect(Message.LParam)^.Top := PRect(Message.LParam)^.Top + 2;
  1997.                   PRect(Message.LParam)^.Bottom := PRect(Message.LParam)^.Bottom + 2;
  1998.                 end;
  1999.           end;
  2000.       end
  2001.   else
  2002.   inherited WndProc(Message);
  2003.   if (Message.Msg = WM_SIZE) and (not MultiLine)
  2004.   then
  2005.     begin
  2006.       CheckScroll;
  2007.     end;
  2008. end;
  2009. function TspSkinTabControl.GetItemRect(index: integer): TRect;
  2010. var
  2011.   R: TRect;
  2012. begin
  2013.   SendMessage(Handle, TCM_GETITEMRECT, index, Integer(@R));
  2014.   Result := R;
  2015. end;
  2016. procedure TspSkinTabControl.SetItemSize;
  2017. begin
  2018.   SendMessage(Handle, TCM_SETITEMSIZE, 0, MakeLParam(AWidth, AHeight));
  2019. end;
  2020. procedure TspSkinTabControl.PaintWindow(DC: HDC);
  2021. var
  2022.   SaveIndex: Integer;
  2023.   RealPicture: TBitMap;
  2024. begin
  2025.   GetSkinData;
  2026.   SaveIndex := SaveDC(DC);
  2027.   try
  2028.     RealPicture := TBitMap.Create;
  2029.     Canvas.Handle := DC;
  2030.     RealPicture.Width := Width;
  2031.     RealPicture.Height := Height;
  2032.     if FIndex = -1
  2033.     then
  2034.       PaintDefaultWindow(RealPicture.Canvas)
  2035.     else
  2036.       PaintSkinWindow(RealPicture.Canvas);
  2037.     DrawTabs(RealPicture.Canvas);
  2038.     Canvas.Draw(0, 0, RealPicture);
  2039.     Canvas.Handle := 0;
  2040.     RealPicture.Free;
  2041.   finally
  2042.     RestoreDC(DC, SaveIndex);
  2043.   end;
  2044. end;
  2045. procedure TspSkinTabControl.DrawTabs;
  2046. var
  2047.   i: integer;
  2048.   R: TRect;
  2049. begin
  2050.   for i := 0 to Tabs.Count-1 do
  2051.   begin
  2052.     R := GetItemRect(i);
  2053.     DrawTab(i, R, i = TabIndex, i = FActiveTab, Cnvs);
  2054.   end;
  2055. end;
  2056. procedure TspSkinTabControl.DrawTab;
  2057. var
  2058.   R: TRect;
  2059.   S: String;
  2060.   TB, BufferTB: TBitMap;
  2061.   DrawGlyph: Boolean;
  2062.   W, H: Integer;
  2063. begin
  2064.   DrawGlyph := (Images <> nil) and (TI < Images.Count);
  2065.   S := Tabs[TI];
  2066.   TB := TBitMap.Create;
  2067.   if (TabPosition = tpTop) or (TabPosition = tpBottom)
  2068.   then
  2069.     begin
  2070.       W := RectWidth(Rct);
  2071.       H := RectHeight(Rct);
  2072.     end
  2073.   else
  2074.     begin
  2075.       H := RectWidth(Rct);
  2076.       W := RectHeight(Rct);
  2077.     end;
  2078.   R := Rect(0, 0, W, H);  
  2079.   if FIndex <> -1
  2080.   then
  2081.     begin
  2082.       if TabHeight <= 0
  2083.       then
  2084.         begin
  2085.           if MouseIn and not Active and not IsNullRect(MouseInTabRect)
  2086.           then
  2087.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2088.              TB, Picture, MouseInTabRect, W, H)
  2089.           else
  2090.             if Active and Focused
  2091.           then
  2092.            CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2093.             TB, Picture, FocusTabRect, W, H)
  2094.           else
  2095.           if Active
  2096.           then
  2097.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2098.               TB, Picture, ActiveTabRect, W, H)
  2099.           else
  2100.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2101.              TB, Picture, TabRect, W, H);
  2102.        end
  2103.      else
  2104.        begin
  2105.          BufferTB := TBitMap.Create;
  2106.          BufferTB.Width := W;
  2107.          BufferTB.Height := RectHeight(TabRect);
  2108.          if MouseIn and not Active and not IsNullRect(MouseInTabRect)
  2109.           then
  2110.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2111.              BufferTB, Picture, MouseInTabRect, W, H)
  2112.           else
  2113.             if Active and Focused
  2114.           then
  2115.            CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2116.             BufferTB, Picture, FocusTabRect, W, H)
  2117.           else
  2118.           if Active
  2119.           then
  2120.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2121.               BufferTB, Picture, ActiveTabRect, W, H)
  2122.           else
  2123.             CreateHSkinImage(TabLeftOffset, TabRightOffset,
  2124.              BufferTB, Picture, TabRect, W, H);
  2125.          TB.Width := W;
  2126.          TB.Height := H;
  2127.          TB.Canvas.StretchDraw(R, BufferTB);
  2128.          BufferTB.Free;
  2129.        end;
  2130.       with TB.Canvas do
  2131.       begin
  2132.         Brush.Style := bsClear;
  2133.         if FUseSkinFont
  2134.         then
  2135.           begin
  2136.             Font.Name := FontName;
  2137.             Font.Style := FontStyle;
  2138.             Font.Height := FontHeight;
  2139.             Font.CharSet := Self.Font.CharSet;
  2140.           end
  2141.         else
  2142.            Font.Assign(Self.Font);
  2143.         if MouseIn and not Active
  2144.         then
  2145.           Font.Color := MouseInFontColor
  2146.         else
  2147.         if Active and Focused
  2148.         then
  2149.           Font.Color := FocusFontColor
  2150.         else
  2151.           if Active
  2152.           then Font.Color := ActiveFontColor
  2153.           else Font.Color := FontColor;
  2154.       end;
  2155.     end
  2156.   else
  2157.     begin
  2158.       TB.Width := W;
  2159.       TB.Height := H;
  2160.       if MouseIn and not Active
  2161.       then
  2162.         begin
  2163.           TB.Canvas.Brush.Color := SP_XP_BTNACTIVECOLOR;
  2164.           TB.Canvas.FillRect(R);
  2165.         end
  2166.       else
  2167.       if Active and Focused
  2168.       then
  2169.         begin
  2170.           Frame3D(TB.Canvas, R, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  2171.           TB.Canvas.Brush.Color := SP_XP_BTNDOWNCOLOR;
  2172.           TB.Canvas.FillRect(R);
  2173.         end
  2174.       else
  2175.       if Active
  2176.       then
  2177.         begin
  2178.           Frame3D(TB.Canvas, R, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  2179.           TB.Canvas.Brush.Color := SP_XP_BTNACTIVECOLOR;
  2180.           TB.Canvas.FillRect(R);
  2181.         end
  2182.       else
  2183.         begin
  2184.           TB.Canvas.Brush.Color := clBtnFace;
  2185.           TB.Canvas.FillRect(R);
  2186.         end;
  2187.       with TB.Canvas do
  2188.       begin
  2189.         Brush.Style := bsClear;
  2190.         Font.Assign(Self.Font);
  2191.       end;
  2192.     end;
  2193.   //
  2194.   if DrawGlyph
  2195.   then
  2196.     DrawTabGlyphAndText(TB.Canvas, TB.Width, TB.Height, S,
  2197.                         Images, TI, True)
  2198.   else
  2199.     DrawText(TB.Canvas.Handle, PChar(S), Length(S), R, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  2200.   if TabPosition = tpLeft
  2201.   then
  2202.     DrawRotate90_1(Cnvs, TB, Rct.Left, Rct.Top)
  2203.   else
  2204.   if TabPosition = tpRight
  2205.   then
  2206.     DrawRotate90_2(Cnvs, TB, Rct.Left, Rct.Top)
  2207.   else
  2208.     Cnvs.Draw(Rct.Left, Rct.Top, TB);
  2209.   TB.Free;
  2210. end;
  2211. procedure TspSkinTabControl.UpDateTabs;
  2212. begin
  2213.   if FIndex <> -1
  2214.   then
  2215.     begin
  2216.       if TabHeight <= 0
  2217.       then
  2218.         SetItemSize(TabWidth, RectHeight(TabRect))
  2219.       else
  2220.         SetItemSize(TabWidth, TabHeight);
  2221.     end
  2222.   else
  2223.     begin
  2224.       if TabHeight <= 0
  2225.       then
  2226.         SetItemSize(TabWidth, FDefaultItemHeight)
  2227.       else
  2228.         SetItemSize(TabWidth, TabHeight);
  2229.     end;
  2230.   if MultiLine and (FSkinUpDown <> nil)
  2231.   then
  2232.     HideSkinUpDown;
  2233.   ReAlign;
  2234. end;
  2235. end.