如何从 DLL 内部获取 HWND?

5
我有一个DLL,想要使用Direct Sound播放声音。为了播放声音,我需要可执行文件的HWND。但是我没有加载DLL的可执行文件的HWND。在不从可执行文件中传递HWND的情况下,我该如何在DLL中获取它?

可执行文件的“HWND”? “HWND”代表“窗口句柄”...你是不是指的是“HMODULE”? - user541686
@Mehrdad: 我认为他需要进程内部窗口的HWND... 直接音频要求使用HWND进行初始化。 - Reed Copsey
1
你能否创建自己的(隐藏)窗口? - shf301
2个回答

6

您可以使用GetCurrentProcessId获取当前进程ID。

然后,您可以调用EnumWindows,并使用GetWindowThreadProcessId检查每个窗口,以查找与您的进程相关联的窗口。

但是,更简单的选项可能是生成自己的窗口。您可以创建一个不可见的1x1像素窗口,并将其与Direct Sound一起使用。

这样做的优点是,即使您的调用进程没有可用的窗口(或定期删除窗口句柄),它也可以工作。


我将尝试创建一个像你和shf301建议的小窗口。 - zooropa
创建窗口当然是非常可能的,但它不应该是你的首选 - 窗口需要相当多的资源,有自己的需求,并且通常针对具有自己消息循环的实际 UI 应用程序(无论是隐式还是显式),这需要考虑和实现很多东西,对于一个小的 DLL 来说太过繁琐。通常更好的方法是通过 DLL 函数传递 HWND 引用到 DLL 中,或从正在运行的可控进程中获取一些可验证的 HWND - 当然,必须监视此进程... - specializt
1
@specializt 不一定总是同意 - 如果您不确定您的 DLL 将如何使用,并希望它是通用的,那么这是一个安全选项。依赖可能被销毁的 HWND 也有其自身的缺点。 - Reed Copsey
在DLL内部生成窗口是绝对不安全的。这实际上是一种安全风险和稳定性问题,因为您的DLL可能会在没有通知的情况下被卸载/销毁,从而泄漏整个窗口等。这是专业人士所谓的“糟糕代码”。如果这还是20世纪90年代,这样的DLL很容易因为内存泄漏而导致整个系统崩溃。感谢上帝,现在已经是21世纪了。 - specializt

1
在主线程上调用GetGUIThreadInfo。这将为您提供一堆HWNDs。如果您需要一个顶级HWND,请选择任何有效的HWND(不是所有值都可能被填充),并使用GetAncestor(GA_ROOT)找到其顶级祖先。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接