скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Сохранение размеров, позиции и состояния окна



Приведу код WindowRestorer - восстановителя размера и состояния окна.

ОПИСАНИЕ: Вы наверное замечали, что профессионально написанные программы "запоминают" состояние и позицию окон с момента их последнего показа? А большинство 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]);

Подсказки: Если вы установили TForm.Position в poScreenCenter или что-то подобное, данный модуль вам не поможет. poDesigned кажется, работает как положено. Можно добавить обработку исключения, если вы пытаетесь установить верхнюю или левую позицию при значении формы poScreenCentere, но при этом вы должны быть осторожными при использовании WinRestoreChildren. Я не проверял это со значениями координат (позиции) и оставил это на усмотрение разработчиков.


unit WinRstor;

interface

uses SysUtils, Forms;

type
  {=============================================================}

  {------------------------------------------------------------------
  Восстановитель окон классовых объектов и связанных типов.
  -------------------------------------------------------------------}
  EWinRestorer = class(Exception);
  TWhatSave = (default, size, location, state);
  STWhatSave = set of TWhatSave;
  TWinRestorer = class(TObject)

  protected
    mIniFile: string;
    mIniSect: string[80];
    mIsInitialized: boolean;
    mDefaultWhat: STWhatSave;
  public
    constructor 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 then
    raise 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)] <> '\' then
      path := 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);
  try
    SectionNm := mIniSect;
    FormNm := TheForm.classname;
    if default in What then
      What := mDefaultWhat;
    {При необходимости обновляем состояние окна}

    if state in What then
      n := ini.ReadInteger(SectionNm, FormNm + '_WindowState', 0);
    case n of
      1: 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
    begin
      w := ini.ReadInteger(SectionNm, FormNm + '_Width', w);
      h := ini.ReadInteger(SectionNm, FormNm + '_Height', h);
    end;
    if location in What then
    begin
      t := ini.ReadInteger(SectionNm, FormNm + '_Top', t);
      l := ini.ReadInteger(SectionNm, FormNm + '_Left', l);
    end;
    TheForm.SetBounds(l, t, w, h);
  finally
    ini.free;
  end;
end;

procedure TWinRestorer.RestoreChildren;
var
  i: integer;
begin

  if TheMDIForm.formstyle <> fsMDIForm then
    raise
      EWinRestorer.create('Попытка сохранения размеров дочернего
        окна для не-MDI окна родителя.')
  else
    for i := 0 to TheMDIForm.MDIChildCount - 1 do
      RestoreWin(TheMDIForm.MDIChildren[i], what);
end;

procedure TWinRestorer.SaveWin;
var
  FormNm, SectionNm: string[80];
  w: STWhatsave;
  ini: TIniFile;

begin

  ini := TIniFile.create(mIniFile);
  try
    SectionNm := mIniSect;
    FormNm := TheForm.ClassName;
    if default in What then
      w := mDefaultWhat
    else
      w := mDefaultWhat;
    if size in w then
    begin
      ini.WriteInteger(SectionNm, FormNm + '_Width', TheForm.Width);
      ini.WriteInteger(SectionNm, FormNm + '_Height', TheForm.Height);
    end;
    if location in w then
    begin
      ini.WriteInteger(SectionNm, FormNm + '_Top', TheForm.Top);
      ini.WriteInteger(SectionNm, FormNm + '_Left', TheForm.Left);
    end;
    if state in w then
      case TheForm.WindowState of
        wsMinimized: ini.WriteInteger(SectionNm, FormNm + '_WindowState', 1);
        wsNormal: ini.WriteInteger(SectionNm, FormNm + '_WindowState', 2);
        wsMaximized: ini.WriteInteger(SectionNm, FormNm + '_WindowState', 3);
      end;
  finally
    ini.free;
  end;
end;

procedure TWinRestorer.SaveChildren;
var
  i: integer;
begin

  if TheMDIForm.formstyle <> fsMDIForm then
    raise
      EWinRestorer.create('Попытка восстановления размеров дочернего
        окна для не-MDI окна родителя.')
  else
    for i := 0 to TheMDIForm.MDIChildCount - 1 do
      SaveWin(TheMDIForm.MDIChildren[i], what);
end;

initialization
end.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook