C语言 使用SetParent将HWND嵌入外部进程

xkrw2x1b  于 2023-03-22  发布在  其他
关注(0)|答案(3)|浏览(230)

我尝试使用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);

这段代码可以工作,我的窗口出现在另一个应用程序中,但引入了以下问题:

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

我希望我的窗口被当作主应用程序的另一个子窗口。

vlf7wbxs

vlf7wbxs1#

我终于找到了我问题的答案。
要修复主应用失去焦点的问题,需要使用AttachThreadInput函数将嵌入窗口线程附加到主应用线程。
此外,还可以使用TranslateAccelerator函数响应WM_KEYDOWN消息,以确保主应用的加速器消息被触发。

vwhgwdsa

vwhgwdsa2#

我不知道你是否仍然有兴趣在这个主题后,近三年.我正在做一个类似的应用程序.我的解决方案是修改窗口样式之前,你调用SetParent.有了这个解决方案,我不需要调用AttachThreadInput.
然而,从外部进程托管子窗口的一个主要问题是,如果外部进程在响应用户键盘或鼠标输入时挂起,则主应用程序也会冻结。主应用程序中的消息循环仍在运行。但是,它不再接收用户输入事件。因此,我相信这是AttachThreadInput的直接结果,因为两个线程的输入事件现在是同步的。如果其中一个被阻塞,两个都被阻塞。

gjmwrych

gjmwrych3#

我遇到了同样的问题,在仔细阅读MSDN文档后,我发现这是一个很容易解决的问题。
您应该删除WS_POPUP并添加WS_CHILDBEFORE您调用setParent
在MSDN中有这样一段话:
由于兼容性原因,SetParent不会修改其父级正在更改的窗口的WS_CHILD或WS_POPUP窗口样式。因此,如果hWndNewParent为NULL,则还应在调用SetParent后清除WS_CHILD位并设置WS_POPUP样式。相反,如果hWndNewParent不为NULL,并且窗口以前是桌面的子级,则在调用SetParent之前,应该清除WS_POPUP样式并设置WS_CHILD样式。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633541(v=vs.85).aspx

相关问题