6

我有 2 个应用程序,一个是隐藏窗口(“hW”),另一个是控制台应用程序(“CA”),我想从中向 hW 发送命令。在控制台应用程序中,我得到了硬件句柄,这是一个问题:如果我正在运行:

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(),这不好,
因为我想要异步消息....


PPS
另外,看起来像

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);

作品。
所有这些对我来说看起来都不合逻辑......是否有一些通用功能可以与任何类型的消息一起正常工作?

4

3 回答 3

8

不同的消息有不同的要求。有些需要发布到队列中。还有一些需要同步交付。因此,该系统被设计为需要两种交付机制。

在 的情况下WM_SETTEXT,总是需要同步交付。这是因为窗口管理器需要能够管理文本数据的生命周期。Raymond Chen 谈到了这个问题:为什么我不能 PostMessage WM_COPYDATA 消息,但我可以 SendMessageTimeout 它有一个微小的超时?

SendMessage当窗口处于另一个进程中时,调用存在危险。如果其他进程挂起,那么您的进程也不会挂起。因为SendMessage是同步的。

解决方案是调用SendMessageTimeout. 这会将您的字符串数据编组到另一个进程中。并且您可以设置超时以确保在其他进程被挂起的情况下,您的进程可以避免这种命运。

于 2012-11-13T21:25:43.260 回答
1

从您的最后一个问题开始:不,没有通用的消息功能可以满足您的需求。

让我们分析一下您的案例:

  1. WM_SETTEXT:该消息需要一个指针,因此您无法在进程之间安全地发布它,因为它们将具有分离的内存地址,并且来自一个进程的指针对另一个进程毫无意义。您可以使用SendMessage(),因为 Windows 知道消息,在幕后复制数据并进行额外的黑客攻击。但是PostMessage()没有(不可能)这样的魔法。

  2. WM_QUIT: 这是一个特殊的消息,它使消息循环中断。简而言之,它所做的只是GetMessage返回FALSE,以便标准消息循环(1)完成。但是,啊!只有你PostMessage()这样做才有效。当您收到SendMessage()一条消息时,它会直接发送到相关的窗口函数,甚至不会停在消息队列中。而windows对它什么也不做WM_QUIT,因为他们根本没想到它。实际上,即使发布,这条消息也不会到达窗口,因为通常的循环不需要DispatchMessage()它。这就是为什么它通常发布到线程,没有窗口,所以存在一个函数来完成所有这些:PostQuitMessage().

(1) 标准消息循环:

while (GetMessage(&msg, 0, 0, 0))
    DispatchMessage(&msg);

作为脚注,您可以使用几种技巧在进程之间移动数据:

  1. 使用WM_COPYDATA. AFAIK 它不能与 一起使用PostMessage(),但也许您可以在目标进程中创建两个线程,以便第一个接收WM_COPYDATA并快速返回,然后将其发布到第二个线程排队。

  2. 使用共享内存(搜索CreateFileMapping())和PostMessage()该内存的偏移量。您可能应该使用一些WM_APP + x用户定义的消息而不是系统消息。但是,请注意同步问题,您将需要互斥锁或其他东西。

  3. 命名管道!(我的最爱)

  4. 插座。

于 2012-11-13T21:04:46.077 回答
0

您要做的是传达两个独立的过程,常规消息不起作用,但有一个可以解决问题:WM_COPYDATA消息。一个相关的问题可以在这里找到

于 2012-11-13T20:49:26.153 回答