source: tags/1.0.0/Packages/Common/UPersistentForm.pas

Last change on this file was 7, checked in by chronos, 5 years ago
  • Added: Remember window dimensions after application restart.
File size: 10.3 KB
Line 
1unit UPersistentForm;
2
3{$mode delphi}
4
5// Date: 2015-04-18
6
7interface
8
9uses
10 Classes, SysUtils, Forms, URegistry, LCLIntf, Registry, Controls, ComCtrls,
11 ExtCtrls;
12
13type
14
15 { TPersistentForm }
16
17 TPersistentForm = class(TComponent)
18 private
19 FEntireVisible: Boolean;
20 FMinVisiblePart: Integer;
21 FRegistryContext: TRegistryContext;
22 procedure LoadControl(Control: TControl);
23 procedure SaveControl(Control: TControl);
24 public
25 FormNormalSize: TRect;
26 FormRestoredSize: TRect;
27 FormWindowState: TWindowState;
28 Form: TForm;
29 procedure LoadFromRegistry(RegistryContext: TRegistryContext);
30 procedure SaveToRegistry(RegistryContext: TRegistryContext);
31 function CheckEntireVisible(Rect: TRect): TRect;
32 function CheckPartVisible(Rect: TRect; Part: Integer): TRect;
33 procedure Load(Form: TForm; DefaultMaximized: Boolean = False);
34 procedure Save(Form: TForm);
35 constructor Create(AOwner: TComponent); override;
36 property RegistryContext: TRegistryContext read FRegistryContext
37 write FRegistryContext;
38 published
39 property MinVisiblePart: Integer read FMinVisiblePart write FMinVisiblePart;
40 property EntireVisible: Boolean read FEntireVisible write FEntireVisible;
41 end;
42
43procedure Register;
44
45implementation
46
47
48procedure Register;
49begin
50 RegisterComponents('Common', [TPersistentForm]);
51end;
52
53{ TPersistentForm }
54
55procedure TPersistentForm.LoadControl(Control: TControl);
56var
57 I: Integer;
58 WinControl: TWinControl;
59begin
60 if Control is TListView then begin
61 with Form, TRegistryEx.Create do
62 try
63 RootKey := RegistryContext.RootKey;
64 OpenKey(RegistryContext.Key + '\Forms\' + Form.Name + '\' + Control.Name, True);
65 for I := 0 to TListView(Control).Columns.Count - 1 do begin
66 if ValueExists('ColWidth' + IntToStr(I)) then
67 TListView(Control).Columns[I].Width := ReadInteger('ColWidth' + IntToStr(I));
68 end;
69 finally
70 Free;
71 end;
72 end;
73
74 if (Control is TPanel) then begin
75 with Form, TRegistryEx.Create do
76 try
77 RootKey := RegistryContext.RootKey;
78 OpenKey(RegistryContext.Key + '\Forms\' + Form.Name + '\' + Control.Name, True);
79 if (TPanel(Control).Align = alRight) or (TPanel(Control).Align = alLeft) then begin
80 if ValueExists('Width') then
81 TPanel(Control).Width := ReadInteger('Width');
82 end;
83 if (TPanel(Control).Align = alTop) or (TPanel(Control).Align = alBottom) then begin
84 if ValueExists('Height') then
85 TPanel(Control).Height := ReadInteger('Height');
86 end;
87 finally
88 Free;
89 end;
90 end;
91
92 if Control is TWinControl then begin
93 WinControl := TWinControl(Control);
94 if WinControl.ControlCount > 0 then begin
95 for I := 0 to WinControl.ControlCount - 1 do begin
96 if WinControl.Controls[I] is TControl then begin
97 LoadControl(WinControl.Controls[I]);
98 end;
99 end;
100 end;
101 end;
102end;
103
104procedure TPersistentForm.SaveControl(Control: TControl);
105var
106 I: Integer;
107 WinControl: TWinControl;
108begin
109 if Control is TListView then begin
110 with Form, TRegistryEx.Create do
111 try
112 RootKey := RegistryContext.RootKey;
113 OpenKey(RegistryContext.Key + '\Forms\' + Form.Name + '\' + Control.Name, True);
114 for I := 0 to TListView(Control).Columns.Count - 1 do begin
115 WriteInteger('ColWidth' + IntToStr(I), TListView(Control).Columns[I].Width);
116 end;
117 finally
118 Free;
119 end;
120 end;
121
122 if (Control is TPanel) then begin
123 with Form, TRegistryEx.Create do
124 try
125 RootKey := RegistryContext.RootKey;
126 OpenKey(RegistryContext.Key + '\Forms\' + Form.Name + '\' + Control.Name, True);
127 if (TPanel(Control).Align = alRight) or (TPanel(Control).Align = alLeft) then begin
128 WriteInteger('Width', TPanel(Control).Width);
129 end;
130 if (TPanel(Control).Align = alTop) or (TPanel(Control).Align = alBottom) then begin
131 WriteInteger('Height', TPanel(Control).Height);
132 end;
133 finally
134 Free;
135 end;
136 end;
137
138 if Control is TWinControl then begin
139 WinControl := TWinControl(Control);
140 if WinControl.ControlCount > 0 then begin
141 for I := 0 to WinControl.ControlCount - 1 do begin
142 if WinControl.Controls[I] is TControl then begin
143 SaveControl(WinControl.Controls[I]);
144 end;
145 end;
146 end;
147 end;
148end;
149
150procedure TPersistentForm.LoadFromRegistry(RegistryContext: TRegistryContext);
151begin
152 with TRegistryEx.Create do
153 try
154 RootKey := RegistryContext.RootKey;
155 OpenKey(RegistryContext.Key + '\Forms\' + Form.Name, True);
156 // Normal size
157 FormNormalSize.Left := ReadIntegerWithDefault('NormalLeft', FormNormalSize.Left);
158 FormNormalSize.Top := ReadIntegerWithDefault('NormalTop', FormNormalSize.Top);
159 FormNormalSize.Right := ReadIntegerWithDefault('NormalWidth', FormNormalSize.Right - FormNormalSize.Left)
160 + FormNormalSize.Left;
161 FormNormalSize.Bottom := ReadIntegerWithDefault('NormalHeight', FormNormalSize.Bottom - FormNormalSize.Top)
162 + FormNormalSize.Top;
163 // Restored size
164 FormRestoredSize.Left := ReadIntegerWithDefault('RestoredLeft', FormRestoredSize.Left);
165 FormRestoredSize.Top := ReadIntegerWithDefault('RestoredTop', FormRestoredSize.Top);
166 FormRestoredSize.Right := ReadIntegerWithDefault('RestoredWidth', FormRestoredSize.Right - FormRestoredSize.Left)
167 + FormRestoredSize.Left;
168 FormRestoredSize.Bottom := ReadIntegerWithDefault('RestoredHeight', FormRestoredSize.Bottom - FormRestoredSize.Top)
169 + FormRestoredSize.Top;
170 // Other state
171 FormWindowState := TWindowState(ReadIntegerWithDefault('WindowState', Integer(wsNormal)));
172 finally
173 Free;
174 end;
175end;
176
177procedure TPersistentForm.SaveToRegistry(RegistryContext: TRegistryContext);
178begin
179 with Form, TRegistryEx.Create do
180 try
181 RootKey := RegistryContext.RootKey;
182 OpenKey(RegistryContext.Key + '\Forms\' + Form.Name, True);
183 // Normal state
184 WriteInteger('NormalWidth', FormNormalSize.Right - FormNormalSize.Left);
185 WriteInteger('NormalHeight', FormNormalSize.Bottom - FormNormalSize.Top);
186 WriteInteger('NormalTop', FormNormalSize.Top);
187 WriteInteger('NormalLeft', FormNormalSize.Left);
188 // Restored state
189 WriteInteger('RestoredWidth', FormRestoredSize.Right - FormRestoredSize.Left);
190 WriteInteger('RestoredHeight', FormRestoredSize.Bottom - FormRestoredSize.Top);
191 WriteInteger('RestoredTop', FormRestoredSize.Top);
192 WriteInteger('RestoredLeft', FormRestoredSize.Left);
193 // Other state
194 WriteInteger('WindowState', Integer(FormWindowState));
195 finally
196 Free;
197 end;
198end;
199
200function TPersistentForm.CheckEntireVisible(Rect: TRect): TRect;
201var
202 Width: Integer;
203 Height: Integer;
204begin
205 Result := Rect;
206 Width := Rect.Right - Rect.Left;
207 Height := Rect.Bottom - Rect.Top;
208 if Result.Left < (Screen.DesktopLeft) then begin
209 Result.Left := Screen.DesktopLeft;
210 Result.Right := Screen.DesktopLeft + Width;
211 end;
212 if Result.Right > (Screen.DesktopLeft + Screen.DesktopWidth) then begin
213 Result.Left := Screen.DesktopLeft + Screen.DesktopWidth - Width;
214 Result.Right := Screen.DesktopLeft + Screen.DesktopWidth;
215 end;
216 if Result.Top < Screen.DesktopTop then begin
217 Result.Top := Screen.DesktopTop;
218 Result.Bottom := Screen.DesktopTop + Height;
219 end;
220 if Result.Bottom > (Screen.DesktopTop + Screen.DesktopHeight) then begin
221 Result.Top := Screen.DesktopTop + Screen.DesktopHeight - Height;
222 Result.Bottom := Screen.DesktopTop + Screen.DesktopHeight;
223 end;
224end;
225
226function TPersistentForm.CheckPartVisible(Rect: TRect; Part: Integer): TRect;
227var
228 Width: Integer;
229 Height: Integer;
230begin
231 Result := Rect;
232 Width := Rect.Right - Rect.Left;
233 Height := Rect.Bottom - Rect.Top;
234 if Result.Right < (Screen.DesktopLeft + Part) then begin
235 Result.Left := Screen.DesktopLeft + Part - Width;
236 Result.Right := Screen.DesktopLeft + Part;
237 end;
238 if Result.Left > (Screen.DesktopLeft + Screen.DesktopWidth - Part) then begin
239 Result.Left := Screen.DesktopLeft + Screen.DesktopWidth - Part;
240 Result.Right := Screen.DesktopLeft + Screen.DesktopWidth - Part + Width;
241 end;
242 if Result.Bottom < (Screen.DesktopTop + Part) then begin
243 Result.Top := Screen.DesktopTop + Part - Height;
244 Result.Bottom := Screen.DesktopTop + Part;
245 end;
246 if Result.Top > (Screen.DesktopTop + Screen.DesktopHeight - Part) then begin
247 Result.Top := Screen.DesktopTop + Screen.DesktopHeight - Part;
248 Result.Bottom := Screen.DesktopTop + Screen.DesktopHeight - Part + Height;
249 end;
250end;
251
252procedure TPersistentForm.Load(Form: TForm; DefaultMaximized: Boolean = False);
253begin
254 Self.Form := Form;
255 // Set default
256 FormNormalSize := Bounds((Screen.Width - Form.Width) div 2,
257 (Screen.Height - Form.Height) div 2, Form.Width, Form.Height);
258 FormRestoredSize := Bounds((Screen.Width - Form.Width) div 2,
259 (Screen.Height - Form.Height) div 2, Form.Width, Form.Height);
260
261 LoadFromRegistry(RegistryContext);
262
263 if not EqualRect(FormNormalSize, FormRestoredSize) or
264 DefaultMaximized then begin
265 // Restore to maximized state
266 Form.WindowState := wsNormal;
267 if not EqualRect(FormRestoredSize, Form.BoundsRect) then
268 Form.BoundsRect := FormRestoredSize;
269 Form.WindowState := wsMaximized;
270 end else begin
271 // Restore to normal state
272 Form.WindowState := wsNormal;
273 if FEntireVisible then FormNormalSize := CheckEntireVisible(FormNormalSize)
274 else if FMinVisiblePart > 0 then
275 FormNormalSize := CheckPartVisible(FormNormalSize, FMinVisiblePart);
276 if not EqualRect(FormNormalSize, Form.BoundsRect) then
277 Form.BoundsRect := FormNormalSize;
278 end;
279 LoadControl(Form);
280end;
281
282procedure TPersistentForm.Save(Form: TForm);
283begin
284 Self.Form := Form;
285 FormNormalSize := Bounds(Form.Left, Form.Top, Form.Width, Form.Height);
286 FormRestoredSize := Bounds(Form.RestoredLeft, Form.RestoredTop, Form.RestoredWidth,
287 Form.RestoredHeight);
288 FormWindowState := Form.WindowState;
289 SaveToRegistry(RegistryContext);
290 SaveControl(Form);
291end;
292
293constructor TPersistentForm.Create(AOwner: TComponent);
294begin
295 inherited;
296 if AOwner is TForm then Form := TForm(AOwner)
297 else Form := nil;
298 FMinVisiblePart := 50;
299 FRegistryContext.RootKey := HKEY_CURRENT_USER;
300end;
301
302end.
303
Note: See TracBrowser for help on using the repository browser.