【问题标题】:Embedding HWND into external process using SetParent使用 SetParent 将 HWND 嵌入到外部进程中
【发布时间】:2010-09-15 07:24:48
【问题描述】:

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

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

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

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

【问题讨论】:

标签: c winapi


【解决方案1】:

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

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

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

【讨论】:

  • 这不是解决方案。调用SetParent 隐式调用AttachThreadInput。再次显式调用它不会改变任何事情(除非您对 SetParent 的调用因其他原因而失败)。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    您应该删除 WS_POPUP 并添加 WS_CHILD BEFORE 您调用 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      相关资源
      最近更新 更多