#include "stdafx.h"
#include "WndBase.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWndBase::CWndBase():
m_hWnd(NULL),
m_hWndParent(NULL),
m_bCreated(FALSE),
m_hEventCreated(NULL),
m_bMsgThrdInside(FALSE),
m_dwStyle(WS_TABSTOP)
{
}
CWndBase::~CWndBase()
{
}
BOOL CWndBase::Create(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,BOOL bMsgThrdInside)
{
return CreateEx(hWndParent,strWndClass,strWndName,WS_TABSTOP,bMsgThrdInside);
}
BOOL CWndBase::RegisterClass()
{
WNDCLASS wc;
GetDataForRegistryClass(wc);
return ::RegisterClass(&wc);
}
LRESULT CALLBACK CWndBase::StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
CWndBase *pObject = reinterpret_cast<CWndBase*>(GetWindowLong(hWnd, GWL_USERDATA));
if(pObject)
{
return pObject->WndProc(hWnd,wMsg,wParam,lParam);
}
else
{
return DefWindowProc(hWnd,wMsg,wParam,lParam);
}
}
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);
}
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;
}
DWORD WINAPI CWndBase::CreateProc(PVOID pArg)
{
//Get the object instance
CWndBase *pObject = reinterpret_cast<CWndBase *>(pArg);
#ifdef _WIN32_WCE
pObject->m_bCreated = pObject->CreateWnd(pObject->m_dwStyle,0);
#else
//Create the window.You should set the WS_EX_NOPARENTNOTIFY here, or maybe the CreateWindowEx
//never return because it is waiting for the parent window responding when the main message loop doesn't begin working.
pObject->m_bCreated = pObject->CreateWnd(pObject->m_dwStyle,WS_EX_NOPARENTNOTIFY);
#endif //#ifdef _WIN32_WCE
//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;
}
BOOL CWndBase::CreateWnd(DWORD dwStyle,DWORD dwExStyle)
{
if(RegisterClass() == FALSE)
{
return FALSE;
}
RECT rcArea = {0};
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcArea, 0);
m_hWnd = CreateWindowEx(dwExStyle,
m_strWndClass.c_str(),
m_strWndName.c_str(),
dwStyle,
rcArea.left,
rcArea.top,
rcArea.right - rcArea.left,
rcArea.bottom - rcArea.top,
m_hWndParent,
NULL,
GetModuleHandle(NULL),
0);
//ASSERT(m_hWnd != FALSE);
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, reinterpret_cast<DWORD>(this));
return TRUE;
}
void CWndBase::OnDestroy(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
if(m_bMsgThrdInside == TRUE)
{
//Exit the inside thread
PostQuitMessage(0x00);
}
}
HWND CWndBase::GetWindow(void) const
{
return m_hWnd;
}
HWND CWndBase::GetParentWindow(void) const
{
if(m_hWnd != NULL)
{
m_hWndParent = ::GetParent(m_hWnd);
}
return m_hWndParent;
}
BOOL CWndBase::SetParentWindow(HWND hWndParent)
{
if(m_hWnd == NULL)
{
m_hWndParent = hWndParent;
return TRUE;
}
LONG lStyle = GetWindowLong(m_hWnd,GWL_STYLE);
lStyle &= ~WS_POPUP; //Remove the WS_POPUP flag
lStyle |= WS_CHILD; //Set the WS_CHILD flag
SetWindowLong(m_hWnd,GWL_STYLE,lStyle);
::SetParent(m_hWnd,hWndParent);
m_hWndParent = GetParentWindow();
//ASSERT(m_hWndParent != NULL);
return (m_hWndParent != NULL);
}
BOOL CWndBase::CreateEx(HWND hWndParent,const TSTRING &strWndClass,const TSTRING &strWndName,DWORD dwStyle,BOOL bMsgThrdInside)
{
m_hWndParent = hWndParent;
m_dwStyle = dwStyle;
m_strWndName = strWndName;
m_strWndClass = strWndClass;
//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(dwStyle,0);
}
}
void CWndBase::GetDataForRegistryClass(WNDCLASS &wc)
{
wc.style = 0;
wc.lpfnWndProc = CWndBase::StaticWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_strWndClass.c_str();
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
}