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( ...
随机推荐
- Qt 程序打包发布
Qt 官方开发环境使用的动态链接库方式,在发布生成的exe程序时,需要复制一大堆 dll,Qt 官方开发环境里自带了一个工具:windeployqt.exe.在Qt安装目录如:C:\Qt\Qt5.7. ...
- mysqldump和xtrabackup备份原理实现说明
背景: MySQL数据库备份分为逻辑备份和物理备份两大类,犹豫到底用那种备份方式的时候先了解下它们的差异: 逻辑备份的特点是:直接生成SQL语句,在恢复的时候执行备份的SQL语句实现数据库数据的重现. ...
- CGAffineTransform
这个是CoreGraphics框架中的CGAffineTransform类,可用于设定UIView的transform属性.控制视图的缩放.旋转和平移操作.另称仿射变换矩阵. Quartz转换实现原理 ...
- 关于计算机改名无法连接TFS的问题
今天重新导入了两台服务器, 修改了机器名,结果VS2012链接TFS报错 --------------------------- Microsoft Visual Studio ----------- ...
- Tomcat7.0+的JNDI问题
上次搭建spring+springmvc+mybatis框架时用的第三方连接池jar包,但是部署到tomcat中后访问没有问题,但是启动时报了个JNDI的错,我没用JNDI你给我报什么,fuck!把错 ...
- SQUID常用命令
Squid日常维护过程中,常用的一些命令: 1,初始化你在 squid.conf 里配置的 cache 目录squid -z如果有错误提示,请检查你的 cache目录的权限.可以使用使用更改目录权限: ...
- C# 小知识
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...
- Guava学习笔记(一)概览
Guava是谷歌开源的一套Java开发类库,以简洁的编程风格著称,提供了很多实用的工具类, 在之前的工作中应用过Collections API和Guava提供的Cache,不过对Guava没有一个系统 ...
- Duilib源码分析(五)UI布局—Layout与各子控件
接下来,继续分析duilib之UI布局Layout,目前提供的布局有:VerticalLayout.HorizontalLayout.TileLayout.TabLayout.ChildLayout分 ...
- 解决select2在bootstrap的modal中默认不显示的问题
在Bootstrap中的Modal,select2插件会有不显示,因为其z-index小于modal,还有另外一个问题是,修正z-index之后,select2不会自动失去焦点的问题.代码解决如下: ...