C++-win32-SendMessage-最简单的进程间消息传递-消息钩子

文章目录

    • 1.WH_CALLWNDPROC-窗口消息钩子
    • 2.同进程消息传递
    • 3.CDR使用线程消息钩子

1.WH_CALLWNDPROC-窗口消息钩子

//Hook窗口过程
static HHOOK ghWindowHook = NULL;
static HWND  ghMainWindow = NULL;

//窗口函数
static LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	//无需处理的hook
	if (nCode < 0)
	{
		return CallNextHookEx(ghWindowHook, nCode, wParam, lParam);
	}

	//按nCode处理
	switch (nCode)
	{
	case HC_ACTION:
	{
		SendMessage2MainWindow::AlertOpt(lParam, ghMainWindow);
		break;
	}
	default:
		break;
	}

	return CallNextHookEx(ghWindowHook, nCode, wParam, lParam);
}


static BOOL SetWndHook()
{
	ghWindowHook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, NULL, GetCurrentThreadId());
	int err = GetLastError();
	//Console << err << (int)ghWindowHook;
	return ghWindowHook != NULL;
}

static BOOL EndWndHook()
{
	return UnhookWindowsHookEx(ghWindowHook);
}

2.同进程消息传递

SendMessage2MainWindow.h

#pragma once
#include 
#include 
class SendMessage2MainWindow
{
public:
	SendMessage2MainWindow();
	~SendMessage2MainWindow();

	//提示消息
	static void Alert(std::string lpText, std::string lpCaption, UINT uType);
	//主窗口接受消息处理
	static void AlertOpt(LPARAM lParam, HWND dstHwnd = NULL);
};

SendMessage2MainWindow.cpp

#include "SendMessage2MainWindow.h"

#include 
#include "jsoncpp/json.h"

#define BUFF_LEN_SMMW 1024

//窗口消息
typedef struct tagWNDINFO
{
	DWORD dwProcessId;
	HWND hWnd;
} WNDINFO, *LPWNDINFO;

//枚举窗口过程
static BOOL CALLBACK EnumProc(HWND hWnd, LPARAM lParam)
{
	//遍历窗口
	DWORD dwProcessId;
	GetWindowThreadProcessId(hWnd, &dwProcessId);//检索创建指定窗口的线程的标识符,以及创建该窗口的进程(可选)的标识符。
	LPWNDINFO pInfo = (LPWNDINFO)lParam;

	if (dwProcessId == pInfo->dwProcessId)
	{
		pInfo->hWnd = hWnd;
		return FALSE;//退出循环-查找与进程相关的第一个窗口
	}
	return TRUE;
}

//获取主窗口句柄
static HWND GetProcessFirstWnd()
{
	DWORD dwProcessId = ::GetCurrentProcessId();
	WNDINFO wi;
	wi.dwProcessId = dwProcessId;
	wi.hWnd = NULL;
	EnumWindows(EnumProc, (LPARAM)&wi);
	return wi.hWnd;
}


SendMessage2MainWindow::SendMessage2MainWindow()
{

}


SendMessage2MainWindow::~SendMessage2MainWindow()
{

}

//发送数据
void SendMessage2MainWindow::Alert(std::string lpText, std::string lpCaption, UINT uType){
	//主窗口句柄
	HWND mainHwnd = GetProcessFirstWnd();
	::MessageBoxA(mainHwnd, lpText.c_str(), lpCaption.c_str(), uType);
	return;

	//分配堆栈数据
	int datalen = BUFF_LEN_SMMW;
	char *buff = (char *)malloc(datalen);
	memset(buff, 0, datalen);

	//格式化数据
	Json::Value root;
	root["lpText"] = lpText;
	root["lpCaption"] = lpCaption;
	root["uType"] = uType;
	std::string rootStr = root.toStyledString();

	//复制数据到缓存
	strcpy(buff, rootStr.c_str());
	//发送数据
	UINT customMsg = WM_USER + 16;
	::SendMessage(mainHwnd, customMsg, 0, (LPARAM)buff);

	//读取结果
	Json::Value result;
	Json::Reader reader;
	std::string returnBuff = buff;
	if (!reader.parse(returnBuff, result)) {
		return;
	}
	std::string state = result["State"].asString();

	//释放数据
	free(buff);
}

//主窗口接受消息处理
void SendMessage2MainWindow::AlertOpt(LPARAM lParam,HWND dstHwnd){
	//转为消息格式
	CWPSTRUCT* pCWPSTRUCT = (CWPSTRUCT*)lParam;

	//获取窗口句柄
	HWND hWnd = pCWPSTRUCT->hwnd;
	UINT msg = pCWPSTRUCT->message;
	char* strBuff = (char*)pCWPSTRUCT->lParam;	

	//目标窗口
	UINT customMsg = WM_USER + 16;
	//if (hWnd == dstHwnd)//窗口过滤
	{
		if (customMsg == msg)//消息过滤
		{
			//数据为空直接返回
			if (!strBuff)
			{
				return;
			}

			//解析数据
			Json::Value infoJV, result;
			Json::Reader reader;
			std::string infoStr = strBuff;
			if (!reader.parse(infoStr, infoJV)) {
				//结果写入
				result["State"] = false;
				std::string resultStr = result.toStyledString();
				memset(strBuff, 0, BUFF_LEN_SMMW);
				strcpy(strBuff, resultStr.c_str());
				return;
			}

			::MessageBoxA(hWnd, infoJV["lpText"].asString().c_str(), infoJV["lpCaption"].asString().c_str(), infoJV["uType"].asUInt());

			//结果写入
			{
				result["State"] = true;
				std::string resultStr = result.toStyledString();
				memset(strBuff, 0, BUFF_LEN_SMMW);
				strcpy(strBuff, resultStr.c_str());
				return;
			}
		}		
	}
}

3.CDR使用线程消息钩子

使用消息钩子会出现bug。

你可能感兴趣的:(C++,Windows,c++,开发语言)