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