//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 );
}
}