SendMessage和PostMessage
声明如下:
LRESULT SendMessage(
HWND hWnd, //目标窗口的句柄。如果为 NULL,则发送到程序的顶层窗口
UINT Msg, //要发送的消息标识符(例如 WM_COMMAND)
WPARAM wParam, //附加的消息特定信息
LPARAM lParam //附加的消息特定信息
);
BOOL PostMessage(
HWND hWnd,//目标窗口的句柄。如果为 NULL,则发送到程序的顶层窗口
UINT Msg, //要发送的消息标识符(例如 WM_COMMAND)
WPARAM wParam,//附加的消息特定信息
LPARAM lParam //附加的消息特定信息
);
这两个函数都用于向某句柄发送消息,差别在于,PostMessage函数调用发送之后,立即返回,不等待消息处理完成。而SendMessage则让调用的线程处于阻塞(BLOCk)状态,直到消息处理完成。
自定义消息
为了防止用户定义的消息ID与系统的消息ID冲突,MS(Microsoft)定义了一个宏WM_USER,小于WM_USER的ID被系统使用,大于WM_USER的ID被用户使用。
const UINT WM_USERMSG=WM_USER+1 即可定义一个自定义消息。
以下代码即可实现,左键点击窗口时候WndProc会执行case WM_LBUTTONDOWN的内容,即发送WM_USERMSG给WndProc自己,然后自己又对WM_USERMSG进行处理,弹窗显示“收到自定义消息”。
const UINT WM_USERMSG = WM_USER + 1;
// 窗口过程函数 - 处理所有发送到窗口的消息
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) // 根据消息类型进行分支处理
{
case WM_LBUTTONDOWN: // 鼠标左键点击时触发
MessageBoxW(hwnd, L"鼠标左键点击", L"提示", MB_OK); // 显示关闭提示
SendMessageW(hwnd, WM_USERMSG, 0, 0);
break;
case WM_USERMSG: //收到自定义消息时触发
MessageBoxW(hwnd, L"自定义消息触发", L"提示", MB_OK);
default: // 其他未处理的消息交给默认处理函数
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0; // 已处理的消息返回0
}
然后再来实现,右键点击时关闭qq窗口,此处用到一个插件Spy++,可以获取指定窗口的句柄:

然后以下代码即可实现,在nopsled窗口点击右键时,会把qq给关掉。
const UINT WM_USERMSG = WM_USER + 1;
// 窗口过程函数 - 处理所有发送到窗口的消息
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) // 根据消息类型进行分支处理
{
case WM_LBUTTONDOWN: // 鼠标左键点击时触发
MessageBoxW(hwnd, L"鼠标左键点击", L"提示", MB_OK); // 显示关闭提示
SendMessageW(hwnd, WM_USERMSG, 0, 0);
break;
case WM_USERMSG: //收到自定义消息时触发
MessageBoxW(hwnd, L"自定义消息触发", L"提示", MB_OK);
case WM_RBUTTONDOWN: // 鼠标右键点击时触发
MessageBoxW(hwnd, L"鼠标右键点击", L"提示", MB_OK); // 显示关闭提示
SendMessageW((HWND)0x00010B4E, WM_CLOSE, 0, 0); //给qq窗口的句柄发送消息,让它关掉。
break;
default: // 其他未处理的消息交给默认处理函数
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0; // 已处理的消息返回0
}