-
Notifications
You must be signed in to change notification settings - Fork 0
/
uGlobalSettingsBinderComp.pas
236 lines (212 loc) · 6.63 KB
/
uGlobalSettingsBinderComp.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
unit uGlobalSettingsBinderComp;
interface
uses
SysUtils, Classes, Windows, Messages, StdCtrls, ExtCtrls, Spin,
AcedContainers,
uGlobalVars,
uGlobalSettings,
uSettingsBaseItem,
uSettingsAStringsList,
uSettingsUStringsList,
uSettingsAStrList,
uSettingsUStrList,
uSettingsBoolList,
uSettingsIntList;
type
TGlobSettingsChangeEvent = procedure(ASender: TObject;
AItem: TSettingsBaseItem; AComp: TComponent; AId: Integer) of object;
type
TGlobalSettingsBinderComp = class(TComponent)
private
FSettings: TGlobalSettingsBase;
FCompById: TIntegerAssociationList;
FIdByComp: TIntegerAssociationList;
FWinHandle: HWND;
FOnGlobSettingsChange: TGlobSettingsChangeEvent;
FOnCompSettingsChange: TNotifyEvent;
FLocked: Boolean;
//---
procedure SetGlobalSettings(ASettings: TGlobalSettingsBase);
procedure CompSettingsChanged(ASender: TObject);
procedure WndProc(var AMsg: TMessage);
procedure UpdateSettingsA(ID: Integer);
procedure UpdateSettingsB(AItem: TSettingsBaseItem);
procedure UpdateSettingsC(AItem: TSettingsBaseItem; AId: Integer);
procedure UpdateSettingsD(A: TSettingsBaseItem; B: TComponent; AId: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
//---
procedure Add(const AComp: TComponent; const AId: Integer); overload;
procedure Add(const AComp: TComponent;
const AItem: TSettingsBaseItem); overload;
//---
property GlobalSettings: TGlobalSettingsBase read FSettings write SetGlobalSettings;
published
property OnGlobSettingsChange: TGlobSettingsChangeEvent
read FOnGlobSettingsChange write FOnGlobSettingsChange;
property OnCompSettingsChange: TNotifyEvent
read FOnCompSettingsChange write FOnCompSettingsChange;
property Locked: Boolean read FLocked write FLocked;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TGlobalSettingsBinderComp]);
end;
{ TGlobalSettingsBinder }
constructor TGlobalSettingsBinderComp.Create(AOwner: TComponent);
begin
inherited;
FSettings := nil;
FCompById := TIntegerAssociationList.Create;
FIdByComp := TIntegerAssociationList.Create;
FWinHandle := Classes.AllocateHWnd(WndProc);
//---
FOnGlobSettingsChange := nil;
FOnCompSettingsChange := nil;
//---
FLocked := True;
end;
destructor TGlobalSettingsBinderComp.Destroy;
begin
Classes.DeallocateHWnd(FWinHandle);
FreeAndNil(FCompById);
FreeAndNil(FIdByComp);
inherited;
end;
procedure TGlobalSettingsBinderComp.SetGlobalSettings(
ASettings: TGlobalSettingsBase);
begin
if Assigned(FSettings) then
begin
FSettings.NotifyHandle := 0;
FSettings := nil;
end;
FSettings := ASettings;
FSettings.NotifyHandle := FWinHandle;
end;
procedure TGlobalSettingsBinderComp.UpdateSettingsA(ID: Integer);
begin
UpdateSettingsC(FSettings.Search(ID), ID)
end;
procedure TGlobalSettingsBinderComp.UpdateSettingsB(AItem: TSettingsBaseItem);
begin
UpdateSettingsC(AItem, AItem.ID)
end;
procedure TGlobalSettingsBinderComp.UpdateSettingsC(AItem: TSettingsBaseItem;
AId: Integer);
begin
UpdateSettingsD(AItem, TComponent(FCompById.Items[AID]), AID)
end;
procedure TGlobalSettingsBinderComp.UpdateSettingsD(A: TSettingsBaseItem;
B: TComponent; AId: Integer);
begin
if FLocked then
Exit;
//---
FLocked := True;
FSettings.DontNotify := True;
try
if (A<>nil) and (B<>nil) then
begin
if (B is TCustomEdit) and (A is TSettingsAStrItem) then
TCustomEdit(B).Text := TSettingsAStrItem(A).Value
else
if (B is TCheckBox) and (A is TSettingsBoolItem) then
TCheckBox(B).Checked := TSettingsBoolItem(A).Value
else
if (B is TComboBox) and (A is TSettingsIntItem) then
TComboBox(B).ItemIndex := TSettingsIntItem(A).Value
else
if (B is TSpinEdit) and (A is TSettingsIntItem) then
TSpinEdit(B).Value := TSettingsIntItem(A).Value
end;
//---
if Assigned(FOnGlobSettingsChange) then
FOnGlobSettingsChange(FSettings, A, B, AId);
//---
finally
FLocked := False;
FSettings.DontNotify := False;
end;
end;
procedure TGlobalSettingsBinderComp.WndProc(var AMsg: TMessage);
var
Handled: Boolean;
begin
Handled := True;
if (AMsg.Msg=WM_USER) and not FLocked then
begin
if AMsg.WParam=WM_UPDATE_SETTINGS then
UpdateSettingsA(AMsg.LParam)
else if AMsg.WParam=WM_UPDATE_SETTINGSA then
UpdateSettingsB(TSettingsBaseItem(AMsg.LParam));
Handled := False;
end;
//---
if Handled then
AMsg.Result := 0
else
AMsg.Result := DefWindowProc(FWinHandle, AMsg.Msg, AMsg.WParam, AMsg.LParam);
end;
procedure TGlobalSettingsBinderComp.Add(const AComp: TComponent;
const AId: Integer);
begin
if AComp is TEdit then
TEdit(AComp).OnChange := CompSettingsChanged
else if AComp is TLabeledEdit then
TLabeledEdit(AComp).OnChange := CompSettingsChanged
else if AComp is TCheckBox then
TCheckBox(AComp).OnClick := CompSettingsChanged
else if AComp is TComboBox then
TComboBox(AComp).OnChange := CompSettingsChanged
else if AComp is TSpinEdit then
TSpinEdit(AComp).OnChange := CompSettingsChanged
;
if AId>0 then
begin
FCompById.Add(AID, AComp);
FIdByComp.Add(Integer(AComp), Pointer(AID));
end;
end;
procedure TGlobalSettingsBinderComp.Add(const AComp: TComponent;
const AItem: TSettingsBaseItem);
begin
Add(AComp, AItem.ID)
end;
procedure TGlobalSettingsBinderComp.CompSettingsChanged(ASender: TObject);
var A: TSettingsBaseItem;
begin
if FLocked then
Exit;
//---
FLocked := True;
FSettings.DontNotify := True;
try
A := FSettings.Search(Integer(FIdByComp.Items[Integer(ASender)]));
if A<>nil then
begin
if (ASender is TCustomEdit) and (A is TSettingsAStrItem) then
TSettingsAStrItem(A).Value := TCustomEdit(ASender).Text
else
if (ASender is TCheckBox) and (A is TSettingsBoolItem) then
TSettingsBoolItem(A).Value := TCheckBox(ASender).Checked
else
if (ASender is TComboBox) and (A is TSettingsIntItem) then
TSettingsIntItem(A).Value := TComboBox(ASender).ItemIndex
else
if (ASender is TSpinEdit) and (A is TSettingsIntItem) then
TSettingsIntItem(A).Value := TSpinEdit(ASender).Value
end;
//---
if Assigned(FOnCompSettingsChange) then
FOnCompSettingsChange(ASender);
//---
finally
FLocked := False;
FSettings.DontNotify := False;
end
end;
end.