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

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49(0)351-8037944               =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/index.html               =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 10.01.99 - 02:42:37 $                                        =}
  24. {========================================================================}
  25. unit MMUtils;
  26. {$I COMPILER.INC}
  27. interface
  28. {.$DEFINE _MMDEBUG_}
  29. uses
  30.     {$IFDEF WIN32}
  31.     Windows,
  32.     Registry,
  33.     {$ELSE}
  34.     WinTypes,
  35.     WinProcs,
  36.     {$ENDIF}
  37.     {$IFDEF DELPHI6}
  38.     Variants,
  39.     {$ENDIF}
  40.     Messages,
  41.     SysUtils,
  42.     Controls,
  43.     Classes,
  44.     Forms,
  45.     FileCtrl,
  46.     Dialogs,
  47.     Graphics
  48.     {$IFDEF BUILD_ACTIVEX}
  49.     ,MMAbout
  50.     {$ENDIF}
  51.     ;
  52. {$I MMTYPES.INC}
  53. {$IFDEF BUILD_ACTIVEX}
  54.    {$I MMREGCODES.INC}
  55. {$ENDIF}
  56. const
  57.     InstalledUser  : string  = '*UI:*******************************************************************************';
  58.     InitCode       : Longint = 0;
  59.     ErrorCode      : Longint = 0;
  60.     SHandle        : integer = 0;
  61.     IValue         : integer = 0;
  62.     DValue         : integer = 0;
  63.     SBuf           : PChar   = nil;
  64.     MMUTILDLLHandle: THandle = 0;
  65. var
  66.     SValue        : string;
  67.     _Win95_       : Boolean;
  68.     _Win98_       : Boolean;
  69.     _WinME_       : Boolean;
  70.     _Win9x_       : Boolean;
  71.     _WinNT3_      : Boolean;
  72.     _WinNT4_      : Boolean;
  73.     _Win2K_       : Boolean;
  74.     _WinXP_       : Boolean;
  75.     _WinNT_       : Boolean;
  76.     _WinNT_NEW_   : Boolean;
  77.     _CPU_         : integer;
  78.     _MMX_         : Boolean;
  79.     _USECPUEXT_   : Boolean;
  80. {$IFDEF USEDLL}
  81. const
  82. {$IFDEF WIN32}
  83.    MMUtilDLLName    = 'MMUTIL32.DLL'#0;//'MMUTIL32.DLL'#0;
  84.    MMUtilDLLKeyName = 'MMKEY32.DLL'#0;
  85. {$ELSE}
  86.    MMUtilDLLName    = 'MMUTIL16.DLL'#0;
  87.    MMUtilDLLKeyName = 'MMKEY16.DLL'#0;
  88. {$ENDIF}
  89. {$ENDIF}
  90. const
  91.     { Processor constants }
  92.     PENTIUM    = 1;
  93.     PENTIUMPRO = 2;
  94.     PENTIUMPRO2= 3;
  95.     MMAXLONG   = 2000000000;
  96.     {$IFDEF WIN32}
  97.     MM_USER    = WM_APP;
  98.     {$ELSE}
  99.     MM_USER    = WM_USER;
  100.     {$ENDIF}
  101.     MM_TIMER   = MM_USER + 10;
  102. {$IFNDEF WIN32}
  103.     MAX_PATH   = 260;
  104.     cl3DLight  = clBtnFace;
  105. procedure MoveWindowOrg(DC: HDC; DX, DY: Integer);
  106. {$ELSE}
  107. function  MMSetThreadPriority(hThread: THandle; nPriority: integer): Boolean;
  108. function  MMSetPriorityClass(hProcess: THandle; fdwPriority: DWORD): Boolean;
  109. function  GetFromRegistry(_RootKey:HKEY;_Localkey,_Field:string;Value:Variant): Variant;
  110. procedure SaveInRegistry(_RootKey:HKEY;_Localkey,_Field:string;Value:Variant);
  111. function  GetFromRegistryBinary(_RootKey:HKEY;_Localkey,_Field:string;var Buffer; BufSize: integer): integer;
  112. procedure SaveInRegistryBinary(_RootKey:HKEY;_Localkey,_Field:string;var Buffer; BufSize: integer);
  113. function  GetCPUUsage: integer;
  114. function  GetShortFileName(Name: TFileName): String;
  115. function  GetCPUType: integer;
  116. function  GetCPUFeatures: Longint;
  117. function  GetCPUMode: integer;
  118. function  GetCPUCycles: int64;
  119. procedure InitTimeMeasure;
  120. procedure StartTimeMeasure;
  121. function  StopTimeMeasure(Scale: integer): string;
  122. procedure InitCyclesMeasure;
  123. procedure StartCyclesMeasure;
  124. function  StopCyclesMeasure(Scale: integer): string;
  125. {$ENDIF}
  126. function  HaveWin95: Boolean;
  127. function  HaveWin98: Boolean;
  128. function  HaveWinME: Boolean;
  129. function  HaveWinNT: Boolean;
  130. function  HaveWinNT4: Boolean;
  131. function  HaveWin2K: Boolean;
  132. function  HaveWinXP: Boolean;
  133. function  TimeGetExactTime: int64;
  134. procedure Delay(ms: DWORD; ProcessMessages: Boolean);
  135. function  NonClientHeight: integer;
  136. function  MenuHeight: integer;
  137. function  BitsPerPixel: integer;
  138. function  ClientToClient(Destination, Source: TControl; P: TPoint): TPoint;
  139. {$IFDEF WIN32}
  140. function  CreateFullDir(Dir: string): Boolean;
  141. procedure DeleteDir(Dir: string);
  142. {$ENDIF}
  143. function  GetFileSize(Name: TFileName): Longint;
  144. function  GetDiskStats(const Directory: string; var nFree, nSize: Int64): Boolean;
  145. function  GetDiskFree(const Directory: string; nBytes: Longint): Boolean;
  146. procedure ChangeColors(Bitmap: TBitmap; DrawInactive: Boolean;
  147.                        ForeColor, InactiveColor, BackColor: TColor);
  148. procedure GetBitmapSize(Bitmap: HBitmap; var W, H: integer);
  149. function  GetTransparentColorEx(Bitmap: HBitmap; Point: TPoint): TColorRef;
  150. function  GetTransparentColor(Bitmap: HBitmap): TColorRef;
  151. procedure DrawTransparentBitmapEx(DC: HDC; Bitmap: HBitmap; X, Y: integer;
  152.                                   Src: TRect; Transparent: TColorRef);
  153. procedure DrawTransparentBitmap(DC: HDC; Bitmap: HBitmap;
  154.                                 X, Y: integer; Transparent: TColorRef);
  155. procedure TileBlt(DC: HDC; Bitmap: HBitmap; const aRect:TRect; ROP: Longint);
  156. procedure FillGradient(DC: HDC; BeginColor, EndColor: TColor;
  157.                        nColors: integer; const aRect: TRect);
  158. procedure FillSolid(DC: HDC; Color: TColor; const aRect: TRect);
  159. function  WinExecAndWait(FileName: TFileName): Boolean;
  160. function  WinExecAndWaitEx(FileName: TFileName; TimeOut: DWORD): Boolean;
  161. procedure TimeDecode(Time: Longint; var Hour, Min, Sec, MSec: Word);
  162. function  TimeToMask(Time: Longint): string;
  163. function  MaskToTime(Mask: string): Longint;
  164. function  CheckFloat(const S: string): string;
  165. {$IFDEF WIN32}
  166. function  TimeToString64Ex(Time: int64; MSec: Boolean): string;
  167. function  TimeToString64(LowTime,HighTime: Cardinal; MSec: Boolean): string;
  168. {$ENDIF}
  169. function  TimeToStringEx(Time: MM_int64; MSec: Boolean): string;
  170. function  TimeToString(Time: MM_int64): string;
  171. function StrToFloatEx(S: string; Limiter: Char): Extended;
  172. function  DBToLin(DB: Float): Float;
  173. function  LinToDB(lin: Float): Float;
  174. function  DBToVolume(DB: Float; Base: Longint): Longint;
  175. function  VolumeToDB(Volume, Base: Longint): Float;
  176. function  VolumeToStringShort(Volume, Base: Longint;  Precision: integer): string;
  177. function  VolumeToString(Volume, Base: Longint;  Precision: integer): string;
  178. function  PanningToString(Panning, Range: Longint): String;
  179. procedure CalcVolume(Base,Volume,Panning: Longint; var Left, Right: Longint);
  180. function  CombineVolume(Vol1,Vol2,Base: Longint): Longint;
  181. function  FormatBigNumber(dw: Longint): String;
  182. function  BytesToString(Bytes: Comp): string;
  183. procedure DrawRubberband(Sender: TObject; aRect: TRect);
  184. procedure DrawRubberLineEx(Sender: TObject; aRect: TRect; Pen: HPEN; ROP: DWORD);
  185. procedure DrawRubberLine(Sender: TObject; aRect: TRect);
  186. procedure TextOutAligned(Canvas: TCanvas; X, Y: integer; Text: String;
  187.                          FontName: PChar; FontSize: integer; Align: Byte);
  188. procedure WinYield(Wnd: THandle);
  189. function  DesignMode: Boolean;
  190. function  CheckPath(Path: string; Flag: Boolean): String;
  191. function  CheckFileName(S: String): string;
  192. function SearchParamStr(Switch: string): Boolean;
  193. function int64shl32(V: int64; Shift: Byte): MMLarge_Integer;
  194. {$IFDEF WIN32}
  195. function  GetTempFile: string;
  196. function  Min64(a, b: int64): int64;
  197. function  Max64(a, b: int64): int64;
  198. function  MinMax64(X, Min, Max: int64): int64;
  199. function  InMinMax64(X,Min,Max: int64): Boolean;
  200. function  Sign(Value: Longint): Longint;
  201. {$ENDIF}
  202. {$IFDEF WIN32}
  203. {$IFNDEF DELPHI3}
  204. type
  205.     EWin32Error = class(Exception)
  206.     public
  207.         ErrorCode: DWORD;
  208.     end;
  209. function    SysErrorMessage(ErrorCode: Integer): string;
  210. procedure   RaiseLastWin32Error;
  211. function    Win32Check(RetVal: BOOL): BOOL;
  212. {$ENDIF}
  213. {$ENDIF}
  214. {========================================================================}
  215. var
  216.    SwapSmall          : procedure (var a, b: SmallInt);
  217.    SwapInt            : procedure (var a, b: integer);
  218.    SwapLong           : procedure (var a, b: Longint);
  219.    Min                : function  (a, b: Longint): Longint;
  220.    Max                : function  (a, b: Longint): Longint;
  221.    MinMax             : function  (X, Min, Max: Longint): Longint;
  222.    Limit              : function  (X, Min, Max: Longint): Longint;
  223.    InMinMax           : function  (X, Min, Max: Longint): Boolean;
  224.    InRange            : function  (X, Min, Max: Longint): Boolean;
  225.    incHuge            : procedure (Var Pointer; nBytes: Longint);
  226.    GlobalFillMem      : procedure (var X; Cnt: Longint; Value: Byte);
  227.    GlobalFillLong     : procedure (var X; Cnt: Longint; Value: Longint);
  228.    GlobalMoveMem      : procedure (const Source; var Dest; Cnt: Longint);
  229.    GlobalCmpMem       : function  (const p1, p2; Cnt: Longint): Boolean;
  230.    {$IFDEF TRIAL}
  231.    IDERunning         : function: Boolean;
  232.    CheckTime          : function: Boolean;
  233.    CheckParam1        : function  (dw1: DWORD; b1: BOOL; lp1: PChar): THandle; stdcall;
  234.    CheckParam2        : function  (lp1, lp2: PChar; dw1: DWORD; lp3, lp4, lp5: PDWORD;
  235.                                    lp6: PChar; dw2: DWORD): Boolean; stdcall;
  236.    {$ENDIF}
  237. function  GlobalAllocMem(Size: Longint): Pointer;
  238. procedure GlobalReAllocMem(var p: Pointer; Size: Longint);
  239. procedure GlobalFreeMem(var p: Pointer);
  240. function  GlobalMemSize(const p: Pointer): Longint;
  241. procedure RegisterPackage(const Pack: string); {$IFDEF BUILD_ACTIVEX} stdcall; export; {$ENDIF}
  242. procedure RegisterFailed(Code: Longint; Control: TComponent; Text: string);
  243. procedure RegisterComponent(Code: Longint; Control: TComponent; Text: string);
  244. function  ComponentRegistered(Code: Longint; Control: TComponent; Text: string): Longint;
  245. function  PackageRegistered(Pack: string): integer;
  246. function FindIDERunning: Boolean;
  247. implementation
  248. uses
  249.     MMSystem,
  250.     MMString,
  251.     MMSearch,
  252.     MMMulDiv,
  253.     MMMath,
  254.     MMInt64
  255.     {$IFDEF _MMDEBUG_}
  256.     ,MMDebug
  257.     {$ENDIF}
  258.     ;
  259. {$IFNDEF WIN32}
  260. {=========================================================================}
  261. procedure MoveWindowOrg(DC: HDC; DX, DY: Integer);
  262. var
  263.   P: TPoint;
  264. begin
  265.    GetWindowOrgEx(DC, @P);
  266.    SetWindowOrgEx(DC, P.X - DX, P.Y - DY, nil);
  267. end;
  268. {$ELSE}
  269. var
  270.    TransSection: TRTLCriticalSection;
  271.    _GetDiskFreeSpaceEx: function (Directory: PChar; var FreeAvailable,
  272.                                   TotalSpace: Int64;
  273.                                   TotalFree: PInt64): Bool stdcall = nil;
  274. {=========================================================================}
  275. function MMSetThreadPriority(hThread: THandle; nPriority: integer): Boolean;
  276. begin
  277. (*
  278.    if (GetPriorityClass(GetCurrentProcess) = REALTIME_PRIORITY_CLASS) then
  279.    begin
  280.       case nPriority of
  281.          //THREAD_PRIORITY_IDLE          : nPriority := ;
  282.          THREAD_PRIORITY_LOWEST        : nPriority := THREAD_PRIORITY_IDLE;
  283.          THREAD_PRIORITY_BELOW_NORMAL  : nPriority := THREAD_PRIORITY_LOWEST;
  284.          THREAD_PRIORITY_NORMAL        : nPriority := THREAD_PRIORITY_BELOW_NORMAL;
  285.          THREAD_PRIORITY_ABOVE_NORMAL  : nPriority := THREAD_PRIORITY_NORMAL;
  286.          //THREAD_PRIORITY_HIGHEST       = THREAD_BASE_PRIORITY_MAX;
  287.          //THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT;
  288.       end;
  289.    end;
  290. *)
  291.    Result := SetThreadPriority(hThread,nPriority);
  292. end;
  293. {=========================================================================}
  294. function MMSetPriorityClass(hProcess: THandle; fdwPriority: DWORD): Boolean;
  295. begin
  296.    Result := SetPriorityClass(hProcess,fdwPriority);
  297. end;
  298. {=========================================================================}
  299. procedure SaveInRegistry(_RootKey:HKEY;_Localkey,_Field:String;Value:Variant);
  300. begin
  301.    try
  302.       with TRegistry.Create do
  303.       try
  304.          { default is  RootKey=HKEY_CURRENT_USER  }
  305.          case _RootKey of
  306.               HKEY_CLASSES_ROOT,
  307.               HKEY_CURRENT_USER,
  308.               HKEY_LOCAL_MACHINE,
  309.               HKEY_USERS,
  310.               HKEY_PERFORMANCE_DATA,
  311.               HKEY_CURRENT_CONFIG,
  312.               HKEY_DYN_DATA : RootKey := _RootKey;
  313.          end;
  314.          OpenKey(_Localkey,True);
  315.          case VarType(Value) of
  316.              varByte,
  317.              varNull,
  318.              varInteger,
  319.              varSmallint: WriteInteger (_Field,Value);
  320.              varSingle,
  321.              varDouble  : WriteFloat   (_Field,Value);
  322.              varCurrency: WriteCurrency(_Field,Value);
  323.              varDate    : WriteDateTime(_Field,Value);
  324.              varBoolean : WriteBool    (_Field,Value);
  325.              varString,
  326.              varOleStr  : WriteString  (_Field,Value);
  327.          end;
  328.          CloseKey;
  329.       finally
  330.          Free;
  331.       end;
  332.    except
  333.    end;
  334. end;
  335. {=========================================================================}
  336. procedure SaveInRegistryBinary(_RootKey:HKEY;_Localkey,_Field:string;var Buffer; BufSize: integer);
  337. begin
  338.    try
  339.       if (BufSize > 0) then
  340.       with TRegistry.Create do
  341.       try
  342.          { default is  RootKey=HKEY_CURRENT_USER  }
  343.          case _RootKey of
  344.              HKEY_CLASSES_ROOT,
  345.              HKEY_CURRENT_USER,
  346.              HKEY_LOCAL_MACHINE,
  347.              HKEY_USERS,
  348.              HKEY_PERFORMANCE_DATA,
  349.              HKEY_CURRENT_CONFIG,
  350.              HKEY_DYN_DATA : RootKey := _RootKey;
  351.          end;
  352.          OpenKey(_Localkey,True);
  353.          WriteBinaryData(_Field,Buffer,BufSize);
  354.          CloseKey;
  355.       finally
  356.           Free;
  357.       end;
  358.    except
  359.    end;
  360. end;
  361. {=========================================================================}
  362. function GetFromRegistry(_RootKey:HKEY;_Localkey,_Field:String;Value:Variant): Variant;
  363. begin
  364.    Result := Value;
  365.    try
  366.       with TRegistry.Create do
  367.       try
  368.          { default is  RootKey=HKEY_CURRENT_USER  }
  369.          case _RootKey of
  370.               HKEY_CLASSES_ROOT,
  371.               HKEY_CURRENT_USER,
  372.               HKEY_LOCAL_MACHINE,
  373.               HKEY_USERS,
  374.               HKEY_PERFORMANCE_DATA,
  375.               HKEY_CURRENT_CONFIG,
  376.               HKEY_DYN_DATA : RootKey := _RootKey;
  377.          end;
  378.          if OpenKey(_Localkey, False) then
  379.          begin
  380.             if ValueExists(_Field) then
  381.             case VarType(Value) of
  382.                 varByte,
  383.                 varNull,
  384.                 varInteger,
  385.                 varSmallint: Result := ReadInteger(_Field);
  386.                 varSingle,
  387.                 varDouble  : Result := ReadFloat   (_Field);
  388.                 varCurrency: Result := ReadCurrency(_Field);
  389.                 varDate    : Result := ReadDateTime(_Field);
  390.                 varBoolean : Result := ReadBool    (_Field);
  391.                 varString,
  392.                 varOleStr  : Result := ReadString  (_Field);
  393.             end;
  394.             CloseKey;
  395.          end;
  396.       finally
  397.          Free;
  398.       end;
  399.    except
  400.    end;
  401. end;
  402. {=========================================================================}
  403. function GetFromRegistryBinary(_RootKey:HKEY;_Localkey,_Field:string;var Buffer; BufSize: integer): integer;
  404. begin
  405.    Result := 0;
  406.    try
  407.       with TRegistry.Create do
  408.       try
  409.          { default is  RootKey=HKEY_CURRENT_USER  }
  410.          case _RootKey of
  411.              HKEY_CLASSES_ROOT,
  412.              HKEY_CURRENT_USER,
  413.              HKEY_LOCAL_MACHINE,
  414.              HKEY_USERS,
  415.              HKEY_PERFORMANCE_DATA,
  416.              HKEY_CURRENT_CONFIG,
  417.              HKEY_DYN_DATA : RootKey := _RootKey;
  418.          end;
  419.          if OpenKey(_Localkey, False) then
  420.          begin
  421.             if ValueExists(_Field) then
  422.             begin
  423.                if (BufSize = 0) then
  424.                    Result := GetDataSize(_Field)
  425.                else
  426.                    Result := ReadBinaryData(_Field,Buffer,BufSize);
  427.             end;
  428.             CloseKey;
  429.          end;
  430.       finally
  431.          Free;
  432.       end;
  433.    except
  434.    end;
  435. end;
  436. {=========================================================================}
  437. function GetCPUUsage: integer;
  438. var
  439.    TempKey: HKEY;
  440.    DataType,BufSize,Dummy: integer;
  441. begin
  442.    Result := 0;
  443.    if _WIN9x_ or _WINNT_NEW_ then
  444.    begin
  445.       TempKey := 0;
  446.       { start measuring }
  447.       if RegOpenKeyEx(HKEY_DYN_DATA, 'PerfStatsStartStat', 0,
  448.                       KEY_ALL_ACCESS, TempKey) <> ERROR_SUCCESS then exit;
  449.       DataType := REG_NONE;
  450.       BufSize := sizeOf(integer);
  451.       if RegQueryValueEx(TempKey, 'KERNELCPUUsage', nil, @DataType,
  452.                          @Dummy, @BufSize) <> ERROR_SUCCESS then exit;
  453.       RegCloseKey(TempKey);
  454.       { get the value }
  455.       if RegOpenKeyEx(HKEY_DYN_DATA, 'PerfStatsStatData', 0,
  456.                       KEY_ALL_ACCESS, TempKey) <> ERROR_SUCCESS then exit;
  457.       RegCloseKey(TempKey);
  458.       DataType := REG_NONE;
  459.       BufSize := sizeOf(integer);
  460.       if RegQueryValueEx(TempKey, 'KERNELCPUUsage', nil, @DataType,
  461.                          @Result, @BufSize) <> ERROR_SUCCESS then exit;
  462.       RegCloseKey(TempKey);
  463.       { stop measuring }
  464.       if RegOpenKeyEx(HKEY_DYN_DATA, 'PerfStatsStopStat', 0,
  465.                       KEY_ALL_ACCESS, TempKey) <> ERROR_SUCCESS then exit;
  466.       DataType := REG_NONE;
  467.       BufSize := sizeOf(integer);
  468.       if RegQueryValueEx(TempKey, 'KERNELCPUUsage', nil, @DataType,
  469.                          @Dummy, @BufSize) <> ERROR_SUCCESS then exit;
  470.       RegCloseKey(TempKey);
  471.    end;
  472. end;
  473. {=========================================================================}
  474. function GetShortFileName(Name: TFileName): String;
  475. var
  476.    SearchRec: TSearchRec;
  477. begin
  478.    Result := '';
  479.    Name := ExpandUNCFileName(Name);
  480.    if (Name <> '') and FileExists(Name) then
  481.    begin
  482.       if (FindFirst(Name,faAnyFile,SearchRec) = 0) and
  483.           Equal(SearchRec.Name, ExtractFileName(Name)) then
  484.       try
  485.          if SearchRec.FindData.cAlternateFileName[0] <> #0 then
  486.             Result := StrPas(SearchRec.FindData.cAlternateFileName)
  487.          else
  488.             Result := StrPas(SearchRec.FindData.cFileName);
  489.       finally
  490.          FindClose(SearchRec);
  491.       end;
  492.    end;
  493. end;
  494. {=========================================================================}
  495. { Returns:                                                                }
  496. {  0 = 8086/88,80286,80386,80486                                          }
  497. {  1 = Pentium(R) Processor                                               }
  498. {  2 = PentiumPro(R) Processor                                            }
  499. {  3 or higher = Processor beyond the PentiumPro(R) Processor            }
  500. {                                                                         }
  501. {=========================================================================}
  502. function GetCPUType: integer;
  503. var
  504.    stepping: Byte;
  505.    model: Byte;
  506. begin
  507.    Result := 0;
  508. {$IFDEF WIN32}
  509.    asm
  510.       pushad
  511.       pushfd
  512.       { look if cpuid is supported }
  513.       pushfd // Get original EFLAGS
  514.       pop    eax
  515.       mov    ecx, eax
  516.       xor    eax, 200000h // Flip ID bit in EFLAGS
  517.       push   eax // Save new EFLAGS value on
  518.        //   stack
  519.       popfd // Replace current EFLAGS value
  520.       pushfd // Get new EFLAGS
  521.       pop     eax // Store new EFLAGS in EAX
  522.       xor     eax, ecx // Can not toggle ID bit,
  523.       jz      @@exit // Processor=80486
  524.       mov     eax, 1
  525.       db      $0F
  526.       db      $a2 // Get family/model/stepping/
  527.          //   features
  528.       mov     stepping, al
  529.       and     stepping, $F
  530.       and     al, $F0
  531.       shr     al, 4
  532.       mov     model, al
  533.       and     eax, $F00
  534.       shr     eax, 8 // Isolate family
  535.       and     eax, $F
  536.       sub     eax, 4
  537.       mov     Result, eax // Set _cpu_type with family
  538.    @@exit:
  539.       popfd
  540.       popad
  541.    end;
  542. {$ENDIF}
  543. end;
  544. {=========================================================================}
  545. function Min64(a, b: int64): int64;
  546. begin
  547.    if a > b then Result := b
  548.    else Result := a;
  549. end;
  550. {=========================================================================}
  551. function Max64(a, b: int64): int64;
  552. begin
  553.    if a > b then Result := a
  554.    else Result := b;
  555. end;
  556. {=========================================================================}
  557. function MinMax64(X, Min, Max: int64): int64;
  558. begin
  559.    if (X < Min) then X := Min
  560.    else if (X > Max) then X := Max;
  561.    Result := X;
  562. end;
  563. {=========================================================================}
  564. function InMinMax64(X,Min,Max: int64): Boolean;
  565. begin
  566.    { if Min > Max then Result is never true }
  567.    if (X < Min) then Result := False
  568.    else if (X > Max) then Result := False
  569.    else Result := True;
  570. end;
  571. {=========================================================================}
  572. function Sign(Value: Longint): Longint;
  573. begin
  574.    if (Value > 0) then
  575.        Result := 1
  576.    else if (Value < 0) then
  577.        Result := -1
  578.    else
  579.        Result := Value;
  580. end;
  581. {=========================================================================}
  582. { Current flag assignment is as follows:                                  }
  583. {                                                                         }
  584. { bit23=1     CPU has MMX extension                         }
  585. { bit15=1     CMOV instruction supported                    }
  586. { bit9 =1     CPU contains a local APIC (iPentium-3V)       }
  587. { bit8 =1     CMPXCHG8B instruction supported               }
  588. { bit7 =1     machine check exception supported             }
  589. { bit6 =0     reserved (36bit-addressing & 2MB-paging)      }
  590. { bit5 =1     iPentium-style MSRs supported                 }
  591. { bit4 =1     time stamp counter TSC supported              }
  592. { bit3 =1     page size extensions supported                }
  593. { bit2 =1     I/O breakpoints supported                     }
  594. { bit1 =1     enhanced virtual 8086 mode supported          }
  595. { bit0 =1     CPU contains a floating-point unit (FPU)      }
  596. {=========================================================================}
  597. function GetCPUFeatures: Longint;
  598. begin
  599.    Result := 0;
  600. {$IFDEF WIN32}
  601.    asm
  602.       pushad
  603.       pushfd
  604.       { look if cpuid is supported }
  605.       pushfd // Get original EFLAGS
  606.       pop    eax
  607.       mov    ecx, eax
  608.       xor    eax, 200000h // Flip ID bit in EFLAGS
  609.       push   eax // Save new EFLAGS value on
  610.        //   stack
  611.       popfd // Replace current EFLAGS value
  612.       pushfd // Get new EFLAGS
  613.       pop     eax // Store new EFLAGS in EAX
  614.       xor     eax, ecx // Can not toggle ID bit,
  615.       jz      @@exit // Processor=80486
  616.       mov     eax, 1
  617.       db      $0F
  618.       db      $a2 // Get family/model/stepping/
  619.          //   features
  620.       mov     Result, edx
  621.    @@exit:
  622.       popfd
  623.       popad
  624.    end;
  625. {$ENDIF}
  626. end;
  627. {=========================================================================}
  628. { Returns:                                                                }
  629. {  0 = Pentium(R) Processor                                               }
  630. {  1 = PentiumPro(R) Processor                                            }
  631. {  2 = MMX Extension                                                      }
  632. {=========================================================================}
  633. function GetCPUMode: integer;
  634. begin
  635.    if _USECPUEXT_ then
  636.    begin
  637.       if _MMX_ then
  638.          Result := 2
  639.       else if _CPU_ > PENTIUM then
  640.          Result := 1
  641.       else
  642.          Result := 0;
  643.    end
  644.    else Result := 0;
  645. end;
  646. {=========================================================================}
  647. function GetCPUCycles: int64;
  648. asm
  649. {$IFDEF WIN32}
  650.       db      00fh              //RDTSC
  651.       db      031h
  652.       {$IFNDEF DELPHI4}
  653.       mov     TLargeInteger(Result).HighPart,edx
  654.       mov     TLargeInteger(Result).LowPart,eax
  655.       {$ENDIF}
  656. {$ENDIF}
  657. end;
  658. var
  659.    TimeCount: Longint;
  660.    OldTime,TimeMin,TimeMax,TimeAvg: int64;
  661. {=========================================================================}
  662. procedure InitTimeMeasure;
  663. begin
  664.    TimeCount:= 0;
  665.    TimeMin  := MAXLONGINT;
  666.    TimeMax  := 0;
  667.    TimeAvg  := 0;
  668. end;
  669. {=========================================================================}
  670. procedure StartTimeMeasure;
  671. begin
  672.    inc(TimeCount);
  673.    OldTime := TimeGetExactTime;
  674. end;
  675. {=========================================================================}
  676. function StopTimeMeasure(Scale: integer): string;
  677. var
  678.    CurTime: int64;
  679. begin
  680.    CurTime := TimeGetExactTime-OldTime;
  681.    if (CurTime < TimeMin) then TimeMin := CurTime;
  682.    if (CurTime > TimeMax) then TimeMax := CurTime;
  683.    TimeAvg := TimeAvg+CurTime;
  684.    if Scale < 1 then Scale := 1;
  685.    Result := Format('Time:  Cur: %f  Min: %f  Max: %f  Avg: %f',[CurTime,
  686.                                                                  TimeMin/Scale,
  687.                                                                  TimeMax/Scale,
  688.                                                                  (TimeAvg/TimeCount)/Scale]);
  689. end;
  690. var
  691.    CycleCount: Longint;
  692.    OldCycles,CyclesMin,CyclesMax,CyclesAvg: int64;
  693. {=========================================================================}
  694. procedure InitCyclesMeasure;
  695. begin
  696.    CycleCount := 0;
  697.    CyclesMin  := MAXLONGINT;
  698.    CyclesMax  := 0;
  699.    CyclesAvg  := 0;
  700. end;
  701. {=========================================================================}
  702. procedure StartCyclesMeasure;
  703. begin
  704.    inc(CycleCount);
  705.    OldCycles := GetCPUCycles;
  706. end;
  707. {=========================================================================}
  708. function StopCyclesMeasure(Scale: integer): string;
  709. var
  710.    CurCycles: int64;
  711. begin
  712.    CurCycles := GetCPUCycles-OldCycles;
  713.    if (CurCycles < CyclesMin) then CurCycles := CyclesMin;
  714.    if (CurCycles > CyclesMax) then CurCycles := CyclesMax;
  715.    CyclesAvg := CyclesAvg+CurCycles;
  716.    if Scale < 1 then Scale := 1;
  717.    Result := Format('CPU-Cycles:  Min: %f Max: %f Avg: %f',[CyclesMin/Scale,
  718.                                                             CyclesMax/Scale,
  719.                                                             (CyclesAvg/CycleCount)/Scale]);
  720. end;
  721. {$ENDIF}
  722. const
  723.      Freq: Longint = 0;
  724. {=========================================================================}
  725. function TimeGetExactTime: int64;
  726. {$IFDEF WIN32}
  727. var
  728.    {$IFDEF DELPHI4}
  729.    CurTime: int64;
  730.    {$ELSE}
  731.    CurTime: MMLARGE_INTEGER;
  732.    {$ENDIF}
  733. {$ENDIF}
  734. begin
  735.    { returns system time in micro second }
  736. {$IFDEF WIN32}
  737.    if (Freq = 0) then
  738.    begin
  739.       QueryPerformanceFrequency(CurTime);           { determine timer frequency }
  740.       {$IFDEF DELPHI4}
  741.       if (Curtime shr 32 > 0) then
  742.           Freq := 1                                 { timer is too fast }
  743.       else
  744.           Freq := CurTime and $FFFFFFFF;            { ticks per second }
  745.       {$ELSE}
  746.       if (Curtime.HighPart > 0) then
  747.           Freq := 1                                 { timer is too fast }
  748.       else
  749.           Freq := CurTime.LowPart;                  { ticks per second }
  750.       {$ENDIF}
  751.    end;
  752.    if (Freq > 1) then
  753.    begin
  754.       QueryPerformanceCounter(CurTime);
  755.       {$IFDEF DELPHI4}
  756.       Result := (1000000 * CurTime) div Freq;
  757.       {$ELSE}
  758.       Result := 1000000;
  759.       Result := (Result * CurTime.QuadPart)/Freq;
  760.       {$ENDIF}
  761.    end
  762.    else
  763. {$ENDIF}
  764.    begin
  765.       { on Win16 we must return the time in a 1000 micro second raster }
  766.       Result := 1000;
  767.       Result := Result * TimeGetTime;
  768.    end;
  769. end;
  770. {=========================================================================}
  771. function HaveWin95: Boolean;
  772. {$IFDEF WIN32}
  773. var
  774.    OS: TOSVERSIONINFO;
  775. begin
  776.    OS.dwOSVersionInfoSize := sizeOf(OS);
  777.    GetVersionEx(OS);
  778.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) and
  779.              (OS.dwMajorVersion = 4) and (OS.dwMinorVersion = 0);
  780. {$ELSE}
  781. begin
  782.    Result:=(GetVersion and $FF = 3)and((GetVersion shr 8)and $FF=95);
  783. {$ENDIF}
  784. end;
  785. {=========================================================================}
  786. function HaveWin98: Boolean;
  787. {$IFDEF WIN32}
  788. var
  789.    OS: TOSVERSIONINFO;
  790. begin
  791.    OS.dwOSVersionInfoSize := sizeOf(OS);
  792.    GetVersionEx(OS);
  793.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) and
  794.              (OS.dwMajorVersion = 4) and (OS.dwMinorVersion = 10);
  795. {$ELSE}
  796. begin
  797.    Result:=(GetVersion and $FF = 3)and((GetVersion shr 8)and $FF=95);
  798. {$ENDIF}
  799. end;
  800. {=========================================================================}
  801. function HaveWinME: Boolean;
  802. {$IFDEF WIN32}
  803. var
  804.    OS: TOSVERSIONINFO;
  805. begin
  806.    OS.dwOSVersionInfoSize := sizeOf(OS);
  807.    GetVersionEx(OS);
  808.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) and
  809.              (OS.dwMajorVersion = 4) and (OS.dwMinorVersion = 90);
  810. {$ELSE}
  811. begin
  812.    Result:=(GetVersion and $FF = 3)and((GetVersion shr 8)and $FF=95);
  813. {$ENDIF}
  814. end;
  815. {=========================================================================}
  816. function HaveWinNT: Boolean;
  817. {$IFDEF WIN32}
  818. var
  819.    OS: TOSVERSIONINFO;
  820. begin
  821.    OS.dwOSVersionInfoSize := sizeOf(OS);
  822.    GetVersionEx(OS);
  823.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_NT) and
  824.              (OS.dwMajorVersion = 3);
  825. {$ELSE}
  826. begin
  827.    Result := (GetWinFlags and $4000) <> 0;
  828. {$ENDIF}
  829. end;
  830. {=========================================================================}
  831. function HaveWinNT4: Boolean;
  832. {$IFDEF WIN32}
  833. var
  834.    OS: TOSVERSIONINFO;
  835. begin
  836.    OS.dwOSVersionInfoSize := sizeOf(OS);
  837.    GetVersionEx(OS);
  838.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_NT) and
  839.              (OS.dwMajorVersion >= 4);
  840. {$ELSE}
  841. begin
  842.    Result := (GetWinFlags and $4000) <> 0;
  843. {$ENDIF}
  844. end;
  845. {=========================================================================}
  846. function HaveWin2K: Boolean;
  847. {$IFDEF WIN32}
  848. var
  849.    OS: TOSVERSIONINFO;
  850. begin
  851.    OS.dwOSVersionInfoSize := sizeOf(OS);
  852.    GetVersionEx(OS);
  853.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_NT) and
  854.              (OS.dwMajorVersion >= 5);
  855. {$ELSE}
  856. begin
  857.    Result := (GetWinFlags and $4000) <> 0;
  858. {$ENDIF}
  859. end;
  860. {=========================================================================}
  861. function HaveWinXP: Boolean;
  862. {$IFDEF WIN32}
  863. var
  864.    OS: TOSVERSIONINFO;
  865. begin
  866.    OS.dwOSVersionInfoSize := sizeOf(OS);
  867.    GetVersionEx(OS);
  868.    Result := (OS.dwPlatformID = VER_PLATFORM_WIN32_NT) and
  869.              (OS.dwMajorVersion >= 5) and (OS.dwMinorVersion = 1);
  870. {$ELSE}
  871. begin
  872.    Result := (GetWinFlags and $4000) <> 0;
  873. {$ENDIF}
  874. end;
  875. {=========================================================================}
  876. procedure Delay(ms: DWORD; ProcessMessages: Boolean);
  877. Var
  878.    Time: DWORD;
  879. begin
  880.   if ms > 0 then
  881.   begin
  882. {$IFDEF WIN32}
  883.     if ProcessMessages then
  884.     begin
  885.       Time := GetTickCount;
  886.       repeat
  887.         case MsgWaitForMultipleObjects(0, nil^, True, Time - GetTickCount + ms, QS_ALLEVENTS) of
  888.           WAIT_OBJECT_0:
  889.           begin
  890.             Application.ProcessMessages;
  891.             if GetTickCount-Time >= ms then break;
  892.           end;
  893.           WAIT_TIMEOUT:
  894.             break;
  895.         end
  896.       until csDestroying in Application.ComponentState
  897.     end
  898.     else Sleep(ms);
  899. {$ELSE}
  900.     Time := GetTickCount;
  901.     repeat
  902.       if ProcessMessages then Application.ProcessMessages;
  903.     until GetTickCount-Time >= ms;
  904. {$ENDIF}
  905.   end;
  906. end;
  907. {=========================================================================}
  908. function ClientToClient(Destination, Source: TControl; P: TPoint): TPoint;
  909. begin
  910.    Result := Destination.ScreenToClient(Source.ClientToScreen(P));
  911. end;
  912. {=========================================================================}
  913. function NonClientHeight: integer;
  914. begin
  915.    { returns the full CaptionBar height }
  916.    Result := GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYFRAME);
  917. end;
  918. {=========================================================================}
  919. function MenuHeight: integer;
  920. begin
  921.    { returns the full Menu height }
  922.    Result := GetSystemMetrics(SM_CYMENU );
  923. end;
  924. {=========================================================================}
  925. function BitsPerPixel: integer;
  926. var
  927.    DC: HDC;
  928. begin
  929.    { returns "Bits Per Pixel" for the actual display
  930.      1     = 16 Color
  931.      8     = 256 Color,
  932.      15/16 = HiColor
  933.      24/32 = TrueColor }
  934.    DC := CreateDC('DISPLAY',nil,nil,nil);
  935.    Result := GetDeviceCaps(DC,BITSPIXEL);
  936.    DeleteDC(DC);
  937. end;
  938. {=========================================================================}
  939. function CheckPath(Path: string; Flag: Boolean): String;
  940. {Funktion pr黤t, ob letztes Zeichen in Pfadangabe ein '' ist
  941.  Flag:
  942.         TRUE - '' Zeichen erw黱scht
  943.         FALSE - '' Zeichen unerw黱scht}
  944. begin
  945.      if (Path <> '') then
  946.      begin
  947.         if (Flag = True) then
  948.         begin
  949.            if Path[Length(Path)] <> '' then
  950.               Path := Path + ''
  951.         end
  952.         else
  953.         begin
  954.            if Path[Length(Path)] = '' then
  955.               Path := Copy(Path,1,Length(Path)-1);
  956.         end;
  957.      end;
  958.      Result := Path;
  959. end;
  960. {=========================================================================}
  961. function CheckFileName(S: String): string;
  962. var
  963.    i: integer;
  964.    FName: string;
  965. begin
  966.    for i := 1 to Length(S) do
  967.    begin
  968.       if (S[i] in ['/','*','?','"','<','>','|',',']) or ((S[i] = ':') and (S[i+1] <> '')) then
  969.           S[i] := '_';
  970.    end;
  971.    FName := ChangeFileExt(ExtractFileName(S),'');
  972.    for i := 1 to Length(FName) do
  973.    begin
  974.       if (FName[i] in ['','.']) then
  975.           FName[i] := '_';
  976.    end;
  977.    Result := CheckPath(ExtractFilePath(S),True)+FName+ExtractFileExt(S);
  978. end;
  979. {==============================================================================}
  980. function int64shl32(V: int64; Shift: Byte): MMLarge_Integer;
  981. var
  982.    R: MMLarge_Integer;
  983. begin
  984.    asm
  985.      {$IFDEF WIN32}
  986.       mov   cl, Shift
  987.       mov   eax, dword ptr V[0]
  988.       mov   edx, dword ptr V[4]
  989.       shld  edx, eax, cl
  990.       shl   eax, cl
  991.       mov   dword ptr R.HighPart, edx
  992.       mov   dword ptr R.LowPart, eax
  993.       {$ELSE}
  994.       mov   cl, Shift
  995.       db    66h
  996.       mov   ax, word ptr V[0]
  997.       db    66h
  998.       mov   dx, word ptr V[4]
  999.       db    66h      { shld  edx, eax, cl }
  1000.       db    0Fh
  1001.       db    0A5h
  1002.       db    0C2h
  1003.       db    66h
  1004.       shl   ax, cl
  1005.       db    66h
  1006.       mov   word ptr R.HighPart, dx
  1007.       db    66h
  1008.       mov   word ptr R.LowPart, ax
  1009.       {$ENDIF}
  1010.    end;
  1011.    Result := R;
  1012. end;
  1013. {$IFDEF WIN32}
  1014. {=========================================================================}
  1015. function GetTempFile: string;
  1016. var
  1017.    aBuf: array[0..MAX_PATH] of Char;
  1018. begin
  1019.    GetTempPath(sizeOf(aBuf)-1,aBuf);
  1020.    GetTempFileName(aBuf,'w'#0,Random(256)+1,aBuf);
  1021.    Result := StrPas(aBuf);
  1022. end;
  1023. {=========================================================================}
  1024. function CreateFullDir(Dir: string): Boolean;
  1025. var
  1026.    Drive,Path,S: string;
  1027.    idx: integer;
  1028.    function ExtractPathTotken(idx: integer; S: string): string;
  1029.    var
  1030.       x,p: integer;
  1031.    begin
  1032.       Result := '';
  1033.       x := -1;
  1034.       while (x < idx) do
  1035.       begin
  1036.          p := Pos('',S);
  1037.          if (p <= 0) then
  1038.          begin
  1039.             Result := '';
  1040.             exit;
  1041.          end;
  1042.          Result := Result+Copy(S,1,p);
  1043.          Delete(S,1,p);
  1044.          inc(x);
  1045.       end;
  1046.    end;
  1047. begin
  1048.    Result := False;
  1049.    Dir := CheckPath(Dir,True);
  1050.    Drive := CheckPath(ExtractFileDrive(Dir),True);
  1051.    Path  := CheckPath(Copy(ExtractFilePath(Dir),Length(Drive)+1,Length(Dir)),True);
  1052.    if (Drive = '') or (Path = '') then exit;
  1053.    idx := 0;
  1054.    repeat
  1055.       S := ExtractPathTotken(idx,Path);
  1056.       if (S <> '') then
  1057.       begin
  1058.          if not DirectoryExists(Drive+S) then
  1059.          begin
  1060.             if not CreateDir(Drive+S) then
  1061.             begin
  1062.                Result := False;
  1063.                exit;
  1064.             end;
  1065.          end;
  1066.          inc(idx);
  1067.       end;
  1068.    until (S = '');
  1069.    Result := True;
  1070. end;
  1071. {=========================================================================}
  1072. procedure DeleteDir(Dir: string);
  1073. var
  1074.    Result: integer;
  1075.    SearchRec: TSearchRec;
  1076. begin
  1077.    Dir := CheckPath(Dir,True);
  1078.    Result := FindFirst(Dir+'*.*',faAnyFile,SearchRec);
  1079.    try
  1080.       while (Result = 0) do
  1081.       begin
  1082.          if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
  1083.              DeleteFile(Dir+SearchRec.Name);
  1084.          Result := FindNext(SearchRec);
  1085.       end;
  1086.    finally
  1087.       FindClose(SearchRec);
  1088.    end;
  1089.    RemoveDir(Dir);
  1090. end;
  1091. {$ENDIF}
  1092. {=========================================================================}
  1093. function GetFileSize(Name: TFileName): Longint;
  1094. var
  1095.    SearchRec: TSearchRec;
  1096. begin
  1097.    try
  1098.       if FindFirst(ExpandFileName(Name), faAnyFile, SearchRec) = 0 then
  1099.          Result := SearchRec.Size
  1100.       else
  1101.          Result := -1;
  1102.    finally
  1103.       FindClose(SearchRec);
  1104.    end;
  1105. end;
  1106. {$IFDEF WIN32}
  1107. { This function is used if the OS doesn't support GetDiskFreeSpaceEx }
  1108. {=========================================================================}
  1109. function BackfillGetDiskFreeSpaceEx(Directory: PChar; var FreeAvailable,
  1110.                                     TotalSpace: Int64;
  1111.                                     TotalFree: PInt64): Bool; stdcall;
  1112. var
  1113.   SectorsPerCluster, BytesPerSector, FreeClusters, TotalClusters: DWORD;
  1114.   Temp: Int64;
  1115.   Dir : PChar;
  1116. begin
  1117.   if Directory <> nil then
  1118.      Dir := PChar(ExtractFileDrive(Directory)+'')
  1119.   else
  1120.      Dir := nil;
  1121.   Result := GetDiskFreeSpace(Dir, SectorsPerCluster, BytesPerSector,
  1122.                              FreeClusters, TotalClusters);
  1123.   Temp := SectorsPerCluster;
  1124.   Temp := Temp * BytesPerSector;
  1125.   FreeAvailable := Temp * FreeClusters;
  1126.   TotalSpace    := Temp * TotalClusters;
  1127. end;
  1128. {$ENDIF}
  1129. {=========================================================================}
  1130. function GetDiskStats(const Directory: string; var nFree, nSize: Int64): Boolean;
  1131. {$IFDEF WIN32}
  1132. begin
  1133.    Result := _GetDiskFreeSpaceEx(PChar(ExtractFileDir(Directory)),nFree, nSize, nil);
  1134.    if not Result then
  1135.    begin { avoid errors from unchecked divisions }
  1136.       nFree := 0;
  1137.       nSize := 1;
  1138.    end;
  1139. {$ELSE}
  1140. var
  1141.    iDrive: Byte;
  1142. begin
  1143.    iDrive := Byte(UpCase(Directory[0]))-64;
  1144.    nSize := DiskSize(iDrive);
  1145.    nFree := DiskFree(iDrive);
  1146.    Result := True;
  1147. {$ENDIF}
  1148. end;
  1149. {=========================================================================}
  1150. function GetDiskFree(const Directory: string; nBytes: Longint): Boolean;
  1151. var
  1152.    nFree,nSize,n: Int64;
  1153. begin
  1154.    Result := False;
  1155.    if GetDiskStats(Directory,nFree,nSize) then
  1156.    begin
  1157.       n := nBytes;
  1158.       Result := nFree >= n;
  1159.    end;
  1160. end;
  1161. const
  1162.      RC_Active     = clWhite; { the resource color for active sements    }
  1163.      RC_Inactive   = clSilver;{ the resource color for inactive segments }
  1164.      RC_Background = clBlack; { the resource color for the background    }
  1165. {=========================================================================}
  1166. { Change the black/white SrcBitmap to a colored DestBitmap                }
  1167. {=========================================================================}
  1168. procedure ChangeColors(Bitmap: TBitmap; DrawInactive: Boolean;
  1169.                        ForeColor, InactiveColor, BackColor: TColor);
  1170. Var
  1171.    aRect: TRect;
  1172.    MaskF, MaskB, MaskI: TBitmap;
  1173.    function CreateMask(Bmp: TBitmap; Color: TColor): TBitmap;
  1174.    begin
  1175.       Result := TBitmap.Create;
  1176.       with Result do
  1177.       begin
  1178.          Monochrome  := True;
  1179.          Width       := Bmp.Width;
  1180.          Height      := Bmp.Height;
  1181.          SetBkColor(Bmp.Canvas.Handle,ColorToRGB(Color));
  1182.          Canvas.Draw(0,0,Bmp);
  1183.       end;
  1184.    end;
  1185.    procedure PutMask(Bmp: TBitmap; aMask: TBitmap; Color: TColor; Mode: TCopyMode);
  1186.    begin
  1187.       with Bmp do
  1188.       begin
  1189.          Canvas.CopyMode := Mode;
  1190.          SetTextColor(Canvas.Handle,0);
  1191.          SetBkColor(Canvas.Handle,ColorToRGB(Color));
  1192.          Canvas.StretchDraw(Bounds(0,0,Width,Height),aMask);
  1193.       end;
  1194.    end;
  1195. begin
  1196.     aRect := Rect(0,0,Bitmap.Width,Bitmap.Height);
  1197.     MaskF := CreateMask(Bitmap,RC_ACTIVE);
  1198.     try
  1199.         MaskB := CreateMask(Bitmap,RC_Background);
  1200.         try
  1201.             MaskI := CreateMask(Bitmap,RC_INACTIVE);
  1202.             try
  1203.                 PutMask(Bitmap,MaskF,ForeColor,cmSrcCopy);
  1204.                 PutMask(Bitmap,MaskB,BackColor,cmSrcInvert);
  1205.                 if DrawInactive then
  1206.                     PutMask(Bitmap,MaskI,InactiveColor,cmSrcInvert)
  1207.                 else
  1208.                     PutMask(Bitmap,MaskI,BackColor,cmSrcInvert);
  1209.             finally
  1210.                 MaskI.Free;
  1211.             end;
  1212.         finally
  1213.             MaskB.Free;
  1214.         end;
  1215.     finally
  1216.         MaskF.Free;
  1217.     end;
  1218. end;
  1219. {=========================================================================}
  1220. procedure GetBitmapSize(Bitmap: HBitmap; var W, H: integer);
  1221. var
  1222. {$IFDEF WIN32}
  1223.    bm: Windows.TBitmap;
  1224. {$ELSE}
  1225.    bm: WinTypes.TBitmap;
  1226. {$ENDIF}
  1227. begin
  1228.    GetObject(Bitmap, SizeOf(bm), @bm);
  1229.    W := bm.bmWidth;
  1230.    H := bm.bmHeight;
  1231. end;
  1232. {=========================================================================}
  1233. function GetTransparentColorEx(Bitmap: HBitmap; Point: TPoint): TColorRef;
  1234. var
  1235.    MemDC: HDC;
  1236.    OldBitmap: HBITMAP;
  1237.    W,H: integer;
  1238. begin
  1239.    MemDC := CreateCompatibleDC(0);
  1240.    OldBitmap := SelectObject(MemDC, Bitmap);
  1241.    GetBitmapSize(Bitmap,W,H);
  1242.    Point.X := MinMax(Point.X,0,W-1);
  1243.    Point.Y := MinMax(Point.Y,0,H-1);
  1244.    Result := GetPixel(MemDC,Point.X,Point.Y);
  1245.    SelectObject(MemDC, OldBitmap);
  1246.    DeleteDC(MemDC);
  1247. end;
  1248. {=========================================================================}
  1249. function GetTransparentColor(Bitmap: HBitmap): TColorRef;
  1250. begin
  1251.    Result := GetTransparentColorEx(Bitmap,Point(0,MaxInt-1));
  1252. end;
  1253. {=========================================================================}
  1254. procedure DrawTransparentBitmapEx(DC: HDC; Bitmap: HBitmap; X, Y: integer;
  1255.                                   Src: TRect; Transparent: TColorRef);
  1256. type
  1257.     _TPoint = record
  1258.         X: integer;
  1259.         Y: integer;
  1260.     end;
  1261. var
  1262.    cColor          : TColorRef;
  1263.    bmAndBack,
  1264.    bmAndObject,
  1265.    bmAndMem,
  1266.    bmSave,
  1267.    bmBackOld,
  1268.    bmObjectOld,
  1269.    bmMemOld,
  1270.    bmSaveOld       : HBitmap;
  1271.    hdcMem,
  1272.    hdcBack,
  1273.    hdcObject,
  1274.    hdcTemp,
  1275.    hdcSave         : HDC;
  1276.    bmWidth,bmHeight: integer;
  1277. begin
  1278.    {$IFDEF WIN32}
  1279.    EnterCriticalSection(TransSection);
  1280.    try
  1281.    {$ENDIF}
  1282.       hdcTemp := CreateCompatibleDC(DC);
  1283.       SelectObject(hdcTemp, Bitmap); { select the bitmap }
  1284.       bmWidth  := Src.Right-Src.Left;
  1285.       bmHeight := Src.Bottom-Src.Top;
  1286.       { create some DCs to hold temporary data }
  1287.       hdcBack   := CreateCompatibleDC(DC);
  1288.       hdcObject := CreateCompatibleDC(DC);
  1289.       hdcMem    := CreateCompatibleDC(DC);
  1290.       hdcSave   := CreateCompatibleDC(DC);
  1291.       { create a bitmap for each DC }
  1292.       { monochrome DC }
  1293.       bmAndBack   := CreateBitmap(bmWidth, bmHeight, 1, 1, nil);
  1294.       bmAndObject := CreateBitmap(bmWidth, bmHeight, 1, 1, nil);
  1295.       bmAndMem    := CreateCompatibleBitmap(DC, bmWidth, bmHeight);
  1296.       bmSave      := CreateCompatibleBitmap(DC, bmWidth, bmHeight);
  1297.       { each DC must select a bitmap object to store pixel data }
  1298.       bmBackOld   := SelectObject(hdcBack, bmAndBack);
  1299.       bmObjectOld := SelectObject(hdcObject, bmAndObject);
  1300.       bmMemOld    := SelectObject(hdcMem, bmAndMem);
  1301.       bmSaveOld   := SelectObject(hdcSave, bmSave);
  1302.       { set proper mapping mode }
  1303.       SetMapMode(hdcTemp, GetMapMode(DC));
  1304.       { save the bitmap sent here, because it will be overwritten }
  1305.       BitBlt(hdcSave, 0, 0, bmWidth, bmHeight, hdcTemp, Src.Left, Src.Top, SRCCOPY);
  1306.       { set the background color of the source DC to the color.
  1307.         contained in the parts of the bitmap that should be transparent }
  1308.       cColor := SetBkColor(hdcTemp, ColorToRGB(Transparent));
  1309.       { create the object mask for the bitmap by performing a BitBlt()
  1310.         from the source bitmap to a monochrome bitmap }
  1311.       BitBlt(hdcObject, 0, 0, bmWidth, bmHeight, hdcTemp, Src.Left, Src.Top, SRCCOPY);
  1312.       { set the background color of the source DC back to the original color }
  1313.       SetBkColor(hdcTemp, cColor);
  1314.       { create the inverse of the object mask }
  1315.       BitBlt(hdcBack, 0, 0, bmWidth, bmHeight, hdcObject, 0, 0, NOTSRCCOPY);
  1316.       { copy the background of the main DC to the destination }
  1317.       BitBlt(hdcMem, 0, 0, bmWidth, bmHeight, DC, X, Y, SRCCOPY);
  1318.       { mask out the places where the bitmap will be placed }
  1319.       BitBlt(hdcMem, 0, 0, bmWidth, bmHeight, hdcObject, 0, 0, SRCAND);
  1320.       { mask out the transparent colored pixels on the bitmap }
  1321.       BitBlt(hdcTemp, Src.Left, Src.Top, bmWidth, bmHeight, hdcBack, 0, 0, SRCAND);
  1322.       { XOR the bitmap with the background on the destination DC }
  1323.       BitBlt (hdcMem, 0, 0, bmWidth, bmHeight, hdcTemp, Src.Left, Src.Top, SRCPAINT);
  1324.       { copy the destination to the screen }
  1325.       BitBlt(DC, X, Y, bmWidth, bmHeight, hdcMem, 0, 0, SRCCOPY);
  1326.       { place the original bitmap back into the bitmap sent here }
  1327.       BitBlt(hdcTemp, Src.Left, Src.Top, bmWidth, bmHeight, hdcSave, 0, 0, SRCCOPY);
  1328.       { delete the memory bitmaps }
  1329.       DeleteObject(SelectObject(hdcBack, bmBackOld));
  1330.       DeleteObject(SelectObject(hdcObject, bmObjectOld));
  1331.       DeleteObject(SelectObject(hdcMem, bmMemOld));
  1332.       DeleteObject(SelectObject(hdcSave, bmSaveOld));
  1333.       { delete the memory DCs }
  1334.       DeleteDC(hdcMem);
  1335.       DeleteDC(hdcBack);
  1336.       DeleteDC(hdcObject);
  1337.       DeleteDC(hdcSave);
  1338.       DeleteDC(hdcTemp);
  1339.    {$IFDEF WIN32}
  1340.    finally
  1341.       LeaveCriticalSection(TransSection);
  1342.    end;
  1343.    {$ENDIF}
  1344. end;
  1345. {=========================================================================}
  1346. procedure DrawTransparentBitmap(DC: HDC; Bitmap: HBitmap; X, Y: integer;
  1347.                                 Transparent: TColorRef);
  1348. var
  1349.    Src: TRect;
  1350. begin
  1351.    Src.TopLeft := Point(0,0);
  1352.    { convert bitmap dimensions from device to logical points }
  1353.    GetBitmapSize(Bitmap, Src.Right, Src.Bottom);
  1354.    DrawTransparentBitmapEx(DC, Bitmap, X, Y,
  1355.                            Src, Transparent);
  1356. end;
  1357. {=========================================================================}
  1358. procedure TileBlt(DC: HDC; Bitmap: HBitmap; const aRect: TRect; ROP: Longint);
  1359. { This procedure tiles the given Bitmap aBitmap on DC. }
  1360. { aRect specifies the dimensions                       }
  1361. var
  1362.    aWidth, aHeight,W,H: integer;
  1363.    TempDC: HDC;
  1364.    oldBitmap: HBitmap;
  1365.    i,j : integer;
  1366. begin
  1367.    {$IFDEF WIN32}
  1368.    EnterCriticalSection(TransSection);
  1369.    try
  1370.    {$ENDIF}
  1371.       OldBitmap := 0;
  1372.       TempDC := CreateCompatibleDC(DC);
  1373.       try
  1374.          OldBitmap := SelectObject(TempDC, Bitmap); { select the bitmap }
  1375.          GetBitmapSize(Bitmap,aWidth,aHeight);
  1376.          i := 0;
  1377.          H := aRect.Bottom-aRect.Top;
  1378.          while H > 0 do
  1379.          begin
  1380.             j := 0;
  1381.             W := aRect.Right-aRect.Left;
  1382.             while W > 0 do
  1383.             begin
  1384.                BitBlt(DC, aRect.Left+j*aWidth, aRect.Top+i*aHeight,
  1385.                       Min(aWidth,W), Min(aHeight,H),
  1386.                       TempDC,0,0,ROP);
  1387.                dec(W,aWidth);
  1388.                inc(j);
  1389.             end;
  1390.             dec(H,aHeight);
  1391.             inc(i);
  1392.          end;
  1393.       finally
  1394.          SelectObject(TempDC, OldBitmap);
  1395.          DeleteDC(TempDC);
  1396.       end;
  1397.    {$IFDEF WIN32}
  1398.    finally
  1399.       LeaveCriticalSection(TransSection);
  1400.    end;
  1401.    {$ENDIF}
  1402. end;
  1403. {=========================================================================}
  1404. procedure FillGradient(DC: HDC; BeginColor, EndColor: TColor;
  1405.                        nColors: integer; const aRect: TRect);
  1406. var
  1407.    BeginRGBValue : array[0..2] of Byte;
  1408.    RGBDifference : array[0..2] of integer;
  1409.    ColorBand     : TRect;
  1410.    i             : Integer;
  1411.    Red,Green,Blue: Byte;
  1412.    Brush,OldBrush: HBrush;
  1413. begin
  1414.    { Extract the begin RGB values, set the Red, Green and Blue colors }
  1415.    BeginRGBValue[0] := GetRValue(ColorToRGB(BeginColor));
  1416.    BeginRGBValue[1] := GetGValue(ColorToRGB(BeginColor));
  1417.    BeginRGBValue[2] := GetBValue(ColorToRGB(BeginColor));
  1418.    { Calculate the difference between begin and end RGB values }
  1419.    RGBDifference[0] := GetRValue(ColorToRGB(EndColor))-BeginRGBValue[0];
  1420.    RGBDifference[1] := GetGValue(ColorToRGB(EndColor))-BeginRGBValue[1];
  1421.    RGBDifference[2] := GetBValue(ColorToRGB(EndColor))-BeginRGBValue[2];
  1422.    { Calculate the color band's top and bottom coordinates, for Left To Right fills }
  1423.    ColorBand.Top := aRect.Top;
  1424.    ColorBand.Bottom := aRect.Bottom;
  1425.    { Perform the fill }
  1426.    for i := 0 to nColors-1 do
  1427.    begin
  1428.       { Calculate the color band's left and right coordinates }
  1429.       ColorBand.Left  := aRect.Left+ MulDiv(i, aRect.Right-aRect.Left, nColors);
  1430.       ColorBand.Right := aRect.Left+ MulDiv(i+1, aRect.Right-aRect.Left, nColors);
  1431.       { Calculate the color band's color }
  1432.       if (nColors > 1) then
  1433.       begin
  1434.          Red   := BeginRGBValue[0] + MulDiv(i, RGBDifference[0],nColors-1);
  1435.          Green := BeginRGBValue[1] + MulDiv(i, RGBDifference[1],nColors-1);
  1436.          Blue  := BeginRGBValue[2] + MulDiv(i, RGBDifference[2],nColors-1);
  1437.       end
  1438.       else
  1439.       begin
  1440.          { Set to the Begin Color if set to only one color }
  1441.          Red   := BeginRGBValue[0];
  1442.          Green := BeginRGBValue[1];
  1443.          Blue  := BeginRGBValue[2];
  1444.       end;
  1445.       { Create a brush with the appropriate color for this band }
  1446.       Brush := CreateSolidBrush(RGB(Red,Green,Blue));
  1447.       { Select that brush into the temporary DC. }
  1448.       OldBrush := SelectObject(DC, Brush);
  1449.       try
  1450.          { Fill the rectangle using the selected brush -- PatBlt is faster than FillRect }
  1451.          PatBlt(DC, ColorBand.Left, ColorBand.Top, ColorBand.Right-ColorBand.Left, ColorBand.Bottom-ColorBand.Top, PATCOPY);
  1452.       finally
  1453.          { Clean up the brush }
  1454.          SelectObject(DC, OldBrush);
  1455.          DeleteObject(Brush);
  1456.       end;
  1457.    end;
  1458. end;
  1459. {=========================================================================}
  1460. procedure FillSolid(DC: HDC; Color: TColor; const aRect: TRect);
  1461. var
  1462.   Brush, OldBrush: HBrush;
  1463. begin
  1464.    Brush := CreateSolidBrush(Color);
  1465.    OldBrush := SelectObject(DC, Brush);
  1466.    try
  1467.       PatBlt(DC, aRect.Left, aRect.Top,
  1468.                  aRect.Right-aRect.Left,
  1469.                  aRect.Bottom-aRect.Top, PATCOPY);
  1470.    finally
  1471.       Brush := SelectObject(DC, OldBrush);
  1472.       DeleteObject(Brush);
  1473.    end;
  1474. end;
  1475. {=========================================================================}
  1476. function WinExecAndWaitEx(FileName: TFileName; TimeOut: DWORD): Boolean;
  1477. var
  1478.    {$IFDEF WIN32}
  1479.    StartupInfo: TStartupInfo;
  1480.    ProcessInfo: TProcessInformation;
  1481.    ExCode,Res : DWORD;
  1482.    {$ELSE}
  1483.    hAppInstance: THandle;
  1484.    Msg         : TMsg;
  1485.    aBuf        : array[0..255] of Char;
  1486.    {$ENDIF}
  1487. begin
  1488.    Result := False;
  1489.    {$IFNDEF WIN32}
  1490.    hAppInstance := WinExec(StrPCopy(aBuf, FileName), SW_NORMAL);
  1491.    if (hAppInstance < HINSTANCE_ERROR) then exit
  1492.    else
  1493.    repeat
  1494.       while PeekMessage(Msg, 0, 0, 0, pm_Remove) do
  1495.       begin
  1496.         TranslateMessage(Msg);
  1497.         DispatchMessage(Msg);
  1498.       end;
  1499.    until (GetModuleUsage(hAppInstance) = 0);
  1500.    Result := True;
  1501.    {$ELSE}
  1502.    FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  1503.    with StartupInfo do
  1504.    begin
  1505.       cb := SizeOf(TStartupInfo);
  1506.       dwFlags := STARTF_USESHOWWINDOW;
  1507.       wShowWindow := SW_NORMAL;
  1508.    end;
  1509.    if CreateProcess(nil,PChar(FileName),nil,nil,False,NORMAL_PRIORITY_CLASS,
  1510.                     nil,nil,StartupInfo,ProcessInfo) then
  1511.    begin
  1512.       Res := WaitforSingleObject(ProcessInfo.hProcess, TIMEOUT);
  1513.       if (Res = WAIT_TIMEOUT) then
  1514.       begin
  1515.          TerminateProcess(ProcessInfo.hProcess,0);
  1516.          CloseHandle(ProcessInfo.hProcess);
  1517.          Result := False;
  1518.       end
  1519.       else
  1520.       begin
  1521.          GetExitCodeProcess(ProcessInfo.hProcess, ExCode);
  1522.          CloseHandle(ProcessInfo.hProcess);
  1523.          Result := True;
  1524.       end;
  1525.    end;
  1526.    {$ENDIF}
  1527. end;
  1528. {=========================================================================}
  1529. function WinExecAndWait(FileName: TFileName): Boolean;
  1530. begin
  1531.    Result := WinExecAndWaitEx(FileName,INFINITE);
  1532. end;
  1533. {=========================================================================}
  1534. procedure TimeDecode(Time: Longint; var Hour, Min, Sec, MSec: Word);
  1535. Var
  1536.    MinCount, MSecCount: Word;
  1537. begin
  1538.    if Time > 0 then
  1539.    begin
  1540.      DivMod32(Time, 60000, MinCount, MSecCount);
  1541.      DivMod32(MinCount, 60, Hour, Min);
  1542.      DivMod32(MSecCount, 1000, Sec, MSec);
  1543.    end
  1544.    else
  1545.    begin
  1546.       Hour := 0;
  1547.       Min := 0;
  1548.       Sec := 0;
  1549.       MSec := 0;
  1550.    end;
  1551. end;
  1552. {=========================================================================}
  1553. function TimeToMask(Time: Longint): string;
  1554. begin
  1555.    Result := Format('%2.2d%2.2d%5.5d',
  1556.                     [Time div 3600000,
  1557.                      Time mod 3600000 div 60000,
  1558.                      Time mod 60000]);
  1559. end;
  1560. {=========================================================================}
  1561. function MaskToTime(Mask: string): Longint;
  1562. begin
  1563.    Result := StrToIntDef(Mask, 0);
  1564.    Result := (Result div 10000000)*3600000+
  1565.              ((Result mod 10000000) mod 100000) +
  1566.              ((Result mod 10000000) div 100000) * 60000;
  1567. end;
  1568. {=========================================================================}
  1569. function CheckFloat(const S: string): string;
  1570. var
  1571.    i: integer;
  1572. begin
  1573.    Result := S;
  1574.    for i := 1 to Length(Result) do
  1575.    begin
  1576.       if (Result[i] in ['.',',',';']) and
  1577.          (Result[i] <> DecimalSeparator) then
  1578.           Result[i] := DecimalSeparator;
  1579.    end;
  1580. end;
  1581. {$IFDEF WIN32}
  1582. {=========================================================================}
  1583. function TimeToString64Ex(Time: int64; MSec: Boolean): string;
  1584. begin
  1585.    if MSec then
  1586.    begin
  1587.       if Time >= 86400000 then
  1588.          Result := Format('%d:%2.2d:%2.2d:%2.2d.%3.3d',[int64Div32(Time,86400000),
  1589.                                                         int64Div32(int64Mod32(Time,86400000),3600000),
  1590.                                                         int64Div32(int64Mod32(Time,3600000),60000),
  1591.                                                         int64Div32(int64Mod32(Time,60000),1000),
  1592.                                                         int64Mod32(Time,1000)])
  1593.       else if Time >= 3600000 then
  1594.          Result := Format('%d:%2.2d:%2.2d.%3.3d',[int64Div32(Time,3600000),
  1595.                                                   int64Div32(int64Mod32(Time,3600000),60000),
  1596.                                                   int64Div32(int64Mod32(Time,60000),1000),
  1597.                                                   int64Mod32(Time,1000)])
  1598.       else
  1599.          Result := Format('%d:%2.2d.%3.3d',[int64Div32(Time,60000),
  1600.                                             int64Div32(int64Mod32(Time,60000),1000),
  1601.                                             int64Mod32(Time,1000)]);
  1602.    end
  1603.    else
  1604.    begin
  1605.       if Time >= 86400000 then
  1606.          Result := Format('%d:%2.2d:%2.2d:%2.2d',[int64Div32(Time,86400000),
  1607.                                                   int64Div32(int64Mod32(Time,86400000),3600000),
  1608.                                                   int64Div32(int64Mod32(Time,3600000),60000),
  1609.                                                   int64Div32(int64Mod32(Time,60000),1000)])
  1610.       else if Time >= 3600000 then
  1611.          Result := Format('%d:%2.2d:%2.2d',[int64Div32(Time,3600000),
  1612.                                             int64Div32(int64Mod32(Time,3600000),60000),
  1613.                                             int64Div32(int64Mod32(Time,60000),1000)])
  1614.       else
  1615.          Result := Format('%d:%2.2d',[int64Div32(Time,60000),
  1616.                                       int64Div32(int64Mod32(Time,60000),1000)]);
  1617.    end;
  1618. end;
  1619. {=========================================================================}
  1620. function TimeToString64(LowTime,HighTime: Cardinal; MSec: Boolean): string;
  1621. var
  1622.    Time: int64;
  1623. begin
  1624.    asm
  1625.       mov  dword ptr Time[0], eax
  1626.       mov  dword ptr Time[4], edx
  1627.    end;
  1628.    Result := TimeToString64Ex(Time, MSec);
  1629. end;
  1630. {$ENDIF}
  1631. {=========================================================================}
  1632. function TimeToStringEx(Time: MM_int64; MSec: Boolean): string;
  1633. begin
  1634.    if MSec then
  1635.    begin
  1636.       {$IFDEF DELPHI4}
  1637.       if Time >= 86400000 then
  1638.          Result := Format('%d:%2.2d:%2.2d:%2.2d.%3.3d',[Time div 86400000,
  1639.                                                        (Time mod 86400000) div 3600000,
  1640.                                                        (Time mod 3600000) div 60000,
  1641.                                                        (Time mod 60000) div 1000,
  1642.                                                        Time mod 1000])
  1643.       else
  1644.       {$ENDIF}
  1645.       if Time >= 3600000 then
  1646.          Result := Format('%d:%2.2d:%2.2d.%3.3d',[Time div 3600000,
  1647.                                                  (Time mod 3600000) div 60000,
  1648.                                                  (Time mod 60000) div 1000,
  1649.                                                  Time mod 1000])
  1650.       else
  1651.          Result := Format('%d:%2.2d.%3.3d',[Time div 60000,
  1652.                                            (Time mod 60000) div 1000,
  1653.                                            Time mod 1000]);
  1654.    end
  1655.    else
  1656.    begin
  1657.       {$IFDEF DELPHI4}
  1658.       if Time >= 86400000 then
  1659.          Result := Format('%d:%2.2d:%2.2d:%2.2d',[Time div 86400000,
  1660.                                                   (Time mod 86400000) div 3600000,
  1661.                                                   (Time mod 3600000) div 60000,
  1662.                                                   (Time mod 60000) div 1000])
  1663.       else
  1664.       {$ENDIF}
  1665.       if Time >= 3600000 then
  1666.          Result := Format('%d:%2.2d:%2.2d',[Time div 3600000,
  1667.                                            (Time mod 3600000) div 60000,
  1668.                                            (Time mod 60000) div 1000])
  1669.       else
  1670.          Result := Format('%d:%2.2d',[Time div 60000,
  1671.                                      (Time mod 60000) div 1000]);
  1672.    end;
  1673. end;
  1674. {=========================================================================}
  1675. function TimeToString(Time: MM_int64): string;
  1676. begin
  1677.    Result := TimeToStringEx(Time,True);
  1678. end;
  1679. {=========================================================================}
  1680. function StrToFloatEx(S: string; Limiter: Char): Extended;
  1681. var
  1682.    idx: integer;
  1683. begin
  1684.    case Limiter of
  1685.         ',': idx := Pos('.',S);
  1686.         '.': idx := Pos(',',S);
  1687.         else idx := -1;
  1688.    end;
  1689.    if (idx > 0) then
  1690.    begin
  1691.       if (Limiter = '.') then
  1692.           S[idx] := '.'
  1693.       else
  1694.           S[idx] := ',';
  1695.    end;
  1696.    Result:= StrToFloat(S);
  1697. end;
  1698. {=========================================================================}
  1699. function DBToLin(DB: Float): Float;
  1700. begin
  1701.    Result := pow(10,DB/20);
  1702. end;
  1703. {=========================================================================}
  1704. function LinToDB(lin: Float): Float;
  1705. begin
  1706.    if lin < 1.0e-6 then Result := -120
  1707.    else Result := log10(abs(lin))*20;
  1708. end;
  1709. {=========================================================================}
  1710. function DBToVolume(DB: Float; Base: Longint): Longint;
  1711. begin
  1712.    { if (DB = Base) then
  1713.        Result := Base
  1714.    else
  1715.    }
  1716.        Result := Round(Base/pow(10,-DB/20));
  1717. end;
  1718. {=========================================================================}
  1719. function VolumeToDB(Volume, Base: Longint): Float;
  1720. begin
  1721.    if (Volume = 0) then Result := -110.0
  1722.    else
  1723.    begin
  1724.       Result := Log10(abs(Volume)/Max(Base,1))*20;
  1725.    end;
  1726. end;
  1727. {=========================================================================}
  1728. function VolumeToStringShort(Volume, Base: Longint; Precision: integer): string;
  1729. var
  1730.    Value: Float;
  1731. begin
  1732.    if (Volume = 0) then Result := '-Inf'
  1733.    else
  1734.    begin
  1735.       Value := Log10(abs(Volume)/Max(Base,1))*20;
  1736.       Result := Format('%2.*f',[Precision,Value]);
  1737.    end;
  1738. end;
  1739. {=========================================================================}
  1740. function VolumeToString(Volume, Base: Longint; Precision: integer): string;
  1741. begin
  1742.    Result := VolumeToStringShort(Volume, Base, Precision) + ' dB';
  1743. end;
  1744. {=========================================================================}
  1745. function PanningToString(Panning, Range: Longint): string;
  1746. begin
  1747.    Result := Format('%d:%d',[(Range-Panning)*50 div Range,
  1748.                              (Panning+Range)*50 div Range]);
  1749. end;
  1750. {=========================================================================}
  1751. procedure CalcVolume(Base,Volume,Panning: Longint; var Left, Right: Longint);
  1752. begin
  1753.    if Panning > 0 then
  1754.    begin
  1755.       Left  := MulDiv((Base-Panning),Volume,Base);
  1756.       Right := Volume;
  1757.    end
  1758.    else
  1759.    begin
  1760.       Left := Volume;
  1761.       Right := MulDiv((Base+Panning),Volume,Base);
  1762.    end;
  1763. end;
  1764. {=========================================================================}
  1765. function CombineVolume(Vol1,Vol2,Base: Longint): Longint;
  1766. begin
  1767.    Result := Min(MulDiv(Vol1,Vol2,Base),Base);
  1768. end;
  1769. {=========================================================================}
  1770. function FormatBigNumber(dw: Longint): String;
  1771. begin
  1772.    { this is ugly... }
  1773.    if (dw >= 1000000000) then
  1774.    begin
  1775.       FmtStr(Result, '%d.%3.3d.%3.3d.%3.3d',
  1776.                      [(dw div 1000000000),
  1777.                       (dw mod 1000000000) div 1000000,
  1778.                       (dw mod 1000000) div 1000,
  1779.                       (dw mod 1000)]);
  1780.    end
  1781.    else if (dw >= 1000000) then
  1782.    begin
  1783.       FmtStr(Result, '%d.%3.3d.%3.3d',
  1784.                      [(dw div 1000000),
  1785.                       (dw mod 1000000) div 1000,
  1786.                       (dw mod 1000)]);
  1787.     end
  1788.     else if (dw >= 1000) then
  1789.     begin
  1790.        FmtStr(Result, '%d.%3.3d',
  1791.                       [(dw div 1000),
  1792.                        (dw mod 1000)]);
  1793.     end
  1794.     else
  1795.     begin
  1796.        FmtStr(Result, '%d', [dw]);
  1797.     end;
  1798. end;
  1799. {=========================================================================}
  1800. function BytesToString(Bytes: Comp): string;
  1801. var
  1802.    OldSep: Char;
  1803. begin
  1804.    OldSep := DecimalSeparator;
  1805.    DecimalSeparator := '.';
  1806.    if (Bytes >= 1024*1024*1024) then
  1807.        Result := Format('%.1f Gb',[Bytes/(1024*1024*1024)])
  1808.    else if (Bytes >= 1000*1024) then
  1809.        Result := Format('%.1f Mb',[Bytes/(1024*1024)])
  1810.    else
  1811.        Result := Format('%.1f Kb',[Bytes/1024]);
  1812.    DecimalSeparator := OldSep;
  1813. end;
  1814. {=========================================================================}
  1815. procedure DrawRubberband(Sender: TObject; aRect: TRect);
  1816. var
  1817.   DC: HDC;
  1818.   PtA, PtB: TPoint;
  1819. begin
  1820.    if Sender is TControl then
  1821.    with (Sender as TControl) do
  1822.    begin
  1823.       DC := GetDC(0);
  1824.       if (aRect.Left <> 0) or (aRect.Top <> 0) or
  1825.          (aRect.Right <> 0) or (aRect.Bottom <> 0) then
  1826.       begin
  1827.          PtA := ClientToScreen(Point(aRect.Left, aRect.Top));
  1828.          PtB := ClientToScreen(Point(aRect.Right, aRect.Bottom));
  1829.          {$IFDEF WIN32}
  1830.          if PtA.X > PtB.X then SwapLong(PtA.X,PtB.X);
  1831.          if PtA.Y > PtB.Y then SwapLong(PtA.Y,PtB.Y);
  1832.          {$ELSE}
  1833.          if PtA.X > PtB.X then SwapInt(PtA.X,PtB.X);
  1834.          if PtA.Y > PtB.Y then SwapInt(PtA.Y,PtB.Y);
  1835.          {$ENDIF}
  1836.          DrawFocusRect(DC, Rect(PtA.X, PtA.Y, PtB.X, PtB.Y));
  1837.       end;
  1838.       ReleaseDC(0,DC);
  1839.    end;
  1840. end;
  1841. {=========================================================================}
  1842. procedure DrawRubberLineEx(Sender: TObject; aRect: TRect; Pen: HPEN; ROP: DWORD);
  1843. var
  1844.   DC: HDC;
  1845.   PtA, PtB: TPoint;
  1846. begin
  1847.    if Sender is TControl then
  1848.    with (Sender as TControl) do
  1849.    begin
  1850.       DC := GetDC(0);
  1851.       Pen := SelectObject(DC,Pen);
  1852.       SetRop2(DC,ROP);
  1853.       if (aRect.Left <> 0) or (aRect.Top <> 0) or
  1854.          (aRect.Right <> 0) or (aRect.Bottom <> 0) then
  1855.       begin
  1856.          PtA := ClientToScreen(Point(aRect.Left, aRect.Top));
  1857.          PtB := ClientToScreen(Point(aRect.Right, aRect.Bottom));
  1858.          {$IFDEF WIN32}
  1859.          MoveToEx(DC,PtA.X,PtA.Y,nil);
  1860.          {$ELSE}
  1861.          MoveToEx(DC,PtA.X,PtA.Y,nil);
  1862.          {$ENDIF}
  1863.          LineTo(DC,PtB.X,PtB.Y);
  1864.       end;
  1865.       SelectObject(DC,Pen);
  1866.       ReleaseDC(0,DC);
  1867.    end;
  1868. end;
  1869. {=========================================================================}
  1870. procedure DrawRubberLine(Sender: TObject; aRect: TRect);
  1871. begin
  1872.    DrawRubberLineEx(Sender,aRect,GetStockObject(WHITE_PEN),R2_XORPEN);
  1873. end;
  1874. {=========================================================================}
  1875. { Align: 0: Left, 1: Right: 2: Vertikal                                   }
  1876. procedure TextOutAligned(Canvas: TCanvas; X, Y: integer; Text: String;
  1877.                          FontName: PChar; FontSize: integer; Align: Byte);
  1878. var
  1879.    DC: THandle;
  1880.    HFont, OldFont: integer;
  1881.    Extent: TSize;
  1882.    Orientation: Word;
  1883. begin
  1884.    DC := Canvas.Handle;
  1885.    if Align = 2 then
  1886.       Orientation := 90
  1887.    else
  1888.       Orientation := 360;
  1889.    if _Win2K_ or _WinXP_ then
  1890.       FontSize := -(FontSize-1);
  1891.       
  1892.    HFont := CreateFont(FontSize,0,Orientation*10,0,fw_normal,0,0,0,1,4,$10,2,4,FontName);
  1893.    OldFont := SelectObject(DC, HFont);
  1894.    GetTextExtentPoint(DC, @Text[1], Length(Text), Extent);
  1895.    case Align of
  1896.        0: begin { left aligned }
  1897.              dec(Y, Extent.cY div 2);
  1898.           end;
  1899.        1: begin { right aligned }
  1900.              dec(X, Extent.cX);
  1901.              dec(Y, Extent.cY div 2);
  1902.           end;
  1903.        2: begin { vertikal aligned }
  1904.              dec(X, Extent.cY div 2);
  1905.              inc(Y, Extent.cX);
  1906.           end;
  1907.    end;
  1908.    Text := Text + #0;
  1909.    TextOut(DC, X, Y, @Text[1], Length(Text)-1);
  1910.    SelectObject(DC, OldFont);
  1911.    DeleteObject(HFont);
  1912. end;
  1913. {=========================================================================}
  1914. function GlobalAllocMem(Size: Longint): Pointer;
  1915. begin
  1916.    Result := GlobalAllocPtr(GPTR, Size);
  1917.    if (Result = nil) then OutOfMemoryError;
  1918. end;
  1919. {=========================================================================}
  1920. procedure GlobalReAllocMem(var p: Pointer; Size: Longint);
  1921. begin
  1922.    GlobalFreeMem(p);
  1923.    p := GlobalAllocMem(Size);
  1924. end;
  1925. {=========================================================================}
  1926. procedure GlobalFreeMem(var p: Pointer);
  1927. begin
  1928.    if (p <> nil) then
  1929.    begin
  1930.       GlobalFreePtr(p);
  1931.       p := nil;
  1932.    end;
  1933. end;
  1934. {=========================================================================}
  1935. function GlobalMemSize(const p: Pointer): Longint;
  1936. begin
  1937.    if (p <> nil) then
  1938.    begin
  1939.       {$IFDEF WIN32}
  1940.       Result := GlobalSize(GlobalHandle(p));
  1941.       {$ELSE}
  1942.       Result := GlobalSize(GlobalHandle(SELECTOROF(p)));
  1943.       {$ENDIF}
  1944.    end
  1945.    else Result := 0;
  1946. end;
  1947. {=========================================================================}
  1948. function SearchParamStr(Switch: string): Boolean;
  1949. var
  1950.    i,idx: integer;
  1951.    S: string;
  1952. begin
  1953.    for i := 1 to ParamCount do
  1954.    begin
  1955.       S := ParamStr(i);
  1956.       idx := Pos(':',S);
  1957.       if (idx > 0) then
  1958.           S := Copy(S,1,idx-1);
  1959.       if (S<> '') and (S[1] in ['-', '/']) and
  1960.          (CompareText(Copy(S, 2, Length(Switch)), Switch) = 0) and
  1961.          (Length(Switch) = Length(S)-1) then
  1962.       begin
  1963.          Result := True;
  1964.          Exit;
  1965.       end;
  1966.    end;
  1967.    Result := False;
  1968. end;
  1969. {=========================================================================}
  1970. procedure WinYield(Wnd: THandle);
  1971. var
  1972.    msg: TMsg;
  1973. begin
  1974.    while PeekMessage(Msg, Wnd, 0, 0, PM_REMOVE) do
  1975.    begin
  1976.       TranslateMessage(Msg);
  1977.       DispatchMessage(Msg);
  1978.    end;
  1979. end;
  1980. {=========================================================================}
  1981. function DesignMode: Boolean;
  1982. var
  1983.    ExeName: array[0..260] of Char;
  1984. begin
  1985.    { in DesignMode? }
  1986.    GetModuleFileName(0, ExeName, sizeOf(ExeName));
  1987.    StrUpper(ExeName);
  1988.    if (StrPos(ExeName, 'DELPHI32') <> nil) or
  1989.       (StrPos(ExeName, 'BCB') <> nil) or
  1990.       (StrPos(ExeName, '.DCP') <> nil) or
  1991.       (StrPos(ExeName, '.BPL') <> nil) or
  1992.       (StrPos(ExeName, '.DCL') <> nil) or
  1993.       (StrPos(ExeName, '.CCL') <> nil) then
  1994.        Result := True
  1995.    else
  1996.        Result := False;
  1997. end;
  1998. {$IFDEF CHECK_REGISTERED}
  1999. {$IFDEF BUILD_ACTIVEX}
  2000.    {$I MMREGAX.INC}
  2001. {$ENDIF}
  2002. {$ENDIF}
  2003. {=========================================================================}
  2004. procedure RegisterPackage(const Pack: string);
  2005. begin
  2006.    {$IFDEF BUILD_ACTIVEX} {$IFDEF CHECK_REGISTERED}
  2007.    _RegisterPackage(Pack);
  2008.    {$ENDIF} {$ENDIF}
  2009. end;
  2010. {=========================================================================}
  2011. procedure RegisterComponent(Code: Longint; Control: TComponent; Text: string);
  2012. begin
  2013.    { only a dummy call to write portable code }
  2014. end;
  2015. {=========================================================================}
  2016. function ComponentRegistered(Code: Longint; Control: TComponent; Text: string): Longint;
  2017. begin
  2018.    Result := 0;
  2019.    {$IFDEF BUILD_ACTIVEX} {$IFDEF CHECK_REGISTERED}
  2020.    Result := _CheckComponent(Code,Control,Text);
  2021.    {$ENDIF} {$ENDIF}
  2022. end;
  2023. {=========================================================================}
  2024. function PackageRegistered(Pack: string): integer;
  2025. begin
  2026.    Result := 0;
  2027.    {$IFDEF BUILD_ACTIVEX} {$IFDEF CHECK_REGISTERED}
  2028.    Result := _CheckPackage(Pack);
  2029.    {$ENDIF} {$ENDIF}
  2030. end;
  2031. const
  2032.      FailCount : Longint = 0;
  2033.      AboutCount: Longint = 0;
  2034.      hAboutSem : THandle = 0;
  2035. {=========================================================================}
  2036. procedure RegisterFailed(Code: Longint; Control: TComponent; Text: string);
  2037. {$IFDEF BUILD_ACTIVEX}
  2038. var
  2039.    SemCount: Longint;
  2040.    function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
  2041.    var
  2042.       CaptionText: array[0..80] of Char;
  2043.    begin
  2044.       GetWindowText(hwnd, CaptionText, sizeOf(CaptionText)-1);
  2045.       if (StrPos(CaptionText, 'Delphi') <> nil) or
  2046.          (StrPos(CaptionText, 'C++ Builder') <> nil) or
  2047.          (StrPos(CaptionText, 'Microsoft Visual Basic') <> nil) or
  2048.          (StrPos(CaptionText, 'Microsoft Developer Studio') <> nil) then
  2049.       begin
  2050.          Boolean(Pointer(lParam)^) := True;
  2051.          Result := False;
  2052.       end
  2053.       else
  2054.           Result := True;
  2055.    end;
  2056.    function FindValidIDE: Boolean;
  2057.    var
  2058.       IDEFound: Boolean;
  2059.    begin
  2060.       IDEFound := False;
  2061.       Result := EnumWindows(@EnumWindowsProc,LPARAM(@IDEFound));
  2062.    end;
  2063. {$ENDIF}
  2064. begin
  2065.    {$IFDEF BUILD_ACTIVEX}
  2066.    if (FailCount = 0) then
  2067.    begin
  2068.       //it should be 0.
  2069.       hAboutSem := OpenSemaphore(EVENT_ALL_ACCESS, False, '_MMToolsX_');
  2070.       if (hAboutSem = 0) then
  2071.           hAboutSem := CreateSemaphore(nil, 0, MaxInt, '_MMToolsX_');
  2072.       if (hAboutSem <> 0) then
  2073.       begin
  2074.          ReleaseSemaphore(hAboutSem,1,@SemCount);
  2075.          if not FindValidIDE or (SemCount mod 10 = 0) then
  2076.             Show_EvalAboutBox(1);
  2077.       end;
  2078.    end;
  2079.    inc(FailCount);
  2080.    {$ELSE}
  2081.    if (FailCount = 0) then
  2082.        Application.MessageBox('Initialization Error',
  2083.                               'Multimedia Tools', MB_OK);
  2084.    if DesignMode then
  2085.       inc(FailCount)
  2086.    else
  2087.       Halt;
  2088.    {$ENDIF}
  2089. end;
  2090. {$IFDEF WIN32}
  2091. {$IFNDEF DELPHI3}
  2092. {-----------------------------------------------------------------------------}
  2093. function SysErrorMessage(ErrorCode: Integer): string;
  2094. var
  2095.    Len     : Integer;
  2096.    Buffer  : array[0..255] of Char;
  2097. begin
  2098.    Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
  2099.                         FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode,
  2100.                         GetThreadLocale, Buffer, SizeOf(Buffer), nil);
  2101.    while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len);
  2102.    SetString(Result, Buffer, Len);
  2103. end;
  2104. { TODO: resource ids }
  2105. const
  2106.     SWin32Error = 'Win32 Error. Code: %d.'#10'%s';
  2107.     SUnkWin32Error = 'A Win32 API function failed';
  2108. {-----------------------------------------------------------------------------}
  2109. procedure RaiseLastWin32Error;
  2110. var
  2111.    LastError: DWORD;
  2112.    Error    : EWin32Error;
  2113. begin
  2114.    LastError := GetLastError;
  2115.    if LastError <> ERROR_SUCCESS then
  2116.       Error := EWin32Error.CreateFmt(SWin32Error, [LastError,SysErrorMessage(LastError)])
  2117.    else
  2118.       Error := EWin32Error.Create(SUnkWin32Error);
  2119.    Error.ErrorCode := LastError;
  2120.    raise Error;
  2121. end;
  2122. {-----------------------------------------------------------------------------}
  2123. function Win32Check(RetVal: BOOL): BOOL;
  2124. begin
  2125.    if not RetVal then
  2126.       RaiseLastWin32Error;
  2127.    Result := RetVal;
  2128. end;
  2129. {$ENDIF}
  2130. {$ENDIF}
  2131. {$IFNDEF USEDLL}
  2132.    {$I MMUTILS.INC}
  2133. {$ELSE}
  2134. var
  2135.    ErrorMode      : Cardinal = 0;
  2136.    GetDeviceID    : function: Longint;
  2137.    GetDeviceStatus: function(Device: Longint): Longint;
  2138. {$ENDIF}
  2139. {------------------------------------------------------------------------}
  2140. procedure NewExitProc; Far;
  2141. begin
  2142.    if MMUTILDLLHandle <> 0 then
  2143.       FreeLibrary(MMUTILDLLHandle);
  2144.    if (SBuf <> nil) then GlobalFreePtr(SBuf);
  2145.    {$IFDEF WIN32}
  2146.    DeleteCriticalSection(TransSection);
  2147.    {$ENDIF}
  2148. end;
  2149. {=========================================================================}
  2150. function FindIDERunning: Boolean;
  2151. var
  2152.   IDEHWnd : THandle;
  2153.   CaptionText: array[0..80] of Char;
  2154.   {$IFDEF TRIAL}
  2155.   h: THandle;
  2156.   {$ENDIF}
  2157. begin
  2158.    Result := False;
  2159.    {$IFDEF TRIAL}
  2160.    (*
  2161.    h := LoadLibrary(MMUtilDLLKeyName);
  2162.    if (h <> 0) then
  2163.    begin
  2164.       {$IFDEF WIN32}
  2165.       {$IFDEF TRIAL}
  2166.       {$DEFINE _HACK3}
  2167.       {$I MMHACK.INC}
  2168.       {$ENDIF}
  2169.       {$ENDIF}
  2170.       FreeLibrary(h);
  2171.       Result := True;
  2172.    end
  2173.    else
  2174.    *)
  2175.    {$ENDIF}
  2176.    begin
  2177.       { Delphi or C++Builder running? }
  2178.       IDEHWnd:= FindWindow('TAppBuilder', Nil);
  2179.       if (IDEHWnd <> 0) then
  2180.       begin
  2181.          GetWindowText(IDEHWnd, CaptionText, sizeOf(CaptionText)-1);
  2182.          StrUpper(CaptionText);
  2183.          if (StrPos(CaptionText, 'DELPHI') <> nil) or
  2184.             (StrPos(CaptionText, 'C++BUILDER') <> nil) then
  2185.              Result := True;
  2186.       end;
  2187.    end;
  2188. end;
  2189. {$IFDEF WIN32}
  2190. {========================================================================}
  2191. procedure InitDriveSpacePtr;
  2192. var
  2193.   Kernel: THandle;
  2194. begin
  2195.   Kernel := GetModuleHandle(Windows.Kernel32);
  2196.   if Kernel <> 0 then
  2197.      @_GetDiskFreeSpaceEx := GetProcAddress(Kernel, 'GetDiskFreeSpaceExA');
  2198.   if not Assigned(_GetDiskFreeSpaceEx) then
  2199.      _GetDiskFreeSpaceEx := @BackfillGetDiskFreeSpaceEx;
  2200. end;
  2201. {$ENDIF}
  2202. {========================================================================}
  2203. procedure InitMMUtils;
  2204. {$IFDEF USEDLL}
  2205. var
  2206.    P: Pointer;
  2207. {$ENDIF}
  2208. begin
  2209.    {$IFDEF USEDLL}
  2210.    ErrorMode := SetErrorMode(SEM_NoOpenFileErrorBox);
  2211.    try
  2212.       GetDeviceID:= nil;
  2213.       if (GetModuleHandle(MMUTILDLLName) = 0) then
  2214.       begin
  2215.          (*MMUTILDLLHandle := LoadLibrary(MMUTILDLLKeyName);
  2216.          P := GetProcAddress(MMUTILDLLHandle,'_GetDeviceID_');
  2217.          if (P = nil) and (MMUTILDLLHandle <> 0) then
  2218.          begin
  2219.             FreeLibrary(MMUTILDLLHandle);
  2220.             MMUTILDLLHandle := 0;
  2221.          end;
  2222.          if MMUTILDLLHandle < HINSTANCE_ERROR then
  2223.          *)   MMUTILDLLHandle := LoadLibrary(MMUTILDLLName);
  2224.       end;
  2225.       if MMUTILDLLHandle >= HINSTANCE_ERROR then
  2226.       begin
  2227.          {$IFNDEF WIN32}
  2228.          AddExitProc(NewExitProc);
  2229.          {$ENDIF}
  2230.          @GetDeviceID        := GetProcAddress(MMUTILDLLHandle,'_GetDeviceID');
  2231.          @GetDeviceStatus    := GetProcAddress(MMUTILDLLHandle,'_GetDeviceStatus');
  2232.          @IDERunning         := GetProcAddress(MMUTILDLLHandle,'_IDERunning');
  2233.          @CheckTime          := GetProcAddress(MMUTILDLLHandle,'_CheckTime');
  2234.          @SwapSmall          := GetProcAddress(MMUTILDLLHandle,'_SwapSmall');
  2235.          @SwapInt            := GetProcAddress(MMUTILDLLHandle,'_SwapInt');
  2236.          @SwapLong           := GetProcAddress(MMUTILDLLHandle,'_SwapLong');
  2237.          @Min                := GetProcAddress(MMUTILDLLHandle,'_Min');
  2238.          @Max                := GetProcAddress(MMUTILDLLHandle,'_Max');
  2239.          @MinMax             := GetProcAddress(MMUTILDLLHandle,'_MinMax');
  2240.          @Limit              := GetProcAddress(MMUTILDLLHandle,'_Limit');
  2241.          @InMinMax           := GetProcAddress(MMUTILDLLHandle,'_InMinMax');
  2242.          @InRange            := GetProcAddress(MMUTILDLLHandle,'_InRange');
  2243.          @incHuge            := GetProcAddress(MMUTILDLLHandle,'_incHuge');
  2244.          @GlobalFillMem      := GetProcAddress(MMUTILDLLHandle,'_GlobalFillMem');
  2245.          @GlobalFillLong     := GetProcAddress(MMUTILDLLHandle,'_GlobalFillLong');
  2246.          @GlobalMoveMem      := GetProcAddress(MMUTILDLLHandle,'_GlobalMoveMem');
  2247.          @GlobalCmpMem       := GetProcAddress(MMUTILDLLHandle,'_GlobalCmpMem');
  2248.          {$IFDEF WIN32}
  2249.          CheckParam1 := @OpenSemaphore;
  2250.          CheckParam2 := @GetVolumeInformation;
  2251.          {$ENDIF}
  2252.       end
  2253.       else
  2254.       begin
  2255.          MessageDlg('Unable to load '+StrPas(MMUtilDLLName), mtError, [mbOK],0);
  2256.          Halt;
  2257.       end;
  2258.    finally
  2259.       SetErrorMode(ErrorMode);
  2260.    end;
  2261.    {$ELSE}
  2262.    SwapSmall          := _SwapSmall;
  2263.    SwapInt            := _SwapInt;
  2264.    SwapLong           := _SwapLong;
  2265.    Min                := _Min;
  2266.    Max                := _Max;
  2267.    MinMax             := _MinMax;
  2268.    Limit              := _Limit;
  2269.    InMinMax           := _InMinMax;
  2270.    InRange            := _InRange;
  2271.    incHuge            := _incHuge;
  2272.    GlobalFillMem      := _GlobalFillMem;
  2273.    GlobalFillLong     := _GlobalFillLong;
  2274.    GlobalMoveMem      := _GlobalMoveMem;
  2275.    GlobalCmpMem       := _GlobalCmpMem;
  2276.    {$ENDIF}
  2277. end;
  2278. {$IFDEF TRIAL}
  2279. var
  2280.    aBuf: array[0..256] of Char;
  2281. {$ENDIF}
  2282. {========================================================================}
  2283. initialization
  2284.      {$IFDEF WIN32}
  2285.      InitializeCriticalSection(TransSection);
  2286.      {$ENDIF}
  2287.      {$IFDEF TRIAL}
  2288.      if not FindIDERunning then
  2289.      begin
  2290.         Application.MessageBox(StrPCopy(aBuf,'IDE not found. Please register !'),
  2291.                                              'Multimedia Tools', MB_OK);
  2292.         Halt;
  2293.      end;
  2294.      {$ENDIF}
  2295.      InitMMUtils;
  2296.      {$IFDEF TRIAL}
  2297.      if assigned(GetDeviceID) then InitCode := GetDeviceID;
  2298.      if (InitCode = 0) then
  2299.          raise Exception.Create('Initialization Error');
  2300.      GetDeviceStatus(InitCode);
  2301.      Randomize;
  2302.      {$ENDIF}
  2303.      SBuf := GlobalAllocMem(50000);
  2304.      FillChar(SBuf^,50000,$FF);
  2305.      _Win95_    := HaveWin95;
  2306.      _Win98_    := HaveWin98;
  2307.      _WinME_    := HaveWinME;
  2308.      _WinNT3_   := HaveWinNT;
  2309.      _WinNT4_   := HaveWinNT4;
  2310.      _Win2K_    := HaveWin2K;
  2311.      _WinXP_    := HaveWinXP;
  2312.      _Win9x_    := _Win95_ or _Win98_ or _WinME_;
  2313.      _WinNT_    := _WinNT3_ or _WinNT4_ or _Win2K_ or _WinXP_;
  2314.      _WinNT_NEW_:= _WinNT4_ or _Win2K_ or _WinXP_;
  2315.      {$IFDEF WIN32}
  2316.      _CPU_      := GetCPUType;
  2317.      _MMX_      := (GetCPUFeatures and $800000 <> 0);
  2318.      _USECPUEXT_:= True;
  2319.       InitDriveSpacePtr;
  2320.      {$ENDIF}
  2321. {$IFDEF WIN32}
  2322. Finalization
  2323.     NewExitProc;
  2324. {$ENDIF}
  2325. end.