source: trunk/Packages/Common/UPersistentForm.pas

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