如何编写全局事件处理程序,使控件可见/启用



我将控件的" visible "one_answers" enabled "属性存储在DB表中。根据用户的角色,我使一些控件不可见/启用。

数据库表" control ";Id, role_id, form (varchar), comp_name(varchar), visible (boolean), enable (boolean)

查询qControls:select * from controls where form=:form

这个过程的调用from OnShow of main form:

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;

我的问题是:

  1. 如何使过程作为一般事件处理程序,而不仅仅是Form1?
  2. 它只查找位于表单上的控件,而不查找位于面板/页面控件(表)上的控件。如何改变它?

用要处理的表单(f.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,请将查询类型更改为合适的类型。

最新更新