zoukankan      html  css  js  c++  java
  • WIN32 窗口封装类实现

    CQWnd.h窗口类定义

    // QWnd.h: interface for the CQWnd class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #if !defined(AFX_QWND_H__9158FC5D_DF60_450D_8BE4_270C74A4F256__INCLUDED_)
    #define AFX_QWND_H__9158FC5D_DF60_450D_8BE4_270C74A4F256__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include <windows.h>
    #include <assert.h>
    
    //定义消息映射宏
    #define QWND_DECLARE_MESSAGE_MAP(cls) public:virtual BOOL DispatchWindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam);
    #define QWND_BEGIN_MESSAGE_MAP(cls,base_cls) BOOL cls::DispatchWindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam){
    #define QWND_MESSAGE_MAP(id,fun) if(uMsg==id){return fun(uMsg,wParam,lParam);}
    #define QWND_MESSAGE_CHAIN_MAP(id,cls) if(uMsg==id){return cls::DispatchWindowProc(id,wParam,lParam);}
    #define QWND_END_MESSAGE_MAP() return CQWnd::DispatchWindowProc(uMsg,wParam,lParam);}
    #define QWND_END_MESSAGE_DEFAULT_MAP() return DefaultWindowProc(uMsg,wParam,lParam);}
    #define QWND_END_MESSAGE_SYS_MAP() return ::DefWindowProc(m_hWnd,uMsg,wParam,lParam);}
    #define QWND_COMMAND_CODE_MAP(code,fun) if(uMsg == WM_COMMAND && code == HIWORD(wParam)){return fun(hWnd,uMsg,wParam,lParam);}  
    #define QWND_COMMAND_ID_MAP(id,fun) if(uMsg == WM_COMMAND && id == LOWORD(wParam)){return fun(hWnd,uMsg,wParam,lParam);}  
    #define QWND_COMMAND_MAP(id,code,fun) if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)){return fun(hWnd,uMsg,wParam,lParam);}  
    //框架支持全局函数
    WNDPROC GetSuperWndProcAddr();
    //纯虚函数接口完成消息映射
    class IMessageMap{
    public:
        virtual BOOL DispatchWindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam)=0;
    };
    
    class ICommandMap{
    public:
        virtual HRESULT DisCommand(UINT uMsg,WPARAM wParam,LPARAM lParam)=0;
    };
    
    //窗口基类
    class CQWnd:public IMessageMap{
    QWND_DECLARE_MESSAGE_MAP(CQWnd)
    public:
        CQWnd();
        virtual ~CQWnd();
    public:
        BOOL Attach(HWND hWnd);
        BOOL CreateEx(DWORD dwExStyle,LPCTSTR lpszClassName,LPCTSTR lpszWindowName,DWORD dwStyle,int x,int y,int cx,int cy,CQWnd* hParent,HMENU mMenu,HINSTANCE hInstance);
        BOOL CenterWindow(BOOL bRepaint=TRUE);
        BOOL Detach(void);
        BOOL DestoryWindow();
        BOOL EnableWindow(BOOL bEnable);
        BOOL GetWindowRect(LPRECT lpRect);
        BOOL GetClientRect(LPRECT lpRect);
        BOOL IsWindowVisible();
        //获取句柄相关窗口对象
        CQWnd* GetWndFromHandle(HWND hWnd);
        BOOL MoveWindow(int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
        BOOL ShowWindow(int nCmdShow);
        BOOL SetWindowText(LPCSTR lpString);
        BOOL SetMenu(HMENU hMenu);
        BOOL SubClassWindow(HWND hWnd);
        BOOL UpdateWindow(void);
        //虚函数定义预知消息
        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
        virtual HRESULT OnCreate(UINT uMsg,WPARAM wParam, LPARAM lParam);
        virtual HRESULT OnClose(UINT uMsg,WPARAM wParam, LPARAM lParam);
        virtual HRESULT OnDestroy(UINT uMsg,WPARAM wParam, LPARAM lParam);
        virtual HRESULT OnNcDestroy(UINT uMsg,WPARAM wParam, LPARAM lParam);
        virtual HRESULT OnNcCreate(UINT uMsg,WPARAM wParam, LPARAM lParam);
        virtual HRESULT OnCommand(UINT uMsg,WPARAM wParam, LPARAM lParam);
        virtual BOOL DefaultWindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam);
    public:
        //静态函数处理窗口函数过程
        static LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
    public:
        //封装窗口句柄
        HWND m_hWnd;
        //原窗口处理函数
        WNDPROC m_lpfnOldWndProc;
    protected:
        CQWnd* m_hParent;
    private:
        BOOL m_bReg;
        BOOL m_bEnableNcCreate;
    };
    
    #endif // !defined(AFX_QWND_H__9158FC5D_DF60_450D_8BE4_270C74A4F256__INCLUDED_)

    CQWnd.cpp窗口类实现

    // QWnd.cpp: implementation of the CQWnd class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include "stdafx.h"
    #include "QWnd.h"
    
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    
    QWND_BEGIN_MESSAGE_MAP(CQWnd,NULL)
        QWND_MESSAGE_MAP(WM_CREATE,CQWnd::OnCreate)
        QWND_MESSAGE_MAP(WM_CLOSE,CQWnd::OnClose)
        QWND_MESSAGE_MAP(WM_DESTROY,CQWnd::OnDestroy)
        QWND_MESSAGE_MAP(WM_NCDESTROY,CQWnd::OnNcDestroy)
        QWND_MESSAGE_MAP(WM_NCCREATE,CQWnd::OnNcCreate)
        QWND_MESSAGE_MAP(WM_COMMAND,CQWnd::OnCommand)
    QWND_END_MESSAGE_DEFAULT_MAP()
    
    CQWnd::CQWnd(){
        m_hWnd=NULL;
        m_lpfnOldWndProc=NULL;
        m_bReg=FALSE;
        m_hParent=NULL;
        m_bEnableNcCreate=FALSE;
    }
    
    CQWnd::~CQWnd(){
    }
    
    BOOL CQWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowName,DWORD dwStyle,int x,int y,int cx,int cy,CQWnd* hParent,HMENU hMenu,HINSTANCE hInstance){
        CREATESTRUCT cs;
        m_hParent=hParent;
        //窗口额外空间(包含当前对象this指针)
        cs.lpCreateParams=(LPVOID)this;
        cs.hInstance=hInstance;
        cs.hMenu=hMenu;
        cs.hwndParent=m_hParent?m_hParent->m_hWnd:NULL;
        cs.cx=cx;
        cs.cy=cy;
        cs.x=x;
        cs.y=y;
        cs.style=dwStyle;
        cs.lpszName=lpszWindowName;
        cs.lpszClass=lpszClassName;
        cs.dwExStyle=dwExStyle;
        BOOL ret=PreCreateWindow(cs);
        assert(ret);
        m_hWnd=CreateWindowEx(cs.dwExStyle,cs.lpszClass,cs.lpszName,cs.style,cs.x,cs.y,cs.cx,cs.cy,cs.hwndParent,cs.hMenu,cs.hInstance,cs.lpCreateParams);
        if(NULL==m_hWnd)
            return FALSE;
        m_lpfnOldWndProc=(WNDPROC)::GetWindowLong(m_hWnd,GWL_WNDPROC);
        if(m_bReg){
            //已注册窗口完成窗口数据更新
            if(m_lpfnOldWndProc!=CQWnd::WindowProc){
                ::SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)CQWnd::WindowProc);
                ::SetWindowLong(m_hWnd,GWL_USERDATA,(LONG)this);
                //发送消息WM_NCCREATE,WM_CREATE,因为已注册窗口第一次发送至默认处理过程无法截取
                if(m_bEnableNcCreate)
                    ::SendMessage(m_hWnd,WM_NCCREATE,0,(LONG)&cs);
                ::SendMessage(m_hWnd,WM_CREATE,0,(LONG)&cs);
            }
        }
        return TRUE;
    }
    
    BOOL CQWnd::PreCreateWindow(CREATESTRUCT& cs){
        //判断窗口是否已经注册
        WNDCLASSEX wcex;
        ZeroMemory(&wcex,sizeof(WNDCLASSEX));
        wcex.cbSize=sizeof(WNDCLASSEX);
        if(GetClassInfoEx(cs.hInstance,cs.lpszClass,&wcex)){
            m_bReg=TRUE;
            return TRUE;
        }
            
        //已注册则直接返回,未注册则注册新的窗口(结构体每项都需要赋值)
        wcex.cbSize=sizeof(WNDCLASSEX);
        wcex.style=CS_HREDRAW|CS_VREDRAW;
        wcex.lpfnWndProc=CQWnd::WindowProc;
        wcex.cbClsExtra=0;
        wcex.cbWndExtra=0;
        wcex.hIcon=::LoadIcon(NULL,IDI_APPLICATION);
        wcex.hIconSm=::LoadIcon(NULL,IDI_WINLOGO);
        wcex.hCursor=::LoadCursor(NULL,IDC_ARROW);
        wcex.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH);
        wcex.lpszMenuName=NULL;
        wcex.hInstance=cs.hInstance;
        wcex.lpszClassName=cs.lpszClass;
        return ::RegisterClassEx(&wcex);
    }
    
    
    LRESULT CALLBACK CQWnd::WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
        if(WM_NCCREATE==uMsg){
            //取出结构,第一次发送WM_NCCREATE消息设置SetWindowLong
            CREATESTRUCT* pCs=(CREATESTRUCT*)lParam;
            if(pCs){
                CQWnd* pWnd=(CQWnd*)pCs->lpCreateParams;
                if(pWnd){
                    //首次为句柄赋值
                    pWnd->m_hWnd=hWnd;
                    //此处必须赋值
                    pWnd->m_lpfnOldWndProc=(WNDPROC)::GetWindowLong(hWnd,GWL_WNDPROC);
                    SetWindowLong(hWnd,GWL_USERDATA,(LONG)pWnd);
                    return pWnd->DispatchWindowProc(uMsg,wParam,lParam);
                }
            }
        }else{
            //取出上次SetWindowLong对象
            CQWnd* pWnd=(CQWnd*)GetWindowLong(hWnd,GWL_USERDATA);
            if(pWnd){
                return pWnd->DispatchWindowProc(uMsg,wParam,lParam);
            }
        }
        return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
    }
    
    //默认消息处理函数
    BOOL CQWnd::DefaultWindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam){
        if(m_lpfnOldWndProc!=CQWnd::WindowProc)
            return ::CallWindowProc(m_lpfnOldWndProc,m_hWnd,uMsg,wParam,lParam);
        return ::DefWindowProc(m_hWnd,uMsg,wParam,lParam);
    }
    
    HRESULT CQWnd::OnCommand(UINT uMsg,WPARAM wParam,LPARAM lParam){
        //向子类派发此类消息
        HWND tmpHWnd=GetDlgItem(m_hWnd,LOWORD(wParam));
        if(tmpHWnd!=NULL)
            return ::SendMessage(tmpHWnd,uMsg,wParam,lParam);
        return DefaultWindowProc(uMsg,wParam,lParam); } BOOL CQWnd::CenterWindow(BOOL bRepaint){ assert(IsWindow(m_hWnd)); RECT rect;
    int screenW = GetSystemMetrics(SM_CXSCREEN); int screenH = GetSystemMetrics(SM_CYSCREEN); //获取窗口矩形 GetWindowRect(&rect); return MoveWindow((screenW-rect.right)/2, (screenH-rect.bottom)/2,rect.right,rect.bottom,bRepaint); } BOOL CQWnd::GetWindowRect(LPRECT lpRect){ assert(IsWindow(m_hWnd)); return ::GetWindowRect(m_hWnd,lpRect); } BOOL CQWnd::GetClientRect(LPRECT lpRect){ assert(IsWindow(m_hWnd)); return ::GetClientRect(m_hWnd,lpRect); } BOOL CQWnd::UpdateWindow(void){ assert(IsWindow(m_hWnd)); return ::UpdateWindow(m_hWnd); } BOOL CQWnd::ShowWindow(int nCmdShow){ assert(IsWindow(m_hWnd)); return ::ShowWindow(m_hWnd,nCmdShow); } BOOL CQWnd::DestoryWindow(){ assert(IsWindow(m_hWnd)); return ::DestroyWindow(m_hWnd); } BOOL CQWnd::Attach(HWND hWnd){ if(hWnd!=NULL){ m_hWnd=hWnd; return TRUE; } return FALSE; } BOOL CQWnd::Detach(void){ m_hWnd=NULL; return TRUE; } CQWnd* CQWnd::GetWndFromHandle(HWND hWnd){ assert(IsWindow(m_hWnd)); return (CQWnd*)GetWindowLong(hWnd,GWL_USERDATA); } BOOL CQWnd::SetWindowText(LPCSTR lpString){ return ::SetWindowText(m_hWnd,lpString); } BOOL CQWnd::SetMenu(HMENU hMenu){ return ::SetMenu(m_hWnd,hMenu); } BOOL CQWnd::SubClassWindow(HWND hWnd){ assert(::IsWindow(hWnd)); if(hWnd==m_hWnd) return TRUE; m_lpfnOldWndProc=(WNDPROC)::GetWindowLong(hWnd,GWL_WNDPROC); if(CQWnd::WindowProc!=m_lpfnOldWndProc){ m_hWnd=hWnd; ::SetWindowLong(hWnd,GWL_USERDATA,(LONG)this); ::SetWindowLong(hWnd,GWL_WNDPROC,(LONG)CQWnd::WindowProc); return TRUE; } return FALSE; } BOOL CQWnd::MoveWindow(int X, int Y, int nWidth, int nHeight, BOOL bRepaint){ return ::MoveWindow(m_hWnd,X,Y,nWidth,nHeight,bRepaint); } BOOL CQWnd::EnableWindow(BOOL bEnable){ return ::EnableWindow(m_hWnd,bEnable); } BOOL CQWnd::IsWindowVisible(){ return ::IsWindowVisible(m_hWnd); } HRESULT CQWnd::OnCreate(UINT uMsg,WPARAM wParam, LPARAM lParam){ return DefaultWindowProc(uMsg,wParam,lParam); } HRESULT CQWnd::OnClose(UINT uMsg,WPARAM wParam, LPARAM lParam){ DestoryWindow(); return 0; } HRESULT CQWnd::OnDestroy(UINT uMsg,WPARAM wParam, LPARAM lParam){ ::PostMessage(m_hWnd,WM_QUIT,0,0); return DefaultWindowProc(uMsg,wParam,lParam); } HRESULT CQWnd::OnNcDestroy(UINT uMsg,WPARAM wParam, LPARAM lParam){ return DefaultWindowProc(uMsg,wParam,lParam); } HRESULT CQWnd::OnNcCreate(UINT uMsg,WPARAM wParam, LPARAM lParam){ return DefaultWindowProc(uMsg,wParam,lParam); } WNDPROC GetSuperWndProcAddr(){ return CQWnd::WindowProc; }

    消息派发及其框架类

    // QWApp.h: interface for the CQWApp class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #if !defined(AFX_QWAPP_H__74A97BCE_7976_4266_A0AD_113C0E65DC90__INCLUDED_)
    #define AFX_QWAPP_H__74A97BCE_7976_4266_A0AD_113C0E65DC90__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    class CQWApp  
    {
    public:
        LPVOID m_pMainWnd;
        virtual BOOL Run();
        virtual BOOL ExitInstance();
        virtual BOOL InitInstance();
        CQWApp();
        virtual ~CQWApp();
    };
    
    #endif // !defined(AFX_QWAPP_H__74A97BCE_7976_4266_A0AD_113C0E65DC90__INCLUDED_)
    
    // QWApp.cpp: implementation of the CQWApp class.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include "stdafx.h"
    #include "QWApp.h"
    
    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    
    CQWApp::CQWApp()
    {
    
    }
    
    CQWApp::~CQWApp()
    {
    
    }
    
    BOOL CQWApp::InitInstance()
    {
        return TRUE;
    }
    
    BOOL CQWApp::ExitInstance()
    {
        return TRUE;
    }
    
    BOOL CQWApp::Run(){
        MSG msg;
        while(GetMessage(&msg,NULL,0,0)){ 
            //从消息队列中取得消息
            TranslateMessage(&msg);
            //检索并生成字符消息WM_CHAR
            DispatchMessage(&msg);
            //将消息发送给相应的窗口函数
        }
        return TRUE;
    }

     

    源码下载:http://files.cnblogs.com/mengdejun/qwnd.zip

     案例下载:http://files.cnblogs.com/mengdejun/qw.zip

  • 相关阅读:
    微信开发创建公众号或小程序菜单45064: no permission to use weapp in menu rid:XXXXXXX
    大文件上传:秒传、断点续传、分片上传
    Linux 给文件夹或者文件增加权限
    常见的架构方式
    RabbitMQ集群
    常见的系统架构思想
    RabbitMQ问题分析
    RabbitMQ实战&管理界面
    Linux安装RabbitMQ
    Redis发布订阅及消息阻塞
  • 原文地址:https://www.cnblogs.com/mengdejun/p/4010320.html
Copyright © 2011-2022 走看看