使用CWndBase快速创建窗口

本文介绍了一种基于CWndBase类快速创建Windows窗口的方法。通过封装窗口创建的基本操作,简化了窗口类的设计,并展示了如何通过继承来扩展基本窗口类的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//========================================================================
//TITLE:
// 使用CWndBase快速创建窗口
//AUTHOR:
// norains
//DATE:
// Saturday 10-November-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================

其实这篇文章从本质来说并不新鲜,充其量只是<四论在C++类中实现Windows窗口的创建>的补充实现而已,具体的原理可参考该篇,本文就不再重复.

首先请出我们今天的主角CWndBase类,这是一个封装了窗口创建的基本类,主要是方便能够快速地书写窗口代码.

该类的实现代码如下:


//////////////////////////////////////////////////////////////////////
//WndBase.h:interfacefortheCWndBaseclass.
//
//Version:
//0.1.0
//
//Date:
//2007.11.10
//////////////////////////////////////////////////////////////////////
#ifndefWNDBASE_H
#defineWNDBASE_H


classCWndBase
{
public:
virtualBOOLShowWindow(BOOLbShow);
virtualBOOLCreate(HINSTANCEhInst,HWNDhWndParent,constTCHAR*pcszWndClass,constTCHAR*pcszWndName);
CWndBase();
virtual~CWndBase();

protected:
virtualLRESULTWndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam);
BOOLRegisterWnd(HINSTANCEhInst,HWNDhWndParent,
constTCHAR*pcszWndClass,constTCHAR*pcszWndName);
staticLRESULTStaticWndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam);

HINSTANCEm_hInst;
HWNDm_hWnd;
HWNDm_hWndParent;
TCHAR
*m_pszWndClass;
};

#endif//#ifndefWNDBASE_H


///////////////////////////////////////////////////////////////////////
//WndBase.cpp:implementationoftheCWndBaseclass.
//
//////////////////////////////////////////////////////////////////////

#include
"stdafx.h"
#include
"WndBase.h"

//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////

CWndBase::CWndBase():
m_hInst(NULL),
m_hWnd(NULL),
m_hWndParent(NULL),
m_pszWndClass(NULL)
{

}

CWndBase::
~CWndBase()
{
if(m_pszWndClass!=NULL)
{
delete[]m_pszWndClass;
}
}

//----------------------------------------------------------------------
//Description:
//Createthewindow
//
//----------------------------------------------------------------------
BOOLCWndBase::Create(HINSTANCEhInst,HWNDhWndParent,constTCHAR*pcszWndClass,constTCHAR*pcszWndName)
{
m_hInst
=hInst;
m_hWndParent
=hWndParent;

if(RegisterWnd(m_hInst,m_hWndParent,pcszWndClass,pcszWndName)==FALSE)
{
returnFALSE;
}

RECTrcArea
={0};
SystemParametersInfo(SPI_GETWORKAREA,
0,&rcArea,0);

m_hWnd
=CreateWindowEx(0,
pcszWndClass,
pcszWndName,
WS_VISIBLE,
rcArea.left,
rcArea.top,
rcArea.right
-rcArea.left,
rcArea.bottom
-rcArea.top,
m_hWndParent,
NULL,
m_hInst,
0);

if(IsWindow(m_hWnd)==FALSE)
{
returnFALSE;
}

//Ifthewindowiscreatedsuccessfully,storethisobjectsothe
//staticwrappercanpasscallstotherealWndProc.
SetWindowLong(m_hWnd,GWL_USERDATA,(DWORD)this);

returnTRUE;
}

//----------------------------------------------------------------------
//Description:
//Registerwindow
//
//----------------------------------------------------------------------
BOOLCWndBase::RegisterWnd(HINSTANCEhInst,HWNDhWndParent,constTCHAR*pcszWndClass,constTCHAR*pcszWndName)
{

if(m_pszWndClass==NULL)
{
intiLen=_tcslen(pcszWndClass);
m_pszWndClass
=newTCHAR[iLen+1];
if(m_pszWndClass==NULL)
{
returnFALSE;
}
_tcscpy(m_pszWndClass,pcszWndClass);

WNDCLASSwc
={0};
wc.style
=0;
wc.lpfnWndProc
=(WNDPROC)CWndBase::StaticWndProc;
wc.cbClsExtra
=0;
wc.cbWndExtra
=0;
wc.hInstance
=m_hInst;
wc.hIcon
=NULL;
wc.hCursor
=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground
=(HBRUSH)GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName
=NULL;
wc.lpszClassName
=m_pszWndClass;

returnRegisterClass(&wc);

}

returnTRUE;
}


//----------------------------------------------------------------------
//Description:
//StaticWndProcwrapperandactualWndProc
//
//----------------------------------------------------------------------
LRESULTCWndBase::StaticWndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam)
{
CWndBase
*pObject=(CWndBase*)GetWindowLong(hWnd,GWL_USERDATA);

if(pObject)
{
returnpObject->WndProc(hWnd,wMsg,wParam,lParam);
}
else
{
returnDefWindowProc(hWnd,wMsg,wParam,lParam);
}
}

//----------------------------------------------------------------------
//Description:
//ActualWndProc
//
//----------------------------------------------------------------------
LRESULTCWndBase::WndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam)
{
returnDefWindowProc(hWnd,wMsg,wParam,lParam);
}


//----------------------------------------------------------------------
//Description:
//ActualWndProc
//
//----------------------------------------------------------------------
BOOLCWndBase::ShowWindow(BOOLbShow)
{
if(m_hWnd==NULL)
{
returnFALSE;
}

if(bShow==TRUE)
{
::ShowWindow(m_hWnd,SW_SHOW);
SetForegroundWindow(m_hWnd);

}
else
{
::ShowWindow(m_hWnd,SW_HIDE);
}



returnTRUE;
}

CWndBase使用也非常简单,如:
CWndBasewndBase;
wndBase.Create(hInstance,NULL,TEXT(
"BASE_WND"),TEXT("BASE_WND"));
wndBase.ShowWindow(TRUE);

但这意义不大,因为也就创建了一个简单无用的窗口而已,其实CWndBase正如其名所语,最适合的角色是作为可继承的基类.

还是以实际用途做例子,如果我们需要建立一个CMainWnd窗口,点击该窗口时会自动销毁.有了CWndBase后一切就变得及其简单,我们只要继承CWndBase,然后重载WndProc消息处理过程即可.

CMainWnd代码如下:

//////////////////////////////////////////////////////////////////////
//MainWnd.h:interfacefortheCMainWndclass.
//
//////////////////////////////////////////////////////////////////////
#ifndefMAINWAN_H
#defineMAINWAN_H

#include
"WndBase.h"

classCMainWnd:publicCWndBase
{
public:
CMainWnd();
virtual~CMainWnd();

protected:
voidOnLButtonUp(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam);
LRESULTWndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam);
};

#endif//#ifndefMAINWAN_H


//////////////////////////////////////////////////////////////////////
//MainWnd.cpp:implementationoftheCMainWndclass.
//
//////////////////////////////////////////////////////////////////////

#include
"stdafx.h"
#include
"MainWnd.h"

//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMainWnd::CMainWnd()
{

}

CMainWnd::
~CMainWnd()
{

}


//----------------------------------------------------------------------
//Description:
//ActualWndProc
//
//----------------------------------------------------------------------
LRESULTCMainWnd::WndProc(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam)
{
switch(wMsg)
{
caseWM_LBUTTONUP:
OnLButtonUp(hWnd,wMsg,wParam,lParam);
return0;
}
returnDefWindowProc(hWnd,wMsg,wParam,lParam);
}


//----------------------------------------------------------------------
//Description:
//OnmessageWM_LBUTTONUP
//
//----------------------------------------------------------------------
voidCMainWnd::OnLButtonUp(HWNDhWnd,UINTwMsg,WPARAMwParam,LPARAMlParam)
{
DestroyWindow(hWnd);
}

由上面的例子可以清楚的看出,继承了CWndBase的CMainWnd代码量大为减少,而这在有多个窗口类的情况下,显得更为重要.


当然咯,还有一点,就是各窗口类都继承CWndBase的话,那么就可以方便的使用指针调用窗口实例了:
CWndBase*pWnd=NULL;

CWndBasewndBase;
pWnd
=&wndBase;
pWnd
->Create(hInstance,NULL,TEXT("BASE_WND"),TEXT("BASE_WND"));
pWnd
->ShowWindow(TRUE);

CMainWndmainWnd1;
pWnd
=&mainWnd1;
pWnd
->Create(hInstance,NULL,TEXT("MAIN_WND_1"),TEXT("MAIN_WND_1"));
pWnd
->ShowWindow(TRUE);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值