加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – 为什么单击子窗口并不总是将应用程序带到前台?

发布时间:2020-12-14 01:51:01 所属栏目:Windows 来源:网络整理
导读:当应用程序落后于其他应用程序时 我点击我的应用程序的任务栏图标,我希望整个应用程序 即使是app-modal,WS_POPUP对话框,也会出现在z顺序的顶部 打开. 但是,有些时候,对于我的一些(和其他人)对话框,只有对话框出现在前面;应用程序的其余部分留在后面. 我看过S
当应用程序落后于其他应用程序时
我点击我的应用程序的任务栏图标,我希望整个应用程序
即使是app-modal,WS_POPUP对话框,也会出现在z顺序的顶部
打开.

但是,有些时候,对于我的一些(和其他人)对话框,只有对话框出现在前面;应用程序的其余部分留在后面.

我看过Spy,对于那些正常工作的人,我可以看到
WM_WINDOWPOSCHANGING被发送到对话框的父级.对于那些
留下应用程序的其余部分,WM_WINDOWPOSCHANGING不存在
发送到对话框的父级.

我有一个例子,其中一个对话框通常带有整个应用程序,而另一个没有.工作对话框和非工作对话框都具有相同的窗口样式,子样式,父级,所有者,个体发生.

简而言之,两者都是使用DialogBoxParam()创建的WS_POPUPWINDOW窗口,
传入相同的HWND作为第三个参数.

有没有人注意到Windows程序中的这种行为奇怪?单击按钮时,TaskBar会向应用程序发送什么消息?谁负责确保所有应用程序的窗口都出现在前台?

在我的情况下,基础父母是一个MDI框架…以某种方式影响这个因素?

解决方法

我知道现在已经很老了,但我偶然发现了它,我知道答案.

在您看到(和写入)将对话框带到前台的应用程序中,主窗口没有随之显示,开发人员只是忽略了指定对话框的所有者.

这适用于模态窗口,如对话框和消息框,以及无模式窗口.设置无模式弹出窗口的所有者也会始终将弹出窗口保持在其所有者之上.

在Win32 API中,调出对话框或消息框的功能将所有者窗口作为参数:

INT_PTR DialogBox(
    HINSTANCE hInstance,LPCTSTR lpTemplate,HWND hWndParent,/* this is the owner */
    DLGPROC lpDialogFunc
);

int MessageBox(
    HWND hWnd,/* this is the owner */
    LPCTSTR lpText,LPCTSTR lpCaption,UINT uType
);

同样,在.NET WinForms中,可以指定所有者:

public DialogResult ShowDialog(
    IWin32Window owner
)

public static DialogResult Show(
    IWin32Window owner,string text
) /* ...and other overloads that include this first parameter */

此外,在WinForms中,可以轻松设置无模式窗口的所有者:

public void Show(
    IWin32Window owner,)

或者,等效地:

form.Owner = this;
form.Show();

在直接WinAPI代码中,可以在创建窗口时设置无模式窗口的所有者:

HWND CreateWindow(
    LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,/* this is the owner if dwStyle does not contain WS_CHILD */
    HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam
);

或之后:

SetWindowLong(hWndPopup,GWL_HWNDPARENT,(LONG)hWndOwner);

或(64位兼容)

SetWindowLongPtr(hWndPopup,GWLP_HWNDPARENT,(LONG_PTR)hWndOwner);

请注意,MSDN有关于SetWindowLong[Ptr]的以下内容:

Do not call SetWindowLongPtr with the GWLP_HWNDPARENT index to change the parent of a child window. Instead,use the 07001 function.

这有点误导,因为它似乎意味着上面的最后两个片段是错误的.事实并非如此.调用SetParent会将预期的弹出窗口转换为父窗口的子窗口(设置其WS_CHILD位),而不是将其设置为拥有窗口.上面的代码是使现有弹出窗口成为拥有窗口的正确方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读