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

Delphi控件源码

开发平台:

Delphi

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