一个有用的Win32消息处理宏HANDLE_MSG

Posted clever101

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个有用的Win32消息处理宏HANDLE_MSG相关的知识,希望对你有一定的参考价值。

作者:朱金灿
来源:clever101的专栏

为什么大多数人学不会人工智能编程?>>>

Win32开发消息处理的常见结构

  Win32的消息处理函数的代码结构一般如下:

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    switch (message)
    
    case WM_COMMAND:
        
            int wmId = LOWORD(wParam);
            // 分析菜单选择: 
            switch (wmId)
            
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            
        
        break;
    case WM_PAINT:
        
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    
    return 0;

  可以看出WndProc函数有两个弊端:一是不同的消息开不同的分支,非常容易导致代码膨胀;二是消息处理所需要的两个参数wParam和 lParam的类型需要针对不同的消息类型进行转化。

HANDLE_MSG宏介绍

  在windowsx.h上我找到一个宏HANDLE_MSG,发现它针对了这种情况做了有效处理,具体代码如下:

#define HANDLE_MSG(hwnd, message, fn)    \\
    case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))
/* BOOL Cls_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) */
#define HANDLE_WM_CREATE(hwnd, wParam, lParam, fn) \\
    ((fn)((hwnd), (LPCREATESTRUCT)(lParam)) ? 0L : (LRESULT)-1L)

  你可以看到它是针对不同的消息进行了不同的参数转换之后再连接到具体的处理函数。以上面的代码为例,可以用HANDLE_MSG进行一番改造:

//((fn)((hwnd), (int)(LOWORD(wParam)), (HWND)(lParam), (UINT)HIWORD(wParam)), 0L)
void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify)

	switch (id)
	
	case IDM_ABOUT:
		DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
		break;
	case IDM_EXIT:
		DestroyWindow(hWnd);
		break;
	default:
		return;
	


/* void OnPaint(HWND hWnd) */
void OnPaint(HWND hWnd)

	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	// TODO: 在此处添加使用 hdc 的任何绘图代码...
	EndPaint(hWnd, &ps);


void OnDestroy(HWND hWnd)

	PostQuitMessage(0);


//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

	switch (message)
	
		HANDLE_MSG(hWnd, WM_COMMAND, OnCommand);
		HANDLE_MSG(hWnd, WM_PAINT, OnPaint);
		HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);

	    default: return DefWindowProc(hWnd, message, wParam, lParam);
	
	return 0;

  如果你不知道HANDLE_MSG对应的各种的消息响应函数原型如何写,可以在windowsx.h中搜索。

以上是关于一个有用的Win32消息处理宏HANDLE_MSG的主要内容,如果未能解决你的问题,请参考以下文章

Win32 消息处理程序错误传播

win32 Message(MSG)消息处理

Win32 处理多个按钮共用一个事件消息

Win10关机提示此应用程序阻止关机怎么处理

WIN32_LEAN_AND_MEAN 含义以及用法

win32中窗口程序的运行过程