#ifndef __WindowThreadImpl_h__
#define __WindowThreadImpl_h__
#if _MSC_VER > 1000
#pragma once
#endif #pragma warning(disable: 4786)
#include <map>
#include <malloc.h>
#include "WindowThreadBase.h"
template <class T>
class TCWindowThreadImpl : public TCWindowThreadBase
{
protected:
typedef TCWindowThreadImpl<T> TCWindowThreadImplBase;
public:
TCWindowThreadImpl(DWORD dwCoInit =
COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
~TCWindowThreadImpl();
public:
virtual TCThread* GetOrCreateThread();
protected:
virtual void InternalCreateWindow(XArgs& args);
virtual void InternalDestroyWindow(XArgs& args);
static unsigned CALLBACK ThreadProc(void* pvParam);
};
template <class T>
inline TCWindowThreadImpl<T>::TCWindowThreadImpl(DWORD dwCoInit) :
TCWindowThreadBase(dwCoInit)
{
}
template <class T>
inline TCWindowThreadImpl<T>::~TCWindowThreadImpl()
{
ShutdownWindowThread();
}
template <class T>
TCThread* TCWindowThreadImpl<T>::GetOrCreateThread()
{
CLock lock(this);
if (!m_pth)
{
TCHandle hevt = CreateEvent(NULL, FALSE, FALSE, NULL);
XThreadArgs args = {static_cast<T*>(this), hevt};
m_pth = TCThread::BeginThread(ThreadProc, &args);
WaitForSingleObject(hevt, INFINITE);
}
return m_pth;
}
template <class T>
void TCWindowThreadImpl<T>::InternalCreateWindow(
TCWindowThreadBase::XArgs& args)
{
T* pThis = static_cast<T*>(this);
args.hwnd = pThis->DoCreateWindowOnThread(args);
args.dwLastError = args.hwnd ? 0 : ::GetLastError();
AddWindow(args);
SubclassWindow(args.hwnd);
}
template <class T>
void TCWindowThreadImpl<T>::InternalDestroyWindow(
TCWindowThreadBase::XArgs& args)
{
T* pThis = static_cast<T*>(this);
if (!pThis->DoDestroyWindowOnThread(args.hwnd))
args.hwnd = NULL;
args.dwLastError = args.hwnd ? 0 : ::GetLastError();
}
template <class T>
unsigned CALLBACK TCWindowThreadImpl<T>::ThreadProc(void* pvParam)
{
XThreadArgs* pArgs = reinterpret_cast<XThreadArgs*>(pvParam);
assert(pArgs);
T* pThis = reinterpret_cast<T*>(pArgs->pvThis);
if (pThis->DoInitThread())
{
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
::SetEvent(pArgs->hevt);
pThis->MessageLoop();
}
CLock lock(pThis);
pThis->m_pth = NULL;
pThis->DoExitThread();
return 0;
}
#endif