使用SetParent将HWND嵌入到外部进程中

时间:2008-10-04 18:26:44

标签: c winapi

我正在尝试使用 SetParent 函数将我的进程中的窗口嵌入到外部进程的窗口中,并且遇到了一些我希望有人可以帮助我的问题。首先,这里是我目前正在将窗口嵌入到应用程序中的概述:

HWND myWindow; //Handle to my application window
HWND externalWindow; //Handle to external application window

SetParent(myWindow,externalWindow);

//Remove WS_POPUP style and add WS_CHILD style
DWORD style = GetWindowLong(myWindow,GWL_STYLE);
style = style & ~(WS_POPUP);
style = style | WS_CHILD;
SetWindowLong(myWindow,GWL_STYLE,style);

此代码有效,我的窗口出现在另一个应用程序中,但引入了以下问题:

  • 当我的窗口获得输入焦点时,外部进程的主应用程序窗口失去焦点(即标题栏改变颜色)
  • 当我的窗口具有焦点时,主应用程序的键盘快捷键命令不起作用

有人知道解决方法吗?我希望我的窗口可以被视为主应用程序的另一个子窗口。

4 个答案:

答案 0 :(得分:11)

好吧,我终于找到了问题的答案。

要解决主要应用程序失去焦点的问题,您需要使用 AttachThreadInput 函数将嵌入式窗口线程附加到主应用程序线程。

此外,可以使用 TranslateAccelerator 函数来响应WM_KEYDOWN消息,以确保触发主应用程序的加速器消息。

答案 1 :(得分:4)

近三年后,我不确定你是否仍然对这个话题感兴趣。 我正在研究类似的应用程序。我的解决方案是在调用SetParent之前修改窗口样式。使用此解决方案,我不必调用AttachThreadInput。

但是,从外部进程托管子窗口的一个主要问题是,如果外部进程在响应用户键盘或鼠标输入时挂起,则主应用程序也会冻结。主应用程序中的消息循环仍在运行。但是,它不再接收用户输入事件。因此,它看起来好像是悬挂的。我相信这是AttachThreadInput的直接结果,因为两个线程的输入事件现在已经同步。如果其中一个被阻止,则两者都被阻止。

答案 2 :(得分:0)

我在Catch22.net使用WM_NACTIVE消息找到了一些相关信息。

它位于防止窗口停用部分。 希望有所帮助。

答案 3 :(得分:0)

我遇到了同样的问题,在仔细阅读了MSDN文档之后,我发现它很容易解决。

你应该删除WS_POPUP并添加WS_CHILD BEFORE 你调用setParent

MSDN中已说明:

出于兼容性原因,SetParent不会修改其父级正在更改的窗口的WS_CHILD或WS_POPUP窗口样式。因此,如果hWndNewParent为NULL,则还应清除WS_CHILD位并在调用SetParent后设置WS_POPUP样式。 相反,如果hWndNewParent不是NULL且窗口以前是桌面的子窗口,则应在调用SetParent之前清除WS_POPUP样式并设置WS_CHILD样式。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633541(v=vs.85).aspx