Автоматическое сохранение и восстановление свойств формы

Очередная маленькая хитрость будет посвящена автоматическому сохранению и восстановлению свойств формы, таких как размер, позиция, состояние. Конечно, существует целый ряд пакетов компонент, у которых есть аналогичные функции, но мне, к примеру, не интересно ставить целый пакет только из-за нескольких функций. К тому же, часто за эти пакеты надо платить деньги. В общем, напишем свой компонент.

Создание пустого компонента и пакета
Для начала сделаем "пустышку" для нашего компонента. Для этого вызываем 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.

Также замечу, что я не ставил перед собой задачи сделать абсолютно устойчивый и правильный модуль, а хотел показать способ, полнейшая реализация которого его в рамки "маленьких хитростей" не вписывается.

Вот и всё, Удачи!


    No results found.
Отменить.