Автоматическое сохранение и восстановление свойств формы
Очередная маленькая хитрость будет посвящена автоматическому сохранению и восстановлению свойств формы, таких как размер, позиция, состояние. Конечно, существует целый ряд пакетов компонент, у которых есть аналогичные функции, но мне, к примеру, не интересно ставить целый пакет только из-за нескольких функций. К тому же, часто за эти пакеты надо платить деньги. В общем, напишем свой компонент.
Создание пустого компонента и пакета
Для начала сделаем "пустышку" для нашего компонента. Для этого вызываем File -> New -> Other:, в диалоге которого выбираем пиктограмму "Component". В появившемся окне заполняем свойства так, как показано на первом рисунке (пути указывайте удобные вам) и нажимаем кнопку "OK".
Теперь, сохраняйте файл компонента и закрывайте его.
Во-вторых, нам потребуется создать пустой пакет, где мы отныне будем размещать компоненты из "Маленьких хитростей". Делается это с помощью пункта меню, в диалоге которого теперь надо выбрать пиктограмму "Package". В окне редактора пакетов (ниже на рисунке) нажмите кнопку "Add" и добавьте недавно созданный файл компонента.
Для проверки нажмите кнопку "Compile", сохраните пакет и возвращайтесь к редактированию компонента, заново открыв его.
Немного проектирования
Следующим номером нашей обширнейшей программы будет вот что: мы определимся с тем, что, как и когда надо сохранять и восстанавливать.
Зная логику работы Delphi-программ, можно уверенно сказать, что сохранять значения следует в обработчике OnDestroy, а восстанавливать в обработчике OnCreate. При этом следует помнить, что во время редактирования формы в IDE ни сохранять, ни восстанавливать ничего не надо.
Оперировать мы будем следующими параметрами: физический размер формы, позиция формы и ее состояние. В этом нам помогут свойства компонента TForm, носящие имена Left, Top, Width, Height и WindowState.
Все параметры мы будем сохранять в ветке HKEY_CURRENT_USER системного реестра. Следовательно, потребуется настроечное свойство, отвечающее за имя ветви, куда сохраняются данные.
Реализация
Напомню, что хитрости маленькие, поэтому не ожидайте чего-то выдающегося. Все очень просто. В процедуре сохранения следует проверить корректность имени ключа реестра, куда будут записаны данные (я сделал минимальную) и, если все хорошо, записать данные. Реализовать это можно вот так:
procedure TgrFormPropSaver.SaveSettings; var reg: TRegistry; frm: TForm; begin if (RegPath = '') then exit; try reg := TRegistry.Create; with reg do begin RootKey := HKEY_CURRENT_USER; OpenKey(RegPath,true); frm := TForm(Owner); if (frm.WindowState = wsNormal) then begin WriteInteger('Left',frm.Left); WriteInteger('Width',frm.Width); WriteInteger('Top',frm.Top); WriteInteger('Height',frm.Height); end; case frm.WindowState of wsNormal: WriteInteger('State',1); wsMinimized: WriteInteger('State',2); wsMaximized: WriteInteger('State',3); end; end; finally FreeAndNil(reg); end; end;Здесь следует пояснить, что, во время состояний формы "максимизирована" и "минимизирована" значения свойств размера и позиции формы могут быть искажены, поэтому я отключил их запись в этих состояниях.
Процедура восстановления также проста, как и сохранения, поэтому я не буду про нее рассказывать.
Вызывать эти процедуры стоит из методов OnCreate и OnDestroy формы, на которой лежит компонент.
Полный текст модуля grFormPropSaver.pas
unit grFormPropSaver; //**! ---------------------------------------------------------- //**! This unit is a part of Gregor.RU pack project (Gregor.RU //**! Delphi Components Package). //**! ---------------------------------------------------------- //**! You may use or redistribute this unit for your purposes //**! while unit's code and this copyright notice is unchanged //**! and exists. //**! ---------------------------------------------------------- //**! URL: http://www.gregor.ru/ //**! Mail: [email protected] //**! ---------------------------------------------------------- //**! (c) Gregor.RU, 2002. All rights reserved. //**! ---------------------------------------------------------- {***} interface {***} uses Classes; type TgrFormPropSaver = class(TComponent) private { Private declarations } FRegPath: string; protected { Protected declarations } public { Public declarations } procedure SaveSettings; procedure LoadSettings; published { Published declarations } property RegPath: string read FRegPath write FRegPath; end; procedure Register; {***} implementation {***} uses Windows, Forms, SysUtils, Registry; procedure Register; begin RegisterComponents('Gregor.RU', [TgrFormPropSaver]); end; { TgrFormPropSaver } procedure TgrFormPropSaver.LoadSettings; var reg: TRegistry; frm: TForm; begin if (csDesigning in ComponentState) or (RegPath = '') then exit; try reg := TRegistry.Create; with reg do begin RootKey := HKEY_CURRENT_USER; OpenKey(RegPath,true); frm := TForm(Owner); frm.Position := poDesigned; case ReadInteger('State') of 1: frm.WindowState := wsNormal; 2: frm.WindowState := wsMinimized; 3: frm.WindowState := wsMaximized; end; frm.Width := ReadInteger('Width'); frm.Height := ReadInteger('Height'); frm.Top := ReadInteger('Top'); frm.Left := ReadInteger('Left'); end; finally FreeAndNil(reg); end; end; procedure TgrFormPropSaver.SaveSettings; var reg: TRegistry; frm: TForm; begin if (csDesigning in ComponentState) or (RegPath = '') then exit; try reg := TRegistry.Create; with reg do begin RootKey := HKEY_CURRENT_USER; OpenKey(RegPath,true); frm := TForm(Owner); if (frm.WindowState = wsNormal) then begin WriteInteger('Left',frm.Left); WriteInteger('Width',frm.Width); WriteInteger('Top',frm.Top); WriteInteger('Height',frm.Height); end; case frm.WindowState of wsNormal: WriteInteger('State',1); wsMinimized: WriteInteger('State',2); wsMaximized: WriteInteger('State',3); end; end; finally FreeAndNil(reg); end; end; end.Также замечу, что я не ставил перед собой задачи сделать абсолютно устойчивый и правильный модуль, а хотел показать способ, полнейшая реализация которого его в рамки "маленьких хитростей" не вписывается. Вот и всё, Удачи!