home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 April A / Pcwk4a98.iso / PROGRAM / DELPHI16 / Calmira / Src / UTILS / MISCUTIL.PAS < prev    next >
Pascal/Delphi Source File  |  1997-02-15  |  9KB  |  369 lines

  1. {*********************************************************}
  2. {                                                         }
  3. {    Calmira System Library 1.0                           }
  4. {    by Li-Hsin Huang,                                    }
  5. {    released into the public domain January 1997         }
  6. {                                                         }
  7. {*********************************************************}
  8.  
  9. unit MiscUtil;
  10.  
  11. { Some useful Delphi and Windows routines }
  12.  
  13. interface
  14.  
  15. uses Classes, SysUtils, Forms, WinTypes, IniFiles, Menus,
  16.   StdCtrls, Dialogs, ExtCtrls, Graphics;
  17.  
  18. const
  19.   MsgDialogSounds : Boolean = False;
  20.  
  21. var
  22.   ApplicationPath : TFilename;
  23.   WinPath : TFilename;
  24.  
  25. function Min(a, b: Integer): Integer;
  26. function Max(a, b: Integer): Integer;
  27. { Returns the smaller and larger of two values respectively }
  28.  
  29. function Range(n, lower, upper: Integer): Integer;
  30. { Constrains n to a lower and upper limit }
  31.  
  32. function Sign(x: Integer) : Integer;
  33. { Returns 1 if x > 0, -1 if x < 0 and 0 if x = 0 }
  34.  
  35. procedure Border3d(Canvas : TCanvas; Width, Height: Integer);
  36. { Draws a raised 3D border on a canvas, typically used in an
  37.   OnPaint method of a TForm }
  38.  
  39. procedure ErrorMsg(const msg: string);
  40. { Displays a message dialog box indicating an error }
  41.  
  42. procedure PlaySound(const filename: TFilename);
  43. { Plays the specified WAV file as a sound effect.  If the filename
  44.   is <None>, nothing is played }
  45.  
  46. function Intersects(const R, S: TRect): Boolean;
  47. { Returns True if the two rectangles intersect }
  48.  
  49. function NormalizeRect(p, q: TPoint): TRect;
  50. { Returns a rectangle defined by any two points.  When dragging a
  51.   selection box with a mouse, the fixed corner and the moving
  52.   corner may not always be top left and bottom right respectively.
  53.   This function creates a valid TRect out of them }
  54.  
  55. function TimeStampToDate(FileDate: Longint): TDateTime;
  56. { Converts a DOS timestamp to TDateTime.  If the timestamp is invalid
  57.   (some programs use invalid stamps as markers), the current date
  58.   is returned instead of raising EConvertError }
  59.  
  60. function GetRegValue(key : string): string;
  61. { Returns a value from the Windows registration database, with the
  62.   specified key from HKEY_CLASSES_ROOT }
  63.  
  64. function GetRadioIndex(const R: array of TRadioButton): Integer;
  65. procedure SetRadioIndex(const R: array of TRadioBUtton; index: Integer);
  66. function GetMenuCheck(const M: array of TMenuItem): Integer;
  67. procedure SetMenuCheck(const M: array of TMenuItem; index: Integer);
  68. { These routines are useful for setting and querying the state of
  69.   several controls.  Use them to simulate arrays and as an alternative
  70.   to TRadioGroup. }
  71.  
  72. procedure RefreshCursor;
  73. { Updates the cursor image when you have changed the Cursor or DragCursor
  74.   property of a control }
  75.  
  76. function AddHistory(Combo : TComboBox): Boolean;
  77. { Adds a combo box's Text string to its listbox, but only if the
  78.   string is not empty and not already present in the list.  The item is
  79.   inserted at the top of the list, and if there are more than 24 items,
  80.   the bottom one is removed.  Returns true if the list is modified }
  81.  
  82. function MsgDialog(const Msg: string; AType: TMsgDlgType;
  83.   AButtons: TMsgDlgButtons; HelpCtx: Longint): Word;
  84. { Calls the MessageDialog function, but also plays a suitable sound
  85.   effect from the Control Panel settings.  The MsgDialogSounds variable
  86.   enables the sounds }
  87.  
  88. function ShowModalDialog(FormClass : TFormClass): TModalResult;
  89. { A very simple way of displaying a dynamic modal form -- just pass the
  90.   form's class name e.g. TForm1, and an instance will be created,
  91.   shown as a modal dialog and then destroyed. }
  92.  
  93. function InitBitmap(ABitmap: TBitmap;
  94.   AWidth, AHeight : Integer; Color : TColor) : TBitmap;
  95. { Initialises the bitmap's dimensions and fills it with the chosen colour }
  96.  
  97. procedure ShrinkIcon(H : HIcon; Glyph : TBitmap);
  98. { Shrinks a 32 x 32 icon down to a 16 x 16 bitmap }
  99.  
  100. implementation
  101.  
  102. uses WinProcs, MMSystem, ShellAPI, Strings;
  103.  
  104.  
  105. function Min(a, b: Integer): Integer; assembler;
  106. asm
  107.   MOV    AX, a
  108.   CMP    AX, b
  109.   JLE    @@1
  110.   MOV    AX, b
  111. @@1:
  112. end;
  113.  
  114.  
  115. function Max(a, b: Integer): Integer; assembler;
  116. asm
  117.   MOV    AX, a
  118.   CMP    AX, b
  119.   JGE    @@1
  120.   MOV    AX, b
  121. @@1:
  122. end;
  123.  
  124. function Range(n, lower, upper: Integer): Integer; assembler;
  125. asm
  126.    MOV  AX, n
  127.    CMP  AX, lower
  128.    JGE  @@1
  129.    MOV  AX, lower
  130.    JMP  @finish
  131. @@1:
  132.    CMP  AX, upper
  133.    JLE  @finish
  134.    MOV  AX, upper
  135.    JMP  @finish
  136. @@2:
  137.    MOV  AX, lower
  138. @finish:
  139. end;
  140.  
  141.  
  142. function Sign(x: Integer) : Integer; assembler;
  143. asm
  144.    MOV  AX, X
  145.    CMP  AX, 0
  146.    JL   @@1
  147.    JG   @@2
  148.    XOR  AX, AX
  149.    JMP  @finish
  150. @@1:
  151.    MOV  AX, -1
  152.    JMP  @finish
  153. @@2:
  154.    MOV  AX, 1
  155. @finish:
  156. end;
  157.  
  158.  
  159.  
  160. procedure Border3d(Canvas : TCanvas; Width, Height: Integer);
  161. begin
  162.   with Canvas do begin
  163.     Pen.Color := clBtnHighLight;
  164.     MoveTo(0, Height);
  165.     LineTo(0, 0);
  166.     LineTo(Width, 0);
  167.     Pen.Color := clBtnShadow;
  168.     LineTo(Width, Height);
  169.     LineTo(0, Height);
  170.   end;
  171. end;
  172.  
  173.  
  174. procedure ErrorMsg(const msg: string);
  175. begin
  176.   MsgDialog(msg, mtError, [mbOK], 0);
  177. end;
  178.  
  179.  
  180. procedure PlaySound(const filename: TFilename);
  181. var s: TFilename;
  182. begin
  183.   if CompareText(filename, '<None>') <> 0 then
  184.     SndPlaySound(StrPCopy(@s, filename), SND_ASYNC or SND_NODEFAULT);
  185. end;
  186.  
  187.  
  188.  
  189. function Intersects(const R, S: TRect): Boolean;
  190. var dummy: TRect;
  191. begin
  192.   Result := IntersectRect(dummy, R, S) > 0;
  193. end;
  194.  
  195. function NormalizeRect(p, q: TPoint): TRect; assembler;
  196. asm
  197.   MOV  AX, p.x
  198.   MOV  BX, p.y
  199.   MOV  CX, q.x
  200.   MOV  DX, q.y
  201.   CMP  AX, CX
  202.   JLE  @@1
  203.   XCHG AX, CX
  204. @@1:
  205.   CMP  BX, DX
  206.   JLE  @@2
  207.   XCHG BX, DX
  208. @@2:
  209.   LES  DI, @Result
  210.   MOV  TRect(ES:[DI]).Left, AX
  211.   MOV  TRect(ES:[DI]).Top, BX
  212.   MOV  TRect(ES:[DI]).Right, CX
  213.   MOV  TRect(ES:[DI]).Bottom, DX
  214. end;
  215.  
  216.  
  217.  
  218. function TimeStampToDate(FileDate: Longint): TDateTime;
  219. begin
  220.   try Result := FileDateToDateTime(FileDate)
  221.   except on EConvertError do Result := Date;
  222.   end;
  223. end;
  224.  
  225. function GetRegValue(key : string): string;
  226. var cb : Longint;
  227. begin
  228.   cb := 255;
  229.   if RegQueryValue(HKEY_CLASSES_ROOT, StringAsPChar(key),
  230.      @Result[1], cb) = ERROR_SUCCESS then
  231.     Result[0] := Chr(cb-1)
  232.   else
  233.     Result := '';
  234. end;
  235.  
  236.  
  237. function GetRadioIndex(const R: array of TRadioButton): Integer;
  238. var i: Integer;
  239. begin
  240.   for i := 0 to High(R) do
  241.     if R[i].Checked then begin
  242.       Result := i;
  243.       exit;
  244.     end;
  245.   Result := 0;
  246. end;
  247.  
  248.  
  249. procedure SetRadioIndex(const R: array of TRadioBUtton; index: Integer);
  250. var i: Integer;
  251. begin
  252.   for i := 0 to High(R) do R[i].Checked := i = index;
  253. end;
  254.  
  255.  
  256. function GetMenuCheck(const M: array of TMenuItem): Integer;
  257. var i: Integer;
  258. begin
  259.   for i := 0 to High(M) do
  260.     if M[i].Checked then begin
  261.       Result := i;
  262.       exit;
  263.     end;
  264.   Result := 0;
  265. end;
  266.  
  267.  
  268. procedure SetMenuCheck(const M: array of TMenuItem; index: Integer);
  269. var i: Integer;
  270. begin
  271.   for i := 0 to High(M) do M[i].Checked := i = index;
  272. end;
  273.  
  274.  
  275. procedure RefreshCursor;
  276. var p: TPoint;
  277. begin
  278.   GetCursorPos(p);
  279.   SetCursorPos(p.x, p.y);
  280. end;
  281.  
  282.  
  283. function AddHistory(Combo : TComboBox): Boolean;
  284. begin
  285.   Result := False;
  286.   with Combo, Combo.Items do
  287.     if (Text <> '') and (IndexOf(Text) = -1) then begin
  288.       Result := True;
  289.       Insert(0, Text);
  290.       if Count > 24 then Delete(Count-1);
  291.     end;
  292. end;
  293.  
  294. function MsgDialog(const Msg: string; AType: TMsgDlgType;
  295.   AButtons: TMsgDlgButtons; HelpCtx: Longint): Word;
  296. const
  297.   Sound : array[TMsgDlgType] of Word =
  298.     (MB_ICONEXCLAMATION, MB_ICONHAND, MB_OK, MB_ICONQUESTION, 0);
  299. begin
  300.   if MsgDialogSounds and (AType < mtCustom) then MessageBeep(Sound[AType]);
  301.   Result := MessageDlg(Msg, AType, AButtons, HelpCtx);
  302. end;
  303.  
  304.  
  305. function ShowModalDialog(FormClass : TFormClass): TModalResult;
  306. begin
  307.   with FormClass.Create(Application) do
  308.   try
  309.     Result := ShowModal;
  310.   finally
  311.     Free;
  312.   end;
  313. end;
  314.  
  315.  
  316. function InitBitmap(ABitmap: TBitmap;
  317.   AWidth, AHeight : Integer; Color : TColor) : TBitmap;
  318. begin
  319.   { initializes a bitmap with width, height and background colour }
  320.  
  321.   with ABitmap do begin
  322.     Width := AWidth;
  323.     Height := AHeight;
  324.     Canvas.Brush.Color := Color;
  325.     Canvas.FillRect(Rect(0, 0, Width, Height));
  326.   end;
  327.   Result := ABitmap;
  328. end;
  329.  
  330.  
  331. procedure ShrinkIcon(H : HIcon; Glyph : TBitmap);
  332. var
  333.   bmp : TBitmap;
  334.   i, j : Integer;
  335.   src, dest : HDC;
  336. begin
  337.   bmp := InitBitmap(TBitmap.Create, 32, 32, clSilver);
  338.   DrawIcon(bmp.Canvas.Handle, 0, 0, H);
  339.  
  340.   try
  341.     with Glyph do begin
  342.       Width := 16;
  343.       Height := 16;
  344.  
  345.       Canvas.StretchDraw(Rect(0, 0, 16, 16), bmp);
  346.       src := bmp.Canvas.Handle;
  347.       dest := Canvas.Handle;
  348.  
  349.       for i := 0 to 15 do
  350.         for j := 0 to 15 do
  351.           if GetPixel(dest, i, j) = clSilver then
  352.            SetPixel(dest, i, j, GetPixel(src, i shl 1, j shl 1));
  353.  
  354.       Canvas.Pixels[0, 15] := clBtnFace;
  355.     end;
  356.   finally
  357.     bmp.Free;
  358.   end;
  359. end;
  360.  
  361.  
  362.  
  363.  
  364. initialization
  365.   ApplicationPath := ExtractFilePath(ParamStr(0));
  366.   WinPath[0] := Chr(GetWindowsDirectory(@WinPath[1], 79));
  367.   WinPath := MakePath(WinPath);
  368. end.
  369.