我有 2 个应用程序,一个是隐藏窗口(“hW”),另一个是控制台应用程序(“CA”),来自 我想向硬件发送命令。 在控制台应用程序中,我得到了硬件句柄,这是一个问题: 如果我跑步:
PostMessage(hwnd, WM_QUIT, NULL, NULL);
一切正常,消息到达硬件并将其关闭。但是如果我正在发送
PostMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)"texttext");
消息根本没有到达硬件。 Spy++ 还显示消息未到达硬件。 WM_SETTEXT 有什么特定的东西可以阻止它吗?预先感谢。
好的。在这里找到答案http://cboard.cprogramming.com/windows-programming/72589-wm_settext-postmessage.html
事实证明 API 试图保护我免受范围问题的影响;发布消息() 总是因 WM_SETTEXT 或任何其他系统定义的消息而失败 一个指针作为参数。这让我进入 SendMessage(),这不好, 因为我想要异步消息传递......
P.P.S.
另外,看起来像
SendMessage(hwnd, WM_QUIT, NULL, NULL);
不会对目标应用程序执行任何操作。即使在像
这样的简单测试应用程序中也是如此 HWND hNote;
if (!(hNote=FindWindow(L"Notepad",NULL)))
exit(1);
SendMessage(hNote, WM_QUIT, NULL, NULL);
同时
PostMessage(hNote, WM_QUIT, NULL, NULL);
有效。
所有这些对我来说看起来都不合逻辑...是否有一些通用函数可以正确处理任何类型的消息?
不同的消息有不同的要求。有些需要发布到队列中。还有一些需要同步交付。因此,系统被设计为需要两种交付机制。
对于
WM_SETTEXT
的情况,总是需要同步传递。这是因为窗口管理器需要能够管理文本数据的生命周期。 Raymond Chen谈到了这个问题:为什么我不能PostMessage WM_COPYDATA消息,但我可以SendMessageTimeout它并有一个微小的超时?
当窗口处于另一个进程中时,调用
SendMessage
存在危险。如果其他进程挂起,您的进程也不会挂起。因为 SendMessage
是同步的。
SendMessageTimeout
。这会将您的字符串数据编组到其他进程中。您可以设置超时,以确保在其他进程被挂起的情况下,您的进程可以避免这种命运。
从你的最后一个问题开始:不,没有一个通用的消息功能可以满足你的要求。
让我们分析一下您的案例:
WM_SETTEXT
:该消息需要一个指针,因此您无法在进程之间安全地发布它,因为它们将具有单独的内存地址,并且来自一个进程的指针对另一个进程毫无意义。您可以使用SendMessage()
,因为Windows知道该消息,在幕后复制数据并进行额外的黑客攻击。但有了 PostMessage()
就没有(不可能)这样的魔法了。WM_QUIT
:这是一条特殊消息,会导致消息循环中断。简而言之,它所做的只是使 GetMessage
返回 FALSE
,以便标准消息循环(1)完成。但是,啊!只有当你 PostMessage()
时,这才会起作用。当您SendMessage()
一条消息时,它会直接发送到相关的窗口函数,甚至不会停留在消息队列中。 Windows 对 WM_QUIT
没有任何作用,因为它们根本就没有期待它。实际上,即使发布了该消息,该消息也不会到达窗口,因为通常的循环不会为其调用 DispatchMessage()
。这就是为什么它通常被发布到线程,没有窗口,因此存在一个函数可以完成所有这一切:PostQuitMessage()
。(1) 标准消息循环:
while (GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
作为脚注,您可以使用多种技巧在进程之间移动数据:
使用
WM_COPYDATA
。 AFAIK 它不能与 PostMessage()
一起使用,但也许您可以在目标进程中创建两个线程,以便第一个线程接收 WM_COPYDATA
并快速返回,然后将其发布到第二个线程排队。使用共享内存(搜索
CreateFileMapping()
)和 PostMessage()
到该内存的偏移量。您可能应该使用一些 WM_APP + x
用户定义的消息而不是系统消息。但是,请注意同步问题,您将需要互斥锁或其他东西。命名管道! (我的最爱)
插座。