如何发送进程间消息?

时间:2019-04-29 15:50:05

标签: c winapi

PostMessageSendNotifyMessage均因ERROR_MESSAGE_SYNC_ONLY而失败。因此,我剩下的唯一选择是SendMessage,但它似乎没有做任何事情-它返回零,而GetLastErrorERROR_ENVVAR_NOT_FOUND

这是我的发件人代码(过程1):

SendMessage(FindWindowEx(HWND_MESSAGE,NULL,"Message","serverwindow"),WM_COPYDATA,HWND_MESSAGE,
        &(COPYDATASTRUCT){0, sizeof "localhost", "localhost"})

接收方(进程0):

HWND hWnd=CreateWindowExA(0,"Message","serverwindow",0,0,0,0,0,HWND_MESSAGE,NULL,GetModuleHandle(NULL),NULL);
MSG msg;
while (Sleep(500), true)
while (PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
    printf("message recieved\n");

1 个答案:

答案 0 :(得分:1)

正如David在评论中所述,WM_COPYDATA已发送消息,而不是已排队消息,因此像您所示的消息循环将永远不会看到(Get|Peek)Message()输出的消息。消息直接传递到接收窗口的WindowProc,因此需要在此处进行处理。但是,当跨线程/进程边界发送消息时,接收线程仍然需要运行消息循环,以便在(Get|Peek)Message()等待时将已发送消息分派到该线程的窗口中排队消息。

根据SendMessage()文档:

  

将指定的消息发送到一个或多个窗口。 SendMessage函数调用指定窗口的窗口过程,直到该窗口过程处理完消息后才返回。

     

...

     

如果指定的窗口是由调用线程创建的,则该窗口过程将作为子例程立即被调用。 如果指定的窗口是由其他线程创建的,则系统切换到该线程并调用适当的窗口过程。仅当接收线程执行消息检索代码时,才处理线程之间发送的消息。发送线程被阻塞,直到接收线程处理该消息为止。但是,发送线程将在等待其消息处理之前处理传入的非排队消息。为避免这种情况,请使用SendMessageTimeout,并将其设置为SMTO_BLOCK。有关非排队消息的更多信息,请参见Nonqueued Messages