博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WIN32 窗口封装类实现
阅读量:5161 次
发布时间:2019-06-13

本文共 11156 字,大约阅读时间需要 37 分钟。

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 
#include
//定义消息映射宏#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 > 1000class 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;}

 

 

源码下载:

 案例下载:

转载于:https://www.cnblogs.com/mengdejun/p/4010320.html

你可能感兴趣的文章
C语言基础小结(一)
查看>>
STL中的优先级队列priority_queue
查看>>
UE4 使用UGM制作血条
查看>>
浏览器对属性兼容性支持力度查询网址
查看>>
OO学习总结与体会
查看>>
虚拟机长时间不关造成的问题
查看>>
面试整理:Python基础
查看>>
Python核心编程——多线程threading和队列
查看>>
Program exited with code **** 相关解释
查看>>
植物大战僵尸中文年度版
查看>>
26、linux 几个C函数,nanosleep,lstat,unlink
查看>>
投标项目的脚本练习2
查看>>
201521123107 《Java程序设计》第9周学习总结
查看>>
Caroline--chochukmo
查看>>
iOS之文本属性Attributes的使用
查看>>
从.Net版本演变看String和StringBuilder性能之争
查看>>
Excel操作 Microsoft.Office.Interop.Excel.dll的使用
查看>>
解决Ubuntu下博通网卡驱动问题
查看>>
【bzoj2788】Festival
查看>>
执行gem install dryrun错误
查看>>