在非透明父窗口之上创建透明子窗口(win 32)

时间:2012-05-09 09:51:32

标签: c++ windows winapi

我有一个不是我写的程序。我没有它的来源,该程序的开发人员正在独立开发。他给了我该程序的HWNDHINSTANCE个句柄。 我使用win32 api在他的窗口上创建了一个子窗口。 我需要的第一件事是让这个子窗口在某些区域具有透明度,在其他区域具有不透明性(如游戏的平视显示器(HUD)),以便用户可以在两个窗口中看到内容。

我需要的第二件事是将所有输入都指向父窗口。我的孩子窗口不需要输入。

我知道WS_EX_TRANSPARENT只会让孩子画画像画家算法一样。 我不能使用WS_EX_LAYERED,因为它是一个子窗口。

提前感谢:)

P.S。 我已经到处寻找,但没有找到任何解决方案,虽然互联网上有类似的问题。 实际上这对于那场比赛来说就像HUD一样。我不能直接在父窗口上绘制,因为多线程的复杂性还有很多其他原因。

- 编辑--------------------------- 大家好, 我还在努力。尝试不同的方式与你们所建议的。 有没有办法将directXSetWindowRgn()函数或directxBitBlt()函数结合使用。我认为这样做会有所帮助。 目前我正在测试所有的东西作为子窗口和分层窗口。

3 个答案:

答案 0 :(得分:3)

好朋友,最后我做了一些疯狂的事情来实现它。但它的效率不如直接使用直接x进行绘图。

我做了什么,

  • 使用(WS_EX_ TRANSPARENT | WS_EX_LAYERED | WS_EX_ TOOLWINDOW)和() 在CreateWindowEx
  • 创建窗口后,从窗口样式中删除(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE) 从扩展窗口样式中删除(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_APPWINDOW)
    • 这给了我一个没有边框的窗口,它现在也显示在 任务栏。最热门的也是传给我背后的任何东西 窗口。
  • 对其他窗口的窗口程序进行了分类并得到了
    • WM_CLOSEWM_DESTROY,分别将WM_CLOSEWM_DESTROY发送到我的窗口
    • WM_SIZEWM_MOVE,根据另一个调整大小并移动我的窗口 窗口
    • WM_LBUTTONUPWM_RBUTTONUPWM_MBUTTONUP,让我的窗口显示在顶部,并仍然将焦点保持在另一个窗口,这样我的窗口就不会隐藏在其他窗口
  • 制作directx设备有两遍,
    • 在第一遍中,它在白色背景上绘制黑色的所有元素,并将后备缓冲区数据复制到另一个表面。(因此它给出了黑白二进制图像)
    • 在第二次通过时,它会正常地绘制东西。
  • 创建另一个线程,通过读取黑色&白色表面,使用SetWindowRgn函数。

这是完美的工作,唯一的事情就是它不是在使事情变得透明。 另一个问题是对绘制的对象进行alpha混合。 但您可以使用SetLayeredWindowAttributes函数轻松设置toatal alpha(透明度)。

感谢你们给予的所有帮助,你们告诉他们使用的所有东西,他们引导我,你们可以看到。 :) 可悲的是我们决定不使用这种方法,因为效率问题:( 但我学到了很多东西,这是一次非常棒的经历。这对我来说很重要:) 谢谢你:))

答案 1 :(得分:2)

您可以将WS_EX_LAYERED用于Windows 8及更高版本的child windows

要支持早期版本的Windows,只需创建一个级别分层窗口作为弹出窗口(没有镶边)并确保其位于游戏窗口的适当位置。大多数用户不会一直移动他们正在使用的窗口,因此,当您需要监视父窗口的移动,并重新定位HUD时,这不应该是显示停止。

不关注焦点(在作为子窗口的情况下)或激活(在弹出窗口的情况下)更有趣,但仍然可以: - 操作系统实际上并不自动分配焦点,或激活,到一个单击的窗口 - Windows WindowProc始终通过调用SetFocus或某些SetActiveWindowSetForegroundWindow的变体来进行焦点或激活。重要的是,如果您使用所有鼠标和非客户端鼠标消息而不将它们传递给DefWindowProc,您的HUD将永远不会因为点击而从游戏窗口中窃取激活或键盘焦点。

作为弹出窗口或另一个线程上的窗口,您可能必须手动处理窗口过程确实获得的任何鼠标消息,并将它们发布到游戏窗口。否则,使用HTTRANSPARENT响应WM_NCHITTEST(与WS_EX_TRANSPARENT实现的效果类似)可以使系统继续将鼠标消息传递到堆栈中,直到找到目标为止。 / p>

答案 2 :(得分:1)

您可以使用SetWindowRgn在父窗口中创建一个洞。

另外,仅仅因为它不是你的窗口并不意味着你不能把它变成一个分层窗口。

http://msdn.microsoft.com/en-us/library/ms997507.aspx

最后,你可以通过使用子类来控制另一个窗口 - 基本上你用Wndproc代替它们来代替它们,处理你想要处理的消息,然后将余数传递给它们原来的wndproc。