// Windows Template Library - WTL version 8.0
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This file is a part of the Windows Template Library.
// The use and distribution terms for this software are covered by the
// Microsoft Permissive License (Ms-PL) which can be found in the file
// Ms-PL.txt at the root of this distribution.

#ifndef __ATLWINCE_H__
#define __ATLWINCE_H__

#pragma once

#ifndef __cplusplus
	#error ATL requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLAPP_H__
	#error atlwince.h requires atlapp.h to be included first
#endif

#ifndef __ATLWIN_H__
	#error atlwince.h requires atlwin.h to be included first
#endif

#ifndef _WIN32_WCE
	#error atlwince.h compiles under Windows CE only
#elif (_WIN32_WCE < 300)
	#error atlwince.h requires Windows CE 3.0 or higher.
#endif

#if defined(WIN32_PLATFORM_WFSP) &&  _MSC_VER < 1400 // EVC compiling SmartPhone code
  #if (WIN32_PLATFORM_WFSP < 200)
	#error atlwince.h requires Smartphone 2003 or higher
  #endif
#endif // WIN32_PLATFORM_WFSP

#if defined(WIN32_PLATFORM_PSPC) &&  _MSC_VER < 1400 // EVC compiling Pocket PC code
  #if (WIN32_PLATFORM_PSPC < 310)
	#error atlwince.h requires Pocket PC 2002 or higher
  #endif
#endif // WIN32_PLATFORM_PSPC

#if !defined(_AYGSHELL_H_) && !defined(__AYGSHELL_H__)
	#error atlwince.h requires aygshell.h to be included first
#else
  #if defined(WIN32_PLATFORM_WFSP) && !defined(_TPCSHELL_H_)
	#error SmartPhone dialog classes require tpcshell.h to be included first
  #endif
#endif

#if (_MSC_VER >= 1400) // VS2005
  #include <DeviceResolutionAware.h>
  #define _WTL_CE_DRA
#endif // (_MSC_VER >= 1400)

#if !defined(_WTL_CE_NO_DIALOGS) &&  !defined(__ATLFRAME_H__)
	#error Orientation aware dialog classes require atlframe.h to be included first
#endif

#if !defined(_WTL_CE_NO_APPWINDOW) &&  !defined(__ATLFRAME_H__)
	#error Application window class require atlframe.h to be included first
#endif

#if !defined(_WTL_CE_NO_ZOOMSCROLL) &&  !defined(__ATLSCRL_H__)
	#error ZoomScroll implementation requires atlscrl.h to be included first
#endif

#if !defined(_WTL_CE_NO_ZOOMSCROLL)
  #if !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES)))
	#error ZoomScroll requires _WTL_NO_WTYPES not to be defined and either atlmisc.h or atltypes.h to be included first
  #endif // !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES)))
#endif // !defined(_WTL_CE_NO_ZOOMSCROLL)

#if !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC)
  #define _WTL_CE_NO_CONTROLS
#endif // !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC)

#ifndef _WTL_CE_NO_CONTROLS
  #ifndef __ATLCTRLS_H__
	#error The PPC/SmartPhone controls classes require atlctrls.h to be included first
  #endif

  #include <htmlctrl.h>
  #pragma comment(lib, "htmlview.lib")

  #include <voicectl.h>
  #pragma comment(lib, "voicectl.lib")

  #ifdef WIN32_PLATFORM_PSPC
    #include <richink.h>
    #pragma comment(lib, "richink.lib")

    #include <inkx.h>
    #pragma comment(lib, "inkx.lib")

    #include <doclist.h>
    #pragma comment(lib, "doclist.lib")
  #endif
#endif


///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CStdDialogBase<T, t_shidiFlags, t_bModal> : Standard PPC/SmartPhone dialog base class
// CStdDialogImplBase - Base implementation of standard dialog
// CStdDialogImpl<T, t_shidiFlags, t_bModal> : Standard dialog implementation
// CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog
// CStdAxDialogImpl<T, t_shidiFlags, t_bModal> : Standard AxDialog implementation
// CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags> : Standard simple dialog
// CStdDialogResizeImplBase - Base implementation of orientation resizing standard dialog
// CStdDialogResizeImpl<T, t_shidiFlags, t_bModal> : Orientation resizing standard dialog implementation
// CStdAxDialogResizeImpl - implementation of orientation resizing standard AxDialog
// CStdSimpleDialogResizeImpl<T, t_wDlgTemplateID, t_shidiFlags> : Standard resizing simple dialog implementation
// CStdOrientedDialogBase - Oriented PPC standard dialog base class
// CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation
// CStdOrientedDialogImpl<T, t_shidiFlags, t_bModal> : Oriented PPC standard dialog implementation
// CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation
// CStdSimpleOrientedDialog<t_wDlgTemplateID, t_wDlgLandscapeID, t_shidiFlags> : Standard simple orientable dialog
//
// CAppInfoBase	 : Helper for application state save/restore to registry
// CAppInfoT<T> : CAppInfoBase constructed from a CAppWindow<T>
// CAppWindowBase<T> : Base class for PPC/SmartPhone well-behaved application window or dialog
// CAppWindow<T> : PPC/SmartPhone well-behaved application window class
// CAppDialog<T> : PPC/SmartPhone well-behaved application dialog class
// CAppStdDialogImplBase - Base implementation of standard application dialogs
// CAppStdDialogImpl<T, t_shidiFlags, t_bModal> : Implementation of standard application dialog
// CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog
// CAppStdAxDialogImpl - Implementation of standard application AxDialog 
// CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog
// CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog
// CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog
//
// CFullScreenFrame<T, t_bHasSip> : Full screen frame class
//
// CZoomScrollImpl<T> : WinCE zooming implementation
//
// CBottomTabViewImpl<T, TBase, TWinTraits> - CBottomTabView 
// CHtmlCtrlT<TBase> - CHtmlCtrl
// CRichInkCtrlT<TBase> - CRichInkCtrl
// CInkXCtrlT<TBase> - CInkXCtrl
// CVoiceRecorderCtrlT<TBase> - CVoiceRecorderCtrl
// CDocListCtrlT<TBase> - CDocListCtrl
// CCapEditT<TBase> - CCapEdit
// CTTStaticT<TBase> - CTTStatic
// CTTButtonT<TBase> - CTTButton
//
// CSpinCtrlT<TBase> - CSpinCtrl : SmartPhone specific UpDown control
// CSpinned<TBase, t_bExpandOnly> : SmartPhone association of control and Spin
// CSpinListBox : SmartPhone spinned ListBox control
// CExpandListBox : SmartPhone expandable ListBox control
// CExpandEdit : SmartPhone expandable Edit control
// CExpandCapEdit : SmartPhone expandable CapEdit control
//
// Global functions:
//   AtlCreateMenuBar()
//   AtlCreateEmptyMenuBar()
//   AtlIsEditFocus()
//   AtlActivateBackKey()

namespace WTL
{

///////////////////////////////////////////////////////////////////////////////
// MenuBar creation functions for property sheets and dialogs
// Frame windows use CreateSimpleCEMenuBar

inline HWND AtlCreateMenuBar(SHMENUBARINFO& mbi)
{
	ATLASSERT(::IsWindow(mbi.hwndParent));
	ATLVERIFY(::SHCreateMenuBar(&mbi) != FALSE);
	return mbi.hwndMB;
};

inline HWND AtlCreateMenuBar(HWND hWnd, UINT nToolBarId = ATL_IDW_TOOLBAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0, COLORREF clrBk = 0)
{
	SHMENUBARINFO mbi = { sizeof(mbi), hWnd, dwFlags, nToolBarId, ModuleHelper::GetResourceInstance(), nBmpId, cBmpImages, 0, clrBk };
	return AtlCreateMenuBar(mbi);
}

inline HWND AtlCreateEmptyMenuBar(HWND hWnd, bool bSip = true)
{
	SHMENUBARINFO embi = { sizeof(SHMENUBARINFO), hWnd, SHCMBF_EMPTYBAR };
	if (!bSip)
		embi.dwFlags |= SHCMBF_HIDESIPBUTTON;
	
	return AtlCreateMenuBar(embi);
}
	
///////////////////////////////////////////////////////////////////////////////
// Helper functions for SmartPhone back key handling

inline bool AtlIsEditFocus()
{
	ATL::CWindow wCtrl = GetFocus();
	if (wCtrl.IsWindow())
	{
		TCHAR szClassName[8] = {0};
		ATLVERIFY(::GetClassName(wCtrl.m_hWnd, szClassName, 8));
		return !_tcscmp(szClassName, _T("Edit")) || !_tcscmp(szClassName, WC_CAPEDIT);
	}
	return false;
}

#if defined WIN32_PLATFORM_WFSP
inline void AtlActivateBackKey(HWND hMenuBar)
{
	ATLASSERT(::IsWindow(hMenuBar));
	::SendMessage(hMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK,
		MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
}
#endif // WIN32_PLATFORM_WFSP

// --- Standard PPC/SmartPhone dialogs ---

#ifndef _WTL_CE_NO_DIALOGS

///////////////////////////////////////////////////////////////////////////////
// CStdDialogBase - base class for standard PPC/SmartPhone dialogs

#define WTL_STD_SHIDIF   SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN
#define WTL_SP_SHIDIF    SHIDIF_SIZEDLGFULLSCREEN

// Title setting macros
#define WTL_DLG_TITLEHEIGHT(iHeight) static const int GetTitleHeight(){return iHeight;}
#define WTL_DLG_NOTITLE	 WTL_DLG_TITLEHEIGHT(0)

///////////////////////////////////////////////////////////////////////////////
// CStdDialogBase - Base class for standard PPC/SmartPhone dialog

template <class T, UINT t_shidiFlags, bool t_bModal = true>
class CStdDialogBase
{
public:
#ifdef WIN32_PLATFORM_PSPC
// Pocket PC only Dialog title handling
	const int nTitleHeight;

	CStdDialogBase() : nTitleHeight(T::GetTitleHeight())
	{ }

// Overloads
	BOOL GetClientRect(LPRECT lpRect) 
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		BOOL bRes = ::GetClientRect(pT->m_hWnd, lpRect);
		lpRect->top += nTitleHeight;
		return bRes;
	}

	BOOL SetWindowText(LPCTSTR lpszString)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		BOOL bRes = ::SetWindowText(pT->m_hWnd, lpszString);
		if (nTitleHeight != 0)
			pT->DoPaintTitle();
		return bRes;
	}

// Overrideables
	static const int GetTitleHeight()
	{
	#ifdef _WTL_CE_DRA
		return DRA::SCALEY(24);
	#else // !_WTL_CE_DRA
		CWindowDC dc(NULL);
		return dc.GetDeviceCaps(LOGPIXELSY) >> 2; // LOGPIXELSY * 24 / 96,
	#endif // !_WTL_CE_DRA
	}

	// Title painting
	bool DoPaintTitle()
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		TCHAR sTitle[48];

		// Preparation
		CPaintDC dc(pT->m_hWnd);
		CFont fontTitle = AtlCreateBoldFont();
		CFontHandle fontOld = dc.SelectFont(fontTitle);
		dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHT));
		int nLen = pT->GetWindowText(sTitle, 48);
		int nWidth = dc.GetDeviceCaps(HORZRES);

		// Display title text
		RECT rTitle = { 0, 0, nWidth, nTitleHeight };
		dc.FillRect(&rTitle, COLOR_3DHIGHLIGHT);
	#ifdef _WTL_CE_DRA
		rTitle.left = DRA::SCALEX(8);
	#else // !_WTL_CE_DRA
		rTitle.left = nTitleHeight / 3; // 8 == 24 / 3
	#endif // !_WTL_CE_DRA
		dc.DrawText(sTitle, nLen, &rTitle, DT_VCENTER | DT_SINGLELINE);
		dc.SelectFont(fontOld);

		// Draw bottom line, 2 pixels thick if HI_RES_AWARE
		CPenHandle penOld = dc.SelectStockPen(BLACK_PEN);
		POINT line[4] = {{0, nTitleHeight}, {nWidth, nTitleHeight}, {0, nTitleHeight - 1}, {nWidth, nTitleHeight - 1}};

	#ifdef _WTL_CE_DRA
		int nSeg = DRA::SCALEY(1);
	#else // !_WTL_CE_DRA
		int nSeg = nTitleHeight / 24; 
	#endif // !_WTL_CE_DRA

		dc.Polyline(line, nSeg <= 2 ? nSeg * 2 : 4);
		dc.SelectPen(penOld);

		return false;
	}

	// Title preparation: move the dialog controls down to make room for title
	void DialogTitleInit()
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());

		ATL::CWindow wCtl = pT->GetWindow(GW_CHILD);
		while (wCtl.IsWindow())
		{
			RECT rCtl = { 0 };
			wCtl.GetWindowRect(&rCtl);
			::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rCtl, 2);
			::OffsetRect(&rCtl, 0, nTitleHeight);
			wCtl.MoveWindow(&rCtl, FALSE);
			wCtl = wCtl.GetWindow(GW_HWNDNEXT);
		}
	}

	// SIP management
	void DoSipInfo()
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());

		SIPINFO si = {sizeof(SIPINFO)};
		SipGetInfo(&si);
		if ((si.fdwFlags & SIPF_ON) ^ SIPF_ON) 
			si.rcVisibleDesktop.bottom = si.rcSipRect.bottom;
		pT->MoveWindow(&si.rcVisibleDesktop, FALSE);
	}

// Title painting handler
	LRESULT OnPaintTitle(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		return bHandled = nTitleHeight ? pT->DoPaintTitle() : FALSE;
	}

// SIP handler
	LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		if (wParam == SPI_SETSIPINFO)
		{
			pT->DoSipInfo();
			return TRUE;
		}
		return bHandled = FALSE;
	}

#elif defined WIN32_PLATFORM_WFSP
// SmartPhone VK_TBACK key standard management
	LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		const UINT uModif = (UINT)LOWORD(lParam);
		const UINT uVirtKey = (UINT)HIWORD(lParam);

		if(uVirtKey == VK_TBACK)
			if (AtlIsEditFocus())
				::SHSendBackToFocusWindow(uMsg, wParam, lParam);
			else if (uModif & MOD_KEYUP)
					pT->StdCloseDialog(IDCANCEL);
		return 1;
	}

 // SmartPhone MenuBar and VK_TBACK key initialization
	void StdSPInit()
	{
		T* pT = static_cast<T*>(this);
		HWND hMenuBar = ::SHFindMenuBar(pT->m_hWnd);

		if (!hMenuBar && (t_shidiFlags & SHIDIF_DONEBUTTON))
			hMenuBar = CreateMenuBar(ATL_IDM_MENU_DONE);

		if(hMenuBar != NULL)
			AtlActivateBackKey(hMenuBar);
	}

	void SetStaticBold()
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());

		CFontHandle fontBold = AtlCreateBoldFont(pT->GetFont());

		ATL::CWindow wCtl = pT->GetWindow(GW_CHILD);

		while (wCtl.IsWindow())
		{
			if ((short int)wCtl.GetDlgCtrlID() == IDC_STATIC)
				wCtl.SetFont(fontBold);
			wCtl = wCtl.GetWindow(GW_HWNDNEXT);
		}
	}
#endif // WIN32_PLATFORM_WFSP

// Platform dependant initialization
	void StdPlatformInit()
	{
		T* pT = static_cast<T*>(this);
#ifdef WIN32_PLATFORM_PSPC // Pocket PC title initialization
		if (nTitleHeight != 0)
			pT->DialogTitleInit();
#elif defined(WIN32_PLATFORM_WFSP)
		pT->StdSPInit();
		SetStaticBold();
#endif // WIN32_PLATFORM_WFSP
	}

	// Menu bar creation
	HWND CreateMenuBar(UINT uiMB = T::IDD, int nBmpImages = 0)
	{
		T* pT = static_cast<T*>(this);
		return AtlCreateMenuBar(pT->m_hWnd, uiMB, 0, nBmpImages ? uiMB : 0, nBmpImages);
	}

	// Dialog closing
	void StdCloseDialog(WORD wID)
	{
		T* pT = static_cast<T*>(this);
		if (t_bModal)
			::EndDialog(pT->m_hWnd, wID);
		else
			pT->DestroyWindow();
	}

	// Shell dialog layout initialization
	void StdShidInit()
	{
		T* pT = static_cast<T*>(this);
		SHINITDLGINFO shidi = { SHIDIM_FLAGS, pT->m_hWnd, t_shidiFlags };
		::SHInitDialog(&shidi);
	}

// IDC_INFOSTATIC background setting
	LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if (::GetDlgCtrlID((HWND)lParam) == IDC_INFOSTATIC)
		{
			::SetBkMode((HDC)wParam, TRANSPARENT);
			return (LRESULT)::GetSysColorBrush(COLOR_INFOBK);
		}
		return bHandled = FALSE;
	}

// Menu dialog ending
	LRESULT OnMenuClose(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		pT->StdCloseDialog((WORD)(wID - ID_MENU_OK + IDOK));
		return 0;
	}

// Standard dialog ending: may be used with any command
	LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		pT->StdCloseDialog(wID);
		return 0;
	}
};


///////////////////////////////////////////////////////////////////////////////
// CStdDialogImplBase - Base implementation of standard PPC/SmartPhone dialog

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true, class TBase = ATL::CDialogImpl< T > >
class ATL_NO_VTABLE CStdDialogImplBase :
		public TBase,
		public CStdDialogBase<T, t_shidiFlags, t_bModal>
{
public:
#ifdef WIN32_PLATFORM_PSPC
	BOOL GetClientRect(LPRECT lpRect) 
	{
		return CStdDialogBase<T, t_shidiFlags, t_bModal>::GetClientRect(lpRect);
	}

	BOOL SetWindowText(LPCTSTR lpszString)
	{
		return CStdDialogBase<T, t_shidiFlags, t_bModal>::SetWindowText(lpszString);
	}
#endif

	BEGIN_MSG_MAP(CStdDialogImplBase)
#ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP
		MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
		MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
#endif
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd)
		COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
	END_MSG_MAP()
	
	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _DEBUG
		T* pT = static_cast<T*>(this);
		ATLASSERT(t_bModal == pT->m_bModal);
#endif
		StdPlatformInit();
		StdShidInit();
		return bHandled = FALSE;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CStdDialogImpl - implementation of standard PPC/SmartPhone dialog

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
class ATL_NO_VTABLE CStdDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal>
{};

///////////////////////////////////////////////////////////////////////////////
// CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog

#if defined __ATLDLGS_H__ 

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true>
class ATL_NO_VTABLE CStdIndirectDialogImpl : 
	public CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl<T, t_shidiFlags, t_bModal> >
{
public:
	typedef CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl<T, t_shidiFlags, t_bModal> >	_baseClass;
	typedef CStdDialogImpl<T, t_shidiFlags, t_bModal> _baseStd;

	INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
	{
		ATLASSERT(t_bModal);

		if (!m_Template.IsValid())
			CreateTemplate();

		if (m_Template.IsTemplateEx())
		{
			if (m_Template.GetTemplateExPtr()->style & DS_CENTER)
			{
				ATLASSERT(m_Template.GetTemplateExPtr()->style ^ WS_CHILD);
				GetTemplateExPtr()->style |= WS_POPUP;
			}
		}
		else
		{
			if (m_Template.GetTemplatePtr()->style & DS_CENTER)
			{
				ATLASSERT(m_Template.GetTemplatePtr()->style ^ WS_CHILD);
				m_Template.GetTemplatePtr()->style |= WS_POPUP;
			}
		}

		return _baseClass::DoModal(hWndParent, dwInitParam);
	}

	HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
	{
		ATLASSERT(!t_bModal);

		if (!m_Template.IsValid())
			CreateTemplate();

		if (m_Template.IsTemplateEx())
		{
			if (GetTemplateExPtr()->style & DS_CENTER)
			{
				ATLASSERT(GetTemplateExPtr()->style ^ WS_CHILD);
				GetTemplateExPtr()->style |= WS_POPUP;
			}
		}
		else
		{
			if (GetTemplatePtr()->style & DS_CENTER)
			{
				ATLASSERT(GetTemplatePtr()->style ^ WS_CHILD);
				GetTemplatePtr()->style |= WS_POPUP;
			}
		}

		return _baseClass::Create(hWndParent, dwInitParam);
	}

	BEGIN_MSG_MAP(CStdIndirectDialogImpl)
		CHAIN_MSG_MAP(_baseStd)
	END_MSG_MAP()

};
 
#endif // defined __ATLDLGS_H__ 

#ifndef _ATL_NO_HOSTING

///////////////////////////////////////////////////////////////////////////////
// CStdAxDialogImpl - implementation of standard  PPC/SmartPhone AxDialog

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
class ATL_NO_VTABLE CStdAxDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl< T > >
{};
#endif // _ATL_NO_HOSTING

///////////////////////////////////////////////////////////////////////////////
// CStdSimpleDialog - standard PPC/SmartPhone simple dialog with SHIDIF_xxx flags

template <WORD t_wDlgTemplateID, UINT t_shidiFlags = WTL_STD_SHIDIF>
class CStdSimpleDialog :
		public ATL::CSimpleDialog<t_wDlgTemplateID, FALSE>,
		public CStdDialogBase<CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>, t_shidiFlags>
{
public:
	typedef CStdDialogBase<CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>, t_shidiFlags> baseClass;

#ifdef WIN32_PLATFORM_PSPC
	BOOL GetClientRect(LPRECT lpRect) 
	{
		return baseClass::GetClientRect(lpRect);
	}

	BOOL SetWindowText(LPCTSTR lpszString)
	{
		return baseClass::SetWindowText(lpszString);
	}
#endif

	BEGIN_MSG_MAP(CStdSimpleDialog)
#ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP
		MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
		MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
#endif
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
		COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		StdPlatformInit();
		StdShidInit();
		return bHandled = FALSE;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CStdDialogResizeImplBase - Base implementation of orientation resizing standard PPC/SmartPhone dialog

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true, class TBase = ATL::CDialogImpl<T> >
class ATL_NO_VTABLE CStdDialogResizeImplBase :
		public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>,
		public CDialogResize<T>
{
public:
	// Note: BEGIN_DLGRESIZE_MAP is required in the derived class.

	BEGIN_MSG_MAP(CStdResizeDialogImplBase)
#ifdef WIN32_PLATFORM_PSPC // Pocket PC title
		MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
		MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
#endif
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd)
		COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
		CHAIN_MSG_MAP(CDialogResize< T >)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _DEBUG
		T* pT = static_cast<T*>(this);
		ATLASSERT(t_bModal == pT->m_bModal);
#endif
		StdPlatformInit();
		DlgResize_Init(FALSE);
		StdShidInit();
		return bHandled = FALSE;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CStdDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone dialog

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
class ATL_NO_VTABLE CStdDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal>
{};

#ifndef _ATL_NO_HOSTING

///////////////////////////////////////////////////////////////////////////////
// CStdAxDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone AxDialog

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
class ATL_NO_VTABLE CStdAxDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl<T> >
{};
#endif // _ATL_NO_HOSTING

///////////////////////////////////////////////////////////////////////////////
// CStdSimpleDialogResizeImpl - implementation of standard resizing simple dialog with SHIDIF_xxx flags

// Usage:
//	class CMyDlg : public CStdSimpleDialogResize<CMyDlg,
//		IDD_MYDLG, SHIDIF_DONEBUTTON | SHIDIF_FULLSCREENNOMENUBAR>
//	{
//	public:
//		BEGIN_DLGRESIZE_MAP(CMyDlg)
//		...
//		END_DLGRESIZE_MAP()
//	};

template <class T, WORD t_wDlgTemplateID, UINT t_shidiFlags = WTL_STD_SHIDIF>
class ATL_NO_VTABLE CStdSimpleDialogResizeImpl :
		public CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>,
		public CDialogResize< T >
{
public:
	typedef CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>::baseClass baseClass;

	BEGIN_MSG_MAP(CStdSimpleDialogResizeImpl)
#ifdef WIN32_PLATFORM_PSPC // Pocket PC title
		MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key
		MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
#endif
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd)
		COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
		CHAIN_MSG_MAP(CDialogResize< T >)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		StdPlatformInit();
		DlgResize_Init(FALSE);
		StdShidInit();
		return bHandled = FALSE;
	}
};

#if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC)

///////////////////////////////////////////////////////////////////////////////
// CStdOrientedDialogBase - Oriented PPC standard dialog base class

template <class T>
class CStdOrientedDialogBase
{
public:
// Operation
	BOOL SetOrientation(DRA::DisplayMode mode)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		ATLASSERT(mode == DRA::GetDisplayMode());
		
		// Derived dialog must enumerate TWO dialog templates with the same control ids and types ie:
		// enum { IDD = IDD_MYDLG, IDD_LANDSCAPE = IDD_MYDLG_L };
		UINT iResource = (mode == DRA::Landscape)? T::IDD_LANDSCAPE : T::IDD;

		BOOL bRes = DRA::RelayoutDialog(ModuleHelper::GetResourceInstance(), pT->m_hWnd, MAKEINTRESOURCE(iResource));
		pT->OnOrientation(mode);
		return bRes;
	}

// Override
	void OnOrientation(DRA::DisplayMode /*mode*/)
	{}

// Message handlers
	LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		if (wParam == SETTINGCHANGE_RESET)
		{
			SetOrientation(DRA::GetDisplayMode());
			pT->StdPlatformInit();
			pT->StdShidInit();
		}
		else if (wParam == SPI_SETSIPINFO)
		{
			pT->DoSipInfo();
			return TRUE;
		}
		return bHandled = FALSE;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true, class TBase = ATL::CDialogImpl<T> >
class ATL_NO_VTABLE CStdOrientedDialogImplBase :
		public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>,
		public CStdOrientedDialogBase<T>
{
public:
	BEGIN_MSG_MAP(CStdOrientedDialogImpl)
		MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, CStdOrientedDialogBase<T>::OnSettingChange)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd)
		COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
#ifdef _DEBUG
		ATLASSERT(t_bModal == pT->m_bModal);
#endif
		if (DRA::GetDisplayMode() == DRA::Landscape)
			SetOrientation(DRA::Landscape);
		pT->StdPlatformInit();
		pT->StdShidInit();
		return bHandled = FALSE;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CStdOrientedDialogImpl - Oriented PPC standard dialog implementation

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
class ATL_NO_VTABLE CStdOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal>
{};

#ifndef _ATL_NO_HOSTING
///////////////////////////////////////////////////////////////////////////////
// CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation

template <class T, UINT t_shidiFlags = WTL_STD_SHIDIF, bool t_bModal = true >
class ATL_NO_VTABLE CStdAxOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl<T> >
{};
#endif // _ATL_NO_HOSTING

///////////////////////////////////////////////////////////////////////////////
// CStdSimpleOrientedDialog - Standard simple orientable dialog

template <WORD t_wDlgTemplateID, WORD t_wDlgLandscapeID, UINT t_shidiFlags = WTL_STD_SHIDIF>
class CStdSimpleOrientedDialog :
		public CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>,
		public CStdOrientedDialogBase<CStdSimpleOrientedDialog<t_wDlgTemplateID, t_wDlgLandscapeID, t_shidiFlags> >
{
public:
	typedef CStdSimpleDialog<t_wDlgTemplateID, t_shidiFlags>::baseClass baseClass;
	typedef CStdOrientedDialogBase<CStdSimpleOrientedDialog<t_wDlgTemplateID, t_wDlgLandscapeID, t_shidiFlags> > baseOriented;

	enum {IDD = t_wDlgTemplateID, IDD_LANDSCAPE = t_wDlgLandscapeID};

	BEGIN_MSG_MAP(CStdSimpleDialog)
		MESSAGE_HANDLER(WM_PAINT, OnPaintTitle)
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, baseOriented::OnSettingChange)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd)
		COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose)
	END_MSG_MAP()

		LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if (DRA::GetDisplayMode() == DRA::Landscape)
			SetOrientation(DRA::Landscape);
		StdPlatformInit();
		StdShidInit();
		return bHandled = FALSE;
	}
};

#endif // _WTL_CE_DRA


#endif // _WTL_CE_NO_DIALOGS


// --- PPC/SmartPhone application window and helpers ---

#ifndef _WTL_CE_NO_APPWINDOW

///////////////////////////////////////////////////////////////////////////////
// CAppInfoBase - Helper for application state save/restore to registry

class CAppInfoBase
{
public:
	ATL::CRegKey m_Key;

	CAppInfoBase(ATL::_U_STRINGorID sAppKey)
	{
		m_Key.Create(HKEY_CURRENT_USER, sAppKey.m_lpstr);
		ATLASSERT(m_Key.m_hKey);
	}

	template <class V>
	LONG Save(V& val, ATL::_U_STRINGorID sName)
	{
		return ::RegSetValueEx(m_Key, sName.m_lpstr, 0, REG_BINARY, (LPBYTE)&val, sizeof(V));
	}

	template <class V>
	LONG Save(int nb, V& val0, ATL::_U_STRINGorID sName)
	{
		return ::RegSetValueEx(m_Key, sName.m_lpstr, 0, REG_BINARY, (LPBYTE)&val0, nb * sizeof(V));
	}

	template <class V>
	LONG Restore(V& val, ATL::_U_STRINGorID sName)
	{
		DWORD valtype;
		DWORD bufSize = sizeof(V);
		return ::RegQueryValueEx(m_Key, sName.m_lpstr, 0, &valtype, (LPBYTE)&val, &bufSize);
	}

	template <class V>
	LONG Restore(int nb, V& val0, ATL::_U_STRINGorID sName)
	{
		DWORD valtype;
		DWORD bufSize = nb * sizeof(V);
		return ::RegQueryValueEx(m_Key, sName.m_lpstr, 0, &valtype, (LPBYTE)&val0, &bufSize);
	}

#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
#if (_ATL_VER < 0x0800)
	LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
	{
		return m_Key.SetValue(sval, sName.m_lpstr);
	}

	LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
	{
		DWORD size = MAX_PATH;
		LONG res = m_Key.QueryValue(sval.GetBuffer(size), sName.m_lpstr, &size);
		sval.ReleaseBuffer();
		return res;
	}
#else // !(_ATL_VER < 0x0800)
	LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
	{
		return m_Key.SetStringValue(sName.m_lpstr, sval);
	}

	LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName)
	{
		DWORD size = MAX_PATH;
		LONG res = m_Key.QueryStringValue(sName.m_lpstr, sval.GetBuffer(size), &size);
		sval.ReleaseBuffer();
		return res;
	}
#endif // !(_ATL_VER < 0x0800)
#else
  #pragma message("Warning: CAppInfoBase compiles without CString support. Do not use CString in Save or Restore.")
#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
	
#if (_ATL_VER < 0x0800)
	LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName)
	{
		return m_Key.SetValue(sval, sName.m_lpstr);
	}

	LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength)
	{
		return m_Key.QueryValue(sval, sName.m_lpstr, plength);
	}
#else // !(_ATL_VER < 0x0800)
	LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName)
	{
		return m_Key.SetStringValue(sName.m_lpstr, sval);
	}

	LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength)
	{
		return m_Key.QueryStringValue(sName.m_lpstr, sval, plength);
	}
#endif // !(_ATL_VER < 0x0800)
	
	LONG Delete(ATL::_U_STRINGorID sName)
	{
		return  m_Key.DeleteValue(sName.m_lpstr);
	}
};


///////////////////////////////////////////////////////////////////////////////
// CAppInfoT - CAppInfoBase constructed from a class with T::GetAppKey() 

// Macro for declaring AppKey
#define DECLARE_APPKEY(uAppKey) \
	static LPCTSTR GetAppKey() \
	{ \
		static LPCTSTR sAppKey = ATL::_U_STRINGorID(uAppKey).m_lpstr; \
		return sAppKey; \
	}

template <class T>
class CAppInfoT : public CAppInfoBase
{
public:
	CAppInfoT() : CAppInfoBase(T::GetAppKey()){}
};


///////////////////////////////////////////////////////////////////////////////
// CAppWindowBase - Base class for PPC/SmartPhone "well-behaved" application window or dialog

// Macros for declaring frame WNDCLASS and AppKey
#define DECLARE_APP_FRAME_CLASS(WndClassName, uCommonResourceID, uAppKey) \
	DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
	DECLARE_APPKEY(uAppKey)

#define DECLARE_APP_FRAME_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd, uAppKey) \
	DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \
	DECLARE_APPKEY(uAppKey)

template <class T>
class CAppWindowBase
{
public:
	typedef class CAppInfoT< T > CAppInfo;

#ifndef WIN32_PLATFORM_WFSP
	SHACTIVATEINFO m_sai; // NoOp on SmartPhones
#endif // WIN32_PLATFORM_WFSP

	bool m_bHibernate;

	CAppWindowBase< T >() : m_bHibernate(false)
	{
#ifndef WIN32_PLATFORM_WFSP
		SHACTIVATEINFO sai = { sizeof(SHACTIVATEINFO) };
		m_sai = sai;
#endif // WIN32_PLATFORM_WFSP
	};

	// Same as WTL 7.1 AppWizard generated ActivatePreviousInstance + SendMessage WM_COPYDATA
	static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR  lpstrCmdLine, bool bDialog)
	{
		// requires T does DECLARE_APP_FRAME_CLASS, DECLARE_APP_FRAME_CLASS_EX or DECLARE_APP_DLG_CLASS
		CFrameWndClassInfo& classInfo = T::GetWndClassInfo();

		ATLVERIFY(::LoadString(hInstance, classInfo.m_uCommonResourceID, classInfo.m_szAutoName, sizeof(classInfo.m_szAutoName)/sizeof(classInfo.m_szAutoName[0])) != 0);

		classInfo.m_wc.lpszClassName = classInfo.m_szAutoName;

		const TCHAR* pszClass = classInfo.m_wc.lpszClassName;

		if(NULL == pszClass || '\0' == *pszClass)
		{
			return E_FAIL;
		}

		const DWORD dRetryInterval = 100;
		const int iMaxRetries = 25;

		for(int i = 0; i < iMaxRetries; ++i)
		{
			HANDLE hMutex = CreateMutex(NULL, FALSE, pszClass);

			DWORD dw = GetLastError();

			if(NULL == hMutex)
			{
				HRESULT hr;

				switch(dw)
				{
				case ERROR_INVALID_HANDLE:
					// A non-mutext object with this name already exists.
					hr = E_INVALIDARG;
					break;
				default:
					// This should never happen...
					hr = E_FAIL;
				}

				return hr;
			}

			// If the mutex already exists, then there should be another instance running
			if(dw == ERROR_ALREADY_EXISTS)
			{
				CloseHandle(hMutex);
				
				HWND hwnd = NULL;
				if (bDialog)
					hwnd = FindWindow(NULL, pszClass);
				else
					hwnd = FindWindow(pszClass, NULL);

				if(hwnd == NULL)
				{
					Sleep(dRetryInterval);
					continue;
				}
				else
				{
					// Transmit our params to previous instance
					if (lpstrCmdLine && *lpstrCmdLine)
					{
						COPYDATASTRUCT cd = { NULL, sizeof(TCHAR) * (wcslen(lpstrCmdLine) + 1), (PVOID)lpstrCmdLine };
						::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cd);
					}
					// Set the previous instance as the foreground window
					if(0 != SetForegroundWindow(reinterpret_cast<HWND>(reinterpret_cast<ULONG>(hwnd) | 0x1)))
						return S_FALSE;
				}
			}
			else
			{
				return S_OK;
			}
		}
		return S_OK;
	}

// Operations overriden in derived class
	bool AppHibernate(bool /*bHibernate*/)
	{
		return false;
	}

	bool AppNewInstance(LPCTSTR /*lpstrCmdLine*/)
	{
		return false;
	}

	void AppSave()
	{
	}

#ifdef WIN32_PLATFORM_WFSP 
	void AppBackKey() 
	{
		::SHNavigateBack();
	}
#endif

// Message map and handlers
	BEGIN_MSG_MAP(CAppWindowBase)
		MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
#ifdef WIN32_PLATFORM_WFSP
		MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)
#else
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
#endif // WIN32_PLATFORM_WFSP
		MESSAGE_HANDLER(WM_HIBERNATE, OnHibernate)
		MESSAGE_HANDLER(WM_COPYDATA, OnNewInstance)
		MESSAGE_HANDLER(WM_CLOSE, OnClose)
	END_MSG_MAP()

	LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		if (m_bHibernate)
			m_bHibernate = pT->AppHibernate(false);
#ifndef WIN32_PLATFORM_WFSP
		::SHHandleWMActivate(pT->m_hWnd, wParam, lParam, &m_sai, 0);
#else
		wParam;
		lParam;
#endif // WIN32_PLATFORM_WFSP
		 return bHandled = FALSE;
	}

#ifdef WIN32_PLATFORM_WFSP
// SmartPhone VK_TBACK key standard management
	LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		const UINT uModif = (UINT)LOWORD(lParam);
		const UINT uVirtKey = (UINT)HIWORD(lParam);
		if(uVirtKey == VK_TBACK)
			if (AtlIsEditFocus())
				::SHSendBackToFocusWindow(uMsg, wParam, lParam);
			else if (uModif & MOD_KEYUP)
				pT->AppBackKey();
		return 1;
	}

#else // !WIN32_PLATFORM_WFSP
// PPC SIP handling
	LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		bHandled = FALSE;
		return ::SHHandleWMSettingChange(pT->m_hWnd, wParam, lParam, &m_sai);
	}
#endif // !WIN32_PLATFORM_WFSP

	LRESULT OnHibernate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		return m_bHibernate = pT->AppHibernate(true);
	}

	LRESULT OnNewInstance(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
		return pT->AppNewInstance((LPCTSTR)pcds->lpData);
	}

	LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		pT->AppSave();
		bHandled = FALSE;
		return 1;
	}
};


///////////////////////////////////////////////////////////////////////////////
// CAppWindow - PPC/SmartPhone "well-behaved" application window class

template <class T>
class CAppWindow : public CAppWindowBase< T >
{
public:
	// Same as WTL 7.1 AppWizard generated Run + lpstrCmdLine in CreateEx
	static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
	{
		CMessageLoop theLoop;
		_Module.AddMessageLoop(&theLoop);

		T wndMain;

		if(wndMain.CreateEx(NULL, NULL, 0, 0, lpstrCmdLine) == NULL)
		{
			ATLTRACE2(atlTraceUI, 0, _T("Main window creation failed!\n"));
			return 0;
		}

		wndMain.ShowWindow(nCmdShow);

		int nRet = theLoop.Run();

		_Module.RemoveMessageLoop();
		return nRet;
	}

	static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR  lpstrCmdLine)
	{
		return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, false);
	}
};


#ifndef _WTL_CE_NO_DIALOGS

///////////////////////////////////////////////////////////////////////////////
// CAppDialog - PPC/SmartPhone "well-behaved" dialog application class

// Macro for declaring dialog WNDCLASS and AppKey
#define DECLARE_APP_DLG_CLASS(WndClassName, uCommonResourceID, uAppKey) \
	static WTL::CFrameWndClassInfo& GetWndClassInfo() \
	{ \
		static WTL::CFrameWndClassInfo wc = \
		{ \
			{ 0, (WNDPROC)StartDialogProc, \
			0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \
			NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
		}; \
		return wc; \
	}; \
	DECLARE_APPKEY(uAppKey)

template <class T>
class CAppDialog : public CAppWindowBase< T >
{
public:
	static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
	{
		CMessageLoop theLoop;
		_Module.AddMessageLoop(&theLoop);

		T dlgMain;

		if(dlgMain.Create(NULL, (LPARAM)lpstrCmdLine) == NULL)
		{
			ATLTRACE2(atlTraceUI, 0, _T("Main dialog creation failed!\n"));
			return 0;
		}

		dlgMain.ShowWindow(nCmdShow);

		int nRet = theLoop.Run();

		_Module.RemoveMessageLoop();
		return nRet;
	}

	static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR  lpstrCmdLine)
	{
		return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, true);
	};
};

// PPC/SmartPhone standard application dialogs

#ifdef WIN32_PLATFORM_WFSP
#define WTL_APP_SHIDIF WTL_SP_SHIDIF
#else
#define WTL_APP_SHIDIF WTL_STD_SHIDIF
#endif

///////////////////////////////////////////////////////////////////////////////
// CAppStdDialogImplBase - Base implementation of standard application dialogs

template <class T, class TImplBase, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdDialogImplBase :
		public TImplBase, 
		public CAppDialog< T >
{ 
public:
	WTL_DLG_NOTITLE;

	void StdCloseDialog(int nVal)
	{
		T* pT = static_cast<T*>(this);
		if (nVal != IDCANCEL)
			pT->AppSave();
		if (t_bModal == false)
		{
			pT->DestroyWindow();
			::PostQuitMessage(nVal);
		}
		else
			::EndDialog(pT->m_hWnd, nVal);
	}
	
	BEGIN_MSG_MAP(CAppStdDialogImplBase)
		MESSAGE_HANDLER(WM_CLOSE, OnSystemClose)
		CHAIN_MSG_MAP(TImplBase)
		CHAIN_MSG_MAP(CAppDialog< T >)
	END_MSG_MAP()

	LRESULT OnSystemClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		T* pT = static_cast<T*>(this);
		pT->StdCloseDialog(IDCANCEL);
		return 0;
	}
};

///////////////////////////////////////////////////////////////////////////////
// CAppStdDialogImpl - Implementation of standard application dialog 

template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdDialogImpl :
		public CAppStdDialogImplBase<T, CStdDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
{};

///////////////////////////////////////////////////////////////////////////////
// CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog

template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdDialogResizeImpl :
		public CAppStdDialogImplBase<T, CStdDialogResizeImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
{};

#ifndef _ATL_NO_HOSTING
///////////////////////////////////////////////////////////////////////////////
// CAppStdAxDialogImpl - Implementation of standard application AxDialog 

template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdAxDialogImpl :
		public CAppStdDialogImplBase<T, CStdAxDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
{};

///////////////////////////////////////////////////////////////////////////////
// CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog

template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdAxDialogResizeImpl :
		public CAppStdDialogImplBase<T, CStdAxDialogResizeImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
{};
#endif // _ATL_NO_HOSTING

#if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC)
///////////////////////////////////////////////////////////////////////////////
// CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog

template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdOrientedDialogImpl :
		public CAppStdDialogImplBase<T, CStdOrientedDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
{};

#ifndef _ATL_NO_HOSTING
///////////////////////////////////////////////////////////////////////////////
// CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog

template <class T, UINT t_shidiFlags = WTL_APP_SHIDIF, bool t_bModal = false>
class ATL_NO_VTABLE CAppStdAxOrientedDialogImpl :
		public CAppStdDialogImplBase<T, CStdAxOrientedDialogImpl<T, t_shidiFlags, t_bModal>, t_shidiFlags, t_bModal>
{};
#endif // _ATL_NO_HOSTING

#endif // defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC)

#endif // _WTL_CE_NO_DIALOGS

#endif // _WTL_CE_NO_APPWINDOW


// --- Full screen support ---

#ifndef _WTL_CE_NO_FULLSCREEN

///////////////////////////////////////////////////////////////////////////////
// CFullScreenFrame - full screen frame implementation

template <class T, bool t_bHasSip = true>
class CFullScreenFrame
{
public:
	bool m_bFullScreen;

	CFullScreenFrame() : m_bFullScreen(false)
	{ }

// Operation	
	void SetFullScreen(bool bFull)
	{
		m_bFullScreen = bFull;
		ShowTaskBar(!bFull, false);
		ShowMenuBar(!bFull);
	}

// Manage TaskBar for modal dialogs and property sheets
	template <class D>
	int FSDoModal(D& dlg)
	{
		T* pT = static_cast<T*>(this);
		pT;   // avoid level 4 warning
		ATLASSERT(pT->IsWindow());
		if (m_bFullScreen)   // Show taskbar if hidden
			ShowTaskBar(true, false);
		int iRet = dlg.DoModal();
		if (m_bFullScreen)   // Hide taskbar if restored
			ShowTaskBar(false);
		return iRet;
	}

// Implementation
	void ShowMenuBar(bool bShow)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		ATL::CWindow MenuBar = pT->m_hWndCECommandBar;
		ATLASSERT(MenuBar.IsWindow());
		MenuBar.ShowWindow(bShow ? SW_SHOWNORMAL : SW_HIDE);
		pT->SizeToMenuBar();
	}
	
	void ShowTaskBar(bool bShow, bool bRepaint = true)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(pT->IsWindow());
		RECT rect = { 0 };
		SystemParametersInfo(SPI_GETWORKAREA, NULL, &rect, FALSE);
		if (!bShow)
			rect.top = 0;

#ifdef WIN32_PLATFORM_PSPC // Pocket PC code
		UINT uShow = t_bHasSip ? SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON : SHFS_SHOWTASKBAR | SHFS_HIDESIPBUTTON;		
		SHFullScreen(pT->m_hWnd, bShow ? uShow : SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
#elif _WIN32_WCE > 0x500 // Smartphone 2005 code
		SHFullScreen(pT->m_hWnd, bShow ? SHFS_SHOWTASKBAR : SHFS_HIDETASKBAR);
#else // Smartphone 2003
		HWND hTaskBar = FindWindow(_T("tray"), NULL);
		ATLASSERT(::IsWindow(hTaskBar));
		::ShowWindow(hTaskBar, bShow ? SW_SHOW : SW_HIDE);
#endif // WIN32_PLATFORM_PSPC

		pT->MoveWindow(&rect, bRepaint);
	}

// Message map and handler
	BEGIN_MSG_MAP(CFullScreenFrame)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
		MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
	END_MSG_MAP()

	LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifndef SETTINGCHANGE_RESET // not defined for PPC 2002
	#define SETTINGCHANGE_RESET SPI_SETWORKAREA
#endif
		if (m_bFullScreen && (wParam & SETTINGCHANGE_RESET))
			SetFullScreen(m_bFullScreen);
		return bHandled = FALSE;
	}

	LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		if (m_bFullScreen)
		{
			ShowTaskBar(!wParam);
			ShowMenuBar(!wParam);
		}
		return bHandled = FALSE;
	}
};

#endif // _WTL_CE_NO_FULLSCREEN


// --- WinCE zoom support ---

#ifndef _WTL_CE_NO_ZOOMSCROLL

///////////////////////////////////////////////////////////////////////////////
// CZoomScrollImpl - WinCE zooming implementation on top of CScrollImpl

template <class T>
class  CZoomScrollImpl: public CScrollImpl< T >
{
public:
// Data members
	_WTYPES_NS::CSize m_sizeTrue;
	double	m_fzoom;

// Creation
	CZoomScrollImpl() : m_sizeTrue(0), m_fzoom(1.)
	{ }

// Zoom operations and access
	void SetZoomScrollSize(_WTYPES_NS::CSize sizeTrue, double fzoom = 1., BOOL bRedraw = TRUE)
	{
		ATLASSERT(fzoom > 0.);
		m_sizeTrue = sizeTrue;
		m_fzoom = fzoom;

		CScrollImpl< T >::SetScrollSize(sizeTrue / fzoom, bRedraw);
	}

	void SetZoomScrollSize(int cx, int cy, double fzoom=1., BOOL bRedraw = TRUE)
	{
		SetZoomScrollSize(_WTYPES_NS::CSize(cx, cy), fzoom, bRedraw);
	}

	void SetZoom(double fzoom, BOOL bRedraw = TRUE)
	{
		_WTYPES_NS::CPoint ptCenter = WndtoTrue(m_sizeClient / 2);
		_WTYPES_NS::CSize sizePage = GetScrollPage();
		_WTYPES_NS::CSize sizeLine = GetScrollLine();

		SetZoomScrollSize(GetScrollSize(), fzoom, bRedraw);

		SetScrollLine(sizeLine);
		SetScrollPage(sizePage);
		_WTYPES_NS::CPoint ptOffset = ptCenter - (m_sizeClient / 2) * fzoom;
		SetScrollOffset(ptOffset, bRedraw);
	}

	double GetZoom()
	{
		return m_fzoom;
	}

// CScrollImpl overrides
	void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE)
	{
		CScrollImpl< T >::SetScrollOffset((int)(x / m_fzoom), (int)(y / m_fzoom), bRedraw);
	}

	void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE)
	{
		SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw);
	}

	void GetScrollOffset(POINT& ptOffset)
	{
		ptOffset.x = (LONG)(m_ptOffset.x * m_fzoom);
		ptOffset.y = (LONG)(m_ptOffset.y * m_fzoom);
	}

	void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE)
	{
		SetZoomScrollSize(cx, cy, GetZoom(), bRedraw);
	}

	void SetScrollSize(SIZE sizeTrue, BOOL bRedraw = TRUE)
	{
		SetZoomScrollSize(sizeTrue, GetZoom(), bRedraw);
	}

	void GetScrollSize(SIZE& sizeTrue) const
	{
		sizeTrue = m_sizeTrue;
	}

	void SetScrollPage(int cxPage, int cyPage)
	{
		SetScrollPage(_WTYPES_NS::CSize(cxPage, cyPage));
	}

	void SetScrollPage(SIZE sizePage)
	{
		CScrollImpl< T >::SetScrollPage(sizePage / m_fzoom);
	}

	void GetScrollPage(SIZE& sizePage) const
	{
		sizePage = m_sizePage * m_fzoom;
	}

	void SetScrollLine(int cxLine, int cyLine)
	{
		SetScrollLine(_WTYPES_NS::CSize(cxLine, cyLine));
	}

	void SetScrollLine(SIZE sizeLine)
	{
		CScrollImpl< T >::SetScrollLine(sizeLine / m_fzoom);
	}

	void GetScrollLine(SIZE& sizeLine) const
	{
		sizeLine = m_sizeLine * m_fzoom;
	}

// Data access complements
	_WTYPES_NS::CSize GetScrollSize()
	{
		return m_sizeTrue;
	}

	_WTYPES_NS::CSize GetScrollPage()
	{
		return m_sizePage * m_fzoom;
	}

	_WTYPES_NS::CSize GetScrollLine()
	{
		return m_sizeLine * m_fzoom;
	}

	_WTYPES_NS::CPoint GetScrollOffset()
	{
		return (_WTYPES_NS::CSize)m_ptOffset * m_fzoom;
	}

// Helper coordinate functions
	_WTYPES_NS::CPoint WndtoTrue(CPoint ptW)
	{
		return (_WTYPES_NS::CSize)ptW * GetZoom() + GetScrollOffset();
	}

	void WndtoTrue(LPPOINT aptW, int nPts)   // in place coord transformation
	{
		for (int i = 0 ; i < nPts ; i++)
			aptW[i] = WndtoTrue(aptW[i]);
	}

	void WndtoTrue(LPRECT prectW)   // in place coord transformation
	{
		WndtoTrue((LPPOINT)prectW, 2);
	}

	_WTYPES_NS::CPoint TruetoWnd(CPoint ptT)
	{
		return (ptT - GetScrollOffset()) / GetZoom();
	}

	void TruetoWnd(LPPOINT aptT, int nPts)   // in place coord transformation
	{
		for (int i = 0 ; i < nPts ; i++)
			aptT[i] = TruetoWnd(aptT[i]);
	}

	void TruetoWnd(LPRECT prectT)   // in place coord transformation
	{
		TruetoWnd((LPPOINT)prectT, 2);
	}

// Drawing operations : assume adequate setting of data members
	BOOL Draw(HBITMAP hbm, HDC hdestDC, DWORD dwROP = SRCCOPY)
	{
		CDC memDC = CreateCompatibleDC(hdestDC);
		CBitmapHandle bmpOld = memDC.SelectBitmap(hbm);
		BOOL bRes = Draw(memDC, hdestDC, dwROP);
		memDC.SelectBitmap(bmpOld);
		return bRes;
	}

	BOOL Draw(HDC hsourceDC, HDC hdestDC, DWORD dwROP = SRCCOPY)
	{
		CDCHandle destDC = hdestDC;
		destDC.SetViewportOrg(0,0);
		_WTYPES_NS::CPoint ptOffset = GetScrollOffset();
		_WTYPES_NS::CSize sizeZClient = m_sizeClient * GetZoom();
		return destDC.StretchBlt(0, 0, m_sizeClient.cx, m_sizeClient.cy, hsourceDC, ptOffset.x, ptOffset.y, sizeZClient.cx, sizeZClient.cy, dwROP);
	}

#ifdef _IMAGING_H
	BOOL Draw(IImage* pIImage, HDC hdestDC)
	{
		CDCHandle destDC = hdestDC;
		destDC.SetViewportOrg(0,0);
		return SUCCEEDED(pIImage->Draw(destDC, _WTYPES_NS::CRect(-_WTYPES_NS::CPoint(m_ptOffset), m_sizeAll), NULL));
	}
#endif

// Message map and handlers
	BEGIN_MSG_MAP(CZoomScrollImpl< T >)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
		CHAIN_MSG_MAP(CScrollImpl< T >)
	END_MSG_MAP()
	
	LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);
		ATLASSERT(::IsWindow(pT->m_hWnd));
		if ((GetScrollExtendedStyle() & SCRL_ERASEBACKGROUND))
		{
			_WTYPES_NS::CRect rect;
			pT->GetClientRect(rect);
			_WTYPES_NS::CSize sizeClient=rect.Size();

			if (m_sizeAll.cx < sizeClient.cx || m_sizeAll.cy < sizeClient.cy)
			{
				CDCHandle hdc = (HDC)wParam;
				HBRUSH hbr = GetSysColorBrush((int)T::GetWndClassInfo().m_wc.hbrBackground - 1);

				if (m_sizeAll.cx < sizeClient.cx)
				{
					_WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(m_sizeAll.cx, 0), sizeClient);
					hdc.FillRect(rectBG, hbr);
				}

				if (m_sizeAll.cy < sizeClient.cy)
				{
					_WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(0, m_sizeAll.cy), sizeClient);
					hdc.FillRect(rectBG, hbr);
				}
			}
		}
		else
		{
			bHandled = FALSE;
		}

		return 1;
 	}
};

#endif // _WTL_CE_NO_ZOOMSCROLL

#ifndef _WTL_CE_NO_CONTROLS

// --- PPC bottom TabView control ---

#if defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC)

///////////////////////////////////////////////////////////////////////////////
// CBottomTabViewImpl

template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CBottomTabViewImpl : public CTabViewImpl<T, TBase, TWinTraits>
{
public:
	DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE)

// Implementation overrideables
	bool CreateTabControl()
	{
		m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | TCS_BOTTOM, 0, m_nTabID);

		ATLASSERT(m_tab.m_hWnd != NULL);
		if(m_tab.m_hWnd == NULL)
			return false;

		m_tab.SendMessage(CCM_SETVERSION, COMCTL32_VERSION);
		m_tab.SetItemExtra(sizeof(TABVIEWPAGE));

		T* pT = static_cast<T*>(this);
		m_cyTabHeight = pT->CalcTabHeight();

		return true;
	}

	int CalcTabHeight()
	{
		int nCount = m_tab.GetItemCount();
		TCITEMEXTRA tcix = { 0 };
		tcix.tciheader.mask = TCIF_TEXT;
		tcix.tciheader.pszText = _T("NS");
		int nIndex = m_tab.InsertItem(nCount, tcix);

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

		m_tab.AdjustRect(FALSE, &rect);
		rcWnd.top = rect.bottom;
		::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle());
		m_tab.DeleteItem(nIndex);

		return rcWnd.bottom - rcWnd.top;
	}

	void UpdateLayout()
	{
		RECT rect;
		GetClientRect(&rect);

		if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0))
			m_tab.SetWindowPos(NULL, 0, rect.bottom - m_cyTabHeight, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER /*| SWP_SHOWWINDOW*/);

		if(m_nActivePage != -1)
				::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, 0, rect.right - rect.left, rect.bottom - m_cyTabHeight, SWP_NOZORDER);
	}

};

class CBottomTabView : public CBottomTabViewImpl<CBottomTabView>
{
public:
	DECLARE_WND_CLASS_EX(_T("WTL_BottomTabView"), 0, COLOR_APPWORKSPACE)
};

#endif // defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC)


// --- PPC/SmartPhone controls ---

////////////////////////////////////////////////////////////////////////////////
// These are wrapper classes for the Pocket PC 2002/2003 and SmartPhone 2003 controls
// To implement a window based on a control, use following:
// Example: Implementing a window based on a Html control
//
// class CMyHtml : CWindowImpl<CMyHtml, CHtmlCtrl>
// {
// public:
//      BEGIN_MSG_MAP(CMyHtml)
//          // put your message handler entries here
//      END_MSG_MAP()
// };
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// CHtmlCtrl

template <class TBase>
class CHtmlCtrlT : public TBase
{
public:
// Constructors
	CHtmlCtrlT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CHtmlCtrlT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		ATLASSERT(hWnd != NULL);   // Did you remember to call InitHTMLControl(hInstance) ??
		return hWnd;
	}

// Attributes
	static LPCTSTR GetWndClassName()
	{
		return WC_HTML;
	}

#if (_WIN32_WCE >= 400)
	void AddStyle(LPCWSTR pszStyle)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ADDSTYLE, 0, (LPARAM)pszStyle);
	}
#endif // (_WIN32_WCE >= 400)

	void AddText(BOOL bPlainText, LPCSTR pszText)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)bPlainText, (LPARAM)pszText);
	}

	void AddHTML(LPCSTR pszHTML)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)FALSE, (LPARAM)pszHTML);
	}

	void AddText(BOOL bPlainText, LPCWSTR pszText)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)bPlainText, (LPARAM)pszText);
	}

	void AddHTML(LPCWSTR pszHTML)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)FALSE, (LPARAM)pszHTML);
	}

	void Anchor(LPCSTR pszAnchor)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ANCHOR, 0, (LPARAM)pszAnchor);
	}

	void Anchor(LPCWSTR pszAnchor)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ANCHORW, 0, (LPARAM)pszAnchor);
	}

#if (_WIN32_WCE >= 420)
	void GetBrowserDispatch(IDispatch** ppDispatch)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(ppDispatch);
		ATLASSERT(*ppDispatch==NULL);
		::SendMessage(m_hWnd, DTM_BROWSERDISPATCH, 0, (LPARAM)ppDispatch);
	}
	void GetDocumentDispatch(IDispatch** ppDispatch)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(ppDispatch);
		ATLASSERT(*ppDispatch==NULL);
		::SendMessage(m_hWnd, DTM_DOCUMENTDISPATCH , 0, (LPARAM)ppDispatch);
	}
#endif // (_WIN32_WCE >= 420)

	void Clear()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_CLEAR, 0, 0L);
	}

	void EnableClearType(BOOL bEnable = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ENABLECLEARTYPE, 0, (LPARAM)bEnable);
	}

	void EnableContextMenu(BOOL bEnable = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ENABLECONTEXTMENU, 0, (LPARAM)bEnable);
	}

	void EnableScripting(BOOL bEnable = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ENABLESCRIPTING, 0, (LPARAM)bEnable);
	}

	void EnableShrink(BOOL bEnable = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ENABLESHRINK, 0, (LPARAM)bEnable);
	}

	void EndOfSource()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ENDOFSOURCE, 0, 0L);
	}

	void ImageFail(DWORD dwCookie)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_IMAGEFAIL, 0, (LPARAM)dwCookie);
	}

	int GetLayoutHeight() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DTM_LAYOUTHEIGHT, 0, 0L);
	}

	int GetLayoutWidth() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DTM_LAYOUTWIDTH, 0, 0L);
	}

	void Navigate(LPCTSTR pstrURL, UINT uFlags = 0)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrURL);
		::SendMessage(m_hWnd, DTM_NAVIGATE, (WPARAM)uFlags, (LPARAM)pstrURL);
	}

	void SelectAll()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_SELECTALL, 0, 0L);
	}

	void SetImage(INLINEIMAGEINFO* pImageInfo)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pImageInfo);
		::SendMessage(m_hWnd, DTM_SETIMAGE, 0, (LPARAM)pImageInfo);
	}

	void ZoomLevel(int iLevel)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_ZOOMLEVEL, 0, (LPARAM)iLevel);
	}

#if (_WIN32_WCE >= 400)
	void Stop()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DTM_STOP, 0, 0L);
	}
#endif // (_WIN32_WCE >= 400)

	void GetScriptDispatch(IDispatch** ppDispatch)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(ppDispatch);
		ATLASSERT(*ppDispatch==NULL);
		::SendMessage(m_hWnd, DTM_SCRIPTDISPATCH, 0, (LPARAM)ppDispatch);
	}
};

typedef CHtmlCtrlT<ATL::CWindow> CHtmlCtrl;


#ifdef WIN32_PLATFORM_PSPC

///////////////////////////////////////////////////////////////////////////////
// CRichInkCtrl

template <class TBase>
class CRichInkCtrlT : public TBase
{
public:
// Constructors
	CRichInkCtrlT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CRichInkCtrlT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		ATLASSERT(hWnd != NULL);   // Did you remember to call InitRichInkDLL() ??
		return hWnd;
	}

// Attributes
	static LPCTSTR GetWndClassName()
	{
		return WC_RICHINK;
	}

	BOOL CanPaste(UINT uFormat = 0) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, (WPARAM)uFormat, 0L);
	}

	BOOL CanRedo() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L);
	}

	BOOL CanUndo() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L);
	}

	void ClearAll(BOOL bRepaint = TRUE) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_CLEARALL, (WPARAM)bRepaint, 0L);
	}

	BOOL GetModify() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L);
	}

	UINT GetPageStyle() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (UINT)::SendMessage(m_hWnd, EM_GETPAGESTYLE, 0, 0L);
	}

	UINT GetPenMode() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (UINT)::SendMessage(m_hWnd, EM_GETPENMODE, 0, 0L);
	}

	UINT GetViewStyle() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (UINT)::SendMessage(m_hWnd, EM_GETVIEW, 0, 0L);
	}

	UINT GetWrapMode() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (UINT)::SendMessage(m_hWnd, EM_GETWRAPMODE, 0, 0L);
	}

	UINT GetZoomPercent() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (UINT)::SendMessage(m_hWnd, EM_GETZOOMPERCENT, 0, 0L);
	}

	void InsertLinks(LPWSTR lpString, int cchLength = -1)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		if(cchLength == -1)
			cchLength = lstrlen(lpString);
		::SendMessage(m_hWnd, EM_INSERTLINKS, (WPARAM)cchLength, (LPARAM)lpString);
	}

	void RedoEvent()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_REDOEVENT, 0, 0L);
	}

	UINT SetInkLayer(UINT uLayer)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (UINT)::SendMessage(m_hWnd, EM_SETINKLAYER, (WPARAM)uLayer, 0L);
	}

	void SetPageStyle(UINT uStyle)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_SETPAGESTYLE, (WPARAM)uStyle, 0L);
	}

	void SetPenMode(UINT uMode)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_SETPENMODE, (WPARAM)uMode, 0L);
	}

	void SetViewStyle(UINT uStyle)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_SETVIEW, (WPARAM)uStyle, 0L);
	}

	void SetViewAttributes(VIEWATTRIBUTES* pAttribs)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pAttribs);
		::SendMessage(m_hWnd, EM_SETVIEWATTRIBUTES, 0, (LPARAM)pAttribs);
	}

	void SetWrapMode(UINT uMode)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_SETWRAPMODE, (WPARAM)uMode, 0L);
	}

	void SetZoomPercent(UINT uPercent)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_SETZOOMPERCENT, (WPARAM)uPercent, 0L);
	}

	LONG StreamIn(UINT uFormat, EDITSTREAM& es)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, (WPARAM)uFormat, (LPARAM)&es);
	}

	LONG StreamOut(UINT uFormat, EDITSTREAM& es)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, (WPARAM)uFormat, (LPARAM)&es);
	}

	void UndoEvent()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_UNDOEVENT, 0, 0L);
	}

// Standard EM_xxx messages
	DWORD GetSel() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L);
	}

	void GetSel(int& nStartChar, int& nEndChar) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar);
	}

	void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM)bCanUndo, (LPARAM)lpszNewText);
	}

	void SetModify(BOOL bModified = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, EM_SETMODIFY, (WPARAM)bModified, 0L);
	}

	int GetTextLength() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L);
	}

// Clipboard operations
	void Clear()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, WM_CLEAR, 0, 0L);
	}

	void Copy()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, WM_COPY, 0, 0L);
	}

	void Cut()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, WM_CUT, 0, 0L);
	}

	void Paste()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, WM_PASTE, 0, 0L);
	}
};

typedef CRichInkCtrlT<ATL::CWindow> CRichInkCtrl;


///////////////////////////////////////////////////////////////////////////////
// CInkXCtrl

template <class TBase>
class CInkXCtrlT : public TBase
{
public:
// Constructors
	CInkXCtrlT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CInkXCtrlT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		ATLASSERT(hWnd != NULL);   // Did you remember to call InitInkX() ??
		return hWnd;
	}

// Attributes
	static LPCTSTR GetWndClassName()
	{
		return WC_INKX;
	}

	static UINT GetHotRecordingMessage()
	{
		return ::RegisterWindowMessage(szHotRecording);
	}

	void ClearAll()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, IM_CLEARALL, 0, 0L);
	}

	int GetData(BYTE* lpBuffer, INT cbBuffer) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(lpBuffer);
		return (int)::SendMessage(m_hWnd, IM_GETDATA, (WPARAM)cbBuffer, (LPARAM)lpBuffer);
	}

	int GetDataLen() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, IM_GETDATALEN, 0, 0L);
	}

	CRichInkCtrl GetRichInk() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (HWND)::SendMessage(m_hWnd, IM_GETRICHINK, 0, 0L);
	}

	BOOL IsRecording() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, IM_RECORDING, 0, 0L);
	}

	void ReInit()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, IM_REINIT, 0, 0L);
	}

	void SetData(const BYTE* lpInkData, INT cbInkData)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(lpInkData);
		::SendMessage(m_hWnd, IM_SETDATA, (WPARAM)cbInkData, (LPARAM)lpInkData);
	}

	void VoicePlay()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, IM_VOICE_PLAY, 0, 0L);
	}

	BOOL IsVoicePlaying() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, IM_VOICE_PLAYING, 0, 0L);
	}

	BOOL VoiceRecord()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, IM_VOICE_RECORD, 0, 0L);
	}

	void VoiceStop()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, IM_VOICE_STOP, 0, 0L);
	}

	void ShowVoiceBar(BOOL bShow = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, IM_VOICEBAR, (WPARAM)bShow, 0L);
	}
};

typedef CInkXCtrlT<ATL::CWindow> CInkXCtrl;

#endif // WIN32_PLATFORM_PSPC


///////////////////////////////////////////////////////////////////////////////
// CVoiceRecorderCtrl

template <class TBase>
class CVoiceRecorderCtrlT : public TBase
{
public:
// Constructors
	CVoiceRecorderCtrlT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CVoiceRecorderCtrlT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, const POINT pt, LPTSTR pstrFileName, UINT nID, DWORD dwStyle = 0)
	{
		ATLASSERT(pstrFileName != NULL);
		CM_VOICE_RECORDER cmvr = { 0 };
		cmvr.cb = sizeof(CM_VOICE_RECORDER);
		cmvr.dwStyle = dwStyle;
		cmvr.xPos = pt.x;
		cmvr.yPos = pt.y;
		cmvr.hwndParent = hWndParent;
		cmvr.id = nID;
		cmvr.lpszRecordFileName = pstrFileName;
		m_hWnd = VoiceRecorder_Create(&cmvr);
		return m_hWnd;
	}

	HWND Create(LPCM_VOICE_RECORDER pAttribs)
	{
		ATLASSERT(pAttribs);
		m_hWnd = VoiceRecorder_Create(pAttribs);
		return m_hWnd;
	}

// Attributes
	void Record()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, VRM_RECORD, 0, 0L);
	}

	void Play()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, VRM_PLAY, 0, 0L);
	}

	void Stop()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, VRM_STOP, 0, 0L);
	}

	void Cancel()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, VRM_CANCEL, 0, 0L);
	}

	void Done()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, VRM_OK, 0, 0L);
	}
};

typedef CVoiceRecorderCtrlT<ATL::CWindow> CVoiceRecorderCtrl;


#ifdef WIN32_PLATFORM_PSPC

///////////////////////////////////////////////////////////////////////////////
// CDocListCtrl

template <class TBase>
class CDocListCtrlT : public TBase
{
public:
// Attributes
	DOCLISTCREATE m_dlc;
	TCHAR m_szPath[MAX_PATH];

// Constructors
	CDocListCtrlT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CDocListCtrlT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, WORD wId, LPCTSTR pszFolder = NULL, LPCTSTR pstrFilter = NULL,
			WORD wFilterIndex = 0, DWORD dwFlags = DLF_SHOWEXTENSION)
	{
		ATLASSERT(pstrFilter != NULL);   // It seems to need a filter badly!!
		::ZeroMemory(&m_dlc, sizeof(DOCLISTCREATE));
		::ZeroMemory(m_szPath, sizeof(m_szPath));
		if(pszFolder != NULL)
			::lstrcpyn(m_szPath, pszFolder, MAX_PATH - 1);
		m_dlc.dwStructSize = sizeof(DOCLISTCREATE);
		m_dlc.hwndParent = hWndParent;
		m_dlc.pszFolder = m_szPath;
		m_dlc.pstrFilter = pstrFilter;
		m_dlc.wFilterIndex = wFilterIndex;
		m_dlc.wId = wId;
		m_dlc.dwFlags = dwFlags;
		m_hWnd = DocList_Create(&m_dlc);
		return m_hWnd;
	}

	HWND Create(DOCLISTCREATE* pDlc)
	{
		m_dlc = *pDlc;
		m_hWnd = DocList_Create(&m_dlc);
		return m_hWnd;
	}

// Attributes
	void DeleteSel()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_DELETESEL, 0, 0L);
	}

	void DisableUpdates()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_DISABLEUPDATES, 0, 0L);
	}

	void EnableUpdates()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_ENABLEUPDATES, 0, 0L);
	}

	int GetFilterIndex() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DLM_GETFILTERINDEX, 0, 0L);
	}

	int GetItemCount() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DLM_GETITEMCOUNT, 0, 0L);
	}

	int GetNextItem(int iIndex, DWORD dwRelation = LVNI_ALL) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)iIndex, (LPARAM)dwRelation);
	}

	int GetFirstItem(DWORD dwRelation = LVNI_ALL) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)-1, (LPARAM)dwRelation);
	}

	BOOL GetNextWave(int* pIndex) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pIndex);
		return (BOOL)::SendMessage(m_hWnd, DLM_GETNEXTWAVE, 0, (LPARAM)pIndex);
	}

	BOOL GetPrevWave(int* pIndex) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pIndex);
		return (BOOL)::SendMessage(m_hWnd, DLM_GETPREVWAVE, 0, (LPARAM)pIndex);
	}

	int GetSelCount() const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DLM_GETSELCOUNT, 0, 0L);
	}

	BOOL GetSelPathName(LPTSTR pstrPath, int cchMax) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrPath);
		return (BOOL)::SendMessage(m_hWnd, DLM_GETSELPATHNAME, (WPARAM)cchMax, (LPARAM)pstrPath);
	}

	void ReceiveIR(LPCTSTR pstrPath) const
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrPath);
		::SendMessage(m_hWnd, DLM_RECEIVEIR, 0, (LPARAM)pstrPath);
	}

	void Refresh()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_REFRESH, 0, 0L);
	}

	BOOL RenameMoveSelectedItems()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, DLM_RENAMEMOVE, 0, 0L);
	}

	int SelectAll()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (int)::SendMessage(m_hWnd, DLM_SELECTALL, 0, 0L);
	}

	HRESULT SelectItem(LPCTSTR pstrPath, BOOL bVisible = TRUE)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrPath);
		return (HRESULT)::SendMessage(m_hWnd, DLM_SELECTITEM, (WPARAM)bVisible, (LPARAM)pstrPath);
	}

	void SendEMail(LPCTSTR pstrAttachment)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_SENDEMAIL, 0, (LPARAM)pstrAttachment);
	}

	void SendIR(LPCTSTR pstrPath)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_SENDIR, 0, (LPARAM)pstrPath);
	}

	HRESULT SetFilterIndex(int iIndex)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (HRESULT)::SendMessage(m_hWnd, DLM_SETFILTERINDEX, (WPARAM)iIndex, 0L);
	}

	void SetFolder(LPCTSTR pstrPath)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrPath);
		::SendMessage(m_hWnd, DLM_SETFOLDER, 0, (LPARAM)pstrPath);
	}

	BOOL SetItemState(int iIndex, const LVITEM* pItem)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pItem);
		return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)pItem);
	}

	BOOL SetItemState(int iIndex, UINT uState, UINT uMask)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		LV_ITEM lvi = { 0 };
		lvi.stateMask = uMask;
		lvi.state = uState;
		return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)&lvi);
	}

	void SetOneItem(int iIndex, LPCVOID pPA)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_SETONEITEM, (WPARAM)iIndex, (LPARAM)pPA);
	}

	void SetSelect(int iIndex)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		::SendMessage(m_hWnd, DLM_SETSELECT, (WPARAM)iIndex, 0L);
	}

	void SetSelPathName(LPCTSTR pstrPath)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrPath);
		::SendMessage(m_hWnd, DLM_SETSELPATHNAME, 0, (LPARAM)pstrPath);
	}

	BOOL SetSortOrder()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, DLM_SETSORTORDER, 0, 0L);
	}

	HRESULT Update()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (HRESULT)::SendMessage(m_hWnd, DLM_UPDATE, 0, 0L);
	}

	BOOL ValidateFolder()
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return (BOOL)::SendMessage(m_hWnd, DLM_VALIDATEFOLDER, 0, 0L);
	}

// Functions
	BOOL GetFirstSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return DocList_GetFirstSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath);
	}

	BOOL GetNextSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		return DocList_GetNextSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath);
	}
};

typedef CDocListCtrlT<ATL::CWindow> CDocListCtrl;

#endif // WIN32_PLATFORM_PSPC


///////////////////////////////////////////////////////////////////////////////
// CCapEdit

template <class TBase>
class CCapEditT : public TBase
{
public:
// Constructors
	CCapEditT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CCapEditT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND hWnd = /*TBase*/CWindow::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		ATLASSERT(hWnd != NULL);   // Did you remember to call SHInitExtraControls() ??
		return hWnd;
	}

// Attributes
	static LPCTSTR GetWndClassName()
	{
		return WC_CAPEDIT;
	}
};

typedef CCapEditT<WTL::CEdit> CCapEdit;

///////////////////////////////////////////////////////////////////////////////
// CTTStatic

#ifndef WIN32_PLATFORM_WFSP // Tooltips not supported on SmartPhone

template <class TBase>
class CTTStaticT : public TBase
{
public:
// Constructors
	CTTStaticT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CTTStaticT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		ATLASSERT(hWnd != NULL);   // Did you remember to call SHInitExtraControls() ??
		return hWnd;
	}

// Attributes
	static LPCTSTR GetWndClassName()
	{
		return WC_TSTATIC;
	}

// Operations
	BOOL SetToolTipText(LPCTSTR pstrTipText)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrTipText);
		ATLASSERT(lstrlen(pstrTipText)<= 253);
		CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
		LPTSTR pstr = buff.Allocate(lstrlen(pstrTipText) + 3);
		if(pstr == NULL)
			return FALSE;
		::lstrcpy(pstr, _T("~~"));
		::lstrcat(pstr, pstrTipText);
		return SetWindowText(pstr);
	}
};

typedef CTTStaticT<WTL::CStatic> CTTStatic;


///////////////////////////////////////////////////////////////////////////////
// CTTButton

template <class TBase>
class CTTButtonT : public TBase
{
public:
// Constructors
	CTTButtonT(HWND hWnd = NULL) : TBase(hWnd)
	{ }

	CTTButtonT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		ATLASSERT(hWnd != NULL);   // Did you remember to call SHInitExtraControls() ??
		return hWnd;
	}

// Attributes
	static LPCTSTR GetWndClassName()
	{
		return WC_TBUTTON;
	}

// Operations
	BOOL SetToolTipText(LPCTSTR pstrTipText)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		ATLASSERT(pstrTipText);
		ATLASSERT(lstrlen(pstrTipText)<= 253);
		CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
		LPTSTR pstr = buff.Allocate(lstrlen(pstrTipText) + 3);
		if(pstr == NULL)
			return FALSE;
		::lstrcpy(pstr, _T("~~"));
		::lstrcat(pstr, pstrTipText);
		return SetWindowText(pstr);
	}
};

typedef CTTButtonT<WTL::CButton> CTTButton;

#endif // !WIN32_PLATFORM_WFSP


// --- SmartPhone specific controls ---

#ifdef WIN32_PLATFORM_WFSP

///////////////////////////////////////////////////////////////////////////////
// CSpinCtrlT - CSpinCtrl : SmartPhone adapted UpDown control

template <class TBase>
class CSpinCtrlT : public CUpDownCtrlT< TBase >
{
public:
// Constructors
	CSpinCtrlT(HWND hWnd = NULL) : CUpDownCtrlT< TBase >(hWnd)
	{ }

	CSpinCtrlT< TBase >& operator =(HWND hWnd)
	{
		m_hWnd = hWnd;
		return *this;
	}

	HWND Create(HWND hWndParent, HWND hBuddy, DWORD dwStyle, int nID, LPCTSTR szExpandedName = NULL)
	{
		ATLASSERT(::IsWindow(hWndParent));
		CUpDownCtrlT< TBase >::Create(hWndParent, NULL, szExpandedName, dwStyle, 0, nID, NULL);
		ATLASSERT(m_hWnd != NULL);   // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)?
		if (hBuddy != NULL)
		{
			ATLASSERT(::IsWindow(hBuddy));
			SetBuddy(hBuddy);
		}
		return m_hWnd;
	}
};

typedef CSpinCtrlT<ATL::CWindow> CSpinCtrl;


///////////////////////////////////////////////////////////////////////////////
// CSpinned - SmartPhone association of control and Spin

template <class TBase, bool t_bExpandOnly>
class CSpinned : public TBase
{
public:
	CSpinCtrl m_SpinCtrl;
	DWORD m_dwSpinnedStyle;

// Constructors
	CSpinned(HWND hWnd = NULL) : TBase(hWnd)
	{
		m_dwSpinnedStyle = WS_VISIBLE | UDS_ALIGNRIGHT | UDS_EXPANDABLE;
		
		if (t_bExpandOnly == true)
			m_dwSpinnedStyle |= UDS_NOSCROLL;
		else
			m_dwSpinnedStyle |= UDS_HORZ | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP;

		if (hWnd != NULL)
			AttachOrCreateSpinCtrl();
	}

	CSpinned<TBase, t_bExpandOnly>& operator =(HWND hWnd)
	{
		Attach(hWnd);
		return *this;
	}

	void Attach(HWND hWnd)
	{
		ATLASSERT(!IsWindow());
		TBase* pT = static_cast<TBase*>(this);
		pT->m_hWnd = hWnd;
		if (hWnd != NULL)
			AttachOrCreateSpinCtrl();
	}

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szExpandedName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{

		TBase* pT = static_cast<TBase*>(this);
		TBase::Create(hWndParent, rect, NULL, dwStyle, dwExStyle, MenuOrID, lpCreateParam);
		ATLASSERT(pT->m_hWnd != NULL);

		m_SpinCtrl.Create(hWndParent, pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + (int)MenuOrID.m_hMenu, szExpandedName);

		ATLASSERT(m_SpinCtrl.m_hWnd != NULL);   // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)?

		return pT->m_hWnd;
	}

// Attributes
	CSpinCtrl& GetSpinCtrl()
	{
		return m_SpinCtrl;
	}

// Implementation
	// Attach our existing SpinCtrl or create one
	bool AttachOrCreateSpinCtrl()
	{
		TBase* pT = static_cast<TBase*>(this);

		HWND hSpin = ::GetDlgItem(pT->GetParent(), ATL_IDW_SPIN_ID + pT->GetDlgCtrlID());

		if (hSpin != NULL)
		{
			m_SpinCtrl.Attach(hSpin);
#ifdef DEBUG
			TCHAR sClassName[16];
			::GetClassName(hSpin, sClassName, 16);
			ATLASSERT(!_tcscmp(sClassName, UPDOWN_CLASS));
			ATLASSERT(m_SpinCtrl.GetBuddy().m_hWnd == pT->m_hWnd);
#endif // DEBUG
		}
		else
		{
			m_SpinCtrl.Create(pT->GetParent(), pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + pT->GetDlgCtrlID());
		}

		return m_SpinCtrl.m_hWnd != NULL;
	}
};


///////////////////////////////////////////////////////////////////////////////
// CSpinListBox - SmartPhone spinned ListBox control
// CExpandListBox - SmartPhone expandable ListBox control
// CExpandEdit - SmartPhone expandable Edit control
// CExpandCapEdit - SmartPhone expandable CapEdit control

typedef CSpinned<CListBox, false>   CSpinListBox;
typedef CSpinned<CListBox, true>    CExpandListBox;
typedef CSpinned<CEdit, true>		CExpandEdit;
typedef CSpinned<CCapEdit, true>    CExpandCapEdit;

#endif // WIN32_PLATFORM_WFSP

#endif // _WTL_CE_NO_CONTROLS

}; // namespace WTL

#endif // __ATLWINCE_H__
