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