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

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 bsUtils;
  15. {$P+,S-,W-,R-}
  16. {$WARNINGS OFF}
  17. {$HINTS OFF}
  18. interface
  19. {$R-}
  20. uses
  21.   Windows, Controls, Messages, SysUtils, Classes, Graphics, IniFiles;
  22. const
  23.   maxi = 10000;
  24.   // xp office color consts
  25.   BS_XP_BTNFRAMECOLOR = 8388608;
  26.   BS_XP_BTNACTIVECOLOR = 13811126;
  27.   BS_XP_BTNDOWNCOLOR = 11899781;
  28. type
  29.   TCharSet = set of char;
  30. { TbsFBitmap }
  31.   TFBColor  = record b,g,r:Byte end;
  32.   PFBColor  =^TFBColor;
  33.   TBLine    = array[0..0]of TFBColor;
  34.   PBLine    =^TBLine;
  35.   TPLines  = array[0..0]of PBLine;
  36.   PPLines  =^TPLines;
  37.   TbsFBitmap = class
  38.   private
  39.     Bits:   Pointer;
  40.     procedure   Initialize;
  41.   public
  42.     Pixels: PPLines;
  43.     Gap,
  44.     RowInc,
  45.     Size,
  46.     Width,
  47.     Height: Integer;
  48.     Handle,
  49.     hDC:        Integer;
  50.     bmInfo:     TBitmapInfo;
  51.     bmHeader:   TBitmapInfoHeader;
  52.     constructor Create(HBmp:Integer);
  53.     destructor  Destroy; override;
  54.   end;
  55.   TRectArray = array[0..maxi] of TRect;
  56.   
  57. //
  58. function EqRects(R1, R2: TRect): Boolean;
  59. function NullRect: TRect;
  60. function IsNullRect(R: TRect): Boolean;
  61. function IsNullPoint(P: TPoint): Boolean;
  62. function RectInRect(R1, R2: TRect): Boolean;
  63. //
  64. function RectWidth(R: TRect): Integer;
  65. function RectHeight(R: TRect): Integer;
  66. function RectToCenter(var R: TRect; Bounds: TRect): TRect;
  67. // Region functions
  68. function CreateRgnFromBmp(B: TBitmap; XO, YO: Integer; var RgnData: PRgnData): integer;
  69. // Stream functions
  70. procedure WriteStringToStream(Str: String; S: TStream);
  71. procedure ReadStringFromStream(var Str: String; S: TStream);
  72. // Skin functions
  73. function GetRect(S: String): TRect;
  74. function GetPoint(S: String): TPoint;
  75. function SetRect(R: TRect): String;
  76. procedure CreateSkinBorderImages(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;
  77.   NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;
  78.   LeftB, TopB, RightB, BottomB, SB: TBitMap; R: TRect; AW, AH: Integer;
  79.   LS, TS, RS, BS: Boolean);
  80. procedure CreateSkinImageBS(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;
  81.   NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;
  82.   B, SB: TBitMap; R: TRect; AW, AH: Integer; DrawClient: Boolean;
  83.   LS, TS, RS, BS: Boolean);
  84. procedure CreateSkinImage(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;
  85.   NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;
  86.   B, SB: TBitMap; R: TRect; AW, AH: Integer; DrawClient: Boolean);
  87. procedure CreateSkinImage2(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;
  88.   NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;
  89.   B, SB: TBitMap; R: TRect; AW, AH: Integer; DrawClient: Boolean);
  90. procedure CreateHSkinImage(LO, RO: Integer;
  91.   B, SB: TBitMap; R: TRect; AW, AH: Integer);
  92. procedure CreateHSkinImage2(LO, RO: Integer;
  93.   B, SB: TBitMap; R: TRect; AW, AH: Integer);
  94. procedure CreateHSkinImage3(LO, RO: Integer;
  95.   B, SB: TBitMap; R: TRect; AW, AH: Integer);
  96. procedure CreateVSkinImage(TpO, BO: Integer;
  97.   B, SB: TBitMap; R: TRect; AW, AH: Integer);
  98.   
  99. procedure CreateSkinMask(LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;
  100.   NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;
  101.   FMask, RMTop, RMLeft, RMRight, RMBottom: TBitMap; AW, AH: Integer);
  102. procedure CreateSkinSimplyRegion(var FRgn: HRgn; FMask: TBitMap);
  103. procedure CreateSkinRegion(var FRgn: HRgn;
  104.   LtPt, RTPt, LBPt, RBPt: TPoint; ClRect: TRect;
  105.   NewLTPt, NewRTPt, NewLBPt, NewRBPt: TPoint; NewClRect: TRect;
  106.   FMask: TBitMap; AW, AH: Integer);
  107. procedure DrawGlyph(Cnvs: TCanvas; X, Y: Integer; FGlyph: TBitMap;
  108.                     FNumGlyphs, FGlyphNum: Integer);
  109. // IniFile funcitons
  110. function ReadRect(IniFile: TCustomIniFile; Section: String; Ident: String): TRect;
  111. function ReadPoint(IniFile: TCustomIniFile; Section: String; Ident: String): TPoint;
  112. function ReadBoolean(IniFile: TCustomIniFile; Section: String; Ident: String): Boolean;
  113. function ReadFontStyles(IniFile: TCustomIniFile;
  114.                         Section: String; Ident: String): TFontStyles;
  115. procedure ReadStrings(IniFile: TCustomIniFile;
  116.                       Section: String; Ident: String; S: TStrings);
  117. procedure ReadStrings1(IniFile: TCustomIniFile;
  118.                        Section: String; Ident: String; S: TStrings);
  119. function ReadAlignment(IniFile: TCustomIniFile;
  120.                        Section: String; Ident: String): TAlignment;
  121. procedure WriteAlignment(IniFile: TCustomIniFile;
  122.                          Section: String; Ident: String; A: TAlignment);
  123. procedure WriteRect(IniFile: TCustomIniFile; Section: String; Ident: String; R: TRect);
  124. procedure WritePoint(IniFile: TCustomIniFile; Section: String; Ident: String; P: TPoint);
  125. procedure WriteBoolean(IniFile: TCustomIniFile; Section: String; Ident: String; B: Boolean);
  126. procedure WriteFontStyles(IniFile: TCustomIniFile;
  127.                           Section: String; Ident: String; FS: TFontStyles);
  128. procedure WriteStrings(IniFile: TCustomIniFile;
  129.                        Section: String; Ident: String; S: TStrings);
  130. procedure WriteStrings1(IniFile: TCustomIniFile;
  131.                         Section: String; Ident: String; S: TStrings);
  132. procedure GetScreenImage(X, Y: Integer; B: TBitMap);
  133. procedure GetWindowsVersion(var Major, Minor: Integer);
  134. function CheckW2KWXP: Boolean;
  135. function CheckWXP: Boolean;
  136. procedure SetAlphaBlendTransparent(WHandle: HWnd; Value: Byte);
  137. procedure Frm3D(Canvas: TCanvas; Rect: TRect; TopColor, BottomColor: TColor);
  138. procedure DrawRadioImage(Cnvs: TCanvas; X, Y: Integer; Color: TColor);
  139. procedure DrawCheckImage(Cnvs: TCanvas; X, Y: Integer; Color: TColor);
  140. procedure DrawArrowImage(Cnvs: TCanvas; R: TRect; Color: TColor; Code: Integer);
  141. procedure DrawTrackArrowImage(Cnvs: TCanvas; R: TRect; Color: TColor);
  142. function PointInRect(R: TRect; P: TPoint): Boolean;
  143. procedure BSDrawText(Cnvs: TCanvas; S: String; R: TRect);
  144. procedure BSDrawText2(Cnvs: TCanvas; S: String; R: TRect);
  145. procedure BSDrawText3(Cnvs: TCanvas; S: String; R: TRect; HorOffset: Integer);
  146. procedure DrawCloseImage(C: TCanvas; X, Y: Integer; Color: TColor);
  147. procedure DrawRCloseImage(C: TCanvas; R: TRect; Color: TColor);
  148. procedure DrawMinimizeImage(C: TCanvas; X, Y: Integer; Color: TColor);
  149. procedure DrawMaximizeImage(C: TCanvas; X, Y: Integer; Color: TColor);
  150. procedure DrawRollUpImage(C: TCanvas; X, Y: Integer; Color: TColor);
  151. procedure DrawRestoreRollUpImage(C: TCanvas; X, Y: Integer; Color: TColor);
  152. procedure DrawRestoreImage(C: TCanvas; X, Y: Integer; Color: TColor);
  153. procedure DrawSysMenuImage(C: TCanvas; X, Y: Integer; Color: TColor);
  154. procedure DrawMTImage(C: TCanvas; X, Y: Integer; Color: TColor);
  155. function ExtractDay(ADate: TDateTime): Word;
  156. function ExtractMonth(ADate: TDateTime): Word;
  157. function ExtractYear(ADate: TDateTime): Word;
  158. function IsLeapYear(AYear: Integer): Boolean;
  159. function DaysPerMonth(AYear, AMonth: Integer): Integer;
  160. function ReplaceStr(const S, Srch, Replace: string): string;
  161. function Max(A, B: Longint): Longint;
  162. function Min(A, B: Longint): Longint;
  163. procedure CorrectTextbyWidth(C: TCanvas; var S: String; W: Integer);
  164. procedure GetParentImage(Control: TControl; Dest: TCanvas);
  165. function GetMonitorWorkArea(const W: HWND; const WorkArea: Boolean): TRect;
  166. function GetPrimaryMonitorWorkArea(const WorkArea: Boolean): TRect;
  167. implementation
  168. uses Forms, Consts;
  169. const
  170.   LWA_ALPHA = $2;
  171. type
  172.   TParentControl = class(TWinControl);
  173. procedure GetParentImage(Control: TControl; Dest: TCanvas);
  174. var
  175.   I, Count, X, Y, SaveIndex: Integer;
  176.   DC: HDC;
  177.   R, SelfR, CtlR: TRect;
  178.   Ctrl: TControl;
  179. begin
  180.   if Control.Parent = nil then Exit;
  181.   Count := Control.Parent.ControlCount;
  182.   DC := Dest.Handle;
  183.   SelfR := Bounds(Control.Left, Control.Top, Control.Width, Control.Height);
  184.   X := -Control.Left; Y := -Control.Top;
  185.   // Copy parent control image
  186.   if Control.Parent is TForm
  187.   then
  188.     begin
  189.       SaveIndex := SaveDC(DC);
  190.       SetViewportOrgEx(DC, X, Y, nil);
  191.       IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth,
  192.          Control.Parent.ClientHeight);
  193.       SendMessage(Control.Parent.Handle, WM_ERASEBKGND, DC, 0);
  194.       RestoreDC(DC, SaveIndex);
  195.     end
  196.   else
  197.     begin
  198.       SaveIndex := SaveDC(DC);
  199.       SetViewportOrgEx(DC, X, Y, nil);
  200.       IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth,
  201.       Control.Parent.ClientHeight);
  202.       TParentControl(Control.Parent).PaintWindow(DC);
  203.       SendMessage(Control.Parent.Handle, WM_ERASEBKGND, DC, 0);
  204.       RestoreDC(DC, SaveIndex);
  205.     end;
  206. end;
  207. procedure CorrectTextbyWidth(C: TCanvas; var S: String; W: Integer);
  208. var
  209.   j: Integer;
  210. begin
  211.   j := Length(S);
  212.   with C do
  213.   begin
  214.     if TextWidth(S) > w
  215.     then
  216.       begin
  217.         repeat
  218.           Delete(S, j, 1);
  219.           Dec(j);
  220.         until (TextWidth(S + '...') <= w) or (S = '');
  221.         S := S + '...';
  222.       end;
  223.   end;
  224. end;
  225. function Max(A, B: Longint): Longint;
  226. begin
  227.   if A > B then Result := A
  228.   else Result := B;
  229. end;
  230. function Min(A, B: Longint): Longint;
  231. begin
  232.   if A < B then Result := A
  233.   else Result := B;
  234. end;
  235. function ReplaceStr(const S, Srch, Replace: string): string;
  236. var
  237.   I: Integer;
  238.   Source: string;
  239. begin
  240.   Source := S;
  241.   Result := '';
  242.   repeat
  243.     I := Pos(Srch, Source);
  244.     if I > 0 then begin
  245.       Result := Result + Copy(Source, 1, I - 1) + Replace;
  246.       Source := Copy(Source, I + Length(Srch), MaxInt);
  247.     end
  248.     else Result := Result + Source;
  249.   until I <= 0;
  250. end;
  251. procedure BSDrawText(Cnvs: TCanvas; S: String; R: TRect);
  252. begin
  253.   DrawText(Cnvs.Handle, PChar(S), Length(S), R,
  254.     DT_VCENTER or DT_SINGLELINE or DT_LEFT);
  255. end;
  256. procedure BSDrawText2(Cnvs: TCanvas; S: String; R: TRect);
  257. var
  258.   TX, TY: Integer;
  259. begin
  260.   TX := R.Left + 2;
  261.   TY := R.Top + RectHeight(R) div 2 - Cnvs.TextHeight(S) div 2;
  262.   Cnvs.TextRect(R, TX, TY, S);
  263. end;
  264. procedure BSDrawText3(Cnvs: TCanvas; S: String; R: TRect; HorOffset: Integer);
  265. var
  266.   TX, TY: Integer;
  267. begin
  268.   TX := R.Left + 2 + HorOffset;
  269.   TY := R.Top + RectHeight(R) div 2 - Cnvs.TextHeight(S) div 2;
  270.   Cnvs.TextRect(R, TX, TY, S);
  271. end;
  272. procedure DrawTrackArrowImage(Cnvs: TCanvas; R: TRect; Color: TColor);
  273. var
  274.   X, Y, i: Integer;
  275. begin
  276.   X := R.Left + RectWidth(R) div 2;
  277.   Y := R.Top + RectHeight(R) div 2 + 2;
  278.   for i := 2 downto 0 do
  279.   with Cnvs do
  280.   begin
  281.     Pen.Color := Color;
  282.     MoveTo(X - i, Y - i);
  283.     LineTo(X + i + 1, Y - i);
  284.   end;
  285. end;
  286. procedure DrawArrowImage(Cnvs: TCanvas; R: TRect; Color: TColor; Code: Integer);
  287. var
  288.   i: Integer;
  289.   X, Y: Integer;
  290. begin
  291.   with Cnvs do
  292.   begin
  293.     Pen.Color := Color;
  294.     case Code of
  295.       1:
  296.         begin
  297.           X := R.Left + RectWidth(R) div 2 - 2;
  298.           Y := R.Top + RectHeight(R) div 2;
  299.           for i := 0 to 3 do
  300.           begin
  301.             MoveTo(X + i, Y - i);
  302.             LineTo(X + i, Y + i + 1);
  303.           end;
  304.         end;
  305.       2:
  306.         begin
  307.           X := R.Left + RectWidth(R) div 2 + 2;
  308.           Y := R.Top + RectHeight(R) div 2;
  309.           for i := 3 downto 0 do
  310.            begin
  311.              MoveTo(X - i, Y + i);
  312.              LineTo(X - i, Y - i - 1);
  313.            end;
  314.         end;
  315.       3:
  316.         begin
  317.           X := R.Left + RectWidth(R) div 2;
  318.           Y := R.Top + RectHeight(R) div 2 - 2;
  319.           for i := 0 to 3 do
  320.           begin
  321.             MoveTo(X - i, Y + i);
  322.             LineTo(X + i + 1, Y + i);
  323.           end;
  324.         end;
  325.       4:
  326.         begin
  327.           X := R.Left + RectWidth(R) div 2;
  328.           Y := R.Top + RectHeight(R) div 2 + 2;
  329.           for i := 3 downto 0 do
  330.           begin
  331.             MoveTo(X - i, Y - i);
  332.             LineTo(X + i + 1, Y - i);
  333.           end;  
  334.         end;
  335.     end;
  336.   end;
  337. end;
  338. procedure DrawRadioImage(Cnvs: TCanvas; X, Y: Integer; Color: TColor);
  339. begin
  340.   with Cnvs do
  341.   begin
  342.     Pen.Color := Color;
  343.     Brush.Color := Color;
  344.     Rectangle(X, Y, X + 6, Y + 6);
  345.   end;
  346. end;
  347. procedure DrawCheckImage(Cnvs: TCanvas; X, Y: Integer; Color: TColor);
  348. var
  349.   i: Integer;
  350. begin
  351.   with Cnvs do
  352.   begin
  353.     Pen.Color := Color;
  354.     for i := 0 to 2 do
  355.     begin
  356.       MoveTo(X, Y + 5 - i);
  357.       LineTo(X + 2, Y + 7 - i);
  358.       LineTo(X + 7, Y + 2 - i);
  359.     end;
  360.   end;
  361. end;
  362. procedure Frm3D;
  363.   procedure DoRect;
  364.   var
  365.     TopRight, BottomLeft: TPoint;
  366.   begin
  367.     with Canvas, Rect do
  368.     begin
  369.       TopRight.X := Right;
  370.       TopRight.Y := Top;
  371.       BottomLeft.X := Left;
  372.       BottomLeft.Y := Bottom;
  373.       Pen.Color := TopColor;
  374.       PolyLine([BottomLeft, TopLeft, TopRight]);
  375.       Pen.Color := BottomColor;
  376.       Dec(BottomLeft.X);
  377.       PolyLine([TopRight, BottomRight, BottomLeft]);
  378.     end;
  379.   end;
  380. begin
  381.   Canvas.Pen.Width := 1;
  382.   Dec(Rect.Bottom); Dec(Rect.Right);
  383.   DoRect;
  384. end;
  385. procedure GetWindowsVersion(var Major, Minor: Integer);
  386. var
  387.   Ver : Longint;
  388. begin
  389.   Ver := GetVersion;
  390.   Major := LoByte(LoWord(Ver));
  391.   Minor := HiByte(LoWord(Ver));
  392. end;
  393. function CheckWXP: Boolean;
  394. var
  395.   Major, Minor : Integer;
  396. begin
  397.   GetWindowsVersion(major, minor);
  398.   Result := (major = 5) and (minor = 1);
  399. end;
  400. function CheckW2kWXP: Boolean;
  401. var
  402.   Major, Minor : Integer;
  403. begin
  404.   GetWindowsVersion(major, minor);
  405.   Result := (major = 5) and ((minor = 0) or (minor = 1) or (minor = 2));
  406. end;
  407. procedure SetAlphaBlendTransparent;
  408. var
  409.   User32: Cardinal;
  410.   SetLayeredWindowAttributes: function (hwnd: LongInt; crKey: byte; bAlpha: byte; dwFlags: LongInt): LongInt; stdcall;
  411. begin
  412.   User32 := LoadLibrary('USER32');
  413.   if User32 <> 0
  414.   then
  415.     try
  416.      SetLayeredWindowAttributes := GetProcAddress(User32, 'SetLayeredWindowAttributes');
  417.      if @SetLayeredWindowAttributes <> nil
  418.      then
  419.        SetLayeredWindowAttributes(WHandle, 0, Value, LWA_ALPHA);
  420.      finally
  421.         FreeLibrary(User32);
  422.      end;
  423. end;
  424. procedure GetScreenImage(X, Y: Integer; B: TBitMap);
  425. var
  426.   DC: HDC;
  427. begin
  428.   DC := GetDC(0);
  429.   BitBlt(B.Canvas.Handle, 0, 0,
  430.          B.Width, B.Height, DC, X, Y, SrcCopy);
  431.   ReleaseDC(0, DC);
  432. end;
  433. function EqRects(R1, R2: TRect): Boolean;
  434. begin
  435.   Result := (R1.Left = R2.Left) and (R1.Top = R2.Top) and
  436.             (R1.Right = R2.Right) and (R1.Bottom = R2.Bottom);
  437. end;
  438. function NullRect: TRect;
  439. begin
  440.   Result := Rect(0, 0, 0, 0);
  441. end;
  442. function IsNullRect(R: TRect): Boolean;
  443. begin
  444.   Result := (R.Right - R.Left <= 0) or (R.Bottom - R.Top <= 0)
  445. end;
  446. function IsNullPoint(P: TPoint): Boolean;
  447. begin
  448.   Result := (P.X = 0) or (P.Y = 0);
  449. end;
  450. function PointInRect(R: TRect; P: TPoint): Boolean;
  451. begin
  452.   Result := (P.X >= R.Left) and (P.Y >= R.Top) and
  453.             (P.X <= R.Right) and (P.Y <= R.Bottom);
  454. end;
  455. function RectInRect(R1, R2: TRect): Boolean;
  456. begin
  457.   Result := PtInRect(R2, R1.TopLeft) and PtInRect(R2, R1.BottomRight)
  458. end;
  459. function RectToCenter(var R: TRect; Bounds: TRect): TRect;
  460. begin
  461.   OffsetRect(R, -R.Left, -R.Top);
  462.   OffsetRect(R, (RectWidth(Bounds) - RectWidth(R)) div 2, (RectHeight(Bounds) - RectHeight(R)) div 2);
  463.   OffsetRect(R, Bounds.Left, Bounds.Top);
  464.   Result := R;
  465. end;
  466. function RectWidth;
  467. begin
  468.   Result := R.Right - R.Left;
  469. end;
  470. function RectHeight;
  471. begin
  472.   Result := R.Bottom - R.Top;
  473. end;
  474. const
  475.     nums = '1234567890';
  476.     symbols = ', ';
  477. function GetPoint(S: String): TPoint;
  478. var
  479.   i, j: Integer;
  480.   S1: String;
  481.   SA: array[1..2] of String;
  482. begin
  483.   S1 := '';
  484.   j := 1;
  485.   for i := 1 to Length(S) do
  486.   begin
  487.     if S[i] = ','
  488.     then
  489.       begin
  490.         SA[j] := S1;
  491.         S1 := '';
  492.         Inc(j);
  493.       end
  494.     else
  495.       if Pos(S[i], nums) <> 0 then S1 := S1 + S[i];
  496.   end;
  497.   SA[j] := S1;
  498.   Result := Point(StrToInt(SA[1]), StrToInt(SA[2]));;
  499. end;
  500. function GetRect(S: String): TRect;
  501. var
  502.   i, j: Integer;
  503.   S1: String;
  504.   SA: array[1..4] of String;
  505. begin
  506.   S1 := '';
  507.   j := 1;
  508.   for i := 1 to Length(S) do
  509.   begin
  510.     if S[i] = ','
  511.     then
  512.       begin
  513.         SA[j] := S1;
  514.         S1 := '';
  515.         Inc(j);
  516.       end
  517.     else
  518.       if Pos(S[i], nums) <> 0 then S1 := S1 + S[i];
  519.   end;
  520.   SA[j] := S1;
  521.   Result := Rect(StrToInt(SA[1]), StrToInt(SA[2]),
  522.                  StrToInt(SA[3]), StrToInt(SA[4]));
  523. end;
  524. function SetRect(R: TRect): String;
  525. begin
  526.   Result := IntToStr(R.Left) + ',' +
  527.     IntToStr(R.Top) + ',' + IntToStr(R.Right) + ',' +
  528.     IntToStr(R.Bottom);
  529. end;
  530. function ReadRect;
  531. var
  532.   S: String;
  533. begin
  534.   S := IniFile.ReadString(Section, Ident, '0,0,0,0');
  535.   Result := GetRect(S);
  536. end;
  537. function ReadPoint;
  538. var
  539.   S: String;
  540. begin
  541.   S := IniFile.ReadString(Section, Ident, '0,0');
  542.   Result := GetPoint(S);
  543. end;
  544. function ReadBoolean;
  545. var
  546.   I: Integer;
  547. begin
  548.   I := IniFile.ReadInteger(Section, Ident, 0);
  549.   Result := I = 1;
  550. end;
  551. function ReadFontStyles;
  552. var
  553.   FS: TFontStyles;
  554.   S: String;
  555. begin
  556.   S := IniFile.ReadString(Section, Ident, '');
  557.   FS := [];
  558.   if Pos('fsbold', S) <> 0 then FS := FS + [fsBold];
  559.   if Pos('fsitalic', S) <> 0 then FS := FS + [fsItalic];
  560.   if Pos('fsunderline', S) <> 0 then FS := FS + [fsUnderline];
  561.   if Pos('fsstrikeout', S) <> 0 then FS := FS + [fsStrikeOut];
  562.   Result := FS;
  563. end;
  564. procedure ReadStrings;
  565. var
  566.   Count, i: Integer;
  567. begin
  568.   Count := IniFile.ReadInteger(Section, Ident + 'linecount', 0);
  569.   for i := 0 to Count - 1 do
  570.     S.Add(IniFile.ReadString(Section, Ident + 'line' + IntToStr(i), ''));
  571. end;
  572. procedure ReadStrings1;
  573. var
  574.   Count, i: Integer;
  575. begin
  576.   Count := IniFile.ReadInteger(Section, Ident + 'count', 0);
  577.   for i := 0 to Count - 1 do
  578.     S.Add(IniFile.ReadString(Section, IntToStr(i), ''));
  579. end;
  580. procedure WriteRect;
  581. var
  582.   S: String;
  583. begin
  584.   S := IntToStr(R.Left) + ',' + IntToStr(R.Top) + ',' +
  585.        IntToStr(R.Right) + ',' + IntToStr(R.Bottom);
  586.   IniFile.WriteString(Section, Ident, S);
  587. end;
  588. procedure WritePoint;
  589. var
  590.   S: String;
  591. begin
  592.   S := IntToStr(P.X) + ',' + IntToStr(P.Y);
  593.   IniFile.WriteString(Section, Ident, S);
  594. end;
  595. procedure WriteBoolean;
  596. var
  597.   I: Integer;
  598. begin
  599.   if B then I := 1 else I := 0;
  600.   IniFile.WriteInteger(Section, Ident, I);
  601. end;
  602. procedure WriteFontStyles;
  603. var
  604.   S: String;
  605. begin
  606.   S := '';
  607.   if fsBold in FS then S := S + 'fsbold';
  608.   if fsItalic in FS
  609.   then
  610.     begin
  611.       if Length(S) > 0 then S := S + ',';
  612.       S := S + 'fsitalic';
  613.     end;
  614.   if fsUnderline in FS
  615.   then
  616.     begin
  617.       if Length(S) > 0 then S := S + ',';
  618.       S := S + 'fsunderline';
  619.     end;
  620.   if fsStrikeOut in FS
  621.   then
  622.     begin
  623.       if Length(S) > 0 then S := S + ',';
  624.       S := S + 'fsstrikeout';
  625.     end;
  626.   IniFile.WriteString(Section, Ident, S);
  627. end;
  628. procedure WriteStrings;
  629. var
  630.   i: Integer;
  631. begin
  632.   IniFile.WriteInteger(Section, Ident + 'linecount', S.Count);
  633.   for i := 0 to S.Count - 1 do
  634.     IniFile.WriteString(Section, Ident + 'line' + IntToStr(i), S[i]);
  635. end;
  636. procedure WriteStrings1;
  637. var
  638.   i: Integer;
  639. begin
  640.   IniFile.WriteInteger(Section, Ident + 'count', S.Count);
  641.   for i := 0 to S.Count - 1 do
  642.     IniFile.WriteString(Section, IntToStr(i), S[i]);
  643. end;
  644. function ReadAlignment;
  645. var
  646.   S: String;
  647. begin
  648.   S := IniFile.ReadString(Section, Ident, 'tacenter');
  649.   if S = 'tacenter' then Result := taCenter else
  650.   if S = 'taleftjustify' then Result := taLeftJustify else
  651.   Result := taRightJustify;
  652. end;
  653. procedure WriteAlignment;
  654. var
  655.   S: String;
  656. begin
  657.   if A = taCenter then S := 'tacenter' else
  658.   if A = taLeftJustify then S := 'taleftjustify' else
  659.   S := 'tarightjustify';
  660.   IniFile.WriteString(Section, Ident, S);
  661. end;
  662. { TbsFBitmap }
  663. constructor TbsFBitmap.Create(HBmp:Integer);
  664. var
  665.   Bmp:   Windows.TBITMAP;
  666.   memDC: Integer;
  667. begin
  668.   GetObject(hBmp,SizeOf(Bmp),@Bmp);
  669.   Width:=Bmp.bmWidth;
  670.   Height:=Bmp.bmHeight;
  671.   Size:=((Width*3)+(Width mod 4))*Height;
  672.   with bmHeader do
  673.   begin
  674.     biSize:=SizeOf(bmHeader);
  675.     biWidth:=Width;
  676.     biHeight:=-Height;
  677.     biPlanes:=1;
  678.     biBitCount:=24;
  679.     biCompression:=BI_RGB;
  680.   end;
  681.   bmInfo.bmiHeader:=bmHeader;
  682.   Handle:=CreateDIBSection(0,
  683.                  bmInfo,
  684.                  DIB_RGB_COLORS,
  685.                  Bits, 0, 0);
  686.   memDC:=GetDC(0);
  687.   GetDIBits(memDC,hBmp,0,Height,Bits,bmInfo,DIB_RGB_COLORS);
  688.   ReleaseDC(0,memDC);
  689.   Initialize;
  690. end;
  691. destructor TbsFBitmap.Destroy;
  692. begin
  693.   DeleteDC(hDC);
  694.   DeleteObject(Handle);
  695.   FreeMem(Pixels);
  696.   inherited;
  697. end;
  698. procedure TbsFBitmap.Initialize;
  699. var
  700.   x,i: Integer;
  701. begin
  702.   GetMem(Pixels,Height*SizeOf(PBLine));
  703.   RowInc:=(Width*3)+Width mod 4;
  704.   Gap:=Width mod 4;
  705.   Size:=RowInc*Height;
  706.   x:=Integer(Bits);
  707.   for i:=0 to Height-1 do
  708.   begin
  709.     Pixels[i]:=Pointer(x);
  710.     Inc(x,RowInc);
  711.   end;
  712.   hDC:=CreateCompatibleDC(0);
  713.   SelectObject(hDC,Handle);
  714. end;
  715. // Region convert
  716. function CreateRgnFromBmp(B: TBitmap; XO, YO: Integer; var RgnData: PRgnData): integer;
  717. const
  718.   max = 10000;
  719. var
  720.   j, i, i1: integer;
  721.   C: TFBColor;
  722.   FB: TbsFBitmap;
  723.   Rts: array [0..max] of TRect;
  724.   Count: integer;
  725. begin
  726.   Result := 0;
  727.   If B.Empty Then Exit;
  728.   Count := 0;
  729.   FB := TbsFBitmap.Create(B.Handle);
  730.   for j := 0 to FB.Height - 1 do
  731.   begin
  732.     i := 0;
  733.     while i < FB.Width do
  734.     begin
  735.       C := FB.Pixels[j, i];
  736.       If C.R + C.G + C.B = 0 Then
  737.       begin
  738.         i1 := i;
  739.         C := FB.Pixels[j, i1];
  740.         while C.R + C.G + C.B = 0 do
  741.         begin
  742.           Inc(i1);
  743.           If i1 > FB.Width - 1 Then Break else C := FB.Pixels[j, i1];
  744.         end;
  745.         Rts[Count] := Rect(i + XO, j + YO, i1 + XO, j + 1 + YO);
  746.         Inc(Count);
  747.         i := i1;
  748.         Continue;
  749.       end;
  750.       Inc(i);
  751.     end;
  752.   end;
  753.   FB.Free;
  754.   // Make Region data
  755.   Result := Count*SizeOf(TRect);
  756.   GetMem(Rgndata, SizeOf(TRgnDataHeader)+Result);
  757.   FillChar(Rgndata^, SizeOf(TRgnDataHeader)+Result, 0);
  758.   RgnData^.rdh.dwSize := SizeOf(TRgnDataHeader);
  759.   RgnData^.rdh.iType := RDH_RECTANGLES;
  760.   RgnData^.rdh.nCount := Count;
  761.   RgnData^.rdh.nRgnSize := 0;
  762.   RgnData^.rdh.rcBound := Rect(0 + XO, 0 + YO, B.Width + XO, B.Height + YO);
  763.   // Update New Region
  764.   Move(Rts, RgnData^.Buffer, Result);
  765.   Result := SizeOf(TRgnDataHeader)+Count*SizeOf(TRect);
  766. end;
  767. procedure WriteStringToStream(Str: String; S: TStream);
  768. var
  769.   L: Integer;
  770. begin
  771.   L := Length(Str);
  772.   S.Write(L, SizeOf(Integer));
  773.   S.Write(Pointer(Str)^, L);
  774. end;
  775. procedure ReadStringFromStream(var Str: String; S: TStream);
  776. var
  777.   L: Integer;
  778. begin
  779.   L := 0;
  780.   S.Read(L, SizeOf(Integer));
  781.   SetLength(Str, L);
  782.   S.Read(Pointer(Str)^, L);
  783. end;
  784. procedure CreateHSkinImage;
  785. var
  786.   X, XCnt, w, XO: Integer;
  787. begin
  788.   B.Width := AW;
  789.   B.Height := RectHeight(R);
  790.   with B.Canvas do
  791.   begin
  792.     if LO <> 0 then
  793.        CopyRect(Rect(0, 0, LO, B.Height), SB.Canvas,
  794.                 Rect(R.Left, R.Top, R.Left + LO, R.Bottom));
  795.     if RO <> 0 then
  796.        CopyRect(Rect(B.Width - RO, 0, B.Width, B.Height),
  797.                 SB.Canvas,
  798.                 Rect(R.Right - RO, R.Top, R.Right, R.Bottom));
  799.     Inc(R.Left, LO);
  800.     Dec(R.Right, RO);
  801.     w := RectWidth(R);
  802.     if w = 0 then w := 1;
  803.     XCnt := (B.Width - LO - RO) div w;
  804.     for X := 0 to XCnt do
  805.     begin
  806.       if LO + X * w + w > B.Width - RO
  807.       then XO := LO + X * w + w - (B.Width - RO)
  808.       else XO := 0;
  809.       B.Canvas.CopyRect(Rect(LO + X * w, 0, LO + X * w + w - XO,
  810.                         B.Height),
  811.                         SB.Canvas,
  812.                         Rect(R.Left, R.Top, R.Right - XO, R.Bottom));
  813.     end;
  814.   end;
  815. end;
  816. procedure CreateHSkinImage2;
  817. var
  818.   X, XCnt, w, XO: Integer;
  819. begin
  820.   B.Width := AW;
  821.   B.Height := RectHeight(R);
  822.   with B.Canvas do
  823.   begin
  824.     if LO <> 0 then
  825.        CopyRect(Rect(0, 0, LO, B.Height), SB.Canvas,
  826.                 Rect(R.Left, R.Top, R.Left + LO, R.Bottom));
  827.     Inc(R.Left, LO);
  828.     Dec(R.Right, RO);
  829.     w := RectWidth(R);
  830.     if w = 0 then w := 1;
  831.     XCnt := (B.Width - LO) div w;
  832.     for X := 0 to XCnt do
  833.     begin
  834.       if LO + X * w + w > B.Width
  835.       then XO := LO + X * w + w - B.Width
  836.       else XO := 0;
  837.       B.Canvas.CopyRect(Rect(LO + X * w, 0, LO + X * w + w - XO,
  838.                         B.Height),
  839.                         SB.Canvas,
  840.                         Rect(R.Left, R.Top, R.Right - XO, R.Bottom));
  841.     end;
  842.   end;
  843. end;
  844. procedure CreateHSkinImage3;
  845. var
  846.   X, XCnt, w, XO: Integer;
  847. begin
  848.   B.Width := AW;
  849.   B.Height := RectHeight(R);
  850.   with B.Canvas do
  851.   begin
  852.     Inc(R.Left, LO);
  853.     Dec(R.Right, RO);
  854.     w := RectWidth(R);
  855.     if w = 0 then w := 1;
  856.     XCnt := B.Width div w;
  857.     for X := 0 to XCnt do
  858.     begin
  859.       if LO + X * w + w > B.Width
  860.       then XO := LO + X * w + w - B.Width
  861.       else XO := 0;
  862.       B.Canvas.CopyRect(Rect(X * w, 0, X * w + w - XO,
  863.                         B.Height),
  864.                         SB.Canvas,
  865.                         Rect(R.Left, R.Top, R.Right - XO, R.Bottom));
  866.     end;
  867.   end;
  868. end;
  869. procedure CreateVSkinImage;
  870. var
  871.   Y, YCnt, h, YO: Integer;
  872. begin
  873.   B.Width := RectWidth(R);
  874.   B.Height := AH;
  875.   with B.Canvas do
  876.   begin
  877.     if TpO <> 0 then
  878.        CopyRect(Rect(0, 0, B.Width, TpO), SB.Canvas,
  879.                 Rect(R.Left, R.Top, R.Right, R.Top + TpO));
  880.     if BO <> 0 then
  881.        CopyRect(Rect(0, B.Height - BO, B.Width, B.Height),
  882.                 SB.Canvas,
  883.                 Rect(R.Left, R.Bottom - BO, R.Right, R.Bottom));
  884.     Inc(R.Top, TpO);
  885.     Dec(R.Bottom, BO);
  886.     h := RectHeight(R);
  887.     if H <> 0
  888.     then 
  889.       YCnt := (B.Height - TpO - BO) div h
  890.     else
  891.       YCnt := 0;
  892.     for Y := 0 to YCnt do
  893.     begin
  894.       if TpO + Y * h + h > B.Height - BO
  895.       then YO := TpO + Y * h + h - (B.Height - BO)
  896.       else YO := 0;
  897.       B.Canvas.CopyRect(
  898.         Rect(0, TpO + Y * h, B.Width, TpO + Y * h + h - YO),
  899.         SB.Canvas,
  900.         Rect(R.Left, R.Top, R.Right, R.Bottom - YO));
  901.     end;
  902.   end;
  903. end;
  904. procedure CreateSkinImageBS;
  905. var
  906.   w, h, rw, rh: Integer;
  907.   X, Y, XCnt, YCnt: Integer;
  908.   XO, YO: Integer;
  909.   Rct, SRct: TRect;
  910.   Buffer: TBitMap;
  911. begin
  912.   B.Width := AW;
  913.   B.Height := AH;
  914.   if (RBPt.X - LTPt.X  = 0) or
  915.      (RBPt.Y - LTPt.Y = 0) or SB.Empty then  Exit;
  916.   with B.Canvas do
  917.   begin
  918.     // Draw lines
  919.     // top
  920.     if not TS
  921.     then
  922.       begin
  923.         w := RTPt.X - LTPt.X;
  924.         XCnt := (NewRTPt.X - NewLTPt.X) div (RTPt.X - LTPt.X);
  925.         for X := 0 to XCnt do
  926.         begin
  927.           if NewLTPt.X + X * w + w > NewRTPt.X
  928.           then XO := NewLTPt.X + X * w + w - NewRTPt.X else XO := 0;
  929.           CopyRect(Rect(NewLTPt.X + X * w, 0, NewLTPt.X + X * w + w - XO, NewClRect.Top),
  930.                SB.Canvas, Rect(R.Left + LTPt.X, R.Top,
  931.                  R.Left + RTPt.X - XO, R.Top + ClRect.Top));
  932.         end;
  933.       end
  934.     else
  935.       begin
  936.         Buffer := TBitMap.Create;
  937.         Buffer.Width := RTPt.X - LTPt.X;
  938.         Buffer.Height := CLRect.Top;
  939.         Rct := Rect(R.Left + LTPt.X, R.Top, R.Left + RTPt.X, R.Top + CLRect.Top);
  940.         Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),
  941.           SB.Canvas, Rct);
  942.         SRct := Rect(NewLTPt.X, 0, NewRTPt.X, NewCLRect.Top);
  943.         StretchDraw(SRct, Buffer);
  944.         Buffer.Free;
  945.       end;
  946.     // bottom
  947.     if not BS
  948.     then
  949.       begin
  950.         w := RBPt.X - LBPt.X;
  951.         XCnt := (NewRBPt.X - NewLBPt.X) div (RBPt.X - LBPt.X);
  952.         for X := 0 to XCnt do
  953.         begin
  954.          if NewLBPt.X + X * w + w > NewRBPt.X
  955.          then XO := NewLBPt.X + X * w + w - NewRBPt.X else XO := 0;
  956.            CopyRect(Rect(NewLBPt.X + X * w, NewClRect.Bottom, NewLBPt.X + X * w + w - XO, AH),
  957.                     SB.Canvas, Rect(R.Left + LBPt.X, R.Top + ClRect.Bottom,
  958.                      R.Left + RBPt.X - XO, R.Bottom));
  959.         end;             
  960.       end
  961.     else
  962.       begin
  963.         Buffer := TBitMap.Create;
  964.         Buffer.Width := RBPt.X - LBPt.X;
  965.         Buffer.Height := RectHeight(R) - CLRect.Bottom;
  966.         Rct := Rect(R.Left + LBPt.X, R.Top + ClRect.Bottom,
  967.                     R.Left + RBPt.X, R.Bottom);
  968.         Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),
  969.           SB.Canvas, Rct);
  970.         SRct := Rect(NewLBPt.X, NewCLRect.Bottom, NewRBPt.X, B.Height);
  971.         StretchDraw(SRct, Buffer);
  972.         Buffer.Free;
  973.       end;
  974.     // left
  975.     w := NewClRect.Left;
  976.     h := LBPt.Y - LTPt.Y;
  977.     if not LS
  978.     then
  979.       begin
  980.         YCnt := (NewLBPt.Y - NewLTPt.Y) div h;
  981.         for Y := 0 to YCnt do
  982.         begin
  983.           if NewLTPt.Y + Y * h + h > NewLBPt.Y
  984.           then YO := NewLTPt.Y + Y * h + h - NewLBPt.Y else YO := 0;
  985.           CopyRect(Rect(0, NewLTPt.Y + Y * h, w, NewLTPt.Y + Y * h + h - YO),
  986.                    SB.Canvas,
  987.                    Rect(R.Left, R.Top + LTPt.Y, R.Left + w, R.Top + LBPt.Y - YO));
  988.         end;
  989.       end
  990.     else
  991.       begin
  992.         Buffer := TBitMap.Create;
  993.         Buffer.Width := ClRect.Left;
  994.         Buffer.Height := LBPt.Y - LTPt.Y;
  995.         Rct := Rect(R.Left, R.Top + LTPt.Y,
  996.                     R.Left + CLRect.Left, R.Top + LBPt.Y);
  997.         Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),
  998.           SB.Canvas, Rct);
  999.         SRct := Rect(0, NewLTPt.Y, NewCLRect.Left, NewLBPt.Y);
  1000.         StretchDraw(SRct, Buffer);
  1001.         Buffer.Free;
  1002.       end;
  1003.     // right
  1004.     h := RBPt.Y - RTPt.Y;
  1005.     if not RS
  1006.     then
  1007.       begin
  1008.         YCnt := (NewRBPt.Y - NewRTPt.Y) div h;
  1009.         for Y := 0 to YCnt do
  1010.         begin
  1011.           if NewRTPt.Y + Y * h + h > NewRBPt.Y
  1012.           then YO := NewRTPt.Y + Y * h + h - NewRBPt.Y else YO := 0;
  1013.           CopyRect(Rect(NewClRect.Right, NewRTPt.Y + Y * h,
  1014.                     AW, NewRTPt.Y + Y * h + h - YO),
  1015.                    SB.Canvas,
  1016.                    Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,
  1017.                    R.Right, R.Top + RBPt.Y - YO));
  1018.         end;
  1019.       end
  1020.     else
  1021.       begin
  1022.         Buffer := TBitMap.Create;
  1023.         Buffer.Width := RectWidth(R) - ClRect.Right;
  1024.         Buffer.Height := RBPt.Y - RTPt.Y;
  1025.         Rct := Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,
  1026.                     R.Right, R.Top + RBPt.Y);
  1027.         Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),
  1028.           SB.Canvas, Rct);
  1029.         SRct := Rect(NewClRect.Right, NewRTPt.Y, B.Width, NewRBPt.Y);
  1030.         StretchDraw(SRct, Buffer);
  1031.         Buffer.Free;
  1032.       end;
  1033.     // Draw corners
  1034.     // lefttop
  1035.     CopyRect(Rect(0, 0, NewLTPt.X, NewClRect.Top),
  1036.              SB.Canvas, Rect(R.Left, R.Top,
  1037.                              R.Left + LTPt.X, R.Top + ClRect.Top));
  1038.     CopyRect(Rect(0, NewClRect.Top, NewClRect.Left, NewLTPt.Y),
  1039.              SB.Canvas, Rect(R.Left, R.Top + ClRect.Top,
  1040.                              R.Left + ClRect.left, R.Top + LTPT.Y));
  1041.     //topright
  1042.     CopyRect(Rect(NewRTPt.X, 0, AW, NewClRect.Top), SB.Canvas,
  1043.              Rect(R.Left + RTPt.X, R.Top,  R.Right, R.Top + ClRect.Top));
  1044.     CopyRect(Rect(NewClRect.Right, NewClRect.Top, AW, NewRTPt.Y), SB.Canvas,
  1045.              Rect(R.Left + ClRect.Right, R.Top + ClRect.Top,
  1046.              R.Right, R.Top + RTPt.Y));
  1047.     //leftbottom
  1048.     CopyRect(Rect(0, NewLBPt.Y, NewClRect.Left, AH), SB.Canvas,
  1049.              Rect(R.Left, R.Top + LBPt.Y, R.Left + ClRect.Left, R.Bottom));
  1050.     CopyRect(Rect(NewClRect.Left, NewClRect.Bottom, NewLBPt.X, AH), SB.Canvas,
  1051.              Rect(R.Left + ClRect.Left, R.Top + ClRect.Bottom, R.Left + LBPt.X, R.Bottom));
  1052.     //rightbottom
  1053.     CopyRect(Rect(NewRBPt.X, NewClRect.Bottom, AW, AH), SB.Canvas,
  1054.              Rect(R.Left + RBPt.X, R.Top + ClRect.Bottom, R.Right, R.Bottom));
  1055.     CopyRect(Rect(NewClRect.Right, NewRBPt.Y, AW, NewClRect.Bottom), SB.Canvas,
  1056.              Rect(R.Left + ClRect.Right, R.Top + RBPt.Y,
  1057.                   R.Right, R.Top + ClRect.Bottom));
  1058.     //Draw client
  1059.     w := RectWidth(ClRect);
  1060.     h := RectHeight(ClRect);
  1061.     rw := RectWidth(NewClRect);
  1062.     rh := RectHeight(NewClRect);
  1063.     if DrawClient
  1064.     then
  1065.       begin
  1066.         // Draw client area
  1067.         XCnt := rw div w;
  1068.         YCnt := rh div h;
  1069.         for X := 0 to XCnt do
  1070.         for Y := 0 to YCnt do
  1071.         begin
  1072.           if X * w + w > rw then XO := X * W + W - rw else XO := 0;
  1073.           if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  1074.           CopyRect(Rect(NewClRect.Left + X * w, NewClRect.Top + Y * h,
  1075.              NewClRect.Left + X * w + w - XO,
  1076.              NewClRect.Top + Y * h + h - YO),
  1077.              SB.Canvas,
  1078.              Rect(R.Left + ClRect.Left, R.Top + ClRect.Top,
  1079.              R.Left + ClRect.Right - XO,
  1080.              R.Top + ClRect.Bottom - YO));
  1081.          end;
  1082.     end;
  1083.   end;
  1084. end;
  1085. procedure CreateSkinImage;
  1086. var
  1087.   w, h, rw, rh: Integer;
  1088.   X, Y, XCnt, YCnt: Integer;
  1089.   XO, YO: Integer;
  1090. begin
  1091.   B.Width := AW;
  1092.   B.Height := AH;
  1093.   if (RBPt.X - LTPt.X  = 0) or
  1094.      (RBPt.Y - LTPt.Y = 0) or SB.Empty then  Exit;
  1095.   with B.Canvas do
  1096.   begin
  1097.     // Draw lines
  1098.     // top
  1099.     w := RTPt.X - LTPt.X;
  1100.     XCnt := (NewRTPt.X - NewLTPt.X) div (RTPt.X - LTPt.X);
  1101.     for X := 0 to XCnt do
  1102.     begin
  1103.       if NewLTPt.X + X * w + w > NewRTPt.X
  1104.       then XO := NewLTPt.X + X * w + w - NewRTPt.X else XO := 0;
  1105.       CopyRect(Rect(NewLTPt.X + X * w, 0, NewLTPt.X + X * w + w - XO, NewClRect.Top),
  1106.                SB.Canvas, Rect(R.Left + LTPt.X, R.Top,
  1107.                  R.Left + RTPt.X - XO, R.Top + ClRect.Top));
  1108.     end;
  1109.     // bottom
  1110.     w := RBPt.X - LBPt.X;
  1111.     XCnt := (NewRBPt.X - NewLBPt.X) div (RBPt.X - LBPt.X);
  1112.     for X := 0 to XCnt do
  1113.     begin
  1114.       if NewLBPt.X + X * w + w > NewRBPt.X
  1115.       then XO := NewLBPt.X + X * w + w - NewRBPt.X else XO := 0;
  1116.       CopyRect(Rect(NewLBPt.X + X * w, NewClRect.Bottom, NewLBPt.X + X * w + w - XO, AH),
  1117.                SB.Canvas, Rect(R.Left + LBPt.X, R.Top + ClRect.Bottom,
  1118.                  R.Left + RBPt.X - XO, R.Bottom));
  1119.     end;
  1120.     // left
  1121.     w := NewClRect.Left;
  1122.     h := LBPt.Y - LTPt.Y;
  1123.     YCnt := (NewLBPt.Y - NewLTPt.Y) div h;
  1124.     for Y := 0 to YCnt do
  1125.     begin
  1126.       if NewLTPt.Y + Y * h + h > NewLBPt.Y
  1127.       then YO := NewLTPt.Y + Y * h + h - NewLBPt.Y else YO := 0;
  1128.       CopyRect(Rect(0, NewLTPt.Y + Y * h, w, NewLTPt.Y + Y * h + h - YO),
  1129.                SB.Canvas,
  1130.                Rect(R.Left, R.Top + LTPt.Y, R.Left + w, R.Top + LBPt.Y - YO));
  1131.     end;
  1132.     // right
  1133.     h := RBPt.Y - RTPt.Y;
  1134.     YCnt := (NewRBPt.Y - NewRTPt.Y) div h;
  1135.     for Y := 0 to YCnt do
  1136.     begin
  1137.       if NewRTPt.Y + Y * h + h > NewRBPt.Y
  1138.       then YO := NewRTPt.Y + Y * h + h - NewRBPt.Y else YO := 0;
  1139.       CopyRect(Rect(NewClRect.Right, NewRTPt.Y + Y * h,
  1140.                     AW, NewRTPt.Y + Y * h + h - YO),
  1141.                SB.Canvas,
  1142.                Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,
  1143.                  R.Right, R.Top + RBPt.Y - YO));
  1144.     end;
  1145.     // Draw corners
  1146.     // lefttop
  1147.     CopyRect(Rect(0, 0, NewLTPt.X, NewClRect.Top),
  1148.              SB.Canvas, Rect(R.Left, R.Top,
  1149.                              R.Left + LTPt.X, R.Top + ClRect.Top));
  1150.     CopyRect(Rect(0, NewClRect.Top, NewClRect.Left, NewLTPt.Y),
  1151.              SB.Canvas, Rect(R.Left, R.Top + ClRect.Top,
  1152.                              R.Left + ClRect.left, R.Top + LTPT.Y));
  1153.     //topright
  1154.     CopyRect(Rect(NewRTPt.X, 0, AW, NewClRect.Top), SB.Canvas,
  1155.              Rect(R.Left + RTPt.X, R.Top,  R.Right, R.Top + ClRect.Top));
  1156.     CopyRect(Rect(NewClRect.Right, NewClRect.Top, AW, NewRTPt.Y), SB.Canvas,
  1157.              Rect(R.Left + ClRect.Right, R.Top + ClRect.Top,
  1158.              R.Right, R.Top + RTPt.Y));
  1159.     //leftbottom
  1160.     CopyRect(Rect(0, NewLBPt.Y, NewClRect.Left, AH), SB.Canvas,
  1161.              Rect(R.Left, R.Top + LBPt.Y, R.Left + ClRect.Left, R.Bottom));
  1162.     CopyRect(Rect(NewClRect.Left, NewClRect.Bottom, NewLBPt.X, AH), SB.Canvas,
  1163.              Rect(R.Left + ClRect.Left, R.Top + ClRect.Bottom, R.Left + LBPt.X, R.Bottom));
  1164.     //rightbottom
  1165.     CopyRect(Rect(NewRBPt.X, NewClRect.Bottom, AW, AH), SB.Canvas,
  1166.              Rect(R.Left + RBPt.X, R.Top + ClRect.Bottom, R.Right, R.Bottom));
  1167.     CopyRect(Rect(NewClRect.Right, NewRBPt.Y, AW, NewClRect.Bottom), SB.Canvas,
  1168.              Rect(R.Left + ClRect.Right, R.Top + RBPt.Y,
  1169.                   R.Right, R.Top + ClRect.Bottom));
  1170.     //Draw client
  1171.     w := RectWidth(ClRect);
  1172.     h := RectHeight(ClRect);
  1173.     rw := RectWidth(NewClRect);
  1174.     rh := RectHeight(NewClRect);
  1175.     if DrawClient
  1176.     then
  1177.       begin
  1178.         // Draw client area
  1179.         XCnt := rw div w;
  1180.         YCnt := rh div h;
  1181.         for X := 0 to XCnt do
  1182.         for Y := 0 to YCnt do
  1183.         begin
  1184.           if X * w + w > rw then XO := X * W + W - rw else XO := 0;
  1185.           if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  1186.           CopyRect(Rect(NewClRect.Left + X * w, NewClRect.Top + Y * h,
  1187.              NewClRect.Left + X * w + w - XO,
  1188.              NewClRect.Top + Y * h + h - YO),
  1189.              SB.Canvas,
  1190.              Rect(R.Left + ClRect.Left, R.Top + ClRect.Top,
  1191.              R.Left + ClRect.Right - XO,
  1192.              R.Top + ClRect.Bottom - YO));
  1193.          end;
  1194.     end;
  1195.   end;
  1196. end;
  1197. procedure CreateSkinImage2;
  1198. var
  1199.   w, h, rw, rh: Integer;
  1200.   X, Y, XCnt, YCnt: Integer;
  1201.   XO, YO: Integer;
  1202.   NCLRect: TRect;
  1203. begin
  1204.   B.Width := AW;
  1205.   B.Height := AH;
  1206.   if (RBPt.X - LTPt.X  = 0) or
  1207.      (RBPt.Y - LTPt.Y = 0) or SB.Empty then  Exit;
  1208.   with B.Canvas do
  1209.   begin
  1210.     // Draw lines
  1211.     // top
  1212.     w := RBPt.X - LTPt.X;
  1213.     XCnt := (AW - NewLTPt.X) div (RBPt.X - LTPt.X);
  1214.     for X := 0 to XCnt do
  1215.     begin
  1216.       if NewLTPt.X + X * w + w > AW
  1217.       then XO := NewLTPt.X + X * w + w - AW else XO := 0;
  1218.       CopyRect(Rect(NewLTPt.X + X * w, 0, NewLTPt.X + X * w + w - XO, NewClRect.Top),
  1219.                SB.Canvas, Rect(R.Left + LTPt.X, R.Top,
  1220.                  R.Left + RTPt.X - XO, R.Top + ClRect.Top));
  1221.     end;
  1222.     // bottom
  1223.     w := RBPt.X - LBPt.X;
  1224.     XCnt := (AW - NewLBPt.X) div (RBPt.X - LBPt.X);
  1225.     for X := 0 to XCnt do
  1226.     begin
  1227.       if NewLBPt.X + X * w + w > AW
  1228.       then XO := NewLBPt.X + X * w + w - AW else XO := 0;
  1229.       CopyRect(Rect(NewLBPt.X + X * w, NewClRect.Bottom, NewLBPt.X + X * w + w - XO, AH),
  1230.                SB.Canvas, Rect(R.Left + LBPt.X, R.Top + ClRect.Bottom,
  1231.                  R.Left + RBPt.X - XO, R.Bottom));
  1232.     end;
  1233.     // left
  1234.     w := NewClRect.Left;
  1235.     h := LBPt.Y - LTPt.Y;
  1236.     YCnt := (NewLBPt.Y - NewLTPt.Y) div h;
  1237.     for Y := 0 to YCnt do
  1238.     begin
  1239.       if NewLTPt.Y + Y * h + h > NewLBPt.Y
  1240.       then YO := NewLTPt.Y + Y * h + h - NewLBPt.Y else YO := 0;
  1241.       CopyRect(Rect(0, NewLTPt.Y + Y * h, w, NewLTPt.Y + Y * h + h - YO),
  1242.                SB.Canvas,
  1243.                Rect(R.Left, R.Top + LTPt.Y, R.Left + w, R.Top + LBPt.Y - YO));
  1244.     end;
  1245.     // lefttop
  1246.     CopyRect(Rect(0, 0, NewLTPt.X, NewClRect.Top),
  1247.              SB.Canvas, Rect(R.Left, R.Top,
  1248.                              R.Left + LTPt.X, R.Top + ClRect.Top));
  1249.     CopyRect(Rect(0, NewClRect.Top, NewClRect.Left, NewLTPt.Y),
  1250.              SB.Canvas, Rect(R.Left, R.Top + ClRect.Top,
  1251.                              R.Left + ClRect.left, R.Top + LTPT.Y));
  1252.     //leftbottom
  1253.     CopyRect(Rect(0, NewLBPt.Y, NewClRect.Left, AH), SB.Canvas,
  1254.              Rect(R.Left, R.Top + LBPt.Y, R.Left + ClRect.Left, R.Bottom));
  1255.     CopyRect(Rect(NewClRect.Left, NewClRect.Bottom, NewLBPt.X, AH), SB.Canvas,
  1256.              Rect(R.Left + ClRect.Left, R.Top + ClRect.Bottom, R.Left + LBPt.X, R.Bottom));
  1257.     //Draw client
  1258.     NCLRect := NewClRect;
  1259.     NCLRect.Right := AW;
  1260.     w := RectWidth(ClRect);
  1261.     h := RectHeight(ClRect);
  1262.     rw := RectWidth(NCLRect);
  1263.     rh := RectHeight(NCLRect);
  1264.     if DrawClient
  1265.     then
  1266.       begin
  1267.         // Draw client area
  1268.         XCnt := rw div w;
  1269.         YCnt := rh div h;
  1270.         for X := 0 to XCnt do
  1271.         for Y := 0 to YCnt do
  1272.         begin
  1273.           if X * w + w > rw then XO := X * W + W - rw else XO := 0;
  1274.           if Y * h + h > rh then YO := Y * h + h - rh else YO := 0;
  1275.           CopyRect(Rect(NCLRect.Left + X * w, NCLRect.Top + Y * h,
  1276.              NCLRect.Left + X * w + w - XO,
  1277.              NCLRect.Top + Y * h + h - YO),
  1278.              SB.Canvas,
  1279.              Rect(R.Left + ClRect.Left, R.Top + ClRect.Top,
  1280.              R.Left + ClRect.Right - XO,
  1281.              R.Top + ClRect.Bottom - YO));
  1282.          end;
  1283.     end;
  1284.   end;
  1285. end;
  1286. procedure CreateSkinMask;
  1287. var
  1288.   i, j, k: Integer;
  1289.   LWidth, TWidth, RWidth, BWidth: Integer;
  1290.   Ofs: Integer;
  1291.   W, H: Integer;
  1292. begin
  1293.   LWidth := ClRect.Left;
  1294.   TWidth := ClRect.Top;
  1295.   RWidth := FMask.Width - ClRect.Right;
  1296.   BWidth := FMask.Height - ClRect.Bottom;
  1297.   //left
  1298.   W := LWidth;
  1299.   H := RectHeight(NewClRect);
  1300.   if (W > 0) and (H > 0) then
  1301.   begin
  1302.   RMLeft.Width := W;
  1303.   RMLeft.Height := H;
  1304.   j := LBPt.Y - LTPt.Y;
  1305.   with RMLeft.Canvas do
  1306.   begin
  1307.     if j <> 0
  1308.     then
  1309.     for i := 0 to RMLeft.Height div j do
  1310.     begin
  1311.       if i * j + j > RMLeft.Height
  1312.       then Ofs := i * j + j - RMLeft.Height else Ofs := 0;
  1313.       CopyRect(Rect(0, i * j, LWidth, i * j + j - Ofs),
  1314.                FMask.Canvas,
  1315.                Rect(0, LTPt.Y, LWidth, LBPt.Y - Ofs));
  1316.     end;
  1317.     k := LTPt.Y - ClRect.Top;
  1318.     if k > 0 then
  1319.       CopyRect(Rect(0, 0, LWidth, k),
  1320.                FMask.Canvas,
  1321.                Rect(0, ClRect.Top, LWidth, LTPt.Y));
  1322.     k := ClRect.Bottom - LBPt.Y;
  1323.     if k > 0 then
  1324.       CopyRect(Rect(0, RMLeft.Height - k, LWidth, RMLeft.Height),
  1325.                FMask.Canvas,
  1326.                Rect(0, LBPt.Y, LWidth, ClRect.Bottom));
  1327.   end;
  1328.   end;
  1329.   //right
  1330.   W := RWidth;
  1331.   H := RectHeight(NewClRect);
  1332.   if (W > 0) and (H > 0) then
  1333.   begin
  1334.   RMRight.Width  := W;
  1335.   RMRight.Height := H;
  1336.   j := RBPt.Y - RTPt.Y;
  1337.   with RMRight.Canvas do
  1338.   begin
  1339.     if j <> 0 then 
  1340.     for i := 0 to RMRight.Height div j do
  1341.     begin
  1342.       if i * j + j > RMRight.Height
  1343.       then Ofs := i * j + j - RMRight.Height else Ofs := 0;
  1344.       CopyRect(Rect(0, i * j, RWidth, i * j + j - Ofs),
  1345.                FMask.Canvas,
  1346.                Rect(ClRect.Right, RTPt.Y, FMask.Width, RBPt.Y - Ofs));
  1347.     end;           
  1348.     k := RTPt.Y - ClRect.Top;
  1349.     if k > 0 then
  1350.       CopyRect(Rect(0, 0, RWidth, k),
  1351.                FMask.Canvas,
  1352.                Rect(FMask.Width - RWidth, ClRect.Top, FMask.Width, RTPt.Y));
  1353.     k := ClRect.Bottom - RBPt.Y;
  1354.     if k > 0 then
  1355.       CopyRect(Rect(0, RMRight.Height - k, RWidth, RMRight.Height),
  1356.                FMask.Canvas,
  1357.                Rect(FMask.Width - RWidth, RBPt.Y, FMask.Width, CLRect.Bottom));
  1358.   end;
  1359.   end;
  1360.   // top
  1361.   H := TWidth;
  1362.   W := AW;
  1363.   if (W > 0) and (H > 0) then
  1364.   begin
  1365.   j := RTPt.X - LTPt.X;
  1366.   RMTop.Height := H;
  1367.   RMTop.Width := W;
  1368.   with RMTop.Canvas do
  1369.   begin
  1370.     if j <> 0 then
  1371.     for i := 0 to RMTop.Width div j do
  1372.     begin
  1373.       if NewLTPt.X + i * j + j > NewRTPt.X
  1374.       then Ofs := NewLTPt.X + i * j + j - NewRTPt.X else Ofs := 0;
  1375.       CopyRect(Rect(NewLTPt.X + i * j, 0, NewLTPt.X + i * j + j - Ofs, TWidth),
  1376.                FMask.Canvas,
  1377.                Rect(LTPt.X, 0, RTPt.X - Ofs, TWidth));
  1378.     end;
  1379.     CopyRect(Rect(0, 0, LTPt.X, TWidth), FMask.Canvas,
  1380.              Rect(0, 0, LTPt.X, TWidth));
  1381.     CopyRect(Rect(NewRTPt.X, 0, RMTop.Width, TWidth), FMask.Canvas,
  1382.              Rect(RTPt.X, 0, FMask.Width, TWidth));
  1383.   end;
  1384.   end;
  1385.   // bottom
  1386.   W := AW;
  1387.   H := BWidth;
  1388.   if (W > 0) and (H > 0) then
  1389.   begin
  1390.   j := RBPt.X - LBPt.X;
  1391.   RMBottom.Height := H;
  1392.   RMBottom.Width := W;
  1393.   with RMBottom.Canvas do
  1394.   begin
  1395.     if j <> 0 then
  1396.     for i := 0 to RMBottom.Width div j do
  1397.     begin
  1398.       if NewLBPt.X + i * j + j > NewRBPt.X
  1399.       then Ofs := NewLBPt.X + i * j + j - NewRBPt.X else Ofs := 0;
  1400.       CopyRect(Rect(NewLBPt.X + i * j, 0, NewLBPt.X + i * j + j - Ofs, BWidth),
  1401.                FMask.Canvas,
  1402.                Rect(LBPt.X, ClRect.Bottom, RBPt.X - Ofs, FMask.Height));
  1403.     end;
  1404.     CopyRect(Rect(0, 0, LBPt.X, BWidth), FMask.Canvas,
  1405.              Rect(0, ClRect.Bottom, LBPt.X, FMask.Height));
  1406.     CopyRect(Rect(NewRBPt.X, 0, RMBottom.Width, BWidth), FMask.Canvas,
  1407.              Rect(RBPt.X, ClRect.Bottom, FMask.Width, FMask.Height));
  1408.   end;
  1409.   end;
  1410. end;
  1411. procedure CreateSkinSimplyRegion(var FRgn: HRgn; FMask: TBitMap);
  1412. var
  1413.   Size: Integer;
  1414.   RgnData: PRgnData;
  1415. begin
  1416.   Size := CreateRgnFromBmp(FMask, 0, 0, RgnData);
  1417.   FRgn := ExtCreateRegion(nil, Size, RgnData^);
  1418.   FreeMem(RgnData, Size);
  1419. end;
  1420. procedure CreateSkinRegion;
  1421. var
  1422.   RMTop, RMBottom, RMLeft, RMRight: TBitMap;
  1423.   Size: Integer;
  1424.   RgnData: PRgnData;
  1425.   R1, R2, R3, R4: HRGN;
  1426. begin
  1427.   if (NewLtPt.X > NewRTPt.X) or (NewLtPt.Y > NewLBPt.Y)
  1428.   then
  1429.     begin
  1430.       FRgn := 0;
  1431.       Exit;
  1432.     end;
  1433.   RMTop := TBitMap.Create;
  1434.   RMBottom := TBitMap.Create;
  1435.   RMLeft := TBitMap.Create;
  1436.   RMRight := TBitMap.Create;
  1437.   //
  1438.   CreateSkinMask(LTPt, RTPt, LBPt, RBPt, ClRect,
  1439.                NewLtPt, NewRTPt, NewLBPt, NewRBPt, NewClRect,
  1440.                FMask, RMTop, RMLeft, RMRight, RMBottom,
  1441.                AW, AH);
  1442.   //
  1443.   if (RMTop.Width > 0) and (RMTop.Height > 0) 
  1444.   then
  1445.     begin
  1446.       Size := CreateRgnFromBmp(RMTop, 0, 0, RgnData);
  1447.       R1 := ExtCreateRegion(nil, Size, RgnData^);
  1448.       FreeMem(RgnData, Size);
  1449.     end
  1450.   else
  1451.     R1 := 0;
  1452.   if (RMBottom.Width > 0) and (RMBottom.Height > 0)
  1453.   then
  1454.     begin
  1455.       Size := CreateRgnFromBmp(RMBottom, 0, NewClRect.Bottom, RgnData);
  1456.       R2 := ExtCreateRegion(nil, Size, RgnData^);
  1457.       FreeMem(RgnData, Size);
  1458.     end
  1459.   else
  1460.     R2 := 0;
  1461.   if (RMLeft.Width > 0) and (RMleft.Height > 0)
  1462.   then
  1463.     begin
  1464.       Size := CreateRgnFromBmp(RMLeft, 0, NewClRect.Top, RgnData);
  1465.       R3 := ExtCreateRegion(nil, Size, RgnData^);
  1466.       FreeMem(RgnData, Size);
  1467.     end
  1468.   else
  1469.     R3 := 0;
  1470.   if (RMRight.Width > 0) and (RMRight.Height > 0)
  1471.   then
  1472.     begin
  1473.       Size := CreateRgnFromBmp(RMRight, NewClRect.Right, NewClRect.Top, RgnData);
  1474.       R4 := ExtCreateRegion(nil, Size, RgnData^);
  1475.       FreeMem(RgnData, Size);
  1476.     end
  1477.   else
  1478.     R4 := 0;  
  1479.   if not isNullRect(NewClRect)
  1480.   then
  1481.     FRgn := CreateRectRgn(NewClRect.Left, NewClRect.Top,
  1482.                           NewClRect.Right, NewClRect.Bottom)
  1483.   else
  1484.     FRgn := 0;
  1485.   CombineRgn(R1, R1, R2, RGN_OR);
  1486.   CombineRgn(R3, R3, R4, RGN_OR);
  1487.   CombineRgn(R3, R3, R1, RGN_OR);
  1488.   CombineRgn(FRgn, FRgn, R3, RGN_OR);
  1489.   DeleteObject(R1);
  1490.   DeleteObject(R2);
  1491.   DeleteObject(R3);
  1492.   DeleteObject(R4);
  1493.   //
  1494.   RMTop.Free;
  1495.   RMBottom.Free;
  1496.   RMLeft.Free;
  1497.   RMRight.Free;
  1498. end;
  1499. procedure DrawGlyph;
  1500. var
  1501.   B: TBitMap;
  1502.   gw, gh: Integer;
  1503.   GR: TRect;
  1504. begin
  1505.   if FGlyph.Empty then Exit;
  1506.   gw := FGlyph.Width div FNumGlyphs;
  1507.   gh := FGlyph.Height;
  1508.   B := TBitMap.Create;
  1509.   B.Width := gw;
  1510.   B.Height := gh;
  1511.   GR := Rect(gw * (FGlyphNum - 1), 0, gw * FGlyphNum, gh);
  1512.   B.Canvas.CopyRect(Rect(0, 0, gw, gh), FGlyph.Canvas, GR);
  1513.   B.Transparent := True;
  1514.   Cnvs.Draw(X, Y, B);
  1515.   B.Free;
  1516. end;
  1517. procedure CreateSkinBorderImages;
  1518. var
  1519.   XCnt, YCnt, i, X, Y, XO, YO, w, h: Integer;
  1520.   TB: TBitMap;
  1521.   TR, TR1: TRect;
  1522. begin
  1523.   // top
  1524.   w := AW;
  1525.   h := NewClRect.Top;
  1526.   if (w > 0) and (h > 0) and (RTPt.X - LTPt.X > 0)
  1527.   then
  1528.     begin
  1529.       TopB.Width := w;
  1530.       TopB.Height := h;
  1531.       w := RTPt.X - LTPt.X;
  1532.       XCnt := TopB.Width div w;
  1533.       if TS
  1534.       then
  1535.         begin
  1536.           TB := TBitMap.Create;
  1537.           TR := Rect(R.Left + LTPt.X, R.Top,
  1538.                      R.Left + RTPt.X, R.Top + h);
  1539.           TR1 := Rect(NewLTPt.X, 0, NewRTPt.X, h);
  1540.           TB.Width := RectWidth(TR);
  1541.           TB.Height := RectHeight(TR);
  1542.           TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),
  1543.             SB.Canvas, TR);
  1544.           TopB.Canvas.StretchDraw(TR1, TB);
  1545.           TB.Free;
  1546.         end
  1547.       else
  1548.         for X := 0 to XCnt do
  1549.         begin
  1550.           if X * w + w > TopB.Width
  1551.           then XO := X * w + w -  TopB.Width else XO := 0;
  1552.           with TopB.Canvas do
  1553.           begin
  1554.             CopyRect(Rect(X * w, 0, X * w + w - XO, h),
  1555.                      SB.Canvas,
  1556.                      Rect(R.Left + LTPt.X, R.Top,
  1557.                      R.Left + RTPt.X - XO, R.Top + h));
  1558.           end;
  1559.         end;
  1560.       with TopB.Canvas do
  1561.       begin
  1562.         CopyRect(Rect(0, 0, NewLTPt.X, h), SB.Canvas,
  1563.                  Rect(R.Left, R.Top, R.Left + LTPt.X, R.Top + h));
  1564.         CopyRect(Rect(NewRTPt.X, 0, TopB.Width, h), SB.Canvas,
  1565.                  Rect(R.Left + RTPt.X, R.Top, R.Right, R.Top + h));
  1566.       end;
  1567.     end;
  1568.   // bottom
  1569.   w := AW;
  1570.   h := AH - NewClRect.Bottom;
  1571.   if (w > 0) and (h > 0) and (RBPt.X - LBPt.X > 0)
  1572.   then
  1573.     begin
  1574.       BottomB.Width := w;
  1575.       BottomB.Height := h;
  1576.       w := RBPt.X - LBPt.X;
  1577.       XCnt := BottomB.Width div w;
  1578.       if BS
  1579.       then
  1580.         begin
  1581.           TB := TBitMap.Create;
  1582.           TR := Rect(R.Left + LBPt.X, R.Bottom - h,
  1583.                           R.Left + RBPt.X, R.Bottom);
  1584.           TR1 := Rect(NewLBPt.X, 0, NewRBPt.X, h);
  1585.           TB.Width := RectWidth(TR);
  1586.           TB.Height := RectHeight(TR);
  1587.           TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),
  1588.           SB.Canvas, TR);
  1589.           BottomB.Canvas.StretchDraw(TR1, TB);
  1590.           TB.Free;
  1591.         end
  1592.       else
  1593.       for X := 0 to XCnt do
  1594.       begin
  1595.         if X * w + w > BottomB.Width
  1596.         then XO := X * w + w -  BottomB.Width else XO := 0;
  1597.           with BottomB.Canvas do
  1598.           begin
  1599.             CopyRect(Rect(X * w, 0, X * w + w - XO, h),
  1600.                      SB.Canvas,
  1601.                      Rect(R.Left + LBPt.X, R.Bottom - h,
  1602.                           R.Left + RBPt.X - XO, R.Bottom));
  1603.           end;
  1604.       end;
  1605.       with BottomB.Canvas do
  1606.       begin
  1607.         CopyRect(Rect(0, 0, NewLBPt.X, h), SB.Canvas,
  1608.                  Rect(R.Left, R.Bottom - h, R.Left + LBPt.X, R.Bottom));
  1609.         CopyRect(Rect(NewRBPt.X, 0, BottomB.Width, h), SB.Canvas,
  1610.                  Rect(R.Left + RBPt.X, R.Bottom - h, R.Right, R.Bottom));
  1611.       end;
  1612.     end;
  1613.   // draw left
  1614.   h := AH - BottomB.Height - TopB.Height;
  1615.   w := NewClRect.Left;
  1616.   if (w > 0) and (h > 0) and (LBPt.Y - LTPt.Y > 0)
  1617.   then
  1618.     begin
  1619.       LeftB.Width := w;
  1620.       LeftB.Height := h;
  1621.       h := LBPt.Y - LTPt.Y;
  1622.       YCnt := LeftB.Height div h;
  1623.       if LS
  1624.       then
  1625.         begin
  1626.           TB := TBitMap.Create;
  1627.           TR := Rect(R.Left, R.Top + LTPt.Y,
  1628.                      R.Left + w, R.Top + LBPt.Y);
  1629.           TR1 := Rect(0, LTPt.Y - ClRect.Top, w,
  1630.                       LeftB.Height - (ClRect.Bottom - LBPt.Y));
  1631.           TB.Width := RectWidth(TR);
  1632.           TB.Height := RectHeight(TR);
  1633.           TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),
  1634.           SB.Canvas, TR);
  1635.           LeftB.Canvas.StretchDraw(TR1, TB);
  1636.           TB.Free;
  1637.         end
  1638.       else
  1639.       for Y := 0 to YCnt do
  1640.       begin
  1641.         if Y * h + h > LeftB.Height
  1642.         then YO := Y * h + h - LeftB.Height else YO := 0;
  1643.         with LeftB.Canvas do
  1644.           CopyRect(Rect(0, Y * h, w, Y * h + h - YO),
  1645.                    SB.Canvas,
  1646.                    Rect(R.Left, R.Top + LTPt.Y, R.Left + w, R.Top + LBPt.Y - YO));
  1647.       end;
  1648.       with LeftB.Canvas do
  1649.       begin
  1650.         YO := LTPt.Y - ClRect.Top;
  1651.         if YO > 0
  1652.         then
  1653.           CopyRect(Rect(0, 0, w, YO), SB.Canvas,
  1654.                    Rect(R.Left, R.Top + ClRect.Top,
  1655.                    R.Left + w, R.Top + LTPt.Y));
  1656.         YO :=  ClRect.Bottom - LBPt.Y;
  1657.         if YO > 0
  1658.         then
  1659.           CopyRect(Rect(0, LeftB.Height - YO, w, LeftB.Height),
  1660.                    SB.Canvas,
  1661.                    Rect(R.Left, R.Top + LBPt.Y,
  1662.                    R.Left + w, R.Top + ClRect.Bottom));
  1663.       end;
  1664.     end;
  1665.    // draw right
  1666.   h := AH - BottomB.Height - TopB.Height;
  1667.   w := AW - NewClRect.Right;
  1668.   if (w > 0) and (h > 0) and (RBPt.Y - RTPt.Y > 0)
  1669.   then
  1670.     begin
  1671.       RightB.Width := w;
  1672.       RightB.Height := h;
  1673.       h := RBPt.Y - RTPt.Y;
  1674.       YCnt := RightB.Height div h;
  1675.       if RS
  1676.       then
  1677.         begin
  1678.           TB := TBitMap.Create;
  1679.           TR := Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,
  1680.                                 R.Right, R.Top + RBPt.Y);
  1681.           TR1 := Rect(0, RTPt.Y - ClRect.Top, w,
  1682.                       RightB.Height - (ClRect.Bottom - RBPt.Y));
  1683.           TB.Width := RectWidth(TR);
  1684.           TB.Height := RectHeight(TR);
  1685.           TB.Canvas.CopyRect(Rect(0, 0, TB.Width, TB.Height),
  1686.           SB.Canvas, TR);
  1687.           RightB.Canvas.StretchDraw(TR1, TB);
  1688.           TB.Free;
  1689.         end
  1690.       else
  1691.       for Y := 0 to YCnt do
  1692.       begin
  1693.         if Y * h + h > RightB.Height
  1694.         then YO := Y * h + h - RightB.Height else YO := 0;
  1695.         with RightB.Canvas do
  1696.         CopyRect(Rect(0, Y * h, w, Y * h + h - YO),
  1697.                  SB.Canvas,
  1698.                  Rect(R.Left + ClRect.Right, R.Top + RTPt.Y,
  1699.                       R.Right, R.Top + RBPt.Y - YO));
  1700.       end;
  1701.       with RightB.Canvas do
  1702.       begin
  1703.         YO := RTPt.Y - ClRect.Top;
  1704.         if YO > 0
  1705.         then
  1706.           CopyRect(Rect(0, 0, w, YO), SB.Canvas,
  1707.                    Rect(R.Left + ClRect.Right, R.Top + ClRect.Top,
  1708.                    R.Right, R.Top + RTPt.Y));
  1709.                   
  1710.         YO :=  ClRect.Bottom - RBPt.Y;
  1711.         if YO > 0
  1712.         then
  1713.           CopyRect(Rect(0, RightB.Height - YO, w, RightB.Height),
  1714.                    SB.Canvas,
  1715.                    Rect(R.Left + ClRect.Right, R.Top + RBPt.Y,
  1716.                         R.Right, R.Top + ClRect.Bottom));
  1717.       end;
  1718.     end;
  1719. end;
  1720. procedure DrawRCloseImage(C: TCanvas; R: TRect; Color: TColor);
  1721. var
  1722.   X, Y: Integer;
  1723. begin
  1724.   X := R.Left + RectWidth(R) div 2 - 5;
  1725.   Y := R.Top + RectHeight(R) div 2 - 5;
  1726.   DrawCloseImage(C, X, Y, Color);
  1727. end;
  1728. procedure DrawCloseImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1729. begin
  1730.   with C do
  1731.   begin
  1732.     Pen.Color := Color;
  1733.     MoveTo(X + 1, Y + 1); LineTo(X + 9, Y + 9);
  1734.     MoveTo(X + 9, Y + 1); LineTo(X + 1, Y + 9);
  1735.     MoveTo(X + 2, Y + 1); LineTo(X + 10, Y + 9);
  1736.     MoveTo(X + 8, Y + 1); LineTo(X, Y + 9);
  1737.   end;
  1738. end;
  1739. procedure DrawSysMenuImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1740. begin
  1741.   with C do
  1742.   begin                
  1743.     Pen.Color := Color;
  1744.     Brush.Style := bsClear;
  1745.     Rectangle(X + 1, Y + 3, X + 9, Y + 6);
  1746.   end;
  1747. end;
  1748. procedure DrawMinimizeImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1749. begin
  1750.   with C do
  1751.   begin
  1752.     Pen.Color := Color;
  1753.     MoveTo(X + 1, Y + 8); LineTo(X + 9, Y + 8);
  1754.     MoveTo(X + 1, Y + 9); LineTo(X + 9, Y + 9);
  1755.   end;
  1756. end;
  1757. procedure DrawMaximizeImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1758. begin
  1759.   with C do
  1760.   begin
  1761.     Brush.Style := bsClear;
  1762.     Pen.Color := Color;
  1763.     Rectangle(X, Y, X + 11, Y + 10);
  1764.     Rectangle(X, Y, X + 11, Y + 2);
  1765.   end;
  1766. end;
  1767. procedure DrawRestoreImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1768. begin
  1769.   with C do
  1770.   begin
  1771.     Brush.Style := bsClear;
  1772.     Pen.Color := Color;
  1773.     Rectangle(X + 2, Y, X + 10, Y + 6);
  1774.     Rectangle(X + 2, Y, X + 10, Y + 2);
  1775.     Rectangle(X, Y + 4, X + 7, Y + 10);
  1776.     Rectangle(X, Y + 4, X + 7, Y + 6);
  1777.   end;
  1778. end;
  1779. procedure DrawRestoreRollUpImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1780. begin
  1781.   with C do
  1782.   begin
  1783.     Pen.Color := Color;
  1784.     MoveTo(X + 5, Y + 6); LineTo(X + 5, Y + 6);
  1785.     MoveTo(X + 4, Y + 5); LineTo(X + 6, Y + 5);
  1786.     MoveTo(X + 3, Y + 4); LineTo(X + 7, Y + 4);
  1787.     MoveTo(X + 2, Y + 3); LineTo(X + 8, Y + 3);
  1788.     MoveTo(X + 1, Y + 2); LineTo(X + 9, Y + 2);
  1789.    end;
  1790. end;
  1791. procedure DrawRollUpImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1792. begin
  1793.   with C do
  1794.   begin
  1795.     Pen.Color := Color;
  1796.     MoveTo(X + 1, Y + 6); LineTo(X + 9, Y + 6);
  1797.     MoveTo(X + 2, Y + 5); LineTo(X + 8, Y + 5);
  1798.     MoveTo(X + 3, Y + 4); LineTo(X + 7, Y + 4);
  1799.     MoveTo(X + 4, Y + 3); LineTo(X + 6, Y + 3);
  1800.     MoveTo(X + 5, Y + 2); LineTo(X + 5, Y + 2);
  1801.   end;
  1802. end;
  1803. procedure DrawMTImage(C: TCanvas; X, Y: Integer; Color: TColor);
  1804. begin
  1805.   with C do
  1806.   begin
  1807.     Pen.Color := Color;
  1808.     Brush.Color := Color;
  1809.     Rectangle(X + 2, Y + 2, X + 7, Y + 7);
  1810.   end;
  1811. end;
  1812. function ExtractDay(ADate: TDateTime): Word;
  1813. var
  1814.   M, Y: Word;
  1815. begin
  1816.   DecodeDate(ADate, Y, M, Result);
  1817. end;
  1818. function ExtractMonth(ADate: TDateTime): Word;
  1819. var
  1820.   D, Y: Word;
  1821. begin
  1822.   DecodeDate(ADate, Y, Result, D);
  1823. end;
  1824. function ExtractYear(ADate: TDateTime): Word;
  1825. var
  1826.   D, M: Word;
  1827. begin
  1828.   DecodeDate(ADate, Result, M, D);
  1829. end;
  1830. function IsLeapYear(AYear: Integer): Boolean;
  1831. begin
  1832.   Result := (AYear mod 4 = 0) and ((AYear mod 100 <> 0) or (AYear mod 400 = 0));
  1833. end;
  1834. function DaysPerMonth(AYear, AMonth: Integer): Integer;
  1835. const
  1836.   DaysInMonth: array[1..12] of Integer =
  1837.     (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  1838. begin
  1839.   Result := DaysInMonth[AMonth];
  1840.   if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result); { leap-year Feb is special }
  1841. end;
  1842. type
  1843.   PMonitorInfo = ^TMonitorInfo;
  1844.   TMonitorInfo = record
  1845.     cbSize: DWORD;
  1846.     rcMonitor: TRect;
  1847.     rcWork: TRect;
  1848.     dwFlags: DWORD;
  1849.   end;
  1850. const
  1851.   MONITOR_DEFAULTTONEAREST = $2;
  1852.   SM_CMONITORS = 80;
  1853. var
  1854.   MonitorFromWindowFunc: function(hWnd: HWND; dwFlags: DWORD): THandle; stdcall;
  1855.   GetMonitorInfoFunc: function(hMonitor: THandle; lpMonitorInfo: PMonitorInfo): BOOL; stdcall;
  1856. function CheckMultiMonitors: Boolean;
  1857. var
  1858.   MonitorCount: Integer;
  1859. begin
  1860.   MonitorCount := GetSystemMetrics(SM_CMONITORS);
  1861.   Result := (MonitorCount > 1) and Assigned(GetMonitorInfoFunc);
  1862. end;
  1863. function GetPrimaryMonitorWorkArea(const WorkArea: Boolean): TRect;
  1864. begin
  1865.   if WorkArea
  1866.   then
  1867.     SystemParametersInfo(SPI_GETWORKAREA, 0, @Result, 0)
  1868.   else
  1869.     Result := Rect(0, 0, Screen.Width, Screen.Height);
  1870. end;
  1871. function GetMonitorWorkArea(const W: HWND; const WorkArea: Boolean): TRect;
  1872. var
  1873.   MonitorInfo: TMonitorInfo;
  1874.   MH: THandle;
  1875. begin
  1876.   if CheckMultiMonitors
  1877.   then
  1878.     begin
  1879.       MH := MonitorFromWindowFunc(W, MONITOR_DEFAULTTONEAREST);
  1880.       MonitorInfo.cbSize := SizeOf(MonitorInfo);
  1881.       if GetMonitorInfoFunc(MH, @MonitorInfo)
  1882.       then
  1883.         begin
  1884.           if not WorkArea
  1885.           then
  1886.             Result := MonitorInfo.rcMonitor
  1887.           else
  1888.             Result := MonitorInfo.rcWork;
  1889.         end;
  1890.     end
  1891.   else
  1892.     Result := GetPrimaryMonitorWorkArea(WorkArea);
  1893. end;
  1894. var
  1895.   User32H: THandle;
  1896. initialization
  1897.   User32H := GetModuleHandle(user32);
  1898.   if User32H > 0 then
  1899.   begin
  1900.     MonitorFromWindowFunc := GetProcAddress(User32H, 'MonitorFromWindow');
  1901.     GetMonitorInfoFunc := GetProcAddress(User32H, 'GetMonitorInfoA');
  1902.   end;
  1903. finalization
  1904.   if User32H > 0 then FreeLibrary(User32H);
  1905.   MonitorFromWindowFunc := nil;
  1906.   GetMonitorInfoFunc := nil;
  1907. end.