home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / kolekce / d456 / DCSLIB25.ZIP / DCEditTools.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-06-28  |  55.7 KB  |  1,993 lines

  1. {
  2.  BUSINESS CONSULTING
  3.  s a i n t - p e t e r s b u r g
  4.  
  5.          Components Library for Borland Delphi 4.x, 5.x
  6.          Copyright (c) 1998 Alex'EM
  7.  
  8.          last modification: 24/04/2000
  9. }
  10. unit DCEditTools;
  11.  
  12. interface
  13. {$I DCConst.inc}
  14.  
  15. uses Windows, Controls, Forms, SysUtils, CommCtrl, Messages, Graphics,
  16.      Classes, DCConst;
  17.  
  18. type
  19.   TDCDBObject = class(TPersistent)
  20.   private
  21.     FNode: string;
  22.     FCode: string;
  23.     FCaption: string;
  24.   published
  25.     property Node: string read FNode write FNode;
  26.     property Code: string read FCode write FCode;
  27.     property Caption: string read FCaption write FCaption;
  28.   end;
  29.  
  30. function _intMin(A, B: integer): integer;
  31. function _intMax(A, B: integer): integer;
  32. function _getFlag(Flag: dword; const Index: Integer): boolean;
  33. procedure _intSwap(var A, B: integer);
  34. procedure _setFlag(var Flag: dword; const Index: Integer; const Value: boolean);
  35.  
  36. procedure StrPCat(var Dest: string; Source: PChar; Len: integer);
  37.  
  38. function IsExistDragging: boolean;
  39. function IsLeapYear(Year: Integer): Boolean;
  40. function DaysPerMonth(Year, Month: Integer): Integer;
  41.  
  42. function DateToStrY2K(Date: TDateTime; var Stroke: string;
  43.   Kind: TDateEditKind = dkDate): boolean; overload;
  44. function DateToStrY2K(Date: string; var Stroke: string;
  45.   Kind: TDateEditKind = dkDate): boolean; overload;
  46.  
  47. function GetNumericFormat(Value: PChar; var Precision: integer;
  48.   var Digits: integer): TNumericFormat;
  49.  
  50. function IsValidInteger(Value: string): boolean;
  51. function IsValidFloat(Value: string): boolean;
  52. function IsValidCurrency(Value: string; APrecision: integer): boolean;
  53.  
  54. function CheckInteger(var Value: string; ADigits: integer): boolean;
  55. function CheckFloat(var Value: string; APrecision, ADigits: integer): boolean;
  56. function CheckCurrency(var Value: string; APrecision, ADigits: integer): boolean;
  57.  
  58. function GetCharWidth(Handle: HWND; Font: TFont): integer;
  59. function GetCharHeight(Handle: HWND; Font: TFont): integer;
  60.  
  61. procedure DrawFocusedRect(DC: HDC; pOldRect, pNewRect: PRect; BorderSize: integer);
  62. function SetRectInDesktop( var Pos: TPoint; AWidth, AHeight: Integer; Offset: TPoint): integer;
  63.  
  64. function GetDCTextWidth(Font: TFont; Value: string; ACanvas: TCanvas = nil) : Longint;
  65. function GetDCTextHeight(Font: TFont; Value: string; ACanvas: TCanvas = nil) : Longint;
  66. function GetTextWidth(DC: HDC; Value: string): integer;
  67. function GetTextHeight(DC: HDC; Value: string): integer;
  68.  
  69. function GetTransparentColor(RGB: integer): integer;
  70.  
  71. procedure TransformBitmap(Source, Dest: TBitmap; Style: TTransformStyle; AColor: TColor = $FFFFFF);
  72. procedure TransformBitmapTransparent(BkgImage, SrcImage: TBitmap;
  73.   var DstImage: TBitmap; Opacity: integer; AColor: TColor = $FFFFFF);
  74.  
  75. procedure DrawBitmap(ACanvas: TCanvas; ABitmap: TBitmap; ARect: TRect;
  76.   AStretch: boolean; ATransparent: boolean = True);
  77. procedure DrawTransparentBitmap(DC: HDC; Bitmap: TBitmap; R: TRect;
  78.   StretchBitmap: boolean; AColor: TColor = $FFFFFF);
  79. procedure DrawStyledBitmap(Canvas: TCanvas; ARect: TRect; X, Y: integer;
  80.  Bitmap: TBitmap; Style: TTransformStyle);
  81.  
  82. function DrawHighLightText(Canvas: TCanvas; Text: PChar;
  83.   ARect: TRect; Mode: byte; DrawFlag: DWORD = DT_END_ELLIPSIS;
  84.   ImageList: TImageList = nil): TPoint;
  85.  
  86. procedure DrawGridFrameBorder(Canvas: TCanvas; ARect: TRect; AStyle: TEdgeBorderStyle;
  87.   AState: TDrawBorerState; FixedColor: TColor);
  88.  
  89. function RecordCount2Str(Count: integer): string;
  90.  
  91. function CreateEmptyRgn: HRGN;
  92. procedure ProcessPaintMessages;
  93.  
  94. function ETGetSystemImages(Mode: integer): TImageList;
  95. procedure ETGetBitmap(Mode, Index: integer; ABitmap: TBitmap);
  96.  
  97. implementation
  98.  
  99. {$R DCSystem.RES}
  100.  
  101. var
  102.  TempBitmap: TBitmap;
  103.  
  104. var
  105.  SystemSmallImages: TImageList;       // Size: 15x15
  106.  
  107. function _intMin(A, B: integer): integer;
  108. {
  109.    -> eax   A
  110.    -> edx   B
  111.    <- eax   A if A < B
  112.             A if A = B
  113.             B if A < B
  114. }
  115. asm
  116.   cmp eax, edx  // ±≡αΓφΦΓασ∞ └ Φ ┬
  117.   jg  @@1       // σ±δΦ eax > edx ΦΣσ∞ ΦΣσ∞ φα @@1
  118.   jmp @@2       // Φφα≈σ Γ√⌡εΣΦ∞
  119. @@1:
  120.   mov eax, edx  // τα∩Φ±√Γασ∞ Γ ┬ Γ Result
  121. @@2:
  122. end;
  123.  
  124. function _intMax(A, B: integer): integer;
  125. {
  126.    -> eax   A
  127.    -> edx   B
  128.    <- eax   A if A > B
  129.             B if A = B
  130.             B if A < B
  131. }
  132. asm
  133.   cmp eax, edx  // ±≡αΓφΦΓασ∞ └ Φ ┬
  134.   jg  @@2       // σ±δΦ eax > edx ΦΣσ∞ ΦΣσ∞ φα @@2
  135.   jmp @@1       // Φφα≈σ Γ√⌡εΣΦ∞
  136. @@1:
  137.   mov eax, edx  // τα∩Φ±√Γασ∞ Γ ┬ Γ Result
  138. @@2:
  139. end;
  140.  
  141. procedure _intSwap(var A, B: integer);
  142. asm
  143.   mov ebx, [eax]
  144.   mov ecx, [edx]
  145.   mov [eax], ecx
  146.   mov [edx], ebx
  147. end;
  148.  
  149. function _getFlag(Flag: dword; const Index: Integer): boolean; assembler;
  150. asm
  151.   bt  eax, edx
  152.   sbb eax, eax
  153.   and eax, 1
  154. end;
  155.  
  156. procedure _setFlag(var Flag: dword; const Index: Integer; const Value: boolean); assembler;
  157. asm
  158.   push esi
  159.   mov esi, [eax]
  160.   or  Value, Value
  161.   jz  @@1
  162.   bts esi, edx
  163.   jmp @@2
  164. @@1:
  165.   btr esi, edx
  166. @@2:
  167.   mov [eax], esi
  168.   pop esi
  169. end;
  170.  
  171. procedure StrPCat(var Dest: string; Source: PChar; Len: integer);
  172.  var
  173.   i, Size: Integer;
  174.   pValue: PChar;
  175. begin
  176.   if Len <> 0 then
  177.   begin
  178.     i := Length(Dest);
  179.     Size := (i + Len + 1)*SizeOf(Char);
  180.     pValue := AllocMem(Size);
  181.     try
  182.       if i > 0 then Move(Pointer(Dest)^, pValue^, i);
  183.       Move(Source^, pValue[i], Len);
  184.       Dest := pValue;
  185.     finally
  186.       FreeMem(pValue, Size);
  187.     end;
  188.   end;
  189. end;
  190.  
  191. function IsExistDragging: boolean;
  192.  var
  193.   i: integer;
  194.   Control: TControl;
  195.  
  196.  function IsDragging(AControl: TControl): boolean;
  197.   var
  198.    i: integer;
  199.    Control: TControl;
  200.  begin
  201.    Result := False;
  202.    if (csAcceptsControls in AControl.ControlStyle) then
  203.      for i := 0 to AControl.ComponentCount-1 do
  204.      begin
  205.         Control := TControl(AControl.Components[i]);
  206.         if Control.Dragging then
  207.           Result := True
  208.         else
  209.           Result := IsDragging(Control);
  210.  
  211.         if Result then Exit;
  212.      end;
  213.  end;
  214. begin
  215.   Result := False;
  216.   for i := 0 to Application.ComponentCount-1 do
  217.   begin
  218.      Control := TControl(Application.Components[i]);
  219.       if Control.Dragging then
  220.         Result := True
  221.       else
  222.         Result := IsDragging(Control);
  223.  
  224.       if Result then Exit;
  225.   end;
  226. end;
  227.  
  228. procedure ProcessPaintMessages;
  229.  var
  230.   Msg: TMsg;
  231. begin
  232.   while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE) do begin
  233.     case Integer(GetMessage(Msg, 0, WM_PAINT, WM_PAINT)) of
  234.       -1: Break;
  235.       0 :
  236.         begin
  237.           PostQuitMessage(Msg.WParam);
  238.           Break;
  239.         end;
  240.     end;
  241.     DispatchMessage(Msg);
  242.   end;
  243. end;
  244.  
  245. function IsLeapYear(Year: Integer): Boolean;
  246. begin
  247.   Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
  248. end;
  249.  
  250. function DaysPerMonth(Year, Month: Integer): Integer;
  251.  const
  252.   DaysInMonth: array[1..12] of Integer = (31, 28, 31,
  253.                                           30, 31, 30,
  254.                                           31, 31, 30,
  255.                                           31, 30, 31);
  256. begin
  257.   Result := DaysInMonth[Month];
  258.   if (Month = 2) and IsLeapYear(Year) then Inc(Result);
  259. end;
  260.  
  261. function DateToStrY2K(Date: TDateTime; var Stroke: string; Kind: TDateEditKind): boolean; overload;
  262.  var
  263.   DateFormat: string;
  264. begin
  265.   Result := True;
  266.   if Date = 0 then
  267.     Stroke := ''
  268.   else begin
  269.     case Kind of
  270.       dkDate:
  271.         DateFormat := Format('dd%0:smm%0:syyyy',[DateSeparator]);
  272.       dkDateTime:
  273.         DateFormat := Format('dd%0:smm%0:syyyy hh%1:snn%1:sss',[DateSeparator, TimeSeparator]);
  274.       else
  275.         DateFormat := Format('dd%0:smm%0:syyyy',[DateSeparator]);
  276.     end;
  277.     DateTimeToString(Stroke, DateFormat, Date);
  278.   end;
  279. end;
  280.  
  281. function DateToStrY2K(Date: string; var Stroke: string; Kind: TDateEditKind): boolean; overload;
  282.  type
  283.   TDateInfo = array[1..6] of integer;
  284.  
  285.  var
  286.   DateInfo: TDateInfo;
  287.  
  288.  function DecodeDateStr(pDate: PChar; var DateInfo: TDateInfo): boolean;
  289.   var
  290.    Section, Count, i: integer;
  291.    xDate: PChar;
  292.  
  293.  begin
  294.    for i := Low(DateInfo) to High(DateInfo) do DateInfo[i] := 0;
  295.  
  296.    xDate  := pDate;
  297.    Count  := 0;
  298.    Section:= Low(DateInfo);
  299.    while pDate^ <> #0 do
  300.    begin
  301.      if not(pDate^ in ['0'..'9']) then
  302.      begin
  303.        if Count > 0 then
  304.        begin
  305.          if Section <= High(DateInfo) then
  306.          begin
  307.            DateInfo[Section] := StrToIntDef(Copy(xDate, 0, Count), 0);
  308.            Inc(Section)
  309.          end
  310.          else begin
  311.            Result := False;
  312.            Exit;
  313.          end;
  314.        end;
  315.        xDate  := pDate+1;
  316.        Count  := 0;
  317.      end
  318.      else
  319.        Inc(Count);
  320.      Inc(pDate);
  321.    end;
  322.    if (Count > 0) and (Section <= High(DateInfo)) then
  323.    begin
  324.      DateInfo[Section] := StrToIntDef(Copy(xDate, 0, Count), 0);
  325.    end;
  326.  
  327.    Result := not( ( (DateInfo[3] = 00) and
  328.                     ( (Section =3) and (Count=0) ) or (Section < 3)
  329.                   ) or
  330.                   (DateInfo[2] = 00) or (DateInfo[2] > 12) or
  331.                   (DateInfo[1] = 00) or (DateInfo[1] > DaysPerMonth(DateInfo[3],DateInfo[2]))
  332.                   or
  333.                   (DateInfo[4] > 23) or (DateInfo[5] > 59));
  334.  end;
  335. begin
  336.   Result := DecodeDateStr(PChar(Date), DateInfo);
  337.   if Result then
  338.   begin
  339.     case DateInfo[3] of
  340.       000..049: DateInfo[3] := 2000 + DateInfo[3];
  341.       050..099: DateInfo[3] := 1900 + DateInfo[3];
  342.       100..999: DateInfo[3] := 2000 + DateInfo[3];
  343.     end;
  344.     case Kind of
  345.       dkDate:
  346.         Stroke := Format('%1:2.2d%0:s%2:2.2d%0:s%3:d',
  347.           [DateSeparator, DateInfo[1], DateInfo[2], DateInfo[3]]);
  348.       dkDateTime:
  349.         Stroke := Format('%1:2.2d%0:s%2:2.2d%0:s%3:d %5:2.2d%4:s%6:2.2d%4:s%7:2.2d',
  350.           [DateSeparator, DateInfo[1], DateInfo[2], DateInfo[3],
  351.            TimeSeparator, DateInfo[4], DateInfo[5], DateInfo[6]]);
  352.       else
  353.         Stroke := Format('%1:2.2d%0:s%2:2.2d%0:s%3:d',
  354.           [DateSeparator, DateInfo[1], DateInfo[2], DateInfo[3]]);
  355.     end;
  356.   end;
  357. end;
  358.  
  359.  
  360. procedure DrawFocusedRect(DC: HDC; pOldRect, pNewRect: PRect; BorderSize: integer);
  361.  var
  362.   Brush: HBRUSH;
  363.   RgnOuterRect, RgnInnerRect, RgnOldBorder, RgnNewBorder: HRGN;
  364.   R: TRect;
  365.   nSavedDC: integer;
  366.  
  367.  function CreateNullRgn: HRGN;
  368.   var
  369.    R: TRect;
  370.  begin
  371.    SetRectEmpty(R);
  372.    Result := CreateRectRgnIndirect(R);
  373.  end;
  374.  
  375.  procedure SetBoundsRgn(Rgn: HRGN; R: TRect);
  376.  begin
  377.    with R do SetRectRgn(Rgn, Left, Top, Right, Bottom);
  378.  end;
  379.  
  380. begin
  381.   RgnOuterRect := CreateNullRgn;
  382.   RgnInnerRect := CreateNullRgn;
  383.   RgnOldBorder := CreateNullRgn;
  384.   RgnNewBorder := CreateNullRgn;
  385.  
  386.   {╤ετΣαφΦσ Brush}
  387.   Brush:= CreateSolidBrush($00999999);
  388.  
  389.   if pOldRect <> nil then
  390.   begin
  391.     R := pOldRect^;
  392.     SetBoundsRgn(RgnOuterRect, R);
  393.     InflateRect(R, -BorderSize, -BorderSize);
  394.     SetBoundsRgn(RgnInnerRect, R);
  395.     CombineRgn(RgnOldBorder, RgnOuterRect, RgnInnerRect, RGN_XOR);
  396.  
  397.   end;
  398.  
  399.   if pNewRect <> nil then
  400.   begin
  401.     R := pNewRect^;
  402.     SetBoundsRgn(RgnOuterRect, R);
  403.     InflateRect(R, -BorderSize, -BorderSize);
  404.     SetBoundsRgn(RgnInnerRect, R);
  405.     CombineRgn(RgnNewBorder, RgnOuterRect, RgnInnerRect, RGN_XOR);
  406.  
  407.     if pOldRect <> nil then
  408.       CombineRgn(RgnNewBorder, RgnOldBorder, RgnNewBorder, RGN_XOR);
  409.  
  410.   end;
  411.  
  412.   if pNewRect = nil then RgnNewBorder := RgnOldBorder;
  413.  
  414.   nSavedDC := SaveDC(DC);
  415.   try
  416.     SelectClipRgn(DC, RgnNewBorder);
  417.     GetClipBox(DC, R);
  418.     SelectObject(DC, Brush);
  419.     PatBlt(DC, R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top, PATINVERT);
  420.   finally
  421.     RestoreDC(DC, nSavedDC);
  422.   end;
  423.  
  424.   DeleteObject(RgnOuterRect);
  425.   DeleteObject(RgnInnerRect);
  426.   DeleteObject(RgnOldBorder);
  427.   DeleteObject(RgnNewBorder);
  428.   DeleteObject(Brush)
  429.  
  430. end;
  431.  
  432. function SetRectInDesktop(var Pos: TPoint; AWidth, AHeight: Integer; Offset: TPoint): integer;
  433. begin
  434.   Result := 0;
  435.   with Screen do
  436.   begin
  437.     if Pos.Y < DesktopTop  then Pos.Y := DesktopTop;
  438.     if (Pos.Y+AHeight) > (DesktopTop+DesktopHeight) then
  439.     begin
  440.       Pos.Y  := (DesktopTop+DesktopHeight)-AHeight-Offset.Y;
  441.       Result := $1;
  442.     end;
  443.     if Pos.X < DesktopLeft then Pos.X := DesktopLeft;
  444.     if (Pos.X+AWidth)  > (DesktopLeft+DesktopWidth) then
  445.     begin
  446.       Pos.X := (DesktopLeft+DesktopWidth)-AWidth-Offset.X;
  447.       Result := Result + $2;
  448.     end;
  449.   end;
  450. end;
  451.  
  452. function GetCharWidth(Handle: HWND; Font: TFont): integer;
  453.  var
  454.   TextMetric: TTextMetric;
  455.   DC: HDC;
  456. begin
  457.   Result := 0;
  458.   DC := GetWindowDC(Handle);
  459.   SelectObject(DC, Font.Handle);
  460.   try
  461.     if GetTextMetrics(DC, TextMetric) then Result := TextMetric.tmMaxCharWidth;
  462.   finally
  463.     ReleaseDC(Handle, DC);
  464.   end;
  465. end;
  466.  
  467. function GetCharHeight(Handle: HWND; Font: TFont): integer;
  468.  var
  469.   TextMetric: TTextMetric;
  470.   DC: HDC;
  471. begin
  472.   Result := 0;
  473.   DC := GetWindowDC(Handle);
  474.   SelectObject(DC, Font.Handle);
  475.   try
  476.     if GetTextMetrics(DC, TextMetric) then Result := TextMetric.tmHeight;
  477.   finally
  478.     ReleaseDC(Handle, DC);
  479.   end;
  480. end;
  481.  
  482. function GetDCTextHeight(Font: TFont; Value: string; ACanvas: TCanvas = nil): Longint;
  483. var
  484.  Canvas: TCanvas;
  485. begin
  486.   if ACanvas = nil then
  487.   begin
  488.     Canvas := nil;
  489.     try
  490.       Canvas := TCanvas.Create;
  491.       Canvas.Handle := GetDC(0);
  492.       Canvas.Font := Font;
  493.       Result := GetTextHeight(Canvas.Handle, Value);
  494.     finally
  495.       ReleaseDC(0, Canvas.Handle);
  496.       Canvas.Free;
  497.     end
  498.   end
  499.   else
  500.     Result := GetTextHeight(ACanvas.Handle, Value);
  501. end;
  502.  
  503. function GetDCTextWidth(Font: TFont; Value: string;  ACanvas: TCanvas = nil): Longint;
  504. var
  505.  Canvas: TCanvas;
  506. begin
  507.   if ACanvas = nil then
  508.   begin
  509.     Canvas := nil;
  510.     try
  511.       Canvas := TCanvas.Create;
  512.       Canvas.Handle := GetDC(0);
  513.       Canvas.Font := Font;
  514.       Result := GetTextWidth(Canvas.Handle, Value);
  515.     finally
  516.       ReleaseDC(0, Canvas.Handle);
  517.       Canvas.Handle := 0;
  518.       Canvas.Free;
  519.     end
  520.   end
  521.   else begin
  522.     Result := GetTextWidth(ACanvas.Handle, Value);
  523.   end;
  524. end;
  525.  
  526.  
  527. function GetTextHeight(DC: HDC; Value: string): integer;
  528.  var
  529.   R: TSize;
  530. begin
  531.   Windows.GetTextExtentPoint(DC, PChar(Value), Length(Value), R);
  532.   Result := R.CY;
  533. end;
  534.  
  535. function GetTextWidth(DC: HDC; Value: string): integer;
  536.  var
  537.   R: TSize;
  538. begin
  539.   Windows.GetTextExtentPoint(DC, PChar(Value), Length(Value), R);
  540.   Result := R.CX;
  541. end;
  542.  
  543. function GetSysColorsNumber(DC: HDC): LongInt;
  544. begin
  545.   Result := (LongInt(1) shl GetDeviceCaps(DC, BitsPixel)) *
  546.     LongInt(GetDeviceCaps(DC, Planes));
  547. end;
  548.  
  549. function ConvertedColor(RGBPart: integer): integer;
  550.  var
  551.   HiByte: integer;
  552. begin
  553.   HiByte := (RGBPart and $8F0) shr 4;
  554.   Result := 0;
  555.   case HiByte of
  556.     00    : Result := 7;
  557.     01, 02: Result := 8;
  558.     03, 05: Result := 9;
  559.     06    : Result := 10;
  560.     07, 08: Result := 11;
  561.     09, 10: Result := 12;
  562.     11, 12: Result := 13;
  563.     13, 14: Result := 14;
  564.     15    : Result := 15;
  565.   end;
  566.   Result := Result shl 4;
  567.   case RGBPart of
  568.    000..019: Result := Result + 11;
  569.    020..039: Result := Result + 04;
  570.    040..069: Result := Result + 05;
  571.    070..089: Result := Result + 14;
  572.    090..099: Result := Result + 13;
  573.    100..109: Result := Result + 06;
  574.    110..129: Result := Result + 05;
  575.    130..149: Result := Result + 13;
  576.    150..189: Result := Result + 06;
  577.    190..209: Result := Result + 14;
  578.    210..255: Result := Result + 07;
  579.   end;
  580. end;
  581.  
  582. function GetTransparentColor(RGB: integer): integer;
  583. begin
  584.   Result  := ConvertedColor(RGB and $FF0000 shr 16) ;
  585.   Result  := Result shl 8 or ConvertedColor(RGB and $00FF00 shr 8);
  586.   Result  := Result shl 8 or ConvertedColor(RGB and $0000FF);
  587. end;
  588.  
  589.  
  590. procedure DrawBitmap(ACanvas: TCanvas; ABitmap: TBitmap; ARect: TRect;
  591.   AStretch: boolean; ATransparent: boolean = True);
  592.  var
  593.   SrcR, DstR: TRect;
  594.   DstH, DstW: integer;
  595. begin
  596.   if Assigned(ABitmap) then
  597.   begin
  598.     DstW := ABitmap.Width;
  599.     DstH := ABitmap.Height;
  600.     SrcR := Rect(0,0,DstW,DstH);
  601.     if AStretch then
  602.       DstR := ARect
  603.     else begin
  604.       DstR := Rect(0, 0, ABitmap.Width, ABitmap.Height);
  605.       OffsetRect(DstR, ARect.Left, ARect.Top);
  606.     end;
  607.     ABitmap.Transparent := ATransparent;
  608.     ACanvas.StretchDraw(DstR, ABitmap);
  609.   end;
  610. end;
  611.  
  612. procedure DrawTransparentBitmap(DC: HDC; Bitmap: TBitmap; R: TRect; StretchBitmap: boolean;
  613.   AColor: TColor);
  614. const
  615.   ROP_DSPDxax = $00E20746;
  616. var
  617.   DstW, DstH: Integer;
  618.   MaskDC: HDC;
  619.   Mask: TBitmap;
  620.   MaskHandle: HBITMAP;
  621.   Color: TColor;
  622. begin
  623.   if Assigned(Bitmap) then
  624.   begin
  625.     if AColor = $FFFFFF then
  626.       Color := Bitmap.Canvas.Pixels[0,Bitmap.Height-1]
  627.     else
  628.       Color := AColor;
  629.     if Bitmap.TransparentColor = Color then
  630.     begin
  631.       Mask := nil;
  632.       MaskHandle := Bitmap.MaskHandle;
  633.       MaskDC := CreateCompatibleDC(0);
  634.       MaskHandle := SelectObject(MaskDC, MaskHandle);
  635.     end
  636.     else
  637.     begin
  638.       Mask := TBitmap.Create;
  639.       Mask.Assign(Bitmap);
  640.       Mask.Mask(Color);
  641.       MaskDC := Mask.Canvas.Handle;
  642.       MaskHandle := 0;
  643.     end;
  644.  
  645.     if StretchBitmap then
  646.     begin
  647.       DstW := R.Right  - R.Left;
  648.       DstH := R.Bottom - R.Top;
  649.     end
  650.     else begin
  651.       DstW := Bitmap.Width;
  652.       DstH := Bitmap.Height;
  653.     end;
  654.  
  655.     try
  656.       TransparentStretchBlt(DC, R.Left, R.Top, DstW, DstH, Bitmap.Canvas.Handle,
  657.         0, 0, Bitmap.Width, Bitmap.Height, MaskDC, 0, 0);
  658.     finally
  659.       if Assigned(Mask) then
  660.         Mask.Free
  661.       else begin
  662.         if MaskHandle <> 0 then SelectObject(MaskDC, MaskHandle);
  663.         DeleteDC(MaskDC);
  664.       end;
  665.     end;
  666.  end;
  667. end;
  668.  
  669. procedure DrawStyledBitmap(Canvas: TCanvas; ARect: TRect; X, Y: integer;
  670.  Bitmap: TBitmap; Style: TTransformStyle);
  671.  var
  672.   DestRect, SourceRect: TRect;
  673. begin
  674.   TransformBitmap(Bitmap, TempBitmap, Style);
  675.   SourceRect := Rect(0, 0, Bitmap.Width, Bitmap.Height);
  676.   DestRect   := SourceRect;
  677.   OffsetRect(DestRect, ARect.Left+X, ARect.Top+Y);
  678.   Canvas.BrushCopy(DestRect, TempBitmap, SourceRect,
  679.     TempBitmap.Canvas.Pixels[0,Bitmap.Height-1]);
  680. end;
  681.  
  682. procedure TransformBitmap(Source, Dest: TBitmap; Style: TTransformStyle;
  683.   AColor: TColor = $FFFFFF);
  684.  var
  685.   i, j, ScanLineWidth, dHeight: integer;
  686.   R, R1: TRect;
  687.   LDScan, LSScan: PByteArray;
  688.   LSScan0, LSScan1, LSScan2: PByteArray;
  689.   AColorRBG: ULong;
  690.   BValue, GValue, RValue: integer;
  691.   TempBitmap: TBitmap;
  692.  
  693.   procedure CopyLScanLine(i: integer);
  694.   begin
  695.     LDScan[i]   := LSScan[i];
  696.     LDScan[i+1] := LSScan[i+1];
  697.     LDScan[i+2] := LSScan[i+2];
  698.   end;
  699.  
  700.   function GetBSelectedBit(i: integer): integer;
  701.   begin
  702.     case i of
  703.       0  :  Result := $42;
  704.       255:  Result := $BD;
  705.       else  Result := i;
  706.     end;
  707.   end;
  708.  
  709.   function GetBluredBit(i: integer): integer;
  710.   begin
  711.     Result := (LSScan0[i] + LSScan1[i] + LSScan2[i] +
  712.       LSScan1[_intMax(0, i-3)] + LSScan1[_intMin(ScanLineWidth, i+3)]) div 5;
  713.   end;
  714.  
  715. begin
  716.   try
  717.     Dest.PixelFormat := pf24Bit;
  718.     if Dest.Handle <> Source.Handle then
  719.     begin
  720.       with Dest do
  721.       begin
  722.         Width  := Source.Width;
  723.         Height := Source.Height;
  724.       end;
  725.     end;
  726.     R := Rect(0, 0, Dest.Width, Dest.Height);
  727.     ScanLineWidth := Integer(Dest.ScanLine[0]) - Integer(Dest.ScanLine[1]) - 1;
  728.   except
  729.     if Dest.Handle <> Source.Handle then
  730.     begin
  731.       with Dest do
  732.       begin
  733.         Width  := Source.Width;
  734.         Height := Source.Height;
  735.       end;
  736.     end;
  737.     R := Rect(0, 0, Dest.Width, Dest.Height);
  738.     if not IsRectEmpty(R) then
  739.     begin
  740.       Dest.Canvas.CopyMode := cmSrcCopy;
  741.       Dest.Canvas.CopyRect(R, Source.Canvas, R);
  742.     end;
  743.     Exit;
  744.   end;
  745.   if AColor <> $FFFFFF then
  746.     AColorRBG := ColorToRGB(AColor)
  747.   else
  748.     AColorRBG := Source.Canvas.Pixels[0, 0];
  749.   {24 bit}
  750.  
  751.   dHeight := Dest.Height-1;
  752.   case Style of
  753.     tsDisable:
  754.       begin
  755.         Source.PixelFormat := pf24Bit;
  756.         for j := 0 to dHeight do
  757.         begin
  758.           LDScan := Dest.ScanLine[j];
  759.           LSScan := Source.ScanLine[j];
  760.           i := 0;
  761.           while (i+2) <= ScanLineWidth do
  762.           begin
  763.             if LSScan[i+2] < $AF then
  764.             begin
  765.               LDScan[i]   := 120;
  766.               LDScan[i+1] := 120;
  767.               LDScan[i+2] := 120;
  768.             end
  769.             else
  770.               if Dest.Canvas.Handle <> Source.Canvas.Handle then CopyLScanLine(i);
  771.             Inc(i, 3);
  772.           end;
  773.         end;
  774.       end;
  775.     tsSelect:
  776.       begin
  777.         Source.PixelFormat := pf24Bit;
  778.         for j := 0 to dHeight do
  779.         begin
  780.           LDScan := Dest.ScanLine[j];
  781.           LSScan := Source.ScanLine[j];
  782.           i := 0;
  783.           while (i+2) <= ScanLineWidth do
  784.           begin
  785.             LDScan[i+2] := LSScan[i+2] div 2;
  786.             LDScan[i+1] := LSScan[i+1] div 2;
  787.             LDScan[i]   := GetBSelectedBit(LSScan[i]);
  788.             Inc(i, 3);
  789.           end;
  790.         end;
  791.       end;
  792.     tsTransparent:
  793.       begin
  794.         Source.PixelFormat := pf24Bit;
  795.         for j := 0 to Dest.Height-1 do
  796.         begin
  797.           LDScan := Dest.ScanLine[j];
  798.           LSScan := Source.ScanLine[j];
  799.           i := 0;
  800.           while (i+3) <= ScanLineWidth do
  801.           begin
  802.             LDScan[i+2] := ConvertedColor(LSScan[i+2]);
  803.             LDScan[i+1] := ConvertedColor(LSScan[i+1]);
  804.             LDScan[i]   := ConvertedColor(LSScan[i]);
  805.             Inc(i, 3);
  806.           end;
  807.         end;
  808.       end;
  809.     tsShadow:
  810.       begin
  811.         Source.PixelFormat := pf24Bit;
  812.         BValue := GetBValue(AColorRBG);
  813.         GValue := GetGValue(AColorRBG);
  814.         RValue := GetRValue(AColorRBG);
  815.         for j := 0 to dHeight do
  816.         begin
  817.           LDScan := Dest.ScanLine[j];
  818.           LSScan := Source.ScanLine[j];
  819.           i := 0;
  820.           while (i+2) <= ScanLineWidth do
  821.           begin
  822.             if (LSScan[i] <> BValue) and (LSScan[i+1] <> GValue) and (LSScan[i+2] <> RValue) and
  823.                (((i div 3) + j) mod 2 = 0) then
  824.             begin
  825.               LDScan[i+2] := 8;
  826.               LDScan[i+1] := 36;
  827.               LDScan[i]   := 107;
  828.             end
  829.             else
  830.               if Dest.Canvas.Handle <> Source.Canvas.Handle then CopyLScanLine(i);
  831.             Inc(i, 3);
  832.           end;
  833.         end;
  834.       end;
  835.     tsBlur:
  836.       begin
  837.         Source.PixelFormat := pf24Bit;
  838.         for j := 0 to dHeight do
  839.         begin
  840.           LDScan  := Dest.ScanLine[j];
  841.  
  842.           LSScan0 := Source.ScanLine[_intMax(0, j-1)];
  843.           LSScan1 := Source.ScanLine[j];
  844.           LSScan2 := Source.ScanLine[_intMin(j+1, dHeight)];
  845.  
  846.           i := 0;
  847.           while i <= ScanLineWidth do
  848.           begin
  849.             LDScan[i] := GetBluredBit(i);
  850.             Inc(i);
  851.           end;
  852.         end;
  853.       end;
  854.     tsNormal:
  855.       begin
  856.         Dest.Canvas.CopyMode := cmSrcCopy;
  857.         Dest.Canvas.CopyRect(R, Source.Canvas, R);
  858.       end;
  859.     tsInvert:
  860.       begin
  861.         Dest.Canvas.CopyMode := cmNotSrcCopy;
  862.         Dest.Canvas.CopyRect(R, Source.Canvas, R);
  863.       end;
  864.     tsXPStyle:
  865.       begin
  866.         Source.PixelFormat := pf24Bit;
  867.         BValue := GetBValue(AColorRBG);
  868.         GValue := GetGValue(AColorRBG);
  869.         RValue := GetRValue(AColorRBG);
  870.         TempBitmap := TBitmap.Create;
  871.         TempBitmap.Assign(Source);
  872.         R1 := R;
  873.         Dest.Canvas.Lock;
  874.         try
  875.           Dest.Canvas.Brush.Color := AColorRBG;
  876.           Dest.Canvas.FillRect(R);
  877.           OffsetRect(R1, 1, 1);
  878.           DrawTransparentBitmap(Dest.Canvas.Handle, TempBitmap, R1, False);
  879.           for j := 0 to dHeight do
  880.           begin
  881.             LDScan := Dest.ScanLine[j];
  882.             LSScan := Dest.ScanLine[j];
  883.             i := 0;
  884.             while (i+2) <= ScanLineWidth do
  885.             begin
  886.               if (LSScan[i] <> BValue) or (LSScan[i+1] <> GValue) or (LSScan[i+2] <> RValue) then
  887.               begin
  888.                 //clXPShadow = $00888D9D;
  889.                 LDScan[i+2] := $88;
  890.                 LDScan[i+1] := $8D;
  891.                 LDScan[i]   := $9D;
  892.               end;
  893.               Inc(i, 3);
  894.             end;
  895.           end;
  896.           OffsetRect(R1, -2, -2);
  897.           DrawTransparentBitmap(Dest.Canvas.Handle, TempBitmap, R1, False);
  898.         finally
  899.           TempBitmap.Free;
  900.           Dest.Canvas.UnLock;
  901.         end;
  902.       end;
  903.   end;
  904. end;
  905.  
  906. procedure TransformBitmapTransparent(BkgImage, SrcImage: TBitmap;
  907.   var DstImage: TBitmap; Opacity: integer; AColor: TColor = $FFFFFF);
  908.  var
  909.   LSrcScan, LBkgScan, LDstScan: PByteArray;
  910.   i, j, ScanLineWidth: integer;
  911.   R: TRect;
  912.   AColorRBG: ULong;
  913.  
  914.   function GetScanAttr(A, B, Opacity: Integer): Integer;
  915.   begin
  916.     Result := ((A* Opacity) + B*(100-Opacity)) div 100;
  917.   end;
  918.    
  919.    procedure SetDstImageBounds;
  920.    begin
  921.      with DstImage do
  922.      begin
  923.        if SrcImage <> nil then
  924.        begin
  925.          Width := _intMin(BkgImage.Width, SrcImage.Width);
  926.          Height:= _intMin(BkgImage.Height, SrcImage.Height);
  927.        end
  928.        else begin
  929.          Width := BkgImage.Width;
  930.          Height:= BkgImage.Height;
  931.        end;
  932.        R := Rect(0, 0, Width, Height);
  933.      end;
  934.    end;
  935.  
  936. begin
  937.   {24 bits only}
  938.  
  939.   try
  940.     with DstImage do
  941.     begin
  942.       PixelFormat := pf24Bit;
  943.       SetDstImageBounds;
  944.       ScanLineWidth := Integer(ScanLine[0]) - Integer(ScanLine[1]);
  945.     end;
  946.   except
  947.     SetDstImageBounds;
  948.     DstImage.Canvas.CopyMode := cmSrcCopy;
  949.     DstImage.Canvas.CopyRect(R, SrcImage.Canvas, R);
  950.     Exit;
  951.   end;
  952.  
  953.   if SrcImage <> nil then SrcImage.PixelFormat := pf24Bit;
  954.   BkgImage.PixelFormat := pf24Bit;
  955.  
  956.   AColorRBG := $FFFFFF;
  957.   if AColor <> $FFFFFF then
  958.     AColorRBG := ColorToRGB(AColor)
  959.   else if SrcImage <> nil then
  960.     AColorRBG := SrcImage.Canvas.Pixels[0, 0];
  961.  
  962.   for j := 0 to DstImage.Height-1 do
  963.   begin
  964.     if SrcImage <> nil then
  965.     begin
  966.       LSrcScan := SrcImage.ScanLine[j];
  967.       LBkgScan := BkgImage.ScanLine[j];
  968.       LDstScan := DstImage.ScanLine[j];
  969.       i := 0;
  970.       while (i +3) <= ScanLineWidth do
  971.       begin
  972.        if AColorRBG <> RGB(LSrcScan[i+2], LSrcScan[i+1], LSrcScan[i]) then
  973.        begin
  974.          LDstScan[i]   := GetScanAttr(LSrcScan[i] ,  LBkgScan[i]  , Opacity);
  975.          LDstScan[i+1] := GetScanAttr(LSrcScan[i+1], LBkgScan[i+1], Opacity);
  976.          LDstScan[i+2] := GetScanAttr(LSrcScan[i+2], LBkgScan[i+2], Opacity);
  977.        end
  978.        else begin
  979.          LDstScan[i]   := LBkgScan[i];
  980.          LDstScan[i+1] := LBkgScan[i+1];
  981.          LDstScan[i+2] := LBkgScan[i+2];
  982.        end;
  983.        inc(i, 3);
  984.       end;
  985.     end
  986.     else begin
  987.       LBkgScan := BkgImage.ScanLine[j];
  988.       LDstScan := DstImage.ScanLine[j];
  989.       i := 0;
  990.       while (i+3) <= ScanLineWidth do
  991.       begin
  992.        LDstScan[i]   := GetScanAttr(GetBValue(AColor), LBkgScan[i]  , Opacity);
  993.        LDstScan[i+1] := GetScanAttr(GetGValue(AColor), LBkgScan[i+1], Opacity);
  994.        LDstScan[i+2] := GetScanAttr(GetRValue(AColor), LBkgScan[i+2], Opacity);
  995.        inc(i, 3);
  996.       end;
  997.     end;
  998.   end;
  999. end;
  1000.  
  1001.  
  1002. function DrawHighLightText(Canvas: TCanvas; Text: PChar; ARect: TRect;
  1003.   Mode: byte; DrawFlag: DWORD = DT_END_ELLIPSIS;
  1004.   ImageList: TImageList = nil): TPoint;
  1005.  
  1006.  var
  1007.   nHeight, nWidth, nLineWidth, nLineHeight: Integer;
  1008.   DrawRect: TRect;
  1009.   pValue, pDrawText: PChar;
  1010.   nDrawCount, nValueCount: integer;
  1011.   lFirstChar: boolean;
  1012.   lTranslateSlash: boolean;
  1013.   LogFont: TLogFont;
  1014.   pFont0, pFont1: HFONT;
  1015.   AFont: TFont;
  1016.  
  1017.  procedure IncDrawCount(nCount: integer = 1);
  1018.    var
  1019.     nTextHeight: integer;
  1020.  begin
  1021.    Inc(nDrawCount, nCount);
  1022.    if lFirstChar then
  1023.    begin
  1024.      nTextHeight := GetDCTextHeight(Canvas.Font, 'Wg');
  1025.      Inc(nLineHeight, nTextHeight);
  1026.      lFirstChar  := False;
  1027.    end
  1028.  end;
  1029.  
  1030.  procedure ClearDrawText;
  1031.  begin
  1032.    pDrawText  := Text;
  1033.    nDrawCount := 0;
  1034.  end;
  1035.  
  1036.  procedure PaintString;
  1037.   var
  1038.    R: TRect;
  1039.  begin
  1040.    R := DrawRect;
  1041.  
  1042.    if (pDrawText^ = #0) or (nDrawCount=0) then
  1043.    begin
  1044.      ClearDrawText;
  1045.      Exit;
  1046.    end;
  1047.  
  1048.    case Mode of
  1049.      0:
  1050.        begin
  1051.          {Γ√≈Φ±δ σ∞ ≡ατ∞σ≡ ≥σΩ±≥α}
  1052.          if DT_WORDBREAK and DrawFlag = 0 then
  1053.            DrawText(Canvas.Handle, pDrawText, nDrawCount, R, DT_CALCRECT or DT_SINGLELINE)
  1054.          else begin
  1055.            DrawText(Canvas.Handle, pDrawText, nDrawCount, R, DT_CALCRECT or DT_WORDBREAK);
  1056.            nLineHeight := R.Bottom - R.Top;
  1057.          end;
  1058.          Inc(nLineWidth, (R.Right-R.Left));
  1059.          DrawRect.Left := DrawRect.Left + (R.Right-R.Left);
  1060.        end;
  1061.      1:
  1062.        if DrawRect.Left < ARect.Right then
  1063.        begin
  1064.          DrawText(Canvas.Handle, pDrawText, nDrawCount, R,
  1065.            DT_CALCRECT or DrawFlag);
  1066.          DrawText(Canvas.Handle, pDrawText, nDrawCount, DrawRect, DrawFlag);
  1067.          Inc(nLineWidth, (R.Right-R.Left));
  1068.          DrawRect.Left := DrawRect.Left + (R.Right-R.Left);
  1069.        end;
  1070.    end;
  1071.  
  1072.    ClearDrawText;
  1073.  end;
  1074.  
  1075.  procedure NewLine;
  1076.  begin
  1077.    Inc(Text);
  1078.    PaintString;
  1079.    lFirstChar := True;
  1080.    nHeight  := nHeight + nLineHeight;
  1081.    nWidth   := _intMax(nWidth, nLineWidth);
  1082.    DrawRect := Rect(ARect.Left, ARect.Top+nHeight, ARect.Right,
  1083.      ARect.Bottom);
  1084.  
  1085.    nLineHeight := 0;
  1086.    nLineWidth  := 0;
  1087.  end;
  1088.  
  1089.  procedure TranslateSpecial;
  1090.   var
  1091.     cFlag: Char;
  1092.     nValue: integer;
  1093.     AR: TRect;
  1094.  
  1095.   function ReadParam: boolean;
  1096.    var
  1097.     pParam: PChar;
  1098.   begin
  1099.     nValueCount := 0;
  1100.     Inc(Text);                        // {
  1101.     Result := False;
  1102.     if Text^ in ['{', ','] then
  1103.     begin
  1104.       repeat
  1105.         Inc(Text)
  1106.       until not(Text^ in [#0, '}', ',', ' ']);
  1107.       pParam := Text;
  1108.       while not(Text^ in [#0, '}', ',']) do
  1109.       begin
  1110.         Inc(Text);
  1111.         Inc(nValueCount);
  1112.       end;
  1113.  
  1114.       if Text^ = ',' then
  1115.         Result := True
  1116.       else
  1117.         if Text^ <> #0 then Inc(Text);
  1118.  
  1119.       ReallocMem(pValue, nValueCount+1);
  1120.       StrLCopy(pValue, pParam, nValueCount);
  1121.     end;
  1122.   end;
  1123.  
  1124.   procedure ReadBitmapTag(AStyle: TTransformStyle; AdjustHeight: boolean);
  1125.    var
  1126.     ANext: boolean;
  1127.     nParam1, nParam2: integer;
  1128.  
  1129.   begin
  1130.     Inc(Text);
  1131.     ANext := ReadParam;
  1132.     if (nValueCount > 0) then
  1133.     begin
  1134.       try
  1135.         case AStyle of
  1136.           tsNormal:
  1137.             begin
  1138.               if Assigned(ImageList) and (pValue^ in ['0'..'9']) then
  1139.               begin
  1140.                 {}
  1141.                 if ANext then
  1142.                 begin
  1143.                   nValue := StrToIntDef(pValue, 0);
  1144.                   Dec(Text);
  1145.                   ReadParam;
  1146.                   if Mode > 0 then with DrawRect do
  1147.                   begin
  1148.                     Canvas.FillRect(Rect(Left, Top, Left + ImageList.Width, Bottom));
  1149.                     ImageList.DrawOverlay(Canvas, DrawRect.Left, DrawRect.Top,
  1150.                        nValue, StrToIntDef(pValue, 0));
  1151.                   end;
  1152.                 end
  1153.                 else
  1154.                   if Mode > 0 then with DrawRect do
  1155.                   begin
  1156.                     Canvas.FillRect(Rect(Left, Top, Left + ImageList.Width, Bottom));
  1157.                     ImageList.Draw(Canvas, Left, Top, StrToIntDef(pValue, 0), True);
  1158.                   end;
  1159.  
  1160.                 if AdjustHeight then
  1161.                 begin
  1162.                   if nLineHeight < ImageList.Height then
  1163.                   begin
  1164.                     nLineHeight := ImageList.Height;
  1165.                     lFirstChar  := False;
  1166.                   end;
  1167.                 end;
  1168.  
  1169.                 DrawRect.Left := DrawRect.Left + ImageList.Width;
  1170.                 Inc(nLineWidth, ImageList.Width);
  1171.               end
  1172.               else
  1173.                 try
  1174.                   TempBitmap.Canvas.Brush.Color := Canvas.Brush.Color;
  1175.                   with TempBitmap do
  1176.                   begin
  1177.                     if Mode > 0 then Canvas.FillRect(Rect(0, 0, Width, Height));
  1178.                     LoadFromResourceName(HInstance, pValue);
  1179.                   end;
  1180.                   if (Mode > 0) and (DrawRect.Left < DrawRect.Right) then
  1181.                     DrawBitmap(Canvas, TempBitmap, DrawRect, False);
  1182.                   DrawRect.Left := DrawRect.Left + TempBitmap.Width;
  1183.                   if AdjustHeight then
  1184.                   begin
  1185.                     if nLineHeight < TempBitmap.Height then
  1186.                     begin
  1187.                       nLineHeight := TempBitmap.Height;
  1188.                       lFirstChar  := False;
  1189.                     end
  1190.                   end;
  1191.                   Inc(nLineWidth, TempBitmap.Width);
  1192.                 except
  1193.                   {}
  1194.                 end;
  1195.             end;
  1196.           tsTransparent:
  1197.             begin
  1198.               TempBitmap.Canvas.Brush.Color := Canvas.Brush.Color;
  1199.  
  1200.               nParam1 := StrToIntDef(pValue, 0);
  1201.               if ANext then
  1202.               begin
  1203.                 Dec(Text);
  1204.                 ANext := ReadParam;
  1205.                 nParam2 := StrToIntDef(pValue, 0)
  1206.               end
  1207.               else
  1208.                 nParam2 := 50;
  1209.  
  1210.               if Assigned(ImageList) and (pValue^ in ['0'..'9']) then
  1211.               begin
  1212.                 if ANext then with TempBitmap do
  1213.                 begin
  1214.                   Width  := ImageList.Width;
  1215.                   Height := ImageList.Height;
  1216.                   Dec(Text);
  1217.                   ReadParam;
  1218.                   if Mode > 0 then
  1219.                   begin
  1220.                     Canvas.FillRect(Rect(0, 0, Width, Height));
  1221.                     ImageList.DrawOverlay(Canvas, 0, 0, nParam1, StrToIntDef(pValue, 0));
  1222.                   end;
  1223.                 end
  1224.                 else begin
  1225.                   with TempBitmap do
  1226.                   begin
  1227.                     if Mode > 0 then Canvas.FillRect(Rect(0, 0, Width, Height));
  1228.                     ImageList.GetBitmap(nParam1, TempBitmap)
  1229.                   end;
  1230.                 end
  1231.               end
  1232.               else
  1233.                 try
  1234.                   TempBitmap.LoadFromResourceName(HInstance, pValue);
  1235.                 except
  1236.                   {}
  1237.                 end;
  1238.  
  1239.               if (Mode > 0) and (DrawRect.Left < DrawRect.Right) then
  1240.               begin
  1241.                 TransformBitmapTransparent(TempBitmap, nil, TempBitmap,
  1242.                   nParam2, TempBitmap.Canvas.Pixels[0,0]);
  1243.                 DrawBitmap(Canvas, TempBitmap, DrawRect, False);
  1244.               end;
  1245.  
  1246.               DrawRect.Left := DrawRect.Left + TempBitmap.Width;
  1247.               Inc(nLineWidth, TempBitmap.Width);
  1248.             end;
  1249.           tsSelect, tsShadow, tsInvert, tsXPStyle:
  1250.             begin
  1251.               TempBitmap.Canvas.Brush.Color := Canvas.Brush.Color;
  1252.               nParam1 := StrToIntDef(pValue, 0);
  1253.  
  1254.               if Assigned(ImageList) and (pValue^ in ['0'..'9']) then
  1255.               begin
  1256.                 if ANext then with TempBitmap do
  1257.                 begin
  1258.                   Width  := ImageList.Width;
  1259.                   Height := ImageList.Height;
  1260.                   Dec(Text);
  1261.                   ReadParam;
  1262.                   if Mode > 0 then
  1263.                   begin
  1264.                     Canvas.FillRect(Rect(0, 0, Width, Height));
  1265.                     ImageList.DrawOverlay(Canvas, 0, 0, nParam1, StrToIntDef(pValue, 0));
  1266.                   end;
  1267.                 end
  1268.                 else begin
  1269.                   with TempBitmap do
  1270.                   begin
  1271.                     if Mode > 0 then Canvas.FillRect(Rect(0, 0, Width, Height));
  1272.                     ImageList.GetBitmap(nParam1, TempBitmap)
  1273.                   end;
  1274.                 end
  1275.               end
  1276.               else
  1277.                 try
  1278.                   TempBitmap.LoadFromResourceName(HInstance, pValue);
  1279.                 except
  1280.                   {}
  1281.                 end;
  1282.  
  1283.               if (Mode > 0) and (DrawRect.Left < DrawRect.Right) then
  1284.               begin
  1285.                 TransformBitmap(TempBitmap, TempBitmap, AStyle);
  1286.                 DrawBitmap(Canvas, TempBitmap, DrawRect, False);
  1287.               end;
  1288.  
  1289.               DrawRect.Left := DrawRect.Left + TempBitmap.Width;
  1290.               Inc(nLineWidth, TempBitmap.Width);
  1291.             end;
  1292.         end;
  1293.  
  1294.         Dec(Text);
  1295.       finally
  1296.         {}
  1297.       end;
  1298.     end
  1299.     else begin
  1300.       Canvas.Font.Style := Canvas.Font.Style  + [fsItalic];
  1301.       Dec(Text, 2);
  1302.     end
  1303.   end;
  1304.  
  1305.  begin
  1306.    Inc(Text);
  1307.    if Text^<>#0 then
  1308.    begin
  1309.      case Text^ of
  1310.        'b':
  1311.           begin
  1312.             if ((Text+1)^<>#0) and ((Text+1)^ = '0') then
  1313.             begin
  1314.               Canvas.Font.Style := Canvas.Font.Style  - [fsBold];
  1315.               Inc(Text);
  1316.             end
  1317.             else
  1318.               Canvas.Font.Style := Canvas.Font.Style  + [fsBold];
  1319.             Inc(Text);
  1320.             ClearDrawText;
  1321.           end;
  1322.        'i':
  1323.           begin
  1324.             if ((Text+1)^<>#0) then
  1325.             begin
  1326.               case (Text+1)^ of
  1327.                '0':
  1328.                  begin
  1329.                   Canvas.Font.Style := Canvas.Font.Style  - [fsItalic];
  1330.                   Inc(Text);
  1331.                  end;
  1332.                'd': ReadBitmapTag(tsTransparent, False);
  1333.                'n': ReadBitmapTag(tsInvert, False);
  1334.                'h': ReadBitmapTag(tsShadow, False);
  1335.                'm': ReadBitmapTag(tsNormal, False);
  1336.                'p': ReadBitmapTag(tsNormal, True);
  1337.                's': ReadBitmapTag(tsSelect, False);
  1338.                'x': ReadBitmapTag(tsXPStyle, False);
  1339.                else
  1340.                  Canvas.Font.Style := Canvas.Font.Style  + [fsItalic];
  1341.               end;
  1342.             end
  1343.             else
  1344.               Canvas.Font.Style := Canvas.Font.Style  + [fsItalic];
  1345.             Inc(Text);
  1346.             ClearDrawText;
  1347.           end;
  1348.        'u':
  1349.           begin
  1350.             if ((Text+1)^<>#0) and ((Text+1)^ = '0') then
  1351.             begin
  1352.               Canvas.Font.Style := Canvas.Font.Style  - [fsUnderline];
  1353.               Inc(Text);
  1354.             end
  1355.             else
  1356.               Canvas.Font.Style := Canvas.Font.Style  + [fsUnderline];
  1357.             Inc(Text);
  1358.             ClearDrawText;
  1359.            end;
  1360.        'f':
  1361.           begin
  1362.             if ((Text+1)^<>#0) and ((Text+1)^ = '0') then
  1363.             begin
  1364.               Canvas.Font.Name := AFont.Name;
  1365.               Inc(Text, 2);
  1366.             end
  1367.             else begin
  1368.               ReadParam;
  1369.               Canvas.Font.Name := Strpas(pValue);
  1370.             end;
  1371.             ClearDrawText;
  1372.           end;
  1373.        's':
  1374.           begin
  1375.             if ((Text+1)^<>#0) then
  1376.             begin
  1377.               case (Text+1)^ of
  1378.                '0':
  1379.                  begin
  1380.                    Canvas.Font.Style := Canvas.Font.Style  - [fsStrikeOut];
  1381.                    Inc(Text);
  1382.                  end;
  1383.                '{':
  1384.                  begin
  1385.                    ReadParam;
  1386.                    nValue := StrToIntDef(pValue, 0);
  1387.                    if (pValue^ = '+') or  (pValue^ = '-')then
  1388.                      Canvas.Font.Size := Canvas.Font.Size + nValue
  1389.                    else
  1390.                    if pValue^ = '0' then
  1391.                      Canvas.Font.Size := AFont.Size
  1392.                    else
  1393.                      Canvas.Font.Size := nValue;
  1394.                    Dec(Text);
  1395.                  end;
  1396.                else
  1397.                  Canvas.Font.Style := Canvas.Font.Style  + [fsStrikeOut];
  1398.               end;
  1399.             end
  1400.             else
  1401.               Canvas.Font.Style := Canvas.Font.Style  + [fsStrikeOut];
  1402.             Inc(Text);
  1403.             ClearDrawText;
  1404.           end;
  1405.        'o':
  1406.           begin
  1407.             if ((Text+1)^<>#0) then
  1408.             begin
  1409.               case (Text+1)^ of
  1410.                 'w','h', 'W', 'H':
  1411.                   begin
  1412.                     Inc(Text);
  1413.                     cFlag := Text^;
  1414.                     ReadParam;
  1415.                     if IsValidInteger(pValue) then
  1416.                     begin
  1417.                       nValue := StrToIntDef(pValue, 0);
  1418.                       case cFlag of
  1419.                         'w':
  1420.                           begin
  1421.                             DrawRect.Left := DrawRect.Left + nValue;
  1422.                             Inc(nLineWidth, nValue);
  1423.                           end;
  1424.                         'h':
  1425.                           begin
  1426.                             DrawRect.Top := DrawRect.Top + nValue;
  1427.                             Inc(nLineHeight, nValue);
  1428.                           end;
  1429.                         'W':
  1430.                           begin
  1431.                             DrawRect.Left := DrawRect.Left - nValue;
  1432.                             Dec(nLineWidth, nValue);
  1433.                           end;
  1434.                         'H':
  1435.                           begin
  1436.                             DrawRect.Top := DrawRect.Top - nValue;
  1437.                             Dec(nLineHeight, nValue);
  1438.                           end;
  1439.                       end;
  1440.                     end
  1441.                     else begin
  1442.                        SetRectEmpty(AR);
  1443.                        DrawText(Canvas.Handle, pValue, Length(pValue), AR, DT_CALCRECT or DT_SINGLELINE);
  1444.                        case cFlag of
  1445.                          'w':
  1446.                            begin
  1447.                              DrawRect.Left := DrawRect.Left + AR.Right - AR.Left;
  1448.                              Inc(nLineWidth, AR.Right - AR.Left);
  1449.                            end;
  1450.                          'h':
  1451.                            begin
  1452.                              DrawRect.Top := DrawRect.Top + AR.Bottom - AR.Top;
  1453.                              Inc(nLineHeight, AR.Bottom - AR.Top);
  1454.                            end;
  1455.                          'W':
  1456.                            begin
  1457.                              DrawRect.Left := DrawRect.Left - AR.Right + AR.Left;
  1458.                              Inc(nLineWidth, - AR.Right + AR.Left);
  1459.                            end;
  1460.                          'H':
  1461.                            begin
  1462.                              DrawRect.Top := DrawRect.Top - AR.Bottom + AR.Top;
  1463.                              Inc(nLineHeight, - AR.Bottom + AR.Top);
  1464.                            end;
  1465.                        end;
  1466.                     end;
  1467.                     ClearDrawText;
  1468.                   end;
  1469.               end;
  1470.             end;
  1471.           end;
  1472.        'c':
  1473.           begin
  1474.             ReadParam;
  1475.             ClearDrawText;
  1476.             try
  1477.               nValue := StringToColor(pValue);
  1478.               Canvas.Font.Color := nValue;
  1479.             except
  1480.             end;
  1481.           end;
  1482.        'l':
  1483.           begin
  1484.             ReadParam;
  1485.             ClearDrawText;
  1486.             try
  1487.               nValue := StringToColor(pValue);
  1488.               Canvas.Pen.Color := nValue;
  1489.               with DrawRect do
  1490.               begin
  1491.                 Canvas.MoveTo(Left , Top);
  1492.                 Canvas.LineTo(Right, Top);
  1493.               end;
  1494.             except
  1495.             end;
  1496.           end;
  1497.        '#':
  1498.          NewLine;
  1499.        else
  1500.          IncDrawCount;
  1501.      end;
  1502.    end
  1503.    else
  1504.      IncDrawCount;
  1505.  end;
  1506.  
  1507. begin
  1508. (*
  1509.   ±∩σ÷Φαδⁿφ√σ ±Φ∞Γεδ√:
  1510.   /b  - ≤±≥αφεΓΩα Bold
  1511.   /b0 - ±φ ≥Φσ Bold
  1512.   /i  - ≤±≥αφεΓΩα Italic
  1513.   /i0 - ±φ ≥Φσ Italic
  1514.   /u  - ≤±≥αφεΓΩα Underline
  1515.   /u0 - ±φ ≥Φσ Underline
  1516.   /s  - StrikeOut
  1517.   /s0 - StrikeOut
  1518.   /f{font name} - ≤±≥αφεΓΩα °≡Φ⌠≥α           **αΩ≥≤αδⁿφε ≥εδⁿΩε Γ φα≈αδσ ±≥≡εΩΦ
  1519.   /s{font size} - ≤±≥αφεΓΩα ≡ατ∞σ≡α          **αΩ≥≤αδⁿφε ≥εδⁿΩε Γ φα≈αδσ ±≥≡εΩΦ
  1520.   /ow{length}    - ±∞σ∙σφΦσ ε≥φε±Φ≥σδⁿφε ∩ε±δσΣφσΘ ∩ετΦ÷ΦΦ ∩ε πε≡Φτεφ≥αδΦ
  1521.   /oh{length}    - ±∞σ∙σφΦσ ε≥φε±Φ≥σδⁿφε ∩ε±δσΣφσΘ ∩ετΦ÷ΦΦ ∩ε Γσ≡≥ΦΩαδΦ
  1522.   /c{color}     - ≤±≥αφεΓΩα ÷Γσ≥α
  1523.   /im{resource name} - ≡Φ±εΓαφΦσ ßΦ≥∞α∩α
  1524.   /ip{resource name} - ≡Φ±εΓαφΦσ ßΦ≥∞α∩α
  1525.   /is{resource name} - ≡Φ±εΓαφΦσ ßΦ≥∞α∩α
  1526.   /l{color}          - ≡Φ±εΓαφΦσ δΦφΦΦ
  1527.   /#                 - φεΓα  ±≥≡εΩα
  1528.   /{.../}            - φα≈αδε ±≥≡εΩΦ ßστ εß≡αßε≥ΩΦ ±∩σ÷.±Φ∞ΓεδεΓ
  1529. *)
  1530.  
  1531.   if Text = '' then begin
  1532.     Result := Point(0,0);
  1533.     Exit;
  1534.   end;
  1535.  
  1536.   pValue := AllocMem(1);
  1537.  
  1538.   AFont := TFont.Create;
  1539.   AFont.Assign(Canvas.Font);
  1540.   GetObject(Canvas.Font.Handle, SizeOf(TLogFont), @LogFont);
  1541.   pFont0 := CreateFontIndirect(LogFont);
  1542.   pFont1 := SelectObject(Canvas.Handle, pFont0);
  1543.  
  1544.  
  1545.   SetBkMode(Canvas.Handle, TRANSPARENT);
  1546.  
  1547.   nHeight := 0;
  1548.   nWidth  := 0;
  1549.  
  1550.   lFirstChar := True;
  1551.   DrawRect   := ARect;
  1552.  
  1553.   nLineHeight := 0;
  1554.   nLineWidth  := 0;
  1555.  
  1556.   ClearDrawText;
  1557.  
  1558.   if Mode = 0 then ARect := Rect(ARect.Left, ARect.Top, MaxInt, MaxInt);
  1559.  
  1560.   lTranslateSlash := True;
  1561.  
  1562.   try
  1563.     while Text^<>#0 do
  1564.     begin
  1565.       case Text^ of
  1566.         '/': begin
  1567.               if ((Text+1)^<>#0) then
  1568.               begin
  1569.                 case (Text+1)^ of
  1570.                   '{':
  1571.                     begin
  1572.                       PaintString;
  1573.                       lTranslateSlash := False;
  1574.                       Inc(Text, 2);
  1575.                       ClearDrawText;
  1576.                     end;
  1577.                   '}':
  1578.                     begin
  1579.                       PaintString;
  1580.                       lTranslateSlash := True;
  1581.                       Inc(Text, 2);
  1582.                       ClearDrawText;
  1583.                     end;
  1584.                   else begin
  1585.                     if lTranslateSlash then
  1586.                     begin
  1587.                       PaintString;
  1588.                       TranslateSpecial;
  1589.                     end
  1590.                     else begin
  1591.                       IncDrawCount;
  1592.                       Inc(Text);
  1593.                     end;
  1594.                   end
  1595.                 end;
  1596.               end
  1597.               else begin
  1598.                 IncDrawCount;
  1599.                 Inc(Text);
  1600.               end;
  1601.              end;
  1602.         #10: begin
  1603.                NewLine;
  1604.              end;
  1605.         #13:begin
  1606.               if not lFirstChar then
  1607.                 NewLine
  1608.               else
  1609.                 Inc(Text);
  1610.               ClearDrawText;
  1611.            end;
  1612.         else begin
  1613.           IncDrawCount;
  1614.           Inc(Text);
  1615.         end;
  1616.       end
  1617.     end;
  1618.     PaintString;
  1619.     nHeight := nHeight + nLineHeight;
  1620.     nWidth  := _intMax(nWidth, nLineWidth) + ARect.Left;
  1621.     Result  := Point(nWidth, nHeight);
  1622.   finally
  1623.     Canvas.Font.Assign(AFont);
  1624.     SelectObject(Canvas.Handle, pFont1);
  1625.     DeleteObject(pFont0);
  1626.     AFont.Free;
  1627.     ReallocMem(pValue,0);
  1628.   end;
  1629. end;
  1630.  
  1631. procedure DrawGridFrameBorder(Canvas: TCanvas; ARect: TRect;
  1632.   AStyle: TEdgeBorderStyle; AState: TDrawBorerState; FixedColor: TColor);
  1633.   var
  1634.    APoints: array of TPoint;
  1635. begin
  1636.   case AStyle of
  1637.     ebsNormal:
  1638.      case AState of
  1639.        dsUp:
  1640.          begin
  1641.            DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT);
  1642.          end;
  1643.        dsDown:
  1644.          begin
  1645.            DrawEdge(Canvas.Handle, ARect, BDR_SUNKENINNER, BF_BOTTOMRIGHT);
  1646.            DrawEdge(Canvas.Handle, ARect, BDR_SUNKENOUTER, BF_TOPLEFT);
  1647.          end;
  1648.      end;
  1649.     ebsFlat:
  1650.      begin
  1651.        case AState of
  1652.          dsUp:
  1653.            begin
  1654.              DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT);
  1655.            end;
  1656.          dsDown:
  1657.            begin
  1658.              DrawEdge(Canvas.Handle, ARect, BDR_SUNKENOUTER, BF_RECT);
  1659.            end;
  1660.        end;
  1661.      end;
  1662.    ebsNone:
  1663.      begin
  1664.        FrameRect(Canvas.Handle, ARect, CreateSolidBrush(ColorToRGB(FixedColor)));
  1665.        SetLength(APoints, 4);
  1666.        APoints[0].X := ARect.Left ; APoints[0].Y := ARect.Bottom;
  1667.        APoints[1].X := ARect.Right; APoints[1].Y := ARect.Bottom;
  1668.        APoints[2].X := ARect.Right; APoints[2].Y := ARect.Top-1;
  1669.        APoints[3].X := ARect.Left ; APoints[3].Y := ARect.Top-1;
  1670.        if ColorToRGB(FixedColor) = clSilver then
  1671.          Canvas.Pen.Color := clGray
  1672.        else
  1673.          Canvas.Pen.Color := clSilver;
  1674.        Canvas.Polyline(APoints);
  1675.      end;
  1676.    ebsShadowFlat:
  1677.       begin
  1678.        InflateRect(Arect, -1, -1);
  1679.        case AState of
  1680.          dsUp:
  1681.            begin
  1682.              DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT);
  1683.            end;
  1684.          dsDown:
  1685.            begin
  1686.              DrawEdge(Canvas.Handle, ARect, BDR_SUNKENOUTER, BF_RECT);
  1687.            end;
  1688.        end;
  1689.       end;
  1690.   end;
  1691. end;
  1692.  
  1693. {$HINTS OFF}
  1694. function GetNumericFormat(Value: PChar; var Precision: integer;
  1695.   var Digits: integer): TNumericFormat;
  1696. type
  1697.  TNumericPart = (npIntegral, npDecimal, npExponent);
  1698.  
  1699.  var
  1700.   NumericPart:  TNumericPart;
  1701.   Values: array[TNumericPart] of string[30];
  1702.   ESigns: array[TNumericPart] of ShortInt;
  1703.   ESChar: array[TNumericPart] of Char;
  1704.   V, E: Integer;
  1705. begin
  1706.   ESigns[npIntegral] := 0;
  1707.   ESigns[npDecimal ] := -1;
  1708.   ESigns[npExponent] := 0;
  1709.  
  1710.   Precision := 0;
  1711.   Digits    := 0;
  1712.  
  1713.   for NumericPart := npIntegral to npExponent do
  1714.   begin
  1715.     Values[NumericPart] := '';
  1716.     ESChar[NumericPart] := '+';
  1717.   end;
  1718.  
  1719.   Result      := nmInteger;
  1720.   NumericPart := npIntegral;
  1721.  
  1722.   while (Value^ <> #0) and (Result <> nmNone) do
  1723.   begin
  1724.     case Value^ of
  1725.       '+', '-':
  1726.         if (ESigns[NumericPart] = 0) and (Values[NumericPart] = '') then
  1727.         begin
  1728.           ESigns[NumericPart] := ESigns[NumericPart] + 1;
  1729.           ESChar[NumericPart] := Value^;
  1730.         end
  1731.         else begin
  1732.           Result := nmNone;
  1733.           continue;
  1734.         end;
  1735.       'E', 'e':
  1736.         if (NumericPart <> npExponent) and
  1737.            ((NumericPart = npIntegral) and (Values[NumericPart] <> '') or
  1738.             (NumericPart = npDecimal ) and (Values[NumericPart] <> '')) then
  1739.         begin
  1740.           NumericPart := npExponent;
  1741.           Result      := nmExponent;
  1742.         end
  1743.         else begin
  1744.           Result := nmNone;
  1745.           continue;
  1746.         end;
  1747.       '0'..'9':
  1748.         Values[NumericPart] := Values[NumericPart] + Value^;
  1749.       else
  1750.         if (Value^ = DecimalSeparator) and
  1751.            (Result = nmInteger)
  1752.         then begin
  1753.           NumericPart := npDecimal;
  1754.           Result      := nmDecimal
  1755.         end
  1756.         else begin
  1757.           Result := nmNone;
  1758.           continue;
  1759.         end;
  1760.     end;
  1761.     Inc(Value);
  1762.   end;
  1763.   case Result of
  1764.     nmInteger:
  1765.       begin
  1766.         Val(Values[npIntegral], V, E);
  1767.         if E <> 0  then Result := nmNone;
  1768.         Digits := Length(Values[npIntegral]);
  1769.       end;
  1770.     nmDecimal:
  1771.       begin
  1772.         if Length(Values[npDecimal])<= CurrencyDecimals then
  1773.           Result := nmCurrency;
  1774.         Digits    := Length(Values[npIntegral]) + Length(Values[npDecimal]) + 1;
  1775.         Precision := Length(Values[npDecimal]);
  1776.       end;
  1777.     nmExponent:
  1778.       begin
  1779.         if Length(Values[npExponent]) = 0 then
  1780.         begin
  1781.           Result := nmNone;
  1782.           Exit;
  1783.         end;
  1784.         Digits := Length(Values[npIntegral]);
  1785.         if Length(Values[npDecimal]) > 0 then
  1786.           Inc(Digits, Length(Values[npDecimal]) + 1);
  1787.         Precision := Length(Values[npDecimal]);
  1788.         Inc(Digits, Length(Values[npExponent]));
  1789.         case ESChar[npExponent] of
  1790.           '+':
  1791.             begin
  1792.               Dec(Precision, Length(Values[npExponent]));
  1793.               if Precision < 0 then Precision := 0;
  1794.             end;
  1795.           '-':
  1796.              Inc(Precision, Length(Values[npExponent]));
  1797.         end;
  1798.       end;
  1799.   end;
  1800. end;
  1801. {$HINTS ON}
  1802.  
  1803. function IsValidInteger(Value: string): boolean;
  1804.  var
  1805.   NumericFormat: TNumericFormat;
  1806.   Precision, Digits: integer;
  1807. begin
  1808.   NumericFormat := GetNumericFormat(PChar(Value), Precision, Digits);
  1809.   Result := (NumericFormat = nmInteger);
  1810. end;
  1811.  
  1812. function IsValidFloat(Value: string): boolean;
  1813.  var
  1814.   NumericFormat: TNumericFormat;
  1815.   Precision, Digits: integer;
  1816. begin
  1817.   NumericFormat := GetNumericFormat(PChar(Value), Precision, Digits);
  1818.   Result := (NumericFormat = nmInteger)  or
  1819.             (NumericFormat = nmDecimal)  or
  1820.             (NumericFormat = nmCurrency) or
  1821.             (NumericFormat = nmExponent);
  1822. end;
  1823.  
  1824. function IsValidCurrency(Value: string; APrecision: integer): boolean;
  1825.  var
  1826.   NumericFormat: TNumericFormat;
  1827.   Precision, Digits: integer;
  1828. begin
  1829.   NumericFormat := GetNumericFormat(PChar(Value), Precision, Digits);
  1830.   Result := (NumericFormat = nmCurrency) or (NumericFormat = nmInteger) or
  1831.             ((NumericFormat = nmDecimal) and ((APrecision = -1) or (Precision <= APrecision)));
  1832. end;
  1833.  
  1834. function CheckInteger(var Value: string; ADigits: integer): boolean;
  1835.  var
  1836.   NumericFormat: TNumericFormat;
  1837.   Precision, Digits: integer;
  1838. begin
  1839.   NumericFormat := GetNumericFormat(PChar(Value), Precision, Digits);
  1840.   Result := (NumericFormat = nmInteger) and ((ADigits = -1) or (Digits <= ADigits));
  1841. end;
  1842.  
  1843. function CheckFloat(var Value: string; APrecision, ADigits: integer): boolean;
  1844.  var
  1845.   NumericFormat: TNumericFormat;
  1846.   Precision, Digits, i, LastDigit: integer;
  1847. begin
  1848.   NumericFormat := GetNumericFormat(PChar(Value), Precision, Digits);
  1849.   Result := ((NumericFormat = nmInteger)  or
  1850.              (NumericFormat = nmDecimal)  or
  1851.              (NumericFormat = nmCurrency) or
  1852.              (NumericFormat = nmExponent)) and
  1853.             ((ADigits = -1) or (Digits <= ADigits)) and
  1854.             ((APrecision = -1) or (Precision <= APrecision));
  1855.   if Result then
  1856.   begin
  1857.     case NumericFormat of
  1858.       nmInteger :
  1859.         begin
  1860.           if APrecision > 0 then
  1861.           begin
  1862.             Value := Value + DecimalSeparator;
  1863.             for i := 0 to APrecision - 1 do Value := Value + '0';
  1864.           end;
  1865.         end;
  1866.       nmCurrency, nmDecimal:
  1867.         for i := Precision to APrecision - 1 do Value := Value + '0';
  1868.     end;
  1869.   end
  1870.   else begin
  1871.     if (NumericFormat = nmDecimal) and (Precision > APrecision) then
  1872.     begin
  1873.       Result    := True;
  1874.       LastDigit := Digits - Precision + APrecision;
  1875.       Value  := Copy(Value, 1, LastDigit);
  1876.     end;
  1877.   end
  1878. end;
  1879.  
  1880. function CheckCurrency(var Value: string; APrecision, ADigits: integer): boolean;
  1881.  var
  1882.   NumericFormat: TNumericFormat;
  1883.   Precision, Digits, i: integer;
  1884. begin
  1885.   NumericFormat := GetNumericFormat(PChar(Value), Precision, Digits);
  1886.   Result := ((NumericFormat = nmCurrency) or (NumericFormat = nmInteger) or
  1887.              ((NumericFormat = nmDecimal) and ((APrecision = -1) or (Precision <= APrecision)))
  1888.             ) and
  1889.             ((ADigits = -1) or (Digits <= ADigits));
  1890.   if Result then
  1891.   begin
  1892.     case NumericFormat of
  1893.       nmInteger :
  1894.         begin
  1895.           Value := Value + DecimalSeparator;
  1896.           for i := 0 to CurrencyDecimals - 1 do Value := Value + '0';
  1897.         end;
  1898.       nmCurrency:
  1899.         for i := Precision to CurrencyDecimals - 1 do Value := Value + '0';
  1900.     end;
  1901.   end;
  1902. end;
  1903.  
  1904. function RecordCount2Str(Count: integer): string;
  1905. begin
  1906.   Result := LoadStr(RES_GRID_REC_ROOT);
  1907.   case (Count mod 10) of
  1908.     1..4     :
  1909.       begin
  1910.         if (Count mod 100) = 11 then
  1911.           Result := Result + LoadStr(RES_GRID_REC_VAL0)
  1912.         else
  1913.           if (Count mod 10) = 1 then
  1914.             Result := Result + LoadStr(RES_GRID_REC_VAL1)
  1915.           else
  1916.             Result := Result + LoadStr(RES_GRID_REC_VAL2);
  1917.       end;
  1918.     0,5..9: Result := Result + LoadStr(RES_GRID_REC_VAL0);
  1919.   end;
  1920. end;
  1921.  
  1922. function CreateEmptyRgn: HRGN;
  1923.  var
  1924.   R: TRect;
  1925. begin
  1926.   SetRectEmpty(R);
  1927.   Result := CreateRectrgnIndirect(R);
  1928. end;
  1929.  
  1930. procedure CreateSystemImages;
  1931.  var
  1932.   Bitmap: TBitmap;
  1933.   i: integer;
  1934.  
  1935.  const
  1936.   SMALL_IMAGE_PREFIX = 'DC_SMALL_IMAGE';
  1937.   LARGE_IMAGE_PREFIX = 'DC_LARGE_IMAGE';
  1938.  
  1939.   SMALL_IMAGE_COUNT  = 10;
  1940.   LARGE_IMAGE_COUNT  = 0;
  1941.  
  1942. begin
  1943.   Bitmap := TBitmap.Create;
  1944.   try
  1945.     i := 0;
  1946.     repeat
  1947.       Bitmap.LoadFromResourceName(HInstance, Format('%s%2.2d', [SMALL_IMAGE_PREFIX, i]));
  1948.       if i = 0 then SystemSmallImages := TImageList.CreateSize(Bitmap.Width, Bitmap.Height);
  1949.       SystemSmallImages.AddMasked(Bitmap, Bitmap.Canvas.Pixels[0,0]);
  1950.       inc(i);
  1951.     until i = SMALL_IMAGE_COUNT;
  1952.   finally
  1953.     Bitmap.Free;
  1954.     SystemSmallImages.Overlay(0, 0);
  1955.     SystemSmallImages.Overlay(1, 1);
  1956.     SystemSmallImages.Overlay(2, 2);
  1957.     SystemSmallImages.Overlay(3, 3);
  1958.   end;
  1959. end;
  1960.  
  1961. procedure DestroySystemImages;
  1962. begin
  1963.   SystemSmallImages.Clear;
  1964.   SystemSmallImages.Free;
  1965. end;
  1966.  
  1967. function ETGetSystemImages(Mode: integer): TImageList;
  1968. begin
  1969.   if Mode and DCGIM_SMALLICON <> 0 then
  1970.     Result := SystemSmallImages
  1971.   else
  1972.     Result := nil;
  1973. end;
  1974.  
  1975. procedure ETGetBitmap(Mode, Index: integer; ABitmap: TBitmap);
  1976. begin
  1977.   if Mode and DCGIM_SMALLICON <> 0 then
  1978.   begin
  1979.     SystemSmallImages.GetBitmap(Index, ABitmap);
  1980.   end;
  1981. end;
  1982.  
  1983. initialization
  1984.  TempBitmap := TBitmap.Create;
  1985.  TempBitmap.PixelFormat := pf24Bit;
  1986.  CreateSystemImages;
  1987.  
  1988. finalization
  1989.  TempBitmap.Free;
  1990.  DestroySystemImages;
  1991.  
  1992. end.
  1993.