При разработке приложений на Delphi часто возникает необходимость сохранять и восстанавливать положение и размер главного окна приложения. Это позволяет пользователю открывать приложение в том же месте и с тем же размером, каким он его оставил ранее. В этой статье мы рассмотрим различные подходы к решению этой задачи, включая использование встроенных возможностей Delphi и сторонних компонентов.
Введение
Для сохранения и восстановления положения и размера главного окна приложения необходимо выполнить следующие шаги: 1. Сохранить позицию, размер и состояние окна при его закрытии. 2. Восстановить позицию, размер и состояние окна при его открытии.
Встроенные возможности Delphi
Delphi предоставляет встроенные возможности для работы с настройками приложения, которые можно использовать для сохранения и восстановления положения и размера окна. Мы рассмотрим два основных подхода: использование INI-файлов и использование компонента TJvFormStorage из библиотеки Jedi VCL Component Library.
Использование INI-файлов
INI-файлы являются простым и распространенным способом хранения настроек приложения. Мы можем использовать класс TIniFile для чтения и записи значений в INI-файл.
uses
IniFiles, Forms;
procedure TFormMain.FormCreate(Sender: TObject);
var
Ini: TIniFile;
begin
Ini := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
try
Left := Ini.ReadInteger('Form', 'Left', Left);
Top := Ini.ReadInteger('Form', 'Top', Top);
Width := Ini.ReadInteger('Form', 'Width', Width);
Height := Ini.ReadInteger('Form', 'Height', Height);
WindowState := TWindowState(Ini.ReadInteger('Form', 'WindowState', Ord(WindowState)));
finally
Ini.Free;
end;
end;
procedure TFormMain.FormDestroy(Sender: TObject);
var
Ini: TIniFile;
begin
Ini := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
try
Ini.WriteInteger('Form', 'Left', Left);
Ini.WriteInteger('Form', 'Top', Top);
Ini.WriteInteger('Form', 'Width', Width);
Ini.WriteInteger('Form', 'Height', Height);
Ini.WriteInteger('Form', 'WindowState', Ord(WindowState));
finally
Ini.Free;
end;
end;
Этот код сохраняет позицию, размер и состояние окна в INI-файл при закрытии приложения и восстанавливает их при открытии.
Использование TJvFormStorage
Компонент TJvFormStorage из Jedi VCL Component Library предоставляет более удобный и гибкий способ сохранения и восстановления настроек формы. Он автоматически обрабатывает сохранение и восстановление позиции, размера и состояния окна, а также других свойств компонентов на форме.
Добавьте компонент TJvFormStorage на форму.
Настройте компонент, указав, какие свойства нужно сохранять.
procedure TFormMain.FormCreate(Sender: TObject);
begin
JvFormStorage1.RestoreForm;
end;
procedure TFormMain.FormDestroy(Sender: TObject);
begin
JvFormStorage1.SaveForm;
end;
Этот код автоматически сохраняет и восстанавливает настройки формы при закрытии и открытии приложения.
Решение проблемы с восстановлением положения окна после максимизации
В вашем исходном коде возникает проблема с восстановлением положения окна после его максимизации. Это связано с тем, что при максимизации окна его позиция и размер не сохраняются, так как они определяются монитором.
Чтобы решить эту проблему, можно использовать код, предложенный Anders Melander:
uses
Math;
procedure TFormMain.ApplyWindowState(const Bounds: TRect; State: TWindowState);
var
Monitor: TMonitor;
WorkareaRect: TRect;
NewTop, NewLeft, NewWidth, NewHeight: integer;
begin
ASSERT(Position = poDesigned);
// Find the monitor containing the top/left corner.
// If the point is outside available monitors then the nearest monitor is used.
Monitor := Screen.MonitorFromPoint(Bounds.TopLeft);
WorkareaRect := Monitor.WorkareaRect;
NewHeight := Min(Bounds.Bottom - Bounds.Top, WorkareaRect.Bottom - WorkareaRect.Top);
NewWidth := Min(Bounds.Right - Bounds.Left, WorkareaRect.Right - WorkareaRect.Left);
if (PtInRect(WorkareaRect, Bounds.TopLeft)) then
begin
NewTop := Bounds.Top;
NewLeft := Bounds.Left;
end else
begin
// Center on monitor if top/left is outside screen (e.g. if a monitor has been
// removed)
NewTop := WorkareaRect.Top + ((WorkareaRect.Bottom - WorkareaRect.Top) - NewHeight) div 2;
NewLeft := WorkareaRect.Left + ((WorkareaRect.Right - WorkareaRect.Left) - NewWidth) div 2;
end;
SetBounds(NewLeft, NewTop, NewWidth, NewHeight);
if (State in [wsNormal, wsMaximized]) then
WindowState := State;
end;
procedure TFormMain.FormCreate(Sender: TObject);
begin
ApplyWindowState(Rect(100, 100, 400, 400), wsMaximized);
end;
Этот код учитывает монитор, на котором находится окно, и корректно восстанавливает его позицию и размер после максимизации.
Альтернативное решение с использованием DefaultMonitor
Предложенный PeterBelow альтернативный подход заключается в установке свойства DefaultMonitor формы в dmDesktop. Это позволяет сохранять позицию и размер окна независимо от монитора, на котором оно находится.
procedure TFormMain.FormCreate(Sender: TObject);
begin
DefaultMonitor := dmDesktop;
// Загрузка позиции, размера и состояния окна
end;
procedure TFormMain.FormDestroy(Sender: TObject);
begin
// Сохранение позиции, размера и состояния окна
end;
Этот подход также решает проблему с восстановлением положения окна после максимизации.
Заключение
Сохранение и восстановление положения и размера главного окна Delphi приложения можно реализовать с помощью встроенных возможностей Delphi или сторонних компонентов. Вариант с использованием INI-файлов прост и понятен, а использование TJvFormStorage предоставляет более гибкие возможности. В случае возникновения проблем с восстановлением положения окна после максимизации можно использовать код, предложенный Anders Melander, или установить свойство DefaultMonitor формы в dmDesktop.
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.