-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSRPanel.pas
487 lines (431 loc) · 13.5 KB
/
SRPanel.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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
unit SRPanel;
{*******************************************************}
{ SPanel }
{ Copyright (C) 2013 HKSS }
{*******************************************************
Unit: SPanel.pas
Purpose: Search Panel VCL Component
Author: kranga
Date: 3/31/2013 2:55:19 PM
Version: 1.0
Tips: if .Exec(sender =nil) then SPanel position is owner(form) center
if Setup() _WH=point(0,0) then Default with(600) & height(400) applies
Sample:
SPanel1.Setup([80,0],'select emp_code as [CODE], emp_name as [NAME] from emp_master where emp_code like :emp_Code or emp_name like :emp_name',Point(300,300),F_Com_Data.Ado_connection_client);
if SPanel1.Exec(Sender)<>mrok exit; //if sender =nil then SPanel position is owner(form) center
l_val:=SPanel1.qy.FieldByName('name').AsString;
sample 2 [DuplicateSearch;]
on enter event:
SPanel1.P_SetupDuplicateSearch(ed_supGName,Point(ed_supGName.Width,200),'SuperGroup','Super_Group_Name',l_con);
on change event:
SPanel1.P_ShowDuplicateSearch;
on exit event:
SPanel1.P_CloseDuplicateSearch;
*******************************************************}
interface
uses ComCtrls, DB, ADODB, Classes, Controls, ExtCtrls, StdCtrls, Dialogs, DBGrids, Windows, Forms, Buttons, Math, Messages;
//{$ObjExportAll On}
type
TSPType = (SPTSearchPanel, SPTDuplicate);
TSPanel = class(TCustomPanel)
public
qy: TADOQuery;
L_Result: integer;
function Exec(Sender: TObject = nil): integer;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
// procedure Setup(ColWArr: array of integer; SqlTxt: string; _Topleft: TPoint; _WH: TPoint; Con: TADOConnection = nil; def_val: string = ''); overload;
procedure Setup(ColWArr: array of integer; SqlTxt: string; _WH: TPoint; Con: TADOConnection = nil; def_val: string = '');
procedure P_Setup(SqlTxt: string; _Topleft: TPoint; _WH: TPoint; Con: TADOConnection = nil; def_val: string = ''; SPType: TSPType = SPTSearchPanel; obj: TWinControl = nil);
procedure P_SetColumnWidth(arg: array of integer; BestFit: boolean = True);//arg="100,20,0,..,0,100" //0 will be ignored // -1 will hide coloumn
procedure P_SetupDuplicateSearch(obj: TWinControl; _WH: TPoint; tbl_name, Fld_name: string; con: TADOConnection);
procedure P_ShowDuplicateSearch();
procedure P_CloseDuplicateSearch();
private
l_focused: boolean;
l_exit: boolean;
l_SPType: TSPType;
l_editBox: TWinControl;
ds: TDataSource;
bt_exit: TSpeedButton;
ed_search: TEdit;
dbgrid: TDBGrid;
function P_SQLGen(tbl_name, fld_name, Fld_caption: string): string;
procedure SPExit(Sender: TObject);
procedure P_KeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
procedure ed_searchChange(Sender: TObject);
procedure bt_okClick(Sender: TObject);
procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY;
procedure WMClose(var Message: TWMClose); message WM_CLOSE;
procedure FocusIn(Sender: TObject);
protected
procedure WndProc(var Msg: TMessage); override;
end;
var
L_SQLRecLimit: integer = 100;
procedure Register;
{---------------------------------------------------------------------------}
implementation
uses Consts, SysUtils;
procedure TSPanel.WndProc(var Msg: TMessage);
begin
inherited;
case Msg.Msg of
WM_DESTROY, WM_CLOSE, WM_KILLFOCUS: l_exit := True;
WM_SETFOCUS: l_focused := True;
end;
end;
procedure TSPanel.FocusIn(Sender: TObject);
begin
l_focused := True;
end;
constructor TSPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Self.Caption := '';
Self.Visible := False;
Self.OnExit := SPExit;
bt_exit := TSpeedButton.Create(Self);
Parent := TWinControl(AOwner);
with bt_exit do
begin
SetBounds(Self.Width - 18, 0, 18, 21);
Caption := 'X';
Font.Color := $00FA8A8A;
Flat := True;
Layout := blGlyphRight;
ParentFont := False;
Font.Name := 'Arial Black';
OnClick := SPExit;
Parent := Self;
Anchors := [akTop, akRight];
end;
ed_search := TEdit.Create(Self);
with ed_search do
begin
SetBounds(0, 0, Self.Width - 19, 21);
Anchors := [akLeft, akTop, akRight];
BevelInner := bvNone;
BevelKind := bkFlat;
BorderStyle := bsNone;
CharCase := ecUpperCase;
TabOrder := 0;
OnChange := ed_searchChange;
OnKeyUp := P_KeyUp;
Parent := Self;
Font.Name := 'Arial';
Font.Size := 12;
end;
qy := TADOQuery.Create(Self);
with qy do
begin
LockType := ltReadOnly;
end;
ds := TDataSource.Create(Self);
with ds do
begin
AutoEdit := False;
DataSet := qY;
end;
dbgrid := TDBGrid.Create(Self);
with dbgrid do
begin
SetBounds(1, 22, Self.Width - 2, Self.Height - 24);
Parent := Self;
DataSource := ds;
BorderStyle := bsNone;
Options := [dgTitles, dgColumnResize, dgColLines, dgRowLines, dgRowSelect, dgConfirmDelete, dgCancelOnExit];
ReadOnly := True;
FixedColor := $00FAFAFA;
Anchors := [akLeft, akTop, akRight, akBottom];
OnKeyUp := P_KeyUp;
OnDblClick := bt_okClick;
OnEnter := FocusIn;
end;
end;
destructor TSPanel.Destroy;
begin
L_result := mrAbort;
qy.Close;
FreeAndNil(qy);
FreeAndNil(dbgrid);
inherited Destroy;
end;
procedure TSPanel.WMClose(var Message: TWMClose);
begin
if L_result = 0 then
L_result := mrCancel;
end;
procedure TSPanel.WMDestroy(var Message: TWMDestroy);
begin
if L_result = 0 then
L_result := mrCancel;
end;
procedure TSPanel.SPExit(Sender: TObject);
begin
if L_result = 0 then
L_result := mrCancel;
end;
function TSPanel.Exec(Sender: TObject = nil): integer;
begin
Result := mrCancel;
if Sender is TControl then
begin
Self.Top := TControl(Sender).ClientOrigin.y - TControl(Owner).ClientOrigin.y;
Self.Left := TControl(Sender).ClientOrigin.X - TControl(Owner).ClientOrigin.X;
end
else
begin
Self.Top := ((TWinControl(Owner).Height - self.Height) div 2) - 20;
Self.Left := (TWinControl(Owner).Width - self.Width) div 2;
end;
if (qy.Connection = nil) or (qy.SQL.Text = '') then
begin
MessageDlg('Not configured.' + #13#10 + 'Call "Setup" method before calling "Exec" method', mtError, [mbOK], 0);
end;
L_result := 0;
AnimateWindow(self.Handle, 200, AW_VER_POSITIVE or AW_SLIDE or AW_ACTIVATE);
Self.Show;
Application.ProcessMessages;
ed_search.SelectAll;
ed_search.SetFocus;
repeat
begin
Application.HandleMessage;
if TForm(Owner).Visible = False then
L_result := mrAbort;
end
until (L_result <> 0);
if L_result = mrAbort then
Exit;
AnimateWindow(self.Handle, 150, AW_VER_NEGATIVE or AW_SLIDE or AW_HIDE);
Self.Hide;
Application.ProcessMessages;
Result := L_result;
if TForm(Owner).ActiveControl <> nil then
TForm(Owner).ActiveControl.SetFocus
else if Sender is TWinControl then
TWinControl(Sender).SetFocus;
end;
procedure TSPanel.P_KeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
begin
if key = vK_Down then
begin
if qy.RecordCount > 0 then
dbgrid.SetFocus;
end
else
if (key = vK_up) then
begin
if (qy.RecNo = 1) then
ed_search.SetFocus;
end else
if (key = VK_ESCAPE) then
begin
SPExit(nil);
end
else if (key = VK_RETURN) then
bt_okClick(nil);
end;
procedure TSPanel.bt_okClick(Sender: TObject);
begin
l_result := mrOk;
if qy.RecordCount < 1 then
begin
l_result := mrCancel;
end;
end;
procedure TSPanel.ed_searchChange(Sender: TObject);
var
i: integer;
begin
Application.ProcessMessages;
with qY do
begin
Close;
for i := 0 to (Parameters.Count - 1) do
Parameters[i].Value := '%' + tedit(l_editBox).Text + '%';
Open;
end;
end;
//procedure TSPanel.Setup(ColWArr: array of integer; SqlTxt: string; _Topleft: TPoint; _WH: TPoint; Con: TADOConnection = nil; def_val: string = '');
//begin
// P_Setup(SqlTxt, _Topleft, _WH, Con, def_val);
// if High(ColWArr) > 0 then
// P_SetColumnWidth(ColWArr);
//end;
procedure TSPanel.Setup(ColWArr: array of integer; SqlTxt: string; _WH: TPoint; Con: TADOConnection = nil; def_val: string = '');
begin
P_Setup(SqlTxt, POINT(0, 0), _WH, Con, def_val);
if High(ColWArr) > 0 then
P_SetColumnWidth(ColWArr);
end;
procedure TSPanel.P_Setup(SqlTxt: string; _Topleft: TPoint; _WH: TPoint; Con: TADOConnection = nil; def_val: string = ''; SPType: TSPType = SPTSearchPanel; obj: TWinControl = nil);
var
i: integer;
begin
qy.Close;
l_SPType := SPType;
if not (con = nil) and (con <> qy.Connection) then
qy.Connection := con;
if (SPType = SPTDuplicate) then
_Topleft := Point(obj.ClientOrigin.X - TControl(Owner).ClientOrigin.X, obj.ClientOrigin.y - TControl(Owner).ClientOrigin.y + obj.Height);
if (_WH.X = 0) and (_WH.Y = 0) then
_WH := point(600, 400);
Self.BoundsRect := Bounds(_Topleft.X - 1, _Topleft.Y - 1, _WH.X - 4, _WH.Y);
if SqlTxt = '' then
exit;
SqlTxt := UpperCase(SqlTxt);
SqlTxt := StringReplace(SqlTxt, '{TOP}', 'TOP ' + IntToStr(100), [rfIgnoreCase]);
if POS(' TOP ', SqlTxt) < 1 then
SqlTxt := StringReplace(SqlTxt, 'SELECT', 'SELECT TOP ' + IntToStr(L_SQLRecLimit), [rfIgnoreCase]);
qy.SQL.Text := SqlTxt;
for i := 0 to (qy.Parameters.Count - 1) do
qy.Parameters[i].Value := '%' + trim(def_val) + '%';
try
ed_search.Text := def_val;
qy.Open;
except
end;
ed_search.Visible := not (SPType = SPTDuplicate);
bt_exit.Visible := not (SPType = SPTDuplicate);
if (SPType = SPTDuplicate) then
begin
dbgrid.SetBounds(1, 1, Self.Width - 2, Self.Height - 2);
dbgrid.Options := [dgRowLines, dgTabs];
l_editBox := obj;
end
else
begin
dbgrid.SetBounds(1, 22, Self.Width - 2, Self.Height - 24);
dbgrid.Options := [dgTitles, dgIndicator, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit];
l_editBox := ed_search;
end;
end;
procedure TSPanel.P_SetColumnWidth(arg: array of integer; BestFit: boolean = True);//arg="100,20,0,..,0,100" //0 will be ignored // -1 will hide coloumn
var
i, _dta, _sum, _vW: integer; // call this after p_setup and befor showmodel
_dtW: real;
begin
_dta := 0;
_vW := 0;
_sum := 0;
for i := 0 to High(arg) do
begin
if arg[i] = 0 then
Inc(_dta)
else if arg[i] > 0 then
_sum := _sum + arg[i];
end;
_dta := _dta + (dbgrid.Columns.Count - (i));
_dtW := (Self.Width - 22) / _sum;
if _dta > 0 then // variable width field exist
_vW := ((Self.Width - 22) - _sum) div _dta;
for i := 0 to High(arg) do
if (arg[i] > 0) and (_dta = 0) then
arg[i] := Round(arg[i] * _dtw)
else if (arg[i] = 0) then
arg[i] := _vW;
for i := 0 to High(arg) do
begin
if arg[i] < 0 then
dbgrid.Columns[i].Visible := False
else
dbgrid.Columns[i].Width := arg[i];
end;
if i < (dbgrid.Columns.Count) then
while i <> (dbgrid.Columns.Count - 1) do
dbgrid.Columns[i].Width := _vW;
//----------------------------------
// _i := 0;
// _dta := 0;
// _vW:=0;
// for i := Low(arg) to High(arg) do
// begin
// if arg[i] = -1 then
// begin
// dbgrid.Columns[i].Visible := False;
// Inc(_i);
// end
// else if arg[i] = 0 then
// Inc(_dta);
// end;
// _sum := Round(SumInt(arg)) - _i;
// if _dta > 0 then
// begin
// _dtW := 1;
// _vW :=((Self.Width - 22) - _Sum) DIV _dta;
// end
// else
// _dtW := (Self.Width - 22) / _sum;
//_i:=0;
// for i := Low(arg) to High(arg) do
// begin
// if arg[i] >-1 then
// begin
// if arg[i] > 0 then
// dbgrid.Columns[i].Width := Round(arg[i] * _dtW)
// else
// dbgrid.Columns[i].Width := _vw;
// _i:=_i+dbgrid.Columns[i].Width
// end;
// end;
//if _i>(dbgrid.Width-20) then
//array
// MaxIntValue()
end;
procedure TSPanel.P_SetupDuplicateSearch(obj: TWinControl; _WH: TPoint; tbl_name, Fld_name: string; con: TADOConnection);
begin
if (Self.Showing) then
Exit;
P_Setup(P_SQLGen(tbl_name, Fld_name, ''), point(0, 0), _wh, con, '', SPTDuplicate, obj);
end;
function TSPanel.P_SQLGen(tbl_name, fld_name, Fld_caption: string): string;
//var
// _sql: string;
begin
if (Fld_caption <> '') then
Fld_caption := ' as ' + Fld_caption;
Result := 'select ' + fld_name + Fld_caption + ' from ' + tbl_name + ' where ' + fld_name + ' like :' + fld_name;
end;
procedure TSPanel.P_ShowDuplicateSearch();
begin
try
if not (Self.Showing) then
begin
Self.BringToFront;
AnimateWindow(self.Handle, 200, AW_VER_POSITIVE or AW_SLIDE or AW_ACTIVATE);
Self.Show;
end;
if qy.Connection <> nil then
begin
ed_searchChange(l_editBox);
dbgrid.Columns[0].Width := dbgrid.ClientWidth - 2;
L_Result := 0;
l_exit := False;
end;
except
end;
end;
procedure TSPanel.P_CloseDuplicateSearch();
var
x: HWND;
begin
try
while (TForm(Owner).ActiveControl.Name = '') and (L_result = 0) and not (l_focused) and not (l_exit) and (TForm(Owner).Showing) do
begin
Application.ProcessMessages;
Sleep(100);
end;
if (TForm(Owner).ActiveControl <> Self) and (TForm(Owner).ActiveControl <> l_editBox) then
Self.Hide;
except
end;
end;
{---------------------------------------------------------------------------}
procedure Register;
begin
RegisterComponents('HKSS', [TSPanel]);
end;
{---------------------------------------------------------------------------}
end.