home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d6 / RX275D6.ZIP / Units / APPUTILS.PAS < prev    next >
Pascal/Delphi Source File  |  2001-06-24  |  27KB  |  885 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit AppUtils;
  11.  
  12. interface
  13.  
  14. {$I RX.INC}
  15.  
  16. uses Windows, Registry, RTLConsts, Classes, Controls, Forms, IniFiles, Grids, VCLUtils;
  17.  
  18. function GetDefaultSection(Component: TComponent): string;
  19. procedure GetDefaultIniData(Control: TControl; var IniFileName,
  20.   Section: string {$IFDEF WIN32}; UseRegistry: Boolean {$ENDIF});
  21. function GetDefaultIniName: string;
  22.  
  23. type
  24.   TOnGetDefaultIniName = function: string;
  25.  
  26. const
  27.   OnGetDefaultIniName: TOnGetDefaultIniName = nil;
  28.  
  29. {$IFDEF WIN32}
  30. var
  31.   DefCompanyName: string = '';
  32.   RegUseAppTitle: Boolean = False;
  33.  
  34. function GetDefaultIniRegKey: string;
  35. {$ENDIF}
  36.  
  37. function FindForm(FormClass: TFormClass): TForm;
  38. function FindShowForm(FormClass: TFormClass; const Caption: string): TForm;
  39. function ShowDialog(FormClass: TFormClass): Boolean;
  40. function InstantiateForm(FormClass: TFormClass; var Reference): TForm;
  41.  
  42. {$IFDEF WIN32}
  43. procedure SaveFormPlacement(Form: TForm; const IniFileName: string;
  44.   UseRegistry: Boolean);
  45. procedure RestoreFormPlacement(Form: TForm; const IniFileName: string;
  46.   UseRegistry: Boolean);
  47. procedure WriteFormPlacementReg(Form: TForm; IniFile: TRegIniFile;
  48.   const Section: string);
  49. procedure ReadFormPlacementReg(Form: TForm; IniFile: TRegIniFile;
  50.   const Section: string; LoadState, LoadPosition: Boolean);
  51. procedure SaveMDIChildrenReg(MainForm: TForm; IniFile: TRegIniFile);
  52. procedure RestoreMDIChildrenReg(MainForm: TForm; IniFile: TRegIniFile);
  53. procedure RestoreGridLayoutReg(Grid: TCustomGrid; IniFile: TRegIniFile);
  54. procedure SaveGridLayoutReg(Grid: TCustomGrid; IniFile: TRegIniFile);
  55. {$ELSE}
  56. procedure SaveFormPlacement(Form: TForm; const IniFileName: string);
  57. procedure RestoreFormPlacement(Form: TForm; const IniFileName: string);
  58. {$ENDIF WIN32}
  59.  
  60. procedure WriteFormPlacement(Form: TForm; IniFile: TIniFile;
  61.   const Section: string);
  62. procedure ReadFormPlacement(Form: TForm; IniFile: TIniFile;
  63.   const Section: string; LoadState, LoadPosition: Boolean);
  64. procedure SaveMDIChildren(MainForm: TForm; IniFile: TIniFile);
  65. procedure RestoreMDIChildren(MainForm: TForm; IniFile: TIniFile);
  66. procedure RestoreGridLayout(Grid: TCustomGrid; IniFile: TIniFile);
  67. procedure SaveGridLayout(Grid: TCustomGrid; IniFile: TIniFile);
  68.  
  69. function GetUniqueFileNameInDir(const Path, FileNameMask: string): string;
  70.  
  71. function StrToIniStr(const Str: string): string;
  72. function IniStrToStr(const Str: string): string;
  73.  
  74. function IniReadString(IniFile: TObject; const Section, Ident,
  75.   Default: string): string;
  76. procedure IniWriteString(IniFile: TObject; const Section, Ident,
  77.   Value: string);
  78. function IniReadInteger(IniFile: TObject; const Section, Ident: string;
  79.   Default: Longint): Longint;
  80. procedure IniWriteInteger(IniFile: TObject; const Section, Ident: string;
  81.   Value: Longint);
  82. function IniReadBool(IniFile: TObject; const Section, Ident: string;
  83.   Default: Boolean): Boolean;
  84. procedure IniWriteBool(IniFile: TObject; const Section, Ident: string;
  85.   Value: Boolean);
  86. procedure IniReadSections(IniFile: TObject; Strings: TStrings);
  87. procedure IniEraseSection(IniFile: TObject; const Section: string);
  88. procedure IniDeleteKey(IniFile: TObject; const Section, Ident: string);
  89.  
  90. {$IFDEF WIN32}
  91. procedure AppBroadcast(Msg, wParam: Longint; lParam: Longint);
  92. {$ELSE}
  93. procedure AppBroadcast(Msg, wParam: Word; lParam: Longint);
  94. {$ENDIF WIN32}
  95.  
  96. procedure AppTaskbarIcons(AppOnly: Boolean);
  97.  
  98. { Internal using utilities }
  99.  
  100. procedure InternalSaveGridLayout(Grid: TCustomGrid; IniFile: TObject;
  101.   const Section: string);
  102. procedure InternalRestoreGridLayout(Grid: TCustomGrid; IniFile: TObject;
  103.   const Section: string);
  104. procedure InternalSaveMDIChildren(MainForm: TForm; IniFile: TObject);
  105. procedure InternalRestoreMDIChildren(MainForm: TForm; IniFile: TObject);
  106.  
  107. implementation
  108.  
  109. uses SysUtils, Messages, Consts, rxStrUtils, FileUtil, Placemnt;
  110.  
  111. function GetDefaultSection(Component: TComponent): string;
  112. var
  113.   F: TCustomForm;
  114.   Owner: TComponent;
  115. begin
  116.   if Component <> nil then begin
  117.     if Component is TCustomForm then Result := Component.ClassName
  118.     else begin
  119.       Result := Component.Name;
  120.       if Component is TControl then begin
  121.         F := GetParentForm(TControl(Component));
  122.         if F <> nil then Result := F.ClassName + Result
  123.         else begin
  124.           if TControl(Component).Parent <> nil then
  125.             Result := TControl(Component).Parent.Name + Result;
  126.         end;
  127.       end
  128.       else begin
  129.         Owner := Component.Owner;
  130.         if Owner is TForm then
  131.           Result := Format('%s.%s', [Owner.ClassName, Result]);
  132.       end;
  133.     end;
  134.   end
  135.   else Result := '';
  136. end;
  137.  
  138. function GetDefaultIniName: string;
  139. begin
  140.   if Assigned(OnGetDefaultIniName) then
  141.     Result:= OnGetDefaultIniName
  142.   else
  143.     Result := ExtractFileName(ChangeFileExt(Application.ExeName, '.INI'));
  144. end;
  145.  
  146. {$IFDEF WIN32}
  147. function GetDefaultIniRegKey: string;
  148. begin
  149.   if RegUseAppTitle and (Application.Title <> '') then
  150.     Result := Application.Title
  151.   else Result := ExtractFileName(ChangeFileExt(Application.ExeName, ''));
  152.   if DefCompanyName <> '' then
  153.     Result := DefCompanyName + '\' + Result;
  154.   Result := 'Software\' + Result;
  155. end;
  156. {$ENDIF}
  157.  
  158. procedure GetDefaultIniData(Control: TControl; var IniFileName,
  159.   Section: string {$IFDEF WIN32}; UseRegistry: Boolean {$ENDIF});
  160. var
  161.   I: Integer;
  162. begin
  163.   IniFileName := EmptyStr;
  164.   with Control do
  165.     if Owner is TCustomForm then
  166.       for I := 0 to Owner.ComponentCount - 1 do
  167.         if (Owner.Components[I] is TFormPlacement) then begin
  168.           IniFileName := TFormPlacement(Owner.Components[I]).IniFileName;
  169.           Break;
  170.         end;
  171.   Section := GetDefaultSection(Control);
  172.   if IniFileName = EmptyStr then
  173. {$IFDEF WIN32}
  174.     if UseRegistry then IniFileName := GetDefaultIniRegKey
  175.     else
  176. {$ENDIF}
  177.     IniFileName := GetDefaultIniName;
  178. end;
  179.  
  180. function FindForm(FormClass: TFormClass): TForm;
  181. var
  182.   I: Integer;
  183. begin
  184.   Result := nil;
  185.   for I := 0 to Screen.FormCount - 1 do begin
  186.     if Screen.Forms[I] is FormClass then begin
  187.       Result := Screen.Forms[I];
  188.       Break;
  189.     end;
  190.   end;
  191. end;
  192.  
  193. function InternalFindShowForm(FormClass: TFormClass;
  194.   const Caption: string; Restore: Boolean): TForm;
  195. var
  196.   I: Integer;
  197. begin
  198.   Result := nil;
  199.   for I := 0 to Screen.FormCount - 1 do begin
  200.     if Screen.Forms[I] is FormClass then
  201.       if (Caption = '') or (Caption = Screen.Forms[I].Caption) then begin
  202.         Result := Screen.Forms[I];
  203.         Break;
  204.       end;
  205.   end;
  206.   if Result = nil then begin
  207.     Application.CreateForm(FormClass, Result);
  208.     if Caption <> '' then Result.Caption := Caption;
  209.   end;
  210.   with Result do begin
  211.     if Restore and (WindowState = wsMinimized) then WindowState := wsNormal;
  212.     Show;
  213.   end;
  214. end;
  215.  
  216. function FindShowForm(FormClass: TFormClass; const Caption: string): TForm;
  217. begin
  218.   Result := InternalFindShowForm(FormClass, Caption, True);
  219. end;
  220.  
  221. function ShowDialog(FormClass: TFormClass): Boolean;
  222. var
  223.   Dlg: TForm;
  224. begin
  225.   Application.CreateForm(FormClass, Dlg);
  226.   try
  227.     Result := Dlg.ShowModal in [mrOk, mrYes];
  228.   finally
  229.     Dlg.Free;
  230.   end;
  231. end;
  232.  
  233. function InstantiateForm(FormClass: TFormClass; var Reference): TForm;
  234. begin
  235.   if TForm(Reference) = nil then
  236.     Application.CreateForm(FormClass, Reference);
  237.   Result := TForm(Reference);
  238. end;
  239.  
  240. function StrToIniStr(const Str: string): string;
  241. var
  242. {$IFDEF WIN32}
  243.   Buffer: array[0..4095] of Char;
  244. {$ELSE}
  245.   Buffer: array[0..255] of Char;
  246. {$ENDIF}
  247.   B, S: PChar;
  248. begin
  249.   if Length(Str) > SizeOf(Buffer) then
  250.     raise Exception.Create(ResStr(SLineTooLong));
  251. {$IFDEF WIN32}
  252.   S := PChar(Str);
  253. {$ELSE}
  254.   S := StrPAlloc(Str);
  255. {$ENDIF}
  256.   try
  257.     B := Buffer;
  258.     while S^ <> #0 do
  259.       case S^ of
  260.         #13, #10:
  261.           begin
  262.             if (S^ = #13) and (S[1] = #10) then Inc(S)
  263.             else if (S^ = #10) and (S[1] = #13) then Inc(S);
  264.             B^ := '\';
  265.             Inc(B);
  266.             B^ := 'n';
  267.             Inc(B);
  268.             Inc(S);
  269.           end;
  270.       else
  271.         B^ := S^;
  272.         Inc(B);
  273.         Inc(S);
  274.       end;
  275.   finally
  276. {$IFNDEF WIN32}
  277.     StrDispose(S);
  278. {$ENDIF}
  279.   end;
  280.   B^ := #0;
  281.   Result := StrPas(Buffer);
  282. end;
  283.  
  284. function IniStrToStr(const Str: string): string;
  285. var
  286. {$IFDEF WIN32}
  287.   Buffer: array[0..4095] of Char;
  288. {$ELSE}
  289.   Buffer: array[0..255] of Char;
  290. {$ENDIF}
  291.   B, S: PChar;
  292. begin
  293.   if Length(Str) > SizeOf(Buffer) then
  294.     raise Exception.Create(ResStr(SLineTooLong));
  295. {$IFDEF WIN32}
  296.   S := PChar(Str);
  297. {$ELSE}
  298.   S := StrPAlloc(Str);
  299. {$ENDIF}
  300.   try
  301.     B := Buffer;
  302.     while S^ <> #0 do
  303.       if (S[0] = '\') and (S[1] = 'n') then
  304.       begin
  305.         B^ := #13;
  306.         Inc(B);
  307.         B^ := #10;
  308.         Inc(B);
  309.         Inc(S);
  310.         Inc(S);
  311.       end
  312.       else
  313.       begin
  314.         B^ := S^;
  315.         Inc(B);
  316.         Inc(S);
  317.       end;
  318.   finally
  319. {$IFNDEF WIN32}
  320.     StrDispose(S);
  321. {$ENDIF}
  322.   end;
  323.   B^ := #0;
  324.   Result := StrPas(Buffer);
  325. end;
  326.  
  327. const
  328. { The following strings should not be localized }
  329.   siFlags     = 'Flags';
  330.   siShowCmd   = 'ShowCmd';
  331.   siMinMaxPos = 'MinMaxPos';
  332.   siNormPos   = 'NormPos';
  333.   siPixels    = 'PixelsPerInch';
  334.   siMDIChild  = 'MDI Children';
  335.   siListCount = 'Count';
  336.   siItem      = 'Item%d';
  337.  
  338. function IniReadString(IniFile: TObject; const Section, Ident,
  339.   Default: string): string;
  340. begin
  341. {$IFDEF WIN32}
  342.   if IniFile is TRegIniFile then
  343.     Result := TRegIniFile(IniFile).ReadString(Section, Ident, Default)
  344.   else
  345. {$ENDIF}
  346.   if IniFile is TIniFile then
  347.     Result := TIniFile(IniFile).ReadString(Section, Ident, Default)
  348.   else Result := Default;
  349. end;
  350.  
  351. procedure IniWriteString(IniFile: TObject; const Section, Ident,
  352.   Value: string);
  353. var
  354.   S: string;
  355. begin
  356. {$IFDEF WIN32}
  357.   if IniFile is TRegIniFile then
  358.     TRegIniFile(IniFile).WriteString(Section, Ident, Value)
  359.   else begin
  360. {$ENDIF}
  361.     S := Value;
  362.     if S <> '' then begin
  363.       if ((S[1] = '"') and (S[Length(S)] = '"')) or
  364.         ((S[1] = '''') and (S[Length(S)] = '''')) then
  365.         S := '"' + S + '"';
  366.     end;
  367.     if IniFile is TIniFile then
  368.       TIniFile(IniFile).WriteString(Section, Ident, S);
  369. {$IFDEF WIN32}
  370.   end;
  371. {$ENDIF}
  372. end;
  373.  
  374. function IniReadInteger(IniFile: TObject; const Section, Ident: string;
  375.   Default: Longint): Longint;
  376. begin
  377. {$IFDEF WIN32}
  378.   if IniFile is TRegIniFile then
  379.     Result := TRegIniFile(IniFile).ReadInteger(Section, Ident, Default)
  380.   else
  381. {$ENDIF}
  382.   if IniFile is TIniFile then
  383.     Result := TIniFile(IniFile).ReadInteger(Section, Ident, Default)
  384.   else Result := Default;
  385. end;
  386.  
  387. procedure IniWriteInteger(IniFile: TObject; const Section, Ident: string;
  388.   Value: Longint);
  389. begin
  390. {$IFDEF WIN32}
  391.   if IniFile is TRegIniFile then
  392.     TRegIniFile(IniFile).WriteInteger(Section, Ident, Value)
  393.   else
  394. {$ENDIF}
  395.   if IniFile is TIniFile then
  396.     TIniFile(IniFile).WriteInteger(Section, Ident, Value);
  397. end;
  398.  
  399. function IniReadBool(IniFile: TObject; const Section, Ident: string;
  400.   Default: Boolean): Boolean;
  401. begin
  402. {$IFDEF WIN32}
  403.   if IniFile is TRegIniFile then
  404.     Result := TRegIniFile(IniFile).ReadBool(Section, Ident, Default)
  405.   else
  406. {$ENDIF}
  407.   if IniFile is TIniFile then
  408.     Result := TIniFile(IniFile).ReadBool(Section, Ident, Default)
  409.   else Result := Default;
  410. end;
  411.  
  412. procedure IniWriteBool(IniFile: TObject; const Section, Ident: string;
  413.   Value: Boolean);
  414. begin
  415. {$IFDEF WIN32}
  416.   if IniFile is TRegIniFile then
  417.     TRegIniFile(IniFile).WriteBool(Section, Ident, Value)
  418.   else
  419. {$ENDIF}
  420.   if IniFile is TIniFile then
  421.     TIniFile(IniFile).WriteBool(Section, Ident, Value);
  422. end;
  423.  
  424. procedure IniEraseSection(IniFile: TObject; const Section: string);
  425. begin
  426. {$IFDEF WIN32}
  427.   if IniFile is TRegIniFile then
  428.     TRegIniFile(IniFile).EraseSection(Section)
  429.   else
  430. {$ENDIF}
  431.   if IniFile is TIniFile then
  432.     TIniFile(IniFile).EraseSection(Section);
  433. end;
  434.  
  435. procedure IniDeleteKey(IniFile: TObject; const Section, Ident: string);
  436. {$IFNDEF WIN32}
  437. var
  438.   CSection: array[0..127] of Char;
  439.   CIdent: array[0..127] of Char;
  440.   CFileName: array[0..127] of Char;
  441. {$ENDIF}
  442. begin
  443. {$IFDEF WIN32}
  444.   if IniFile is TRegIniFile then
  445.     TRegIniFile(IniFile).DeleteKey(Section, Ident)
  446.   else if IniFile is TIniFile then
  447.     TIniFile(IniFile).DeleteKey(Section, Ident);
  448. {$ELSE}
  449.   if IniFile is TIniFile then begin
  450.     WritePrivateProfileString(StrPLCopy(CSection, Section, SizeOf(CSection) - 1),
  451.       StrPLCopy(CIdent, Ident, SizeOf(CIdent) - 1), nil,
  452.       StrPLCopy(CFileName, TIniFile(IniFile).FileName, SizeOf(CFileName) - 1));
  453.   end;
  454. {$ENDIF}
  455. end;
  456.  
  457. {$IFNDEF WIN32}
  458. procedure IniFileReadSections(IniFile: TIniFile; Strings: TStrings);
  459. const
  460.   BufSize = 8192;
  461. var
  462.   CFileName: array[0..127] of Char;
  463.   Buffer, P: PChar;
  464. begin
  465.   GetMem(Buffer, BufSize);
  466.   try
  467.     Strings.BeginUpdate;
  468.     try
  469.       Strings.Clear;
  470.       if GetPrivateProfileString(nil, nil, nil, Buffer, BufSize,
  471.         StrPLCopy(CFileName, IniFile.FileName, SizeOf(CFileName) - 1)) <> 0 then
  472.       begin
  473.         P := Buffer;
  474.         while P^ <> #0 do begin
  475.           Strings.Add(StrPas(P));
  476.           Inc(P, StrLen(P) + 1);
  477.         end;
  478.       end;
  479.     finally
  480.       Strings.EndUpdate;
  481.     end;
  482.   finally
  483.     FreeMem(Buffer, BufSize);
  484.   end;
  485. end;
  486. {$ENDIF}
  487.  
  488. procedure IniReadSections(IniFile: TObject; Strings: TStrings);
  489. begin
  490. {$IFDEF WIN32}
  491.   if IniFile is TIniFile then
  492.     TIniFile(IniFile).ReadSections(Strings)
  493.   else if IniFile is TRegIniFile then
  494.     TRegIniFile(IniFile).ReadSections(Strings);
  495. {$ELSE}
  496.   if IniFile is TIniFile then
  497.     IniFileReadSections(TIniFile(IniFile), Strings);
  498. {$ENDIF}
  499. end;
  500.  
  501. procedure InternalSaveMDIChildren(MainForm: TForm; IniFile: TObject);
  502. var
  503.   I: Integer;
  504. begin
  505.   if (MainForm = nil) or (MainForm.FormStyle <> fsMDIForm) then
  506.     raise EInvalidOperation.Create(ResStr(SNoMDIForm));
  507.   IniEraseSection(IniFile, siMDIChild);
  508.   if MainForm.MDIChildCount > 0 then begin
  509.     IniWriteInteger(IniFile, siMDIChild, siListCount,
  510.       MainForm.MDIChildCount);
  511.     for I := 0 to MainForm.MDIChildCount - 1 do
  512.       IniWriteString(IniFile, siMDIChild, Format(siItem, [I]),
  513.         MainForm.MDIChildren[I].ClassName);
  514.   end;
  515. end;
  516.  
  517. procedure InternalRestoreMDIChildren(MainForm: TForm; IniFile: TObject);
  518. var
  519.   I: Integer;
  520.   Count: Integer;
  521.   FormClass: TFormClass;
  522. begin
  523.   if (MainForm = nil) or (MainForm.FormStyle <> fsMDIForm) then
  524.     raise EInvalidOperation.Create(ResStr(SNoMDIForm));
  525.   StartWait;
  526.   try
  527.     Count := IniReadInteger(IniFile, siMDIChild, siListCount, 0);
  528.     if Count > 0 then begin
  529.       for I := 0 to Count - 1 do begin
  530.         FormClass := TFormClass(GetClass(IniReadString(IniFile, siMDIChild,
  531.           Format(siItem, [Count - I - 1]), '')));
  532.         if FormClass <> nil then
  533.           InternalFindShowForm(FormClass, '', False);
  534.       end;
  535.     end;
  536.   finally
  537.     StopWait;
  538.   end;
  539. end;
  540.  
  541. {$IFDEF WIN32}
  542. procedure SaveMDIChildrenReg(MainForm: TForm; IniFile: TRegIniFile);
  543. begin
  544.   InternalSaveMDIChildren(MainForm, IniFile);
  545. end;
  546.  
  547. procedure RestoreMDIChildrenReg(MainForm: TForm; IniFile: TRegIniFile);
  548. begin
  549.   InternalRestoreMDIChildren(MainForm, IniFile);
  550. end;
  551. {$ENDIF WIN32}
  552.  
  553. procedure SaveMDIChildren(MainForm: TForm; IniFile: TIniFile);
  554. begin
  555.   InternalSaveMDIChildren(MainForm, IniFile);
  556. end;
  557.  
  558. procedure RestoreMDIChildren(MainForm: TForm; IniFile: TIniFile);
  559. begin
  560.   InternalRestoreMDIChildren(MainForm, IniFile);
  561. end;
  562.  
  563. procedure InternalSaveGridLayout(Grid: TCustomGrid; IniFile: TObject;
  564.   const Section: string);
  565. var
  566.   I: Longint;
  567. begin
  568.   for I := 0 to TDrawGrid(Grid).ColCount - 1 do
  569.     IniWriteInteger(IniFile, Section, Format(siItem, [I]),
  570.       TDrawGrid(Grid).ColWidths[I]);
  571. end;
  572.  
  573. procedure InternalRestoreGridLayout(Grid: TCustomGrid; IniFile: TObject;
  574.   const Section: string);
  575. var
  576.   I: Longint;
  577. begin
  578.   for I := 0 to TDrawGrid(Grid).ColCount - 1 do
  579.     TDrawGrid(Grid).ColWidths[I] := IniReadInteger(IniFile, Section,
  580.       Format(siItem, [I]), TDrawGrid(Grid).ColWidths[I]);
  581. end;
  582.  
  583. {$IFDEF WIN32}
  584. procedure RestoreGridLayoutReg(Grid: TCustomGrid; IniFile: TRegIniFile);
  585. begin
  586.   InternalRestoreGridLayout(Grid, IniFile, GetDefaultSection(Grid));
  587. end;
  588.  
  589. procedure SaveGridLayoutReg(Grid: TCustomGrid; IniFile: TRegIniFile);
  590. begin
  591.   InternalSaveGridLayout(Grid, IniFile, GetDefaultSection(Grid));
  592. end;
  593. {$ENDIF WIN32}
  594.  
  595. procedure RestoreGridLayout(Grid: TCustomGrid; IniFile: TIniFile);
  596. begin
  597.   InternalRestoreGridLayout(Grid, IniFile, GetDefaultSection(Grid));
  598. end;
  599.  
  600. procedure SaveGridLayout(Grid: TCustomGrid; IniFile: TIniFile);
  601. begin
  602.   InternalSaveGridLayout(Grid, IniFile, GetDefaultSection(Grid));
  603. end;
  604.  
  605. function CrtResString: string;
  606. begin
  607.   Result := Format('(%dx%d)', [GetSystemMetrics(SM_CXSCREEN),
  608.     GetSystemMetrics(SM_CYSCREEN)]);
  609. end;
  610.  
  611. function ReadPosStr(IniFile: TObject; const Section, Ident: string): string;
  612. begin
  613.   Result := IniReadString(IniFile, Section, Ident + CrtResString, '');
  614.   if Result = '' then Result := IniReadString(IniFile, Section, Ident, '');
  615. end;
  616.  
  617. procedure WritePosStr(IniFile: TObject; const Section, Ident, Value: string);
  618. begin
  619.   IniWriteString(IniFile, Section, Ident + CrtResString, Value);
  620.   IniWriteString(IniFile, Section, Ident, Value);
  621. end;
  622.  
  623. procedure InternalWriteFormPlacement(Form: TForm; IniFile: TObject;
  624.   const Section: string);
  625. var
  626.   Placement: TWindowPlacement;
  627. begin
  628.   Placement.Length := SizeOf(TWindowPlacement);
  629.   GetWindowPlacement(Form.Handle, @Placement);
  630.   with Placement, TForm(Form) do begin
  631.     if (Form = Application.MainForm) and IsIconic(Application.Handle) then
  632.       ShowCmd := SW_SHOWMINIMIZED;
  633.     if (FormStyle = fsMDIChild) and (WindowState = wsMinimized) then
  634.       Flags := Flags or WPF_SETMINPOSITION;
  635.     IniWriteInteger(IniFile, Section, siFlags, Flags);
  636.     IniWriteInteger(IniFile, Section, siShowCmd, ShowCmd);
  637.     IniWriteInteger(IniFile, Section, siPixels, Screen.PixelsPerInch);
  638.     WritePosStr(IniFile, Section, siMinMaxPos, Format('%d,%d,%d,%d',
  639.       [ptMinPosition.X, ptMinPosition.Y, ptMaxPosition.X, ptMaxPosition.Y]));
  640.     WritePosStr(IniFile, Section, siNormPos, Format('%d,%d,%d,%d',
  641.       [rcNormalPosition.Left, rcNormalPosition.Top, rcNormalPosition.Right,
  642.       rcNormalPosition.Bottom]));
  643.   end;
  644. end;
  645.  
  646. {$IFDEF WIN32}
  647. procedure WriteFormPlacementReg(Form: TForm; IniFile: TRegIniFile;
  648.   const Section: string);
  649. begin
  650.   InternalWriteFormPlacement(Form, IniFile, Section);
  651. end;
  652. {$ENDIF WIN32}
  653.  
  654. procedure WriteFormPlacement(Form: TForm; IniFile: TIniFile;
  655.   const Section: string);
  656. begin
  657.   InternalWriteFormPlacement(Form, IniFile, Section);
  658. end;
  659.  
  660. {$IFDEF WIN32}
  661. procedure SaveFormPlacement(Form: TForm; const IniFileName: string;
  662.   UseRegistry: Boolean);
  663. {$ELSE}
  664. procedure SaveFormPlacement(Form: TForm; const IniFileName: string);
  665. {$ENDIF WIN32}
  666. var
  667.   IniFile: TObject;
  668. begin
  669. {$IFDEF WIN32}
  670.   if UseRegistry then IniFile := TRegIniFile.Create(IniFileName)
  671.   else IniFile := TIniFile.Create(IniFileName);
  672. {$ELSE}
  673.   IniFile := TIniFile.Create(IniFileName);
  674. {$ENDIF WIN32}
  675.   try
  676.     InternalWriteFormPlacement(Form, IniFile, Form.ClassName);
  677.   finally
  678.     IniFile.Free;
  679.   end;
  680. end;
  681.  
  682. {$IFDEF WIN32}
  683.   {$HINTS OFF}
  684. {$ENDIF}
  685.  
  686. type
  687.  
  688. {*******************************************************}
  689. { !! ATTENTION Nasty implementation                     }
  690. {*******************************************************}
  691. {                                                       }
  692. { This class definition was copied from FORMS.PAS.      }
  693. { It is needed to access some private fields of TForm.  }
  694. {                                                       }
  695. { Any changes in the underlying classes may cause       }
  696. { errors in this implementation!                        }
  697. {                                                       }
  698. {*******************************************************}
  699.  
  700.   TNastyForm = class(TScrollingWinControl)
  701.   private
  702.     FActiveControl: TWinControl;
  703.     FFocusedControl: TWinControl;
  704.     FBorderIcons: TBorderIcons;
  705.     FBorderStyle: TFormBorderStyle;
  706. {$IFDEF RX_D4}
  707.     FSizeChanging: Boolean;
  708. {$ENDIF}
  709.     FWindowState: TWindowState; { !! }
  710.   end;
  711.  
  712.   THackComponent = class(TComponent);
  713. {$IFDEF WIN32}
  714.   {$HINTS ON}
  715. {$ENDIF}
  716.  
  717. procedure InternalReadFormPlacement(Form: TForm; IniFile: TObject;
  718.   const Section: string; LoadState, LoadPosition: Boolean);
  719. const
  720.   Delims = [',',' '];
  721. var
  722.   PosStr: string;
  723.   Placement: TWindowPlacement;
  724.   WinState: TWindowState;
  725.   DataFound: Boolean;
  726. begin
  727.   if not (LoadState or LoadPosition) then Exit;
  728.   Placement.Length := SizeOf(TWindowPlacement);
  729.   GetWindowPlacement(Form.Handle, @Placement);
  730.   with Placement, TForm(Form) do begin
  731.     if not IsWindowVisible(Form.Handle) then
  732.       ShowCmd := SW_HIDE;
  733.     if LoadPosition then begin
  734.       DataFound := False;
  735.       Flags := IniReadInteger(IniFile, Section, siFlags, Flags);
  736.       PosStr := ReadPosStr(IniFile, Section, siMinMaxPos);
  737.       if PosStr <> '' then begin
  738.         DataFound := True;
  739.         ptMinPosition.X := StrToIntDef(ExtractWord(1, PosStr, Delims), 0);
  740.         ptMinPosition.Y := StrToIntDef(ExtractWord(2, PosStr, Delims), 0);
  741.         ptMaxPosition.X := StrToIntDef(ExtractWord(3, PosStr, Delims), 0);
  742.         ptMaxPosition.Y := StrToIntDef(ExtractWord(4, PosStr, Delims), 0);
  743.       end;
  744.       PosStr := ReadPosStr(IniFile, Section, siNormPos);
  745.       if PosStr <> '' then begin
  746.         DataFound := True;
  747.         rcNormalPosition.Left := StrToIntDef(ExtractWord(1, PosStr, Delims), Left);
  748.         rcNormalPosition.Top := StrToIntDef(ExtractWord(2, PosStr, Delims), Top);
  749.         rcNormalPosition.Right := StrToIntDef(ExtractWord(3, PosStr, Delims), Left + Width);
  750.         rcNormalPosition.Bottom := StrToIntDef(ExtractWord(4, PosStr, Delims), Top + Height);
  751.       end;
  752.       if Screen.PixelsPerInch <> IniReadInteger(IniFile, Section, siPixels,
  753.         Screen.PixelsPerInch) then DataFound := False;
  754.       if DataFound then begin
  755.         if not (BorderStyle in [bsSizeable {$IFDEF WIN32}, bsSizeToolWin {$ENDIF}]) then
  756.           rcNormalPosition := Rect(rcNormalPosition.Left, rcNormalPosition.Top,
  757.             rcNormalPosition.Left + Width, rcNormalPosition.Top + Height);
  758.         if rcNormalPosition.Right > rcNormalPosition.Left then begin
  759.           if (Position in [poScreenCenter {$IFDEF RX_D4}, poDesktopCenter {$ENDIF}]) and
  760.             not (csDesigning in ComponentState) then
  761.           begin
  762.             THackComponent(Form).SetDesigning(True);
  763.             try
  764.               Position := poDesigned;
  765.             finally
  766.               THackComponent(Form).SetDesigning(False);
  767.             end;
  768.           end;
  769.           SetWindowPlacement(Handle, @Placement);
  770.         end;
  771.       end;
  772.     end;
  773.     if LoadState then begin
  774.       WinState := wsNormal;
  775.       { default maximize MDI main form }
  776.       if ((Application.MainForm = Form) {$IFDEF RX_D4} or
  777.         (Application.MainForm = nil) {$ENDIF}) and ((FormStyle = fsMDIForm) or
  778.         ((FormStyle = fsNormal) and (Position = poDefault))) then
  779.         WinState := wsMaximized;
  780.       ShowCmd := IniReadInteger(IniFile, Section, siShowCmd, SW_HIDE);
  781.       case ShowCmd of
  782.         SW_SHOWNORMAL, SW_RESTORE, SW_SHOW:
  783.           WinState := wsNormal;
  784.         SW_MINIMIZE, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE:
  785.           WinState := wsMinimized;
  786.         SW_MAXIMIZE: WinState := wsMaximized;
  787.       end;
  788. {$IFDEF WIN32}
  789.       if (WinState = wsMinimized) and ((Form = Application.MainForm)
  790.         {$IFDEF RX_D4} or (Application.MainForm = nil) {$ENDIF}) then
  791.       begin
  792.         TNastyForm(Form).FWindowState := wsNormal;
  793.         PostMessage(Application.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
  794.         Exit;
  795.       end;
  796. {$ENDIF}
  797.       if FormStyle in [fsMDIChild, fsMDIForm] then
  798.         TNastyForm(Form).FWindowState := WinState
  799.       else WindowState := WinState;
  800.     end;
  801.     Update;
  802.   end;
  803. end;
  804.  
  805. {$IFDEF WIN32}
  806. procedure ReadFormPlacementReg(Form: TForm; IniFile: TRegIniFile;
  807.   const Section: string; LoadState, LoadPosition: Boolean);
  808. begin
  809.   InternalReadFormPlacement(Form, IniFile, Section, LoadState, LoadPosition);
  810. end;
  811. {$ENDIF WIN32}
  812.  
  813. procedure ReadFormPlacement(Form: TForm; IniFile: TIniFile;
  814.   const Section: string; LoadState, LoadPosition: Boolean);
  815. begin
  816.   InternalReadFormPlacement(Form, IniFile, Section, LoadState, LoadPosition);
  817. end;
  818.  
  819. {$IFDEF WIN32}
  820. procedure RestoreFormPlacement(Form: TForm; const IniFileName: string;
  821.   UseRegistry: Boolean);
  822. {$ELSE}
  823. procedure RestoreFormPlacement(Form: TForm; const IniFileName: string);
  824. {$ENDIF}
  825. var
  826.   IniFile: TObject;
  827. begin
  828. {$IFDEF WIN32}
  829.   if UseRegistry then begin
  830.     IniFile := TRegIniFile.Create(IniFileName);
  831.   {$IFDEF RX_D5} 
  832.     TRegIniFile(IniFile).Access := KEY_READ;
  833.   {$ENDIF}
  834.   end
  835.   else 
  836.     IniFile := TIniFile.Create(IniFileName);
  837. {$ELSE}
  838.   IniFile := TIniFile.Create(IniFileName);
  839. {$ENDIF WIN32}
  840.   try
  841.     InternalReadFormPlacement(Form, IniFile, Form.ClassName, True, True);
  842.   finally
  843.     IniFile.Free;
  844.   end;
  845. end;
  846.  
  847. function GetUniqueFileNameInDir(const Path, FileNameMask: string): string;
  848. var
  849.   CurrentName: string;
  850.   I: Integer;
  851. begin
  852.   Result := '';
  853.   for I := 0 to MaxInt do begin
  854.     CurrentName := Format(FileNameMask, [I]);
  855.     if not FileExists(NormalDir(Path) + CurrentName) then begin
  856.       Result := CurrentName;
  857.       Exit;
  858.     end;
  859.   end;
  860. end;
  861.  
  862. {$IFDEF WIN32}
  863. procedure AppBroadcast(Msg, wParam: Longint; lParam: Longint);
  864. {$ELSE}
  865. procedure AppBroadcast(Msg, wParam: Word; lParam: Longint);
  866. {$ENDIF WIN32}
  867. var
  868.   I: Integer;
  869. begin
  870.   for I := 0 to Screen.FormCount - 1 do
  871.     SendMessage(Screen.Forms[I].Handle, Msg, wParam, lParam);
  872. end;
  873.  
  874. procedure AppTaskbarIcons(AppOnly: Boolean);
  875. var
  876.   Style: Longint;
  877. begin
  878.   Style := GetWindowLong(Application.Handle, GWL_STYLE);
  879.   if AppOnly then Style := Style or WS_CAPTION
  880.   else Style := Style and not WS_CAPTION;
  881.   SetWindowLong(Application.Handle, GWL_STYLE, Style);
  882.   if AppOnly then SwitchToWindow(Application.Handle, False);
  883. end;
  884.  
  885. end.