我有两种"无模式"形式:
你可以看到:
从这种无模式的形式,我想展示一个模态:
的模态形式被构造为:
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;
问题是:
在过去的十年里,我已经问了7次这个问题.我最后一次承诺将MainForm作为主要形式将解决所有问题.
好处:自.NET 1.0以来,WinForms已经正确处理了这个问题.
关于模态对话框的内容存在很多困惑.在您继续使用其所有者之前必须与其进行交互时,对话框是模态的.从Windows界面设计指南:
对话框有两种基本类型:
- 模态对话框要求用户在继续使用所有者窗口之前完成并关闭.这些对话框最适用于需要在继续之前完成的关键或不常见的一次性任务.
- 无模式对话框允许用户根据需要在对话框和所有者窗口之间切换.这些对话框最适用于频繁,重复,正在进行的任务.
Windows具有"所有者"的概念.当窗口"拥有"时,它将始终显示在其所有者之上.当窗口是"模态"时,意味着所有者被禁用,直到模态任务完成.
你在ProgressDialogAPI中看到这个效果:
Run Code Online (Sandbox Code Playgroud)HRESULT StartProgressDialog( [in] HWND hwndParent, IUnknown *punkEnableModless, DWORD dwFlags, LPCVOID pvReserved );hwndParent [in]
类型:HWND
对话框父窗口的句柄.dwFlags
类型:DWORD
PROGDLG_MODAL
进度对话框将模块化为hwndParent指定的窗口.默认情况下,进度对话框是无模式的.
当然,你可能是卑鄙的,并禁用所有其他窗口
但我希望有正确的行为.我想要做:
自1998年以来,我一直想在我的Delphi应用程序中使用它; 当实现Delphi 3没有正确支持Windows 95和任务栏时.
ShowModal禁用同一线程中的所有其他顶级窗口.这包括你的主要表格.
您必须精心显示此表单,以使其按您希望的方式运行.请执行下列操作:
Show.你可以在第2步和第3步之间运行你自己的模态消息循环,ShowModal但这可能是过度的.我只是将表单显示为无模式,但禁用其所有者使其与该所有者"模态".
这个过程有点微妙.寻找ShowModal灵感来源.此外,雷蒙德关于情态的史诗系列文章是必不可少的阅读.我在这里链接到它:为什么MessageBox不会在同步线程上阻止应用程序? 
Raymond的更多内容:禁用和启用Windows的正确顺序:
当您销毁模式对话框时,您正在通过前景激活来销毁窗口.窗口管理器现在需要找到其他人来激活.它试图将它提供给对话框的所有者,但是所有者仍然被禁用,因此窗口管理器会跳过它并查找其他窗口,某些未被禁用的窗口.
这就是你得到奇怪的闯入者窗口的原因.
破坏模态对话框的正确顺序是
- 重新启用所有者.
- 销毁模态对话框.
这次,当模态对话框被销毁时,窗口管理器会向所有者查找,而这次它已启用,因此它继承了激活.
没有闪烁.没有闯入者.
| 归档时间: | 
 | 
| 查看次数: | 3687 次 | 
| 最近记录: |