2011-09-30 68 views
2

我想从加载我的DLL的进程获取消息。如何安全地从DLL中挂接消息泵?

我已经试过:

SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)WndProc, hInstance, 0); 

这给了我错误的弹出窗口如何“节目X无法启动,因为Y.dll从您的系统中缺少”。这就是我在标题中“安全”放置的原因。

我也试过:

SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)WndProc, hInstance, threadId); 

threadId是在我的DLLMain GetCurrentThreadId()结果。 这一个工程,但我没有得到任何消息的窗口(只是一堆512和1025)。

回答

4

消息与线程和窗口有关,你的DLL可能被进程加载。所以没有直接的对应关系。

挂钩另一方面是全局或每线程。

所有这一切意味着您必须选择是否仅从特定线程或全局(特定桌面中所有进程中的所有线程)发送消息,您将自己筛选出您感兴趣的进程。

你的第二个代码片段是一个线程钩子。第一个是全局钩子,你肯定做错了,因为成功的钩子本身不会导致你提到的错误信息。

+0

谢谢,这回答了我很多问题。我正在使用需要'hwnd'传递消息的wintab库。线程是否有层次结构,我可以爬上去找到最近的窗口,或者在我的DLL中创建一个隐藏的窗口? –

+0

如果你正在做一个窗口句柄这个复杂的东西,那么肯定不会钩住某人的财产。创建你自己的。但请注意,您的窗口必须位于具有消息循环的线程上。所以,如果你足够幸运,你只需创建一个窗口;否则你需要创建一个带窗口的后台线程和一个消息循环。无论如何,这两种方法都更容易,更可靠。 –

0

我猜你是直接从DLLMain中调用这些函数。您可以从DLLMain安全地调用哪些函数有严重的限制,请参阅MSDN documentation on DLLMain

没有安全和不安全函数的明确列表,但似乎在您的第一个代码片段中对SetWindowsHookEx的调用正在做一些在DLLMain函数中被禁止的内容,因此DLL无法正确加载。

+0

其实我在DLLMain中使用'CreateThread',然后在回调中调用这段代码。之后,我有一个基本的消息循环。对不起,我应该澄清一点。 –

+0

我想说,你不能安全地调用DLLMain中的CreateThread,但经过一些研究后,我得出了可以做出的结论,尽管它不被推荐。 :-) –

+0

在这种情况下,第一个示例中对SetWindowsHookEx的调用几乎肯定不会运行;在你的新线程有机会运行之前,“丢失的DLL”错误应该导致进程终止。也许你无意中从DLLMain返回0? –