窗口类封装之--窗口对象消息处理的映射方法(1)

对界面进行封装,一般都是一个窗口一个类,比如实现一个最基本的窗口类CMyWnd,你一定会把窗口过程作为这个类的成员函数,但是使用WINAPI创建窗口时必须注册类WNDCLASS,里面有个成员数据lpfnWndProc需要WNDPROC的函数指针,一般想法就是把窗口类的消息处理函数指针传过去,使用静态类成员函数,或者全局的消息处理函数,否则无法转换到WNDPROC。

静态消息处理函数:缺点,消息处理函数无法获取到窗口对象的窗口句柄。

全局消息处理函数:无法得到窗口类对象指针。

一种解决方法是用窗口列表,开一个结构数组,窗口类对象创建窗口的时候把窗口HWND和this指针放入数组,全局消息处理函数遍历数组,利用HWND找出this指针,然后定位到对象内部的消息处理函数。这种方法查找对象的时间会随着窗口个数的增多而增长。代码如下:

#ifndef _WINDOW_H_
#define _WINDOW_H_
#include "stdafx.h"
#include "Resource.h"
#include <map>
class window{
public:
    window():_hwnd(NULL){}
    ~window(){}
    bool Create(HINSTANCE hInstance,const LPCTSTR lpszClassName);
protected:
    HWND _hwnd;
private:
    LRESULT CALLBACK WndProc(UINT message, WPARAM wParam, LPARAM lParam);
    void RemoveHwndFormMap();
     
protected:
    static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static std::map<HWND,window*>* _sWindowMap;
};
 
 
std::map<HWND,window*>* window::_sWindowMap = new std::map<HWND,window*>;
 
bool window::Create(HINSTANCE hInstance,LPCTSTR lpszClassName)
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = StaticWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_TEST);
    wcex.lpszClassName  = lpszClassName;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    RegisterClassEx(&wcex);
 
    _hwnd = CreateWindow(lpszClassName, NULL, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
 
    if (_hwnd == NULL)
    {
        MessageBox(NULL,TEXT("Error"),NULL,NULL);
        return FALSE;
    }
 
    //_sWindowMap[_hwnd] = this;
    (*_sWindowMap).insert(std::make_pair(_hwnd,this));
 
    ShowWindow(_hwnd, SW_SHOW);
    UpdateWindow(_hwnd);
    return TRUE;
 
}
LRESULT CALLBACK window::StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 
    if ((*_sWindowMap).empty())
    {
        return ::DefWindowProcW(hWnd, message, wParam, lParam);
    }else
        return (*_sWindowMap)[hWnd]->WndProc(  message,  wParam, lParam);
}
 
LRESULT CALLBACK window::WndProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            //DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            MessageBox(NULL,TEXT("AboutDlg"),TEXT("关于"),NULL);
            break;
        case IDM_EXIT:
            DestroyWindow(_hwnd);
            RemoveHwndFormMap();
            break;
        default:
            return DefWindowProc(_hwnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(_hwnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(_hwnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        RemoveHwndFormMap();
        break;
    default:
        return ::DefWindowProc(_hwnd, message, wParam, lParam);
    }
    return 0;
 
}
 
void window::RemoveHwndFormMap()
{
    std::map<HWND,window*>::iterator it;
    it = (*_sWindowMap).find(_hwnd);
    (*_sWindowMap).erase(it);
 
}
 
#endif

posted on   Pro.Charm  阅读(1069)  评论(0编辑  收藏  举报

编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档

导航

< 2011年4月 >
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
1 2 3 4 5 6 7

统计

点击右上角即可分享
微信分享提示