您的位置:首页 > 其它

使用CWndBase快速创建窗口

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

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

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

该类的实现代码如下:


//////////////////////////////////////////////////////////////////////
// WndBase.h: interface for the CWndBase class.
//
//Version:
// 0.1.0
//
//Date:
// 2007.11.10
//////////////////////////////////////////////////////////////////////
#ifndef WNDBASE_H
#define WNDBASE_H

class CWndBase
{
public:
virtual BOOL ShowWindow(BOOL bShow);
virtual BOOL Create(HINSTANCE hInst,HWND hWndParent,const TCHAR *pcszWndClass,const TCHAR *pcszWndName);
CWndBase();
virtual ~CWndBase();

protected:
virtual LRESULT WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
BOOL RegisterWnd(HINSTANCE hInst, HWND hWndParent,const TCHAR *pcszWndClass,const TCHAR *pcszWndName);
static LRESULT StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

HINSTANCE m_hInst;
HWND m_hWnd;
HWND m_hWndParent;
TCHAR *m_pszWndClass;
};

#endif //#ifndef WNDBASE_H

///////////////////////////////////////////////////////////////////////
// WndBase.cpp: implementation of the CWndBase class.
//
//////////////////////////////////////////////////////////////////////

#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:
// Create the window
//
//----------------------------------------------------------------------
BOOL CWndBase::Create(HINSTANCE hInst, HWND hWndParent, const TCHAR *pcszWndClass, const TCHAR *pcszWndName)
{
m_hInst = hInst;
m_hWndParent = hWndParent;

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

RECT rcArea = {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)
{
return FALSE;
}

// If the window is created successfully, store this object so the
//static wrapper can pass calls to the real WndProc.
SetWindowLong(m_hWnd, GWL_USERDATA, (DWORD)this);

return TRUE;
}

//----------------------------------------------------------------------
//Description:
// Register window
//
//----------------------------------------------------------------------
BOOL CWndBase::RegisterWnd(HINSTANCE hInst, HWND hWndParent,const TCHAR *pcszWndClass,const TCHAR *pcszWndName)
{

if(m_pszWndClass == NULL)
{
int iLen = _tcslen(pcszWndClass);
m_pszWndClass = new TCHAR[iLen + 1];
if(m_pszWndClass == NULL)
{
return FALSE;
}
_tcscpy(m_pszWndClass,pcszWndClass);

WNDCLASS wc = {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;

return RegisterClass(&wc);

}

return TRUE;
}

//----------------------------------------------------------------------
//Description:
// Static WndProc wrapper and actual WndProc
//
//----------------------------------------------------------------------
LRESULT CWndBase::StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
CWndBase *pObject = (CWndBase*)GetWindowLong(hWnd, GWL_USERDATA);

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

//----------------------------------------------------------------------
//Description:
// Actual WndProc
//
//----------------------------------------------------------------------
LRESULT CWndBase::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd,wMsg,wParam,lParam);
}

//----------------------------------------------------------------------
//Description:
// Actual WndProc
//
//----------------------------------------------------------------------
BOOL CWndBase::ShowWindow(BOOL bShow)
{
if(m_hWnd == NULL)
{
return FALSE;
}

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

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


return TRUE;
}

CWndBase使用也非常简单,如:

CWndBase wndBase;
wndBase.Create(hInstance,NULL,TEXT("BASE_WND"),TEXT("BASE_WND"));
wndBase.ShowWindow(TRUE);

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

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

CMainWnd代码如下:

//////////////////////////////////////////////////////////////////////
// MainWnd.h: interface for the CMainWnd class.
//
//////////////////////////////////////////////////////////////////////
#ifndef MAINWAN_H
#define MAINWAN_H

#include "WndBase.h"

class CMainWnd:public CWndBase
{
public:
CMainWnd();
virtual ~CMainWnd();

protected:
void OnLButtonUp(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam);
LRESULT WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
};

#endif //#ifndef MAINWAN_H

//////////////////////////////////////////////////////////////////////
// MainWnd.cpp: implementation of the CMainWnd class.
//
//////////////////////////////////////////////////////////////////////

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

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

CMainWnd::CMainWnd()
{

}

CMainWnd::~CMainWnd()
{

}

//----------------------------------------------------------------------
//Description:
// Actual WndProc
//
//----------------------------------------------------------------------
LRESULT CMainWnd::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg)
{
case WM_LBUTTONUP:
OnLButtonUp(hWnd, wMsg, wParam, lParam);
return 0;
}
return DefWindowProc(hWnd,wMsg,wParam,lParam);
}

//----------------------------------------------------------------------
//Description:
// On message WM_LBUTTONUP
//
//----------------------------------------------------------------------
void CMainWnd::OnLButtonUp(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
DestroyWindow(hWnd);
}

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


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

CWndBase *pWnd = NULL;

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

CMainWnd mainWnd1;
pWnd = &mainWnd1;
pWnd->Create(hInstance,NULL,TEXT("MAIN_WND_1"),TEXT("MAIN_WND_1"));
pWnd->ShowWindow(TRUE);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: