winapi实现自定义消息处理类

上一篇介绍了如何实现主窗口界面的创建,接下来创建一个消息处理类,可以实现各种消息的可视化显示,使我们熟悉界面变化时出现的各种消息,为以后的开发打下基础。
这里创建了类WindowsMessageMap.h

#pragma once
#include<unordered_map>
#include<string>
#include<Windows.h>
class WindowsMessageMap
{
public:
	WindowsMessageMap() noexcept;
	std::string operator()(DWORD msg, LPARAM lp, WPARAM wp) const noexcept;//重载()
private:
	std::unordered_map<DWORD, std::string> map;//创建数据存储
};

WindowsMessageMap.cpp

#include "WindowsMessageMap.h"
#include <string>
#include <sstream>
#include <iomanip>

// secret messages
#define WM_UAHDESTROYWINDOW 0x0090
#define WM_UAHDRAWMENU 0x0091
#define WM_UAHDRAWMENUITEM 0x0092
#define WM_UAHINITMENU 0x0093
#define WM_UAHMEASUREMENUITEM 0x0094
#define WM_UAHNCPAINTMENUPOPUP 0x0095

#define REGISTER_MESSAGE(msg){msg,#msg}将msg与名称保持对应并存在map中
//这些定义可以在官方手册中查出
WindowsMessageMap::WindowsMessageMap() noexcept
	:
	map({
		REGISTER_MESSAGE(WM_CREATE),
		REGISTER_MESSAGE(WM_DESTROY),
		REGISTER_MESSAGE(WM_MOVE),
		REGISTER_MESSAGE(WM_SIZE),
		REGISTER_MESSAGE(WM_ACTIVATE),
		REGISTER_MESSAGE(WM_SETFOCUS),
		REGISTER_MESSAGE(WM_KILLFOCUS),
		REGISTER_MESSAGE(WM_ENABLE),
		REGISTER_MESSAGE(WM_SETREDRAW),
		REGISTER_MESSAGE(WM_SETTEXT),
		REGISTER_MESSAGE(WM_GETTEXT),
		REGISTER_MESSAGE(WM_GETTEXTLENGTH),
		REGISTER_MESSAGE(WM_PAINT),
		REGISTER_MESSAGE(WM_CLOSE),
		REGISTER_MESSAGE(WM_QUERYENDSESSION),
		REGISTER_MESSAGE(WM_QUIT),
		REGISTER_MESSAGE(WM_QUERYOPEN),
		REGISTER_MESSAGE(WM_ERASEBKGND),
		REGISTER_MESSAGE(WM_SYSCOLORCHANGE),
		REGISTER_MESSAGE(WM_ENDSESSION),
		REGISTER_MESSAGE(WM_SHOWWINDOW),
		REGISTER_MESSAGE(WM_CTLCOLORMSGBOX),
		REGISTER_MESSAGE(WM_CTLCOLOREDIT),
		REGISTER_MESSAGE(WM_CTLCOLORLISTBOX),
		REGISTER_MESSAGE(WM_CTLCOLORBTN),
		REGISTER_MESSAGE(WM_CTLCOLORDLG),
		REGISTER_MESSAGE(WM_CTLCOLORSCROLLBAR),
		REGISTER_MESSAGE(WM_CTLCOLORSTATIC),
		REGISTER_MESSAGE(WM_WININICHANGE),
		REGISTER_MESSAGE(WM_SETTINGCHANGE),
		REGISTER_MESSAGE(WM_DEVMODECHANGE),
		REGISTER_MESSAGE(WM_ACTIVATEAPP),
		REGISTER_MESSAGE(WM_FONTCHANGE),
		REGISTER_MESSAGE(WM_TIMECHANGE),
		REGISTER_MESSAGE(WM_CANCELMODE),
		REGISTER_MESSAGE(WM_SETCURSOR),
		REGISTER_MESSAGE(WM_MOUSEACTIVATE),
		REGISTER_MESSAGE(WM_CHILDACTIVATE),
		REGISTER_MESSAGE(WM_QUEUESYNC),
		REGISTER_MESSAGE(WM_GETMINMAXINFO),
		REGISTER_MESSAGE(WM_ICONERASEBKGND),
		REGISTER_MESSAGE(WM_NEXTDLGCTL),
		REGISTER_MESSAGE(WM_SPOOLERSTATUS),
		REGISTER_MESSAGE(WM_DRAWITEM),
		REGISTER_MESSAGE(WM_MEASUREITEM),
		REGISTER_MESSAGE(WM_DELETEITEM),
		REGISTER_MESSAGE(WM_VKEYTOITEM),
		REGISTER_MESSAGE(WM_CHARTOITEM),
		REGISTER_MESSAGE(WM_SETFONT),
		REGISTER_MESSAGE(WM_GETFONT),
		REGISTER_MESSAGE(WM_QUERYDRAGICON),
		REGISTER_MESSAGE(WM_COMPAREITEM),
		REGISTER_MESSAGE(WM_COMPACTING),
		REGISTER_MESSAGE(WM_NCCREATE),
		REGISTER_MESSAGE(WM_NCDESTROY),
		REGISTER_MESSAGE(WM_NCCALCSIZE),
		REGISTER_MESSAGE(WM_NCHITTEST),
		REGISTER_MESSAGE(WM_NCPAINT),
		REGISTER_MESSAGE(WM_NCACTIVATE),
		REGISTER_MESSAGE(WM_GETDLGCODE),
		REGISTER_MESSAGE(WM_NCMOUSEMOVE),
		REGISTER_MESSAGE(WM_NCLBUTTONDOWN),
		REGISTER_MESSAGE(WM_NCLBUTTONUP),
		REGISTER_MESSAGE(WM_NCLBUTTONDBLCLK),
		REGISTER_MESSAGE(WM_NCRBUTTONDOWN),
		REGISTER_MESSAGE(WM_NCRBUTTONUP),
		REGISTER_MESSAGE(WM_NCRBUTTONDBLCLK),
		REGISTER_MESSAGE(WM_NCMBUTTONDOWN),
		REGISTER_MESSAGE(WM_NCMBUTTONUP),
		REGISTER_MESSAGE(WM_NCMBUTTONDBLCLK),
		REGISTER_MESSAGE(WM_KEYDOWN),
		REGISTER_MESSAGE(WM_KEYUP),
		REGISTER_MESSAGE(WM_CHAR),
		REGISTER_MESSAGE(WM_DEADCHAR),
		REGISTER_MESSAGE(WM_SYSKEYDOWN),
		REGISTER_MESSAGE(WM_SYSKEYUP),
		REGISTER_MESSAGE(WM_SYSCHAR),
		REGISTER_MESSAGE(WM_SYSDEADCHAR),
		REGISTER_MESSAGE(WM_KEYLAST),
		REGISTER_MESSAGE(WM_INITDIALOG),
		REGISTER_MESSAGE(WM_COMMAND),
		REGISTER_MESSAGE(WM_SYSCOMMAND),
		REGISTER_MESSAGE(WM_TIMER),
		REGISTER_MESSAGE(WM_HSCROLL),
		REGISTER_MESSAGE(WM_VSCROLL),
		REGISTER_MESSAGE(WM_INITMENU),
		REGISTER_MESSAGE(WM_INITMENUPOPUP),
		REGISTER_MESSAGE(WM_MENUSELECT),
		REGISTER_MESSAGE(WM_MENUCHAR),
		REGISTER_MESSAGE(WM_ENTERIDLE),
		REGISTER_MESSAGE(WM_MOUSEWHEEL),
		REGISTER_MESSAGE(WM_MOUSEMOVE),
		REGISTER_MESSAGE(WM_LBUTTONDOWN),
		REGISTER_MESSAGE(WM_LBUTTONUP),
		REGISTER_MESSAGE(WM_LBUTTONDBLCLK),
		REGISTER_MESSAGE(WM_RBUTTONDOWN),
		REGISTER_MESSAGE(WM_RBUTTONUP),
		REGISTER_MESSAGE(WM_RBUTTONDBLCLK),
		REGISTER_MESSAGE(WM_MBUTTONDOWN),
		REGISTER_MESSAGE(WM_MBUTTONUP),
		REGISTER_MESSAGE(WM_MBUTTONDBLCLK),
		REGISTER_MESSAGE(WM_PARENTNOTIFY),
		REGISTER_MESSAGE(WM_MDICREATE),
		REGISTER_MESSAGE(WM_MDIDESTROY),
		REGISTER_MESSAGE(WM_MDIACTIVATE),
		REGISTER_MESSAGE(WM_MDIRESTORE),
		REGISTER_MESSAGE(WM_MDINEXT),
		REGISTER_MESSAGE(WM_MDIMAXIMIZE),
		REGISTER_MESSAGE(WM_MDITILE),
		REGISTER_MESSAGE(WM_MDICASCADE),
		REGISTER_MESSAGE(WM_MDIICONARRANGE),
		REGISTER_MESSAGE(WM_MDIGETACTIVE),
		REGISTER_MESSAGE(WM_MDISETMENU),
		REGISTER_MESSAGE(WM_CUT),
		REGISTER_MESSAGE(WM_COPYDATA),
		REGISTER_MESSAGE(WM_COPY),
		REGISTER_MESSAGE(WM_PASTE),
		REGISTER_MESSAGE(WM_CLEAR),
		REGISTER_MESSAGE(WM_UNDO),
		REGISTER_MESSAGE(WM_RENDERFORMAT),
		REGISTER_MESSAGE(WM_RENDERALLFORMATS),
		REGISTER_MESSAGE(WM_DESTROYCLIPBOARD),
		REGISTER_MESSAGE(WM_DRAWCLIPBOARD),
		REGISTER_MESSAGE(WM_PAINTCLIPBOARD),
		REGISTER_MESSAGE(WM_VSCROLLCLIPBOARD),
		REGISTER_MESSAGE(WM_SIZECLIPBOARD),
		REGISTER_MESSAGE(WM_ASKCBFORMATNAME),
		REGISTER_MESSAGE(WM_CHANGECBCHAIN),
		REGISTER_MESSAGE(WM_HSCROLLCLIPBOARD),
		REGISTER_MESSAGE(WM_QUERYNEWPALETTE),
		REGISTER_MESSAGE(WM_PALETTEISCHANGING),
		REGISTER_MESSAGE(WM_PALETTECHANGED),
		REGISTER_MESSAGE(WM_DROPFILES),
		REGISTER_MESSAGE(WM_POWER),
		REGISTER_MESSAGE(WM_WINDOWPOSCHANGED),
		REGISTER_MESSAGE(WM_WINDOWPOSCHANGING),
		REGISTER_MESSAGE(WM_HELP),
		REGISTER_MESSAGE(WM_NOTIFY),
		REGISTER_MESSAGE(WM_CONTEXTMENU),
		REGISTER_MESSAGE(WM_TCARD),
		REGISTER_MESSAGE(WM_MDIREFRESHMENU),
		REGISTER_MESSAGE(WM_MOVING),
		REGISTER_MESSAGE(WM_STYLECHANGED),
		REGISTER_MESSAGE(WM_STYLECHANGING),
		REGISTER_MESSAGE(WM_SIZING),
		REGISTER_MESSAGE(WM_SETHOTKEY),
		REGISTER_MESSAGE(WM_PRINT),
		REGISTER_MESSAGE(WM_PRINTCLIENT),
		REGISTER_MESSAGE(WM_POWERBROADCAST),
		REGISTER_MESSAGE(WM_HOTKEY),
		REGISTER_MESSAGE(WM_GETICON),
		REGISTER_MESSAGE(WM_EXITMENULOOP),
		REGISTER_MESSAGE(WM_ENTERMENULOOP),
		REGISTER_MESSAGE(WM_DISPLAYCHANGE),
		REGISTER_MESSAGE(WM_STYLECHANGED),
		REGISTER_MESSAGE(WM_STYLECHANGING),
		REGISTER_MESSAGE(WM_GETICON),
		REGISTER_MESSAGE(WM_SETICON),
		REGISTER_MESSAGE(WM_SIZING),
		REGISTER_MESSAGE(WM_MOVING),
		REGISTER_MESSAGE(WM_CAPTURECHANGED),
		REGISTER_MESSAGE(WM_DEVICECHANGE),
		REGISTER_MESSAGE(WM_PRINT),
		REGISTER_MESSAGE(WM_PRINTCLIENT),
		REGISTER_MESSAGE(WM_IME_SETCONTEXT),
		REGISTER_MESSAGE(WM_IME_NOTIFY),
		REGISTER_MESSAGE(WM_NCMOUSELEAVE),
		REGISTER_MESSAGE(WM_EXITSIZEMOVE),
		REGISTER_MESSAGE(WM_UAHDESTROYWINDOW),
		REGISTER_MESSAGE(WM_DWMNCRENDERINGCHANGED),
		REGISTER_MESSAGE(WM_ENTERSIZEMOVE),
		})
{}

std::string WindowsMessageMap::operator()(DWORD msg, LPARAM lp, WPARAM wp) const noexcept
{
	constexpr int firstColWidth = 25;
	const auto i = map.find(msg);//查找msg是否在map中

	std::ostringstream oss;
	if (i != map.end())//存在则输出对应的名称
	{
		oss << std::left << std::setw(firstColWidth) << i->second << std::right;
	}
	else
	{//否则表示该信息未收录在自定的map中
		std::ostringstream padss;
		padss << "Unknown message: 0x" << std::hex << msg;
		oss << std::left << std::setw(firstColWidth) << padss.str() << std::right;
	}
	//输出lp和wp代表的信息
	oss << "   LP: 0x" << std::hex << std::setfill('0') << std::setw(8) << lp;
	oss << "   WP: 0x" << std::hex << std::setfill('0') << std::setw(8) << wp << std::endl;

	return oss.str();
}

上面的类主要是实现消息的翻译,将接受的消息转化为我们更加熟悉的字符串。具体介绍已经注释标出,下面我们创建一个自定义的消息处理程序记作wndproc

LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	static WindowsMessageMap mm;//调用msg翻译类
	OutputDebugString( mm(msg, lparam, wparam).c_str());//将传入的信息进行翻译,可以看到wparam和lparam数据
	switch (msg)
	{
	case WM_CLOSE:
		PostQuitMessage(69);
		break;
	case WM_KEYDOWN://键盘按键是否按下
		if (wparam == 'F');//是否是F键
		{
			SetWindowText(hwnd,"keydown");//将窗口标题设置为keydown
		}
		break;
	case WM_KEYUP://按键松开的消息
		if (wparam == 'F');
		{
			SetWindowText(hwnd, "keyup");
		}
		break;
	case WM_CHAR://数据传入
	{
		static std::string title;
		title.push_back((char)wparam);
		SetWindowText(hwnd, title.c_str());
		break;
	}
		
	case WM_LBUTTONDOWN://鼠标左键按下
	{
		const POINTS pt = MAKEPOINTS(lparam);//32位其中高16位和低16位组合成坐标位置,每个msg代表信息不同,因此输出之后更加清晰
		std::ostringstream otsting;
		otsting << "(" << pt.x << "," << pt.y << ")";
		SetWindowText(hwnd, otsting.str().c_str());//标题设置为目前鼠标的坐标
		break;
	}
	}

	return DefWindowProc(hwnd, msg, wparam, lparam);
}

主程序如下,主要是将自定义消息处理函数绑定,替换默认处理函数

int CALLBACK WinMain( HINSTANCE hinstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	
	const auto pclassname = "hw3dbutts";
	WNDCLASSEX wc = { 0 };
	wc.cbSize = sizeof(wc);
	wc.style = CS_OWNDC;
	wc.lpfnWndProc = wndproc;//将自定义消息处理函数绑定,替换默认处理函数
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hinstance;
	wc.hIcon = nullptr;
	wc.hCursor = nullptr;
	wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
	wc.lpszMenuName = nullptr;
	wc.lpszClassName = pclassname;
	wc.hIconSm = nullptr;

	RegisterClassEx(&wc);

	HWND hd;
	hd = CreateWindowExA(0,pclassname,"windows test",WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU,200,200,640,480,nullptr,nullptr
	,hinstance,nullptr);
	ShowWindow(hd, SW_SHOW);
	MSG msg;
	while (GetMessage(&msg, nullptr, 0, 0) > 0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);

	}
	return 0;
}

运行结果如下
在这里插入图片描述
由图可知此实鼠标左键点击触发msg信号WM_LBUTTONDOWN,msg传入的lparam和wparam经过我们的翻译类可以在左下角看到,其中lp为0x00890137,wp为0x00000001
对于鼠标主要是看lp参数,由进制转换可以得到
在这里插入图片描述
在这里插入图片描述
刚好得到鼠标此时的坐标

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值