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)=;
}; class ICommandMap{
public:
virtual HRESULT DisCommand(UINT uMsg,WPARAM wParam,LPARAM lParam)=;
}; //窗口基类
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,,(LONG)&cs);
::SendMessage(m_hWnd,WM_CREATE,,(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=;
wcex.cbWndExtra=;
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)/, (screenH-rect.bottom)/,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 ;
} HRESULT CQWnd::OnDestroy(UINT uMsg,WPARAM wParam, LPARAM lParam){
::PostMessage(m_hWnd,WM_QUIT,,);
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,,)){
//从消息队列中取得消息
TranslateMessage(&msg);
//检索并生成字符消息WM_CHAR
DispatchMessage(&msg);
//将消息发送给相应的窗口函数
}
return TRUE;
}

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

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

WIN32 窗口封装类实现的更多相关文章

  1. 第一个手写Win32窗口程序

    第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...

  2. WIN32窗口程序

    // Win32.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32.h" void TRACE( ...

  3. Win32窗口消息机制 x Android消息机制 x 异步执行

    如果你开发过Win32窗口程序,那么当你看到android代码到处都有的mHandler.sendEmptyMessage和 private final Handler mHandler = new ...

  4. 如何在Console下面生成一个WIN32窗口

    一个小挑战? VS2017里面,新建一个控制台工程,输入名字(你不需要也成,有默认的),得到一个控制台工程. 好了,生成的代码,如下: // Win32InConsole.cpp : This fil ...

  5. Win32窗口框架

    Win32窗口框架 WindowClass 单例,负责窗口初始化注册和取消注册: 负责提供静态方法: 放在Window类内部,方便初始化时,wndProc(HandleMsgSetup)的赋值: cl ...

  6. Win32 - 窗口

    Win32 - 窗口 目录 Win32 - 窗口 前言 流程图 创建项目 VS MinGW Win32API字符串 Unicode 和 ANSI 函数 TCHAR WinMain:Win32 Appl ...

  7. WIN32 API ------ 最简单的Windows窗口封装类

    1 开发语言抉择 1.1 关于开发Win32 程序的语言选择 C还是C++ 在决定抛弃MFC,而使用纯Win32 API 开发Window桌面程序之后,还存在一个语言的选择,这就是是否使用C++.C+ ...

  8. 解决WIN32窗口不响应WM_LBUTTONDBLCLK消息

    原文链接: http://www.cnblogs.com/xukaixiang/archive/2012/05/27/2520059.html 今天在做一个软件时,发现win32创建的窗体不能响应WM ...

  9. win32窗口映射(部分)

    先理解一下“窗口”与“视区”的概念.“窗口”是逻辑坐标下的矩形区域,“视区”是设备坐标系下的区域.根据“窗口”和“视区”的大小可以确定x方向和y方向的比例因子. 例子如下: VOID OnPaint( ...

随机推荐

  1. android 6.0 高通平台sensor 工作机制及流程(原创)

    最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...

  2. VC++ : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall std::basic_string<wchar_t,struct std::char_traits<wchar_t>

    最近学习Google Breakpad,将其用在了自己的项目中,编译的版本为VS2010,没有什么问题.但是为了和之前的程序兼容,需要使用VS2008版本的程序,于是又编译了VS2008版本的代码,但 ...

  3. LocalDB连接失败

    最近项目尝试放弃sqlexpress2005使用LocalDb2014,遇到问题: LocalDB安装成功,能正常添加实例,但同一个winform程序 在不同的win7电脑上有的能连上,有的怎么也连接 ...

  4. 转载:《.NET 编程结构》专题汇总(C#)

    <.NET 编程结构>专题汇总(C#) - M守护神 - 博客园http://www.cnblogs.com/liusuqi/p/3213597.html 前言     掌握一门技术,首要 ...

  5. iOS 对象和json互相转换

    // 将字典或者数组转化为JSON串 - (NSData *)toJSONData:(id)theData { NSError *error = nil; NSData *jsonData = [NS ...

  6. iOS 修改状态栏preferredStatusBarStyle不执行问题

    一.在老版本的iOS中,状态栏永远都是白色风格.而在iOS 7中,我们可以修改每个view controller中状态栏的外观.通过UIStatusBarStyle常量可以指定状态栏的内容是暗色或亮色 ...

  7. IO边读边写

      using (FileStream fs = new FileStream(@"C:\Users\Desktop\lijia1.txt",FileMode.Open))     ...

  8. 快速掌握、学习HTML的方法

    链接 超级链接用<a>标签表示,href属性指定了链接到的地址.<a>标签可以包含文本,也可以包含图片. 点击查看效果 <a href="http://deer ...

  9. 使用Azure REST API创建虚拟机

    Hollis Yao, Shihao Rong  使用REST API创建虚拟机之前,首先要确保Azure订阅中已经建好了"云服务"和"存储账号".如果没有的话 ...

  10. eclipse优化设置

    1. Eclipse的控制台console有时候经常的跳出来,非常的烦人! 让它不经常的调出来,可以按下面的操作去掉它: windows  ->   preferences   ->  r ...