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)=;
}; 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 窗口封装类实现的更多相关文章
- 第一个手写Win32窗口程序
第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...
- WIN32窗口程序
// Win32.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "Win32.h" void TRACE( ...
- Win32窗口消息机制 x Android消息机制 x 异步执行
如果你开发过Win32窗口程序,那么当你看到android代码到处都有的mHandler.sendEmptyMessage和 private final Handler mHandler = new ...
- 如何在Console下面生成一个WIN32窗口
一个小挑战? VS2017里面,新建一个控制台工程,输入名字(你不需要也成,有默认的),得到一个控制台工程. 好了,生成的代码,如下: // Win32InConsole.cpp : This fil ...
- Win32窗口框架
Win32窗口框架 WindowClass 单例,负责窗口初始化注册和取消注册: 负责提供静态方法: 放在Window类内部,方便初始化时,wndProc(HandleMsgSetup)的赋值: cl ...
- Win32 - 窗口
Win32 - 窗口 目录 Win32 - 窗口 前言 流程图 创建项目 VS MinGW Win32API字符串 Unicode 和 ANSI 函数 TCHAR WinMain:Win32 Appl ...
- WIN32 API ------ 最简单的Windows窗口封装类
1 开发语言抉择 1.1 关于开发Win32 程序的语言选择 C还是C++ 在决定抛弃MFC,而使用纯Win32 API 开发Window桌面程序之后,还存在一个语言的选择,这就是是否使用C++.C+ ...
- 解决WIN32窗口不响应WM_LBUTTONDBLCLK消息
原文链接: http://www.cnblogs.com/xukaixiang/archive/2012/05/27/2520059.html 今天在做一个软件时,发现win32创建的窗体不能响应WM ...
- win32窗口映射(部分)
先理解一下“窗口”与“视区”的概念.“窗口”是逻辑坐标下的矩形区域,“视区”是设备坐标系下的区域.根据“窗口”和“视区”的大小可以确定x方向和y方向的比例因子. 例子如下: VOID OnPaint( ...
随机推荐
- 【iBeacon】iBeacon前沿初探技术备忘
iBeacon是工作在蓝牙4.0(BLE)硬件下的一种协议,属于蓝牙4.0广播协议的一种,通过该协议和一个蓝牙模块可以实现非接触的身份识别.位置检测等. How does BLE communicat ...
- 最常用的ES6特性(转)
最常用的ES6特性 let, const, class, extends, super, arrow functions, template string, destructuring, defaul ...
- Macbook 的 print screen 是什么
- JSP页面JSTL提供的函数标签EL表达式操作字符串的方法
首先在jsp页面导入标签<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions&quo ...
- NodeJS+Express下构建后端MVC文件结构
关于MVC的结构大体上有两种方式,其一按照层级进行文件夹分类,其二是按照业务进行文件夹分类.关于这个demo相关的业务简单,所以暂采用第一种的方式,当然实际当中很恨复杂的项目可以采用两种方式相结合的方 ...
- Winform的"透明"
手头目前的一个项目(.Net4.0)中有这样一个需求:在程序中要进行视频采集,并且要在视频影像区域进行绘图编辑,对绘图能进行拉伸,拖拽和删除.从需求来看,必须得在视频影像区的上方盖一层画布才能这么操作 ...
- Date、Calender类及日期和字符串转换
Calendar是一个抽象类,抽象类java.util.Calendar 不可以通过new来获取一个实例,可以通过类方法getinstance()获取此类型的一个通用的对象 ①用法: Calendar ...
- 在ubuntu下安装google chrome
由于手上有两台电脑,再加上我那个选择困难症加上纠结劲.所以果断把其中一台电脑只装linux系统,另一台电脑只装windows了.免得我老纠结!于是linux便选择了ubuntu. 由于浏览器一直用的是 ...
- byte[] 转十进制
short s = 0; //一个16位整形变量,初值为 0000 0000 0000 0000 byte b1 = 1; //一个byte的变量,作为转换后的高8位,假设初值为 0000 0001 ...
- .NET Remoting 应用实例
前言 项目中运用到.NET Remoting ,前段时间也看了下.NET Remoting的相关资料,感觉自己应该动手写个实例来梳理下对.NET Remoting认识和理解,不足的地方请大家指正. 简 ...