我的应用程序有几个模块,每个模块位于主窗体的一个选项卡中。 使用对话框时,可以方便地调用ShowModal,因为您知道对话框何时完成。但对于用户而言,在对话框关闭之前锁定整个程序并不好。
我想要一个本地模态对话框。因此,一个模块可以打开一个对话框,它只锁定当前模块。用户仍然可以切换到另一个模块并继续工作。如果用户返回到第一个模块,则对话框在那里等待关闭,然后用户才能继续在该模块中工作。
我必须为此创建某种框架,以便应用程序中的所有对话框都可以使用。 我有一个基类用于所有对话框TAttracsForm,我想这里是添加我的Show()方法的地方。
这应该只锁定当前模块中对所有wincontrols的访问。 它应该模拟对ShowModal()的调用。我怎样才能做到这一点?
此致
答案 0 :(得分:2)
您必须执行以下操作:
您可能需要对此建议进行微调,直到您获得所需的确切功能。
答案 1 :(得分:2)
你还想用“你知道什么时候对话完成”比喻来实现这个吗? 所以喜欢
DoSomethingBeforeDialog();
Form:=TFakeFormDialog.Create(Nil);
try
Form.FakeShowModal();
finally
Form.Free;
end;
DoSomethingAfterDialog();
如果答案是肯定的,那么您可以尝试使用线程实现此功能,例如Google Chrome使用标签页执行此操作。但是,如果没有线程,您可以使用像这样的代码来捕获消息处理
function TFakeModalDlg.FakeShowModal(FormParent: TWinControl): boolean;
begin
Parent:=FormParent;
SetBounds((FormParent.Width - Width) div 2, (FormParent.Height - Height) div 2,
Width, Height);
Show;
while NoButtonIsPressed() do
begin
Application.HandleMessage;
end;
Hide;
end;
你甚至有以下代码......
Form:=TFakeModalDlg.Create(Nil);
try
(Sender as TButton).Caption:='Going modal...';
Form.FakeShowModal(TabSheet1);
(Sender as TButton).Caption:='Returned from modal';
finally
Form.Free;
end;
从选项卡中调用乘法时间,但问题是这些“对话框”应该以“堆栈顺序”关闭,即与它们显示的顺序相反。我认为强制用户在开发者偏好顺序中关闭表单是不可能的。
答案 2 :(得分:1)
我现在几乎实现了本地模态对话框。 它是建立在当TForms Enabled属性设置为False时,整个表单从输入锁定。我的模块只是TForm的后代。
我的ViewManager类决定了哪些模块是当前的添加/关闭模块等,它有两种新方法。 LockCurrentView和UnLOckCurrentView。
function TViewManager.LockCurrentView: TChildTemplate;
begin
Result := CurrentView;
Result.Enabled := False;
Result.VMDeactivate; // DeActivate menus and toolbas for this module
end;
procedure TViewManager.UnLockCurrentView(aCallerForm: TChildTemplate);
begin
aCallerForm.VMActivate; // Activate menus and toolbas for this module
aCallerForm.Enabled := True;
end;
TAttracsForm是所有对话框的基类。我重写FormClose并添加一个新方法ShowLocalModal来调用而不是ShowModal。我还必须在对话框关闭时添加要调用的TNotifyEvent OnAfterDestruction。
procedure TAttracsForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(fCallerForm) then
begin
ClientMainForm.ViewManager.UnLockCurrentView(fCallerForm as TChildTemplate);
if Assigned(OnAfterDestruction) then
OnAfterDestruction(Self);
Action := caFree;
end;
end;
{ Call to make a dialog modal per module.
Limitation is that the creator of the module must be a TChildtemplate.
Several modal dialogs cannot be stacked with this method.}
procedure TAttracsForm.ShowLocalModal(aNotifyAfterClose: TNotifyEvent);
begin
fCallerForm := ClientMainForm.ViewManager.LockCurrentView; // Lock current module and return it
PopupParent := fCallerForm;
OnAfterDestruction := aNotifyAfterClose;
Show;
end;
使用简单对话框进行一些测试看起来很有希望。所以模块只需要调用ShowLocalModal(myMethod),它有一个TNotifyEvent作为参数。关闭对话框时会调用此方法。