/////////////////////////////////////////////////////////////////////////////
//
//	$Revision: 1 $
//
//	Name		:	XUIHelper.cpp
//
//	Purpose		:	Helper functions
//	
//	Written		:	cchow	07/2006
//
//	Description	:	Miscellaneous helper functions
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <Shlwapi.h>
#include "XUIHelper.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CXUIHelper::CXUIHelper()
{
}

CXUIHelper::~CXUIHelper()
{
}

////////////////////////////////////////////////////////////////////////////////
//
//   Function   :	IsPPCLayout
//
//   Description:	Determines if we are in the PocketPC (portrait) layout
//
//   Arguments  :	none
//
//   Returns:   :	true if PPC layout, false otherwise
//
//   Comments   :	none
//
////////////////////////////////////////////////////////////////////////////////
bool CXUIHelper::IsPPCLayout()
{
	return SCR_PPC == GetScreenLayout();
}

////////////////////////////////////////////////////////////////////////////////
//
//   Function   :	GetScreenLayout
//
//   Description:	Determines the screen layout
//
//   Arguments  :	none
//
//   Returns:   :	Screen Layout enumeration
//
//   Comments   :	none
//
////////////////////////////////////////////////////////////////////////////////
E_SCREENLAYOUT CXUIHelper::GetScreenLayout()
{
	int iX, iY;

	// Get screen size
	iX = GetSystemMetrics(SM_CXSCREEN);
	iY = GetSystemMetrics(SM_CYSCREEN);

	if (240 == iX &&
		320 >= iY)
	{
		// Pocket PC
		return SCR_PPC;
	}
	else if (	320 == iX &&
				240 >= iY)
	{
		// Pocket PC Landscape
		return SCR_PPC_LANDSCAPE;
	}
#ifdef UNDER_CE
	else if (	640 == iX &&
				480 >= iY)
	{
		// Also Pocket PC Landscape
		return SCR_PPC_LANDSCAPE;
	}
#endif //UNDER_CE
	else
	{
		// Default
		return SCR_NORMAL;
	}
}

/////////////////////////////////////////////////////////////////////////////
//
//   Function   :	GetWorkingWindowRect
//
//   Description:	Returns the work area RECT of the specified window
//
//   Arguments  :	[in]hwnd		- handle of window
//					[out]rect		- rect coordinates of work area
//
//   Returns:   :	none
//
//   Comments   :	rect is not guaranteed to be positive (for multiple
//					monitors)
//
/////////////////////////////////////////////////////////////////////////////
void CXUIHelper::GetWorkingWindowRect(HWND hwnd, LPRECT rect)
{
	HMONITOR	hMon;
	MONITORINFO	mi;

	// Get closest monitor to window
	hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

	memset(&mi, 0, sizeof(MONITORINFO));
	mi.cbSize	= sizeof(MONITORINFO);
	if (GetMonitorInfo(hMon, &mi))
	{
		*rect = mi.rcWork;
	}
	else
	{
		// Get screen rect of default display
		::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0);
	}
}

#ifndef UNDER_CE
/////////////////////////////////////////////////////////////////////////////
//
//   Function   :	BoldRichEditText
//
//   Description:	Bolds text in a richedit control
//
//   Arguments  :	[in]pEditCtrl	- rich edit control
//					[in]szDelim		- delimiter enclosing text to bold
//
//   Returns:   :	none
//
//   Comments   :	Text to be bolded must be enclosed in a pair of
//					arbitrary delimiters
//
/////////////////////////////////////////////////////////////////////////////
void CXUIHelper::BoldRichEditText(CRichEditCtrl* pEditCtrl, LPCTSTR szDelim)
{
	if (NULL == pEditCtrl ||
		!::IsWindow(pEditCtrl->GetSafeHwnd()))
	{
		return;
	}

	CString	strText;
	int		nPosStart	= -1;
	int		nPosEnd		= -1;

	pEditCtrl->GetWindowText(strText);
	nPosStart = strText.Find(szDelim);
	if (-1 != nPosStart)
	{
		nPosEnd = strText.Find(szDelim, nPosStart+1);

		if (-1 != nPosEnd)
		{
			CHARFORMAT cf;

			// Bold the text
			memset(&cf, 0, sizeof(cf));
			cf.cbSize		= sizeof(cf);
			cf.dwMask		= CFM_BOLD;
			cf.dwEffects	= CFE_BOLD;

			pEditCtrl->SetSel(nPosStart, nPosEnd);
			pEditCtrl->SetSelectionCharFormat(cf);

			// Remove the delimiters
			pEditCtrl->SetReadOnly(FALSE);
			pEditCtrl->SetSel(nPosEnd, nPosEnd+1);
			pEditCtrl->Clear();
			pEditCtrl->SetSel(nPosStart, nPosStart+1);
			pEditCtrl->Clear();
			pEditCtrl->SetReadOnly(TRUE);
		}
	}

}
#endif // UNDER_CE

////////////////////////////////////////////////////////////////////////////////
//
//   Function   :	IsApplicationThemed
//
//   Description:	Determines whether the application has themed UI (ComCtl32.dll v6.0+)
//
//   Arguments  :	none
//
//   Returns:   :	True if the app. UI is themed
//
//   Comments   :	Can return true on XP / WinServer 2003 / Vista when themes are
//                  enabled and the app. has appropriate manifest (embeded or external)
//
////////////////////////////////////////////////////////////////////////////////
bool CXUIHelper::IsApplicationThemed()
{
	bool ret = false;
	
	OSVERSIONINFO ovi = {0};
	ovi.dwOSVersionInfoSize = sizeof ovi;
	GetVersionEx(&ovi);
	
	if (ovi.dwMajorVersion > 5 || (ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1))
	{  // WinXP and newer
		typedef BOOL WINAPI ISAPPTHEMED();
		typedef BOOL WINAPI ISTHEMEACTIVE();
		ISAPPTHEMED* pISAPPTHEMED = NULL;
		ISTHEMEACTIVE* pISTHEMEACTIVE = NULL;

		HMODULE hMod = LoadLibrary(_T("uxtheme.dll"));
		if (hMod)
		{
#ifdef UNDER_CE
			pISAPPTHEMED = reinterpret_cast<ISAPPTHEMED*>(GetProcAddress(hMod, _T("IsAppThemed")));
			pISTHEMEACTIVE = reinterpret_cast<ISTHEMEACTIVE*>(GetProcAddress(hMod, _T("IsThemeActive")));
#else
			pISAPPTHEMED = reinterpret_cast<ISAPPTHEMED*>(GetProcAddress(hMod, "IsAppThemed"));
			pISTHEMEACTIVE = reinterpret_cast<ISTHEMEACTIVE*>(GetProcAddress(hMod, "IsThemeActive"));
#endif
			if (pISAPPTHEMED && pISTHEMEACTIVE && pISAPPTHEMED() && pISTHEMEACTIVE())
			{
				typedef HRESULT CALLBACK DLLGETVERSION(DLLVERSIONINFO*);
				DLLGETVERSION* pDLLGETVERSION = NULL;

				HMODULE hModComCtl = LoadLibrary(_T("comctl32.dll"));
				if (hModComCtl)
				{
#ifdef UNDER_CE
					pDLLGETVERSION = reinterpret_cast<DLLGETVERSION*>(
						GetProcAddress(hModComCtl, _T("DllGetVersion")));
#else
					pDLLGETVERSION = reinterpret_cast<DLLGETVERSION*>(
						GetProcAddress(hModComCtl, "DllGetVersion"));
#endif // UNDER_CE
					if (pDLLGETVERSION)
					{
						DLLVERSIONINFO dvi = {0};
						dvi.cbSize = sizeof dvi;
						if (pDLLGETVERSION(&dvi) == NOERROR)
							ret = dvi.dwMajorVersion >= 6;
					}
					FreeLibrary(hModComCtl);
				}
			}
            FreeLibrary(hMod);
		}
	}
    return ret;
}
