如何编写使控件成为全局事件处理程序 visible/enabled
How to write global event handler procedure that makes controls visible/enabled
我将控件 'visible' 和 'enabled' 属性 存储在数据库 table 中。根据用户的角色,我做了一些不 visible/enabled.
的控件
数据库的字段Table“控件”:id,role_id,表单(varchar),comp_name(varchar),可见(布尔值),启用(布尔值)
查询 qControls: select * from controls where form=:form
从主窗体的 OnShow 调用此过程:
application.CreateForm(TForm1, Form1);
FORM := 'Form1';
Form1.showModal;
调用过程:
procedure RightsOnControls();
var i:integer;
begin
fMain.qControls.Close;
fMain.qControls.Params[0].AsString:= FORM; //FORM is global variable: FORM:='Form1'
fMain.qControls.Open;
if fMain.qControls.RecordCount>0 then begin
while not fMain.Controls.Eof do begin
for I := 0 to form1.ControlCount - 1 do
if uppercase(form1.Controls[i].Name)= uppercase(fMain.qControlsComp_name.AsString) then
begin
form1.Controls[i].Visible:=fmain.qControlsVisible.AsBoolean;
form1.Controls[i].Enabled:=fmain.qControlsEnable.AsBoolean;
end;
fMain.qControls.next;
end;
end;
end;
我的问题是:
- 如何将过程作为通用事件处理程序,而不仅仅是 Form1?
- 它只找到位于窗体上的控件,而不是位于 panel/Page 控件(选项卡)上的控件。怎么改?
使用要处理的表单 (f.i.form1) 和查询 (fMain.qControls):
procedure RightsOnControls(AForm: TForm; AQuery: TFDQuery);
function FindChildControl(Parent: TWinControl; const ControlName: string): TControl;
var
I: Integer;
begin
for I := 0 to Parent.ControlCount - 1 do begin
Result := Parent.Controls[I];
if SameText(Result.Name, ControlName) then Exit;
if Result is TWinControl then begin
Result := FindChildControl(TWinControl(Result), ControlName);
if Result <> nil then Exit;
end;
end;
Result := nil;
end;
var
ctl: TControl;
begin
AQuery.Close;
AQuery.Params[0].AsString := AForm.Name;
AQuery.Open;
while not AQuery.Eof do begin
ctl := FindChildControl(AForm, AQuery.FieldByName('Comp_name').AsString);
if ctl <> nil then begin
ctl.Visible := AQuery.FieldByName('Visible').AsBoolean;
ctl.Enabled := AQuery.FieldByName('Enable').AsBoolean;
end;
AQuery.next;
end;
end;
如果您不使用 FireDAC,请将查询类型更改为合适的类型。
我将控件 'visible' 和 'enabled' 属性 存储在数据库 table 中。根据用户的角色,我做了一些不 visible/enabled.
的控件数据库的字段Table“控件”:id,role_id,表单(varchar),comp_name(varchar),可见(布尔值),启用(布尔值)
查询 qControls: select * from controls where form=:form
从主窗体的 OnShow 调用此过程:
application.CreateForm(TForm1, Form1);
FORM := 'Form1';
Form1.showModal;
调用过程:
procedure RightsOnControls();
var i:integer;
begin
fMain.qControls.Close;
fMain.qControls.Params[0].AsString:= FORM; //FORM is global variable: FORM:='Form1'
fMain.qControls.Open;
if fMain.qControls.RecordCount>0 then begin
while not fMain.Controls.Eof do begin
for I := 0 to form1.ControlCount - 1 do
if uppercase(form1.Controls[i].Name)= uppercase(fMain.qControlsComp_name.AsString) then
begin
form1.Controls[i].Visible:=fmain.qControlsVisible.AsBoolean;
form1.Controls[i].Enabled:=fmain.qControlsEnable.AsBoolean;
end;
fMain.qControls.next;
end;
end;
end;
我的问题是:
- 如何将过程作为通用事件处理程序,而不仅仅是 Form1?
- 它只找到位于窗体上的控件,而不是位于 panel/Page 控件(选项卡)上的控件。怎么改?
使用要处理的表单 (f.i.form1) 和查询 (fMain.qControls):
procedure RightsOnControls(AForm: TForm; AQuery: TFDQuery);
function FindChildControl(Parent: TWinControl; const ControlName: string): TControl;
var
I: Integer;
begin
for I := 0 to Parent.ControlCount - 1 do begin
Result := Parent.Controls[I];
if SameText(Result.Name, ControlName) then Exit;
if Result is TWinControl then begin
Result := FindChildControl(TWinControl(Result), ControlName);
if Result <> nil then Exit;
end;
end;
Result := nil;
end;
var
ctl: TControl;
begin
AQuery.Close;
AQuery.Params[0].AsString := AForm.Name;
AQuery.Open;
while not AQuery.Eof do begin
ctl := FindChildControl(AForm, AQuery.FieldByName('Comp_name').AsString);
if ctl <> nil then begin
ctl.Visible := AQuery.FieldByName('Visible').AsBoolean;
ctl.Enabled := AQuery.FieldByName('Enable').AsBoolean;
end;
AQuery.next;
end;
end;
如果您不使用 FireDAC,请将查询类型更改为合适的类型。