ОПИСАНИЕ: Вы наверное замечали, что профессионально написанные программы "запоминают" состояние и позицию окон с момента их последнего показа? А большинство RAD-приложений это игнорируют? Вы можете исправить эту ошибку, взяв на вооружение этот модуль. Он позволяет сохранять позицию, размер и состояние окна, поэтому пользователь, открыв его вновь, увидит его в том же состоянии, в котором он видел его в последний раз.
ИСПОЛЬЗОВАНИЕ: Поместите WINRSTOR в список используемых модулей главной или любой другой формы, состояние, размер и позицию которой вы хотите сохранить. (Если вы сэкономить время и для восстановления дочерних форм использовать WinSaveChildren и WinRestoreChildren из главной формы, вы должны объявить этот модуль только в главной форме.)
В MainForm.Create, инициализируйте глобальный объект WinRestorer следующим образом (он должен предварительно быть объявлен, но еще не инициализирован):
GlobalWinRestorer := TWinRestorer.create( Application, TRUE, WHATSAVE_ALL); |
Или так:
|
GlobalWinRestorer := TWinRestorer.create( Application, TRUE, [location, size, state]); |
Затем в MainForm.Destroy вы должны разрушить глобальный объект WinRestorer следующим образом:
GlobalWinRestorer.free; |
Хорошее место для сохранения статуса формы - в обработчике события queryclose или в специально созданной кнопке или пункте меню. Я обычно создаю этот пункт в меню "Файл" с именем '&Сохранение рабочей области' и обрабатываю следующим образом:
GlobalWinRestorer.SaveChildren(Self, [default]); |
И при закрытии основной формы необходимо сделать следующее:
GlobalWinRestorer.SaveWin(Self, [WHATSAVE_ALL]); |
Восстановить состояние дочерних форм можно следующим образом:
GlobalWinRestorer.RestoreWin(Self, [default]); |
Я же переместил данный код в обработчик события show моей главной формы:
GlobalWinRestorer.RestoreWin(Self, [default]);GlobalWinRestorer.RestoreChildren(Self, [default]); |
unit WinRstor; INTERFACE USES SysUtils, Forms; TYPE {=============================================================} {------------------------------------------------------------------ Восстановитель окон классовых объектов и связанных типов. -------------------------------------------------------------------} EWinRestorer = class( Exception); TWhatSave = (default, size, location, state); STWhatSave = set of TWhatSave; TWinRestorer = class(TObject) protectedmIniFile: string;mIniSect: string[80];mIsInitialized: boolean;mDefaultWhat: STWhatSave;publicconstructor Create( TheApp: TApplication; LocalDir: boolean; DefaultWhatSave: STWhatSave);{Если localDir = true, каталог ini = каталогу приложения. Else, ini dir is the windows dir.}procedure SaveWin(TheForm: TForm; What: STWhatSave);procedure SaveChildren(TheMDIForm: TForm; What: STWhatSave);procedure RestoreWin( TheForm: TForm; What: STWhatSave);procedure RestoreChildren(TheMDIForm: TForm; What: STWhatSave);property IniFileName: string read mIniFile;end; CONST WHATSAVE_ALL = [size, location, state]; VAR GlobalWinRestorer: TWinRestorer; IMPLEMENTATION Uses IniFiles; constructor TWinRestorer.create; var fname, path: string[100]; begin inherited create; {Получаем имя ini-файла} if default in DefaultWhatSave thenraise EWinRestorer.create('Попытка инициализации параметров с позицией окна по умолчанию ' +' с установленным элементом [default]. ' +'Параметры по умолчанию могут содержать только установленные элементы - [size, location, state]. ')else mDefaultWhat := DefaultWhatSave; fname := ChangeFileExt( ExtractFileName( TheApp.exeName), '.INI');if LocalDir then begin {вычисляем путь и добавляем к нему имя файла}path := ExtractFilePath(TheApp.exeName);if path[length(path)] <> '\' thenpath := path + '\';fname := path + fname;end;{заполняем поля объекта} mIniFile := fname;mIniSect := 'WindowsRestorer';{Для культуры напишем некоторое примечание в секцию с именем [WinRestorer Notes]} end; procedure TWinRestorer.RestoreWin; var FormNm, SectionNm: string[80]; ini: TIniFile; n,l,t,w,h: integer; {Left, Top Width, Height}begin ini := TIniFile.create( mIniFile);TRYSectionNm := mIniSect;FormNm := TheForm.classname;if default in What then What := mDefaultWhat;{При необходимости обновляем состояние окна} if state in What thenn := ini.ReadInteger( SectionNm, FormNm + '_WindowState', 0);case n of1: TheForm.WindowState := wsMinimized;2: TheForm.WindowState := wsNormal;3: TheForm.WindowState := wsMaximized;end;{При необходимости обновляем размеры и позицию.} with TheForm do begin l:=left; t:=top; h:=height; w:=width; end; {Сохраняем текущие значения.}if size in What then beginw := ini.ReadInteger( SectionNm, FormNm + '_Width', w);h := ini.ReadInteger( SectionNm, FormNm + '_Height', h);end;if location in What then begint := ini.ReadInteger( SectionNm, FormNm + '_Top', t);l := ini.ReadInteger( SectionNm, FormNm + '_Left', l);end;TheForm.SetBounds(l,t,w,h);FINALLYini.free;END;end; procedure TWinRestorer.RestoreChildren; var i: integer; begin if TheMDIForm.formstyle <> fsMDIForm thenraise EWinRestorer.create('Попытка сохранения размеров дочернего окна для не-MDI окна родителя.')elsefor i := 0 to TheMDIForm.MDIChildCount - 1 doRestoreWin( TheMDIForm.MDIChildren[i], what);end; procedure TWinRestorer.SaveWin; var FormNm, SectionNm: string[80]; w : STWhatsave; ini: TIniFile; begin ini := TIniFile.create( mIniFile);TRYSectionNm := mIniSect;FormNm := TheForm.ClassName;if default in What then w := mDefaultWhat else w := mDefaultWhat;if size in w then beginini.WriteInteger( SectionNm, FormNm + '_Width', TheForm.Width);ini.WriteInteger( SectionNm, FormNm + '_Height', TheForm.Height);end;if location in w then beginini.WriteInteger( SectionNm, FormNm + '_Top', TheForm.Top);ini.WriteInteger( SectionNm, FormNm + '_Left', TheForm.Left);end;if state in w thencase TheForm.WindowState ofwsMinimized: ini.WriteInteger( SectionNm, FormNm + '_WindowState', 1);wsNormal: ini.WriteInteger( SectionNm, FormNm + '_WindowState', 2);wsMaximized: ini.WriteInteger( SectionNm, FormNm + '_WindowState', 3);end;FINALLYini.free;END;end; procedure TWinRestorer.SaveChildren; var i: integer; begin if TheMDIForm.formstyle <> fsMDIForm thenraise EWinRestorer.create('Попытка восстановления размеров дочернего окна для не-MDI окна родителя.')elsefor i := 0 to TheMDIForm.MDIChildCount - 1 doSaveWin( TheMDIForm.MDIChildren[i], what);end; INITIALIZATION END. |