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;
}

 

 

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

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

posted @ 2014-10-08 00:07  小孟文摘  阅读(1902)  评论(0编辑  收藏  举报