2012-05-09 147 views
2

我有一个程序不是由我写的。我没有它的来源,该程序的开发者正在独立开发。他给了我该程序的HWNDHINSTANCE句柄。 我使用win32 api在他的窗口上创建了一个子窗口。 我需要做的第一件事就是让这个子窗口在某些区域具有透明度,而在其他区域则具有不透明度(例如游戏的头部显示(HUD)),以便用户可以在两个窗口中看到事物。在非透明父窗口(win 32)上创建一个透明子窗口

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

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

在此先感谢:)

p.s. 我看到处处都是,但没有找到任何解决方案,虽然有类似的问题在互联网上。 实际上这是一款适用于该游戏的HUD。我不能直接在父窗口上绘制,因为多线程的复杂性还有很多其他的原因。

- 编辑--------------------------- 嘿家伙, 我仍在努力。尝试不同的方式与你所有的建议。 是否有将directXSetWindowRgn()函数或directxBitBlt()函数结合的方法。我认为这会做到这一点。 当前我正在测试所有的东西作为子窗口和分层窗口。

+0

它很丑,但你可以在窗口上创建一个顶层框架并跟踪窗口下方的移动。然后设置透明区域: http://www.codeguru.com/cpp/wd/dislog/non-rectangulardialogs/article.php/c5037/Creating-Shaped-Windows-Using-Regions-with-Win32.htm – Pete

+0

如果你使窗口透明,只允许你看到父窗口。你想在父窗口打个洞吗? – Ben

+0

那么,你至少需要WS_EX_TRANSPARENT。你需要处理的一个问题是,作者将在WM_ERASEBKGND消息上擦除他的窗口,这将消除你从样式标志中获得的背景像素。因此,您需要对其窗口过程进行子类化并取消或替换该消息。使用WM_PAINT绘制的内容是否仍然运行良好是您需要自行找出的一个悬而未决的问题。如果包含任何具有消除锯齿边缘的文字或图形,则赔率很低。作为评论发布,因为成功的可能性很小。 –

回答

3

好的朋友,最后我做了一些疯狂的事情,让它发生。但其效率不如直接使用x直接绘制。

我做什么,

  • 用在CreateWindowEx
  • (WS_EX_ TRANSPARENT | WS_EX_LAYERED | WS_EX_ TOOLWINDOW)和() 创建窗口后,取出(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_LBUTTONUP,WM_RBUTTONUP,WM_MBUTTONUP,使我的窗口到顶部,仍然保持着对其他窗口,让我的窗口没有得到隐藏在其他窗口后面
  • 作出的DirectX设备有两个通道,
    • 在第一遍它绘制在黑色的所有元素在白色背景上的顶并将backbuffer数据复制到另一个表面(所以​​它给出了黑色的&白色的二进制图像)
    • 在第二遍中,它将正常绘制事物。
  • 通过使用SetWindowRgn函数读取黑色&白色曲面,创建另一个线程来保持窗口透明度。

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

感谢你们给予的所有帮助,你们告诉我的所有事情都被使用过了,他们引导我如你所见。 :) 可悲的是我们决定不使用这种方法,因为效率问题:( 但我学到了很多东西,这是一个很棒的体验。那对我来说都很重要:) 谢谢:)

1

您可以使用SetWindowRgn在父窗口打个洞。

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

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

最后,您可以通过使用子类采取另一个窗口的控制 - 本质上,你替换你的WndProc代替他们的,处理要处理消息,然后将残余传递到原来的WndProc。

+0

SetWindowRgn()只是使屏幕绘制在屏幕仪式的某个部分?我试过了,它可以帮助我。 谢谢。 :) – Deamonpog

+0

我看到之前的链接,并尝试过他们。但我担心如果它会以某种其他方式影响该程序(游戏)。所以即时尝试不改变那个窗口,只是得到他的手柄和其他信息,并操纵我的窗口。谢谢你的想法:) – Deamonpog

2

您可以使用WS_EX_LAYERED来自Windows 8及更高版本中的child windows

为了支持Windows的早期版本,只需创建一个层级窗口作为弹出窗口(不带铬)并确保其位于游戏窗口的适当位置。大多数用户不会随时移动他们正在工作的窗户,因此,当您需要监控移动的父窗口并重新定位HUD时,这不应该成为阻挡器。

不注意焦点(在作为子窗口的情况下)或激活(在弹出的情况下)更有趣,但仍然相当有用: - 操作系统实际上不会自动分配任何焦点或激活到一个点击的窗口 - Windows WindowProc总是通过调用SetFocus或其他变体SetActiveWindowSetForegroundWindow自己来关注或激活。这里最重要的是,如果你在不传递给DefWindowProc的情况下消耗所有鼠标和非客户端鼠标消息,你的HUD将永远不会通过点击来从游戏窗口窃取激活或键盘焦点。

作为一个弹出窗口或另一个线程上的窗口,您可能必须手动处理窗口过程所获得的任何鼠标消息,并将它们发布到游戏窗口。否则,对WM_NCHITTESTHTTRANSPARENT(类似于WS_EX_TRANSPARENT达到的效果)的响应可以使系统继续向下传递鼠标消息,直到找到目标为止。