我有两个“无模式”窗体:
- 一个是特殊的MainForm
- 另一个是无模式窗体
你可以看到:
- 两者都存在于任务栏上
- 两者都有任务栏按钮
- 两者可以独立最小化
- 两者可以独立还原
- 两者都不是始终位于其他窗口之上(拥有)
现在展示一个模式窗体
从这个无模式窗体中,我想展示一个模式窗体:
这个模式窗体被构建为:
var
frmExchangeConfirm: TfrmExchangeConfirm;
begin
frmExchangeConfirm := TfrmExchangeConfirm.Create(Application);
try
//Setting popupMode and popupParent still makes the MainForm disabled
// frmExchangeConfirm.PopupMode := pmExplicit;
// frmExchangeConfirm.PopupParent := Self; //owned by us
frmExchangeConfirm.OwnerForm := Self; //tell the form which owner to use
frmExchangeConfirm.ShowModal;
finally
frmExchangeConfirm.Free;
end;
模态窗口通过新的
OwnerForm
属性指定使用哪个所有者:protected
procedure SetOwnerForm(const Value: TForm);
public
property OwnerForm: TForm read GetOwnerForm write SetOwnerForm;
end;
这会强制重新创建一个句柄:
procedure TfrmExchangeConfirm.SetOwnerForm(const Value: TForm);
begin
FOwnerForm := Value;
if Self.HandleAllocated then
Self.RecreateWnd;
end;
然后第二次通过CreateParams
:
procedure TfrmExchangeConfirm.CreateParams(var Params: TCreateParams);
begin
inherited;
if FOwnerForm <> nil then
Params.WndParent := FOwnerForm.Handle;
end;
问题是:
- 一旦显示了这个所拥有的模态窗体,我就无法与 MainForm 交互
- 我无法使用任务栏按钮最小化 MainForm
- 我无法使用任务栏按钮最小化模态窗口或其所有父级
- 如果我使用 最小化 按钮最小化模式窗体,MainForm 就会消失
- 我可以使用任务栏按钮激活 MainForm,但我无法与其交互
在过去的十年里,我已经问了这个问题大约7次。最后一次,我被承诺将主窗体设置为 MainForm 就可以解决所有问题。
奖励: WinForms自.NET 1.0以来已正确处理此问题。
关于模态对话框,存在很多混淆。在Windows界面设计指南中提到:
对话框有两种基本类型:
- 模态对话框要求用户在继续使用 所有者窗口之前完成并关闭。这些对话框最适用于需要在继续之前完成的关键或不频繁的一次性任务。
- 非模态对话框允许用户根据需要在对话框和 所有者窗口之间切换。这些对话框最适用于频繁、重复、持续进行的任务。
Windows有一个“所有者”的概念。当一个窗口被“拥有”时,它将始终显示在其所有者上方。当一个窗口是“模态”时,这意味着直到模态任务完成,所有者才会被禁用。
您可以在ProgressDialog
API中看到此效果:
当然,你可以采取不好的方式,禁用所有其他窗口:
HRESULT StartProgressDialog( [in] HWND hwndParent, IUnknown *punkEnableModless, DWORD dwFlags, LPCVOID pvReserved );
hwndParent [in]
Type: HWND
A handle to the dialog box's parent window.dwFlags
Type: DWORD
PROGDLG_MODAL
The progress dialog box will be modal to the window specified by hwndParent. By default, a progress dialog box is modeless.
- 在线程中
- 在进程中
- 或者在系统中
- 像Windows一样
- 像Office应用程序一样
- 像Beyond Compare一样
- 像WinForms一样
- 像WPF一样
- 像我使用过的每个应用程序一样
- 以及任何用户期望的一样