CWndBase更新至v0.1.6

时间:2021-07-22 17:39:43
//========================================================================
//TITLE:
//    CWndBase更新至v0.1.6
//AUTHOR:
//    norains
//DATE:
//    Saturday  12-January-2008
//Environment:
//    VS2005 + SDK-WINCE5.0-MIPSII  
//    EVC + SDK-WINCE5.0-MIPSII 
//========================================================================

    v0.1.0版本见:http://blog.csdn.net/norains/archive/2007/11/10/1878218.aspx
   
    相对v0.1.0版本,有如下变动:
    1.创建窗口时将WS_VISIBLE属性换成WS_TABSTOP,因为并不是每次创建的时候都需要显示
    2.修正采用该类创建子窗口的bug
    3.改进在非主线程中也可正常创建窗口.
   
    关于第三点,只需要在调用Create()函数时,将bMsgThrdInside形参设置为TRUE即可.

///////////////////////////////////////////////////////////////////// /
//  WndBase.h: interface for the CWndBase class.
//
// Version:
//     0.1.6
//
// Date:
//     2008.01.03
///////////////////////////////////////////////////////////////////// /
#pragma  once

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

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


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

private :
    
static  DWORD CreateProc(PVOID pArg);
    BOOL CreateWnd(
void );

    BOOL m_bCreated;
    BOOL m_bMsgThrdInside;
    HANDLE m_hEventCreated;


    
};


///////////////////////////////////////////////////////////////////// /
//  WndBase.cpp
//
///////////////////////////////////////////////////////////////////// /
#include  " stdafx.h "
#include 
" WndBase.h "

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

CWndBase::CWndBase():
m_hInst(NULL),
m_hWnd(NULL),
m_hWndParent(NULL),
m_pszWndClass(NULL),
m_pszWndName(NULL),
m_bCreated(FALSE),
m_hEventCreated(NULL),
m_bMsgThrdInside(FALSE)
{

}

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

    
if (m_pszWndName  !=  NULL)
    {
        delete []m_pszWndName;
        m_pszWndName 
=  NULL;
    }
}

// ----------------------------------------------------------------------
// Description:
//     Create the window
//
// Parameters:
//     hInst : [in] The handle of instance of the application
//     hWndParent : [in] The parent window
//     pcszWndClass : [in] The class of the window
//     pcszWndName : [in] The name of the windows
//     bMsgThrdInside : [in] The message thread process is inside or not
//
// ----------------------------------------------------------------------
BOOL CWndBase::Create(HINSTANCE hInst, HWND hWndParent,  const  TCHAR  * pcszWndClass,  const  TCHAR  * pcszWndName,BOOL bMsgThrdInside)
{
    m_hInst 
=  hInst;
    m_hWndParent 
=  hWndParent;
    m_bMsgThrdInside 
=  bMsgThrdInside;

    
// Store the window class name
     if (m_pszWndClass  !=  NULL)
    {
        delete []m_pszWndClass;
        m_pszWndClass 
=  NULL;
    }

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



    
// Store the window name
     if (m_pszWndName  !=  NULL)
    {
        delete []m_pszWndName;
        m_pszWndName 
=  NULL;
    }

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


    
// Create the window
     if (bMsgThrdInside  ==  TRUE)
    {

        HANDLE hdThrd 
=  CreateThread(NULL, 0 ,CreateProc, this , 0 ,NULL);
        
if (hdThrd  ==  NULL )
        {
            
return  FALSE;
        }
        
else
        {
            CloseHandle(hdThrd);

            
// Create the event and wait
            m_hEventCreated  =  CreateEvent(NULL,FALSE,FALSE,NULL);
            
if (m_hEventCreated  !=  NULL)
            {
                WaitForSingleObject(m_hEventCreated,INFINITE);
                CloseHandle(m_hEventCreated);
                m_hEventCreated 
=  NULL;

                
return  m_bCreated;
            }
            
else
            {
                
return  FALSE;
            }
            
        }
    }
    
else
    {
        
return  CreateWnd();
    }


}

// ----------------------------------------------------------------------
// Description:
//     Register window
//
// ----------------------------------------------------------------------
BOOL CWndBase::RegisterWnd(HINSTANCE hInst, const  TCHAR  * 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 
=  pcszWndClass;

    
return  RegisterClass( & wc);

    
}


// ----------------------------------------------------------------------
// 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)
{
    
switch (wMsg)
    {
        
case  WM_DESTROY:
            OnDestroy(hWnd,wMsg,wParam,lParam);
            
break ;
    }
    
return  DefWindowProc(hWnd,wMsg,wParam,lParam);
}


// ----------------------------------------------------------------------
// Description:
//     Show the window
//
// ----------------------------------------------------------------------
BOOL CWndBase::ShowWindow(BOOL bShow)
{
    
if (m_hWnd  ==  NULL)
    {
        
return  FALSE;
    }

    
if (bShow  ==  TRUE)
    {
        SetForegroundWindow(m_hWnd);
        SetWindowPos(m_hWnd,HWND_TOP,
0 , 0 , 0 , 0 ,SWP_NOMOVE  |  SWP_NOSIZE  |  SWP_SHOWWINDOW);            
    }
    
else
    {
        ::ShowWindow(m_hWnd,SW_HIDE);
    }
    


    
return  TRUE;
}


// ----------------------------------------------------------------------
// Description:
//     The process thread is for creating the window
//
// ----------------------------------------------------------------------
DWORD CWndBase::CreateProc(PVOID pArg)
{
    
// Get the object instance
    CWndBase  * pObject  =  (CWndBase  * )pArg;
    
    
// Create the window
    pObject -> m_bCreated  =  pObject -> CreateWnd();

    
// Set the event
     if (pObject -> m_hEventCreated  !=  NULL)
    {
        SetEvent(pObject
-> m_hEventCreated);
    }

    
if (pObject -> m_bCreated  ==  FALSE)
    {
        
// Failed in creating the window, so return and needn't the message loop
         return   0x01 ;
    }


    
// The message loop    
    MSG msg;
    
while (GetMessage( & msg,NULL, 0 , 0 ))
    {
        TranslateMessage(
& msg);
        DispatchMessage(
& msg);
    }

    
return   0 ;

}



// ----------------------------------------------------------------------
// Description:
//     Create the window
//
// ----------------------------------------------------------------------
BOOL CWndBase::CreateWnd( void )
{    

    
if (RegisterWnd(m_hInst,m_pszWndClass)  ==  FALSE)
    {
        
return  FALSE;
    }

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

    m_hWnd 
=  CreateWindowEx( 0 ,
                m_pszWndClass,
                m_pszWndName,
                WS_TABSTOP,
                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:
//     On Message WM_DESTROY
//
// ----------------------------------------------------------------------
void  CWndBase::OnDestroy(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{

    
if (m_bMsgThrdInside  ==  TRUE)
    {
        
// Exit the inside thread
        PostQuitMessage( 0x00 );
    }


}