1 SendMessage

1.1 SendMessage定义

官方文档:https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessage

函数原型

LRESULT SendMessage(
  [in] HWND   hWnd,
  [in] UINT   Msg,
  [in] WPARAM wParam,
  [in] LPARAM lParam
);

函数参数

  • hwnd:接收消息的窗口句柄
  • Msg:要发送的消息
  • wParam:附加消息
  • lParam:附加消息

返回值

返回值指定消息处理的结果

2 PostMessage

2.1 PostMessage定义

函数原型

LRESULT SendMessage(
  [in] HWND   hWnd,
  [in] UINT   Msg,
  [in] WPARAM wParam,
  [in] LPARAM lParam
);

函数参数

  • hwnd:接收消息的窗口句柄
  • Msg:要发送的消息
  • wParam:附加消息
  • lParam:附加消息

返回值

如果函数执行成功,返回非零值;如果函数执行失败,返回值为零。

3 SendMessage和PostMessage的区别

  • SendMessage发送消息是同步的,PostMessage发送消息是异步的。SendMessage需要等待消息处理完成才返回,如果所发送的消息没有处理,则发送消息的线程将一直处于阻塞状态,等待消息返回。PostMessage只是将消息放在消息队列中,不管消息是不是被处理都马上返回,这可能导致所发送的消息不会被处理。
  • 在同一个线程中,PostMessage发送消息时,消息要先放入系统消息队列中,系统会根据存放的消息,找到对应的线程(窗口、程序)的消息队列中,然后由GetMessage/PeekMessage提交给TranslateMessage,如果是键盘、鼠标消息,TranslateMessage会处理提交给DispatchMessage,如不是,则直接提交给DispatchMessage,最后DispatchMessage经USER模块协助,将消息传递给窗口处理函数;而SendMessage发送消息时,由USER模块调用目标窗口的处理函数处理消息,并将结果返回。
  • 不在同一个线程,基本都是用PostThreadMessage代替PostMessage,因为PostThreadMessage是直接指定线程ID来确定目标线程;而SendMessage发送消息到目标窗口所属的线程的消息队列中,然后发送消息的线程在UESR模块内监视和等待消息处理,直到目标窗口处理完返回。