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