WIN32 窗口封装类实现

时间:2022-02-02 05:31:51

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

 

 WIN32 窗口封装类实现

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

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