使用CWndBase快速创建窗口

//========================================================================
//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);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值