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

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: Desdechado

WEB-сайт: http://delphibase.endimus.com

{ **** UBPFD *********** by delphibase.endimus.com ****

>> Сохранение и восстановление положения и размеров окон

Процедуры SaveWndPos и SetWndPos работают в паре.

Сохраняют для конкретного пользователя Windows в реестре местоположение,

размер окон (и прочих Control’ов при явном указании),

а также ширины и порядок расположения колонок в DBGrid’ах на форме.

Не дает «потерять» колонки совсем.

Возможные проблемы:

1. С записью в реестр без прав (в некую левую ветку).

2. При изменении имен и количества полей в DBGrid’е.

3. С окнами неизменяемого размера, если его в Design-time поменяли.

Комментарии:

1. Статус колонки DBGrid (visible, readonly) не сохраняется, но сделать

это несложно.

2. Для формы, которая используются для разных целей, но хотелось бы

сохранить ее характеристики для каждой цели отдельно, можно явно

указывать УНИКАЛЬНЫЙ класс.

Важное уточнение:

Сохранение параметров DBGrid происходит ТОЛЬКО при статически

описанных колонках в самом гриде.

Еще комментарий:

параметр lSetSize в SetWndPos применяется только к размерам формы, а

не к ширине колонок. Но можно и это учесть.

Зависимости: Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, Registry, Math, DB, DbTables, dbGrids

Автор: Александр Хабаров aka Desdechado, x_a_u@mail.ru, Феодосия

Copyright: Александр Хабаров

Дата: 13 мая 2002 г.

***************************************************** }

const

cRegKey = ‘\Software\CoolSoft\Настройки\’;

procedure SaveWndPos(frm: TControl; cClass: string = »);

var

rct: TRect;

oReg: TRegistry;

grid: TDBGrid;

i, j: Integer;

begin

{— определить параметры —}

rct := frm.BoundsRect;

if (cClass = ») then

cClass := frm.ClassName;

{— сохранить в реестре —}

oReg := TRegistry.Create();

with (oReg) do

try

RootKey := HKEY_CURRENT_USER;

{— … размер окна —}

if (OpenKey(cRegKey cClass, True)) then

begin

if (frm is TForm) then

WriteInteger(‘Show’, Ord((frm as TForm).WindowState));

if (not (frm is TForm) or

((frm as TForm).WindowState = wsNormal)) then

begin

WriteInteger(‘Left’, rct.Left);

WriteInteger(‘Top’, rct.Top);

WriteInteger(‘Right’, rct.Right);

WriteInteger(‘Bottom’, rct.Bottom);

end;

end;

CloseKey();

{— … размеры и положение колонок в Grid’ах —}

for i := 0 to frm.ComponentCount — 1 do

if (frm.Components[i].ClassName = D

if (frm.Components[i].ClassName = ‘TDBGrid’) then

begin

grid := TDBGrid(frm.Components[i]);

for j := 0 to grid.Columns.Count — 1 do

begin

if (OpenKey(cRegKey cClass ‘\’ grid.Name ‘\’

IntToStr(j), True)) then

begin

WriteString(‘Name’, grid.Columns[j].FieldName);

WriteInteger(‘Width’, grid.Columns[j].Width);

end;

CloseKey();

end; // for( j )

end;

finally

CloseKey();

Free;

end;

end;

procedure SetWndPos(frm: TControl; lSetSize: Boolean = True;

cClass: string = »);

var

rct: TRect;

oReg: TRegistry;

nShow, i, j, k: Integer;

grid: TDBGrid;

cName: string;

begin

nShow := Ord(wsNormal);

{— текущие параметры (на случай, если нет в реестре) —}

rct := frm.BoundsRect;

if (cClass = ») then

cClass := frm.ClassName;

if (frm is TForm) then

nShow := Ord((frm as TForm).WindowState);

{— считать из реестра —}

oReg := TRegistry.Create();

with (oReg) do

try

RootKey := HKEY_CURRENT_USER;

{— … размер окна —}

if (OpenKeyReadOnly(cRegKey cClass)) then

begin

if (frm is TForm) then

nShow := ReadInteger(‘Show’);

if (ValueExists(‘Left’)) then

rct.Left := ReadInteger(‘Left’);

if (ValueExists(‘Top’)) then

rct.Top := ReadInteger(‘Top’);

if (ValueExists(‘Right’)) then

rct.Right := ReadInteger(‘Right’);

if (ValueExists(‘Bottom’)) then

rct.Bottom := ReadInteger(‘Bottom’);

end;

CloseKey();

{— … размеры и положение колонок в Grid’ах —}

for i := 0 to frm.ComponentCount — 1 do

if (frm.Components[i].ClassName = ‘TDBGrid’) then

begin

grid := TDBGrid(frm.Components[i]);

for j := 0 to grid.Columns.Count — 1 do

begin

if (OpenKeyReadOnly(cRegKey cClass ‘\’ grid.Name ‘\’

IntToStr(j))) then

begin

cName := ReadString(‘Name’);

for k := 0 to grid.Columns.Count — 1 do

if (grid.Columns[k].FieldName = cName) then

begin

grid.Columns[k].Index := j;

break;

end;

grid.Columns[j].Width := ReadInteger(‘Width’);

end;

CloseKey();

{— экстремальные ширины — нормировать —}

grid.Columns[j].Width := Max(grid.Columns[j].Width, 3);

grid.Columns[j].Width := Min(grid.Columns[j].Width,

grid.ClientWidth — 3);

end; // for( j )

end;

finally

CloseKey();

Free;

end;

{— применить считанное к окну —}

if (lSetSize) then

frm.BoundsRect := rct

else

begin

frm.Top := rct.Top;

frm.Left := rct.Left;

end;

if ((frm is TForm) and (nShow = Ord(wsMaximized))) then

(frm as TForm).WindowState := wsMaximized;

end;

procedure FitDeskTop(frm: TControl);

var

rct: TRect;

begin

rct := frm.BoundsRect;

if (rct.Top < 0) then

rct.Top := 0

else if (rct.Bottom >= Screen.DeskTopHeight) then

rct.Top := rct.Top Screen.DeskTopHeight — rct.Bottom — 1;

if (rct.Left < 0) then

rct.Left := 0

else if (rct.Right >= Screen.DeskTopWidth) then

rct.Left := rct.Left Screen.DeskTopWidth — rct.Right — 1;

rct.Bottom := rct.Top frm.Height;

rct.Right := rct.Left frm.Width;

frm.BoundsRect := rct;

end;

Пример использования:

{

0. не забудьте поменять константу для СВОЕЙ ветки в реестре

1. после создания окна перед Show

2. перед frm.Release (удалением) надо вызывать SaveWndPos

}

procedure TfrmCard.FormCreate(Sender: TObject);

begin

// прочий код здесь

SetWndPos(Self);

end;

procedure TfrmCard.FormClose(Sender: TObject; var Action: TCloseAction);

begin

// прочий код здесь

SaveWndPos(Self);

Action := caFree;

end;

{/codecitation}

Добавить комментарий