diff --git a/Source/3rd Party/WTL/WTL.vcproj b/Source/3rd Party/WTL/WTL.vcproj
index acbf10d8c..c8297c90d 100644
--- a/Source/3rd Party/WTL/WTL.vcproj
+++ b/Source/3rd Party/WTL/WTL.vcproj
@@ -17,107 +17,15 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/3rd Party/WTL/atlapp.h b/Source/3rd Party/WTL/atlapp.h
index b62e09704..504bc53aa 100644
--- a/Source/3rd Party/WTL/atlapp.h
+++ b/Source/3rd Party/WTL/atlapp.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -15,7 +15,7 @@
#pragma once
#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
+ #error WTL requires C++ compilation (use a .cpp suffix)
#endif
#ifndef __ATLBASE_H__
@@ -34,11 +34,15 @@
#ifdef _ATL_NO_COMMODULE
#error WTL requires that _ATL_NO_COMMODULE is not defined
-#endif // _ATL_NO_COMMODULE
+#endif
+
+#if (_ATL_VER >= 0x0900) && defined(_ATL_MIN_CRT)
+ #error _ATL_MIN_CRT is not supported with ATL 9.0 and higher
+#endif
#if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT)
#pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT")
-#endif // defined(_WIN32_WCE) && defined(_ATL_MIN_CRT)
+#endif
#include
#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
@@ -51,8 +55,8 @@
#include
#ifndef _WIN32_WCE
-#pragma comment(lib, "comctl32.lib")
-#endif // !_WIN32_WCE
+ #pragma comment(lib, "comctl32.lib")
+#endif
#ifndef _WIN32_WCE
#include "atlres.h"
@@ -63,11 +67,15 @@
// We need to disable this warning because of template class arguments
#pragma warning(disable: 4127)
+#if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL)
+ #define _SECURE_ATL 1
+#endif
+
///////////////////////////////////////////////////////////////////////////////
// WTL version number
-#define _WTL_VER 0x0800
+#define _WTL_VER 0x0810
///////////////////////////////////////////////////////////////////////////////
@@ -80,8 +88,11 @@
// CAppModule
// CServerAppModule
//
+// CRegKeyEx
+//
// Global functions:
// AtlGetDefaultGuiFont()
+// AtlCreateControlFont()
// AtlCreateBoldFont()
// AtlInitCommonControls()
@@ -460,11 +471,15 @@ static CWndClassInfo& GetWndClassInfo() \
#endif // ATLVERIFY
#endif // (_ATL_VER < 0x0700)
-// Forward declaration for ATL3 fix
-#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE)
+// Forward declaration for ATL3 and ATL11 fix
+#if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); };
#endif
+#ifndef WM_MOUSEHWHEEL
+ #define WM_MOUSEHWHEEL 0x020E
+#endif
+
namespace WTL
{
@@ -490,7 +505,7 @@ inline bool AtlIsOldWindows()
return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90)));
}
-// default GUI font helper
+// Default GUI font helper - "MS Shell Dlg" stock font
inline HFONT AtlGetDefaultGuiFont()
{
#ifndef _WIN32_WCE
@@ -500,24 +515,39 @@ inline HFONT AtlGetDefaultGuiFont()
#endif // _WIN32_WCE
}
-// bold font helper (NOTE: Caller owns the font, and should destroy it when done using it)
+// Control font helper - default font for controls not in a dialog
+// (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
+inline HFONT AtlCreateControlFont()
+{
+#ifndef _WIN32_WCE
+ LOGFONT lf = { 0 };
+ ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
+ HFONT hFont = ::CreateFontIndirect(&lf);
+ ATLASSERT(hFont != NULL);
+ return hFont;
+#else // CE specific
+ return (HFONT)::GetStockObject(SYSTEM_FONT);
+#endif // _WIN32_WCE
+}
+
+// Bold font helper
+// (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
inline HFONT AtlCreateBoldFont(HFONT hFont = NULL)
{
- if(hFont == NULL)
- hFont = AtlGetDefaultGuiFont();
- ATLASSERT(hFont != NULL);
- HFONT hFontBold = NULL;
LOGFONT lf = { 0 };
- if(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT))
- {
- lf.lfWeight = FW_BOLD;
- hFontBold = ::CreateFontIndirect(&lf);
- ATLASSERT(hFontBold != NULL);
- }
+#ifndef _WIN32_WCE
+ if(hFont == NULL)
+ ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
else
- {
- ATLASSERT(FALSE);
- }
+ ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
+#else // CE specific
+ if(hFont == NULL)
+ hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
+ ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
+#endif // _WIN32_WCE
+ lf.lfWeight = FW_BOLD;
+ HFONT hFontBold = ::CreateFontIndirect(&lf);
+ ATLASSERT(hFontBold != NULL);
return hFontBold;
}
@@ -583,6 +613,70 @@ namespace RunTimeHelper
BOOL bRet = ::GetVersionEx(&ovi);
return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6));
}
+
+ inline bool IsThemeAvailable()
+ {
+ bool bRet = false;
+
+ if(IsCommCtrl6())
+ {
+ HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
+ if(hThemeDLL != NULL)
+ {
+ typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)();
+ PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive");
+ ATLASSERT(pfnIsThemeActive != NULL);
+ bRet = (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE);
+ if(bRet)
+ {
+ typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)();
+ PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed");
+ ATLASSERT(pfnIsAppThemed != NULL);
+ bRet = (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE);
+ }
+
+ ::FreeLibrary(hThemeDLL);
+ }
+ }
+
+ return bRet;
+ }
+
+ inline bool IsWin7()
+ {
+ OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
+ BOOL bRet = ::GetVersionEx(&ovi);
+ return ((bRet != FALSE) && (ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1));
+ }
+
+ inline bool IsRibbonUIAvailable()
+ {
+ static INT iRibbonUI = -1;
+
+#if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
+ if (iRibbonUI == -1)
+ {
+ HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll"));
+ if (hRibbonDLL != NULL)
+ {
+ const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } };
+ // block - create instance
+ {
+ ATL::CComPtr pIUIFramework;
+ iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0;
+ }
+ ::FreeLibrary(hRibbonDLL);
+ }
+ else
+ {
+ iRibbonUI = 0;
+ }
+ }
+#endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
+
+ return (iRibbonUI == 1);
+ }
+
#endif // !_WIN32_WCE
inline int SizeOf_REBARBANDINFO()
@@ -848,7 +942,9 @@ namespace SecureHelper
return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
#else
cchBuff; // Avoid unused argument warning
+#pragma warning(disable: 4996)
return _vstprintf(lpstrBuff, lpstrFormat, args);
+#pragma warning(default: 4996)
#endif
}
@@ -882,6 +978,91 @@ namespace SecureHelper
}; // namespace SecureHelper
+///////////////////////////////////////////////////////////////////////////////
+// MinCrtHelper - helper functions for using _ATL_MIN_CRT
+
+namespace MinCrtHelper
+{
+ inline int _isspace(TCHAR ch)
+ {
+#ifndef _ATL_MIN_CRT
+ return _istspace(ch);
+#else // _ATL_MIN_CRT
+ WORD type = 0;
+ ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
+ return (type & C1_SPACE) == C1_SPACE;
+#endif // _ATL_MIN_CRT
+ }
+
+ inline int _isdigit(TCHAR ch)
+ {
+#ifndef _ATL_MIN_CRT
+ return _istdigit(ch);
+#else // _ATL_MIN_CRT
+ WORD type = 0;
+ ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
+ return (type & C1_DIGIT) == C1_DIGIT;
+#endif // _ATL_MIN_CRT
+ }
+
+ inline int _atoi(LPCTSTR str)
+ {
+#ifndef _ATL_MIN_CRT
+ return _ttoi(str);
+#else // _ATL_MIN_CRT
+ while(_isspace(*str) != 0)
+ ++str;
+
+ TCHAR ch = *str++;
+ TCHAR sign = ch; // save sign indication
+ if(ch == _T('-') || ch == _T('+'))
+ ch = *str++; // skip sign
+
+ int total = 0;
+ while(_isdigit(ch) != 0)
+ {
+ total = 10 * total + (ch - '0'); // accumulate digit
+ ch = *str++; // get next char
+ }
+
+ return (sign == '-') ? -total : total; // return result, negated if necessary
+#endif // _ATL_MIN_CRT
+ }
+
+ inline LPCTSTR _strrchr(LPCTSTR str, TCHAR ch)
+ {
+#ifndef _ATL_MIN_CRT
+ return _tcsrchr(str, ch);
+#else // _ATL_MIN_CRT
+ LPCTSTR lpsz = NULL;
+ while(*str != 0)
+ {
+ if(*str == ch)
+ lpsz = str;
+ str = ::CharNext(str);
+ }
+ return lpsz;
+#endif // _ATL_MIN_CRT
+ }
+
+ inline LPTSTR _strrchr(LPTSTR str, TCHAR ch)
+ {
+#ifndef _ATL_MIN_CRT
+ return _tcsrchr(str, ch);
+#else // _ATL_MIN_CRT
+ LPTSTR lpsz = NULL;
+ while(*str != 0)
+ {
+ if(*str == ch)
+ lpsz = str;
+ str = ::CharNext(str);
+ }
+ return lpsz;
+#endif // _ATL_MIN_CRT
+ }
+}; // namespace MinCrtHelper
+
+
///////////////////////////////////////////////////////////////////////////////
// CMessageFilter - Interface for message filter support
@@ -1542,6 +1723,261 @@ public:
};
+///////////////////////////////////////////////////////////////////////////////
+// CRegKeyEx - adds type-specific methods to ATL3 CRegKey
+
+#if (_ATL_VER < 0x0700)
+
+class CRegKeyEx : public ATL::CRegKey
+{
+public:
+// Constructors and operators
+ CRegKeyEx(HKEY hKey = NULL)
+ {
+ m_hKey = hKey;
+ }
+
+ CRegKeyEx(CRegKeyEx& key)
+ {
+ Attach(key.Detach());
+ }
+
+ CRegKeyEx& operator =(CRegKeyEx& key)
+ {
+ Close();
+ Attach(key.Detach());
+ return *this;
+ }
+
+// Methods
+ LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes)
+ {
+ ATLASSERT(m_hKey != NULL);
+ return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast(pValue), nBytes);
+ }
+
+ LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+
+ OLECHAR szGUID[64] = { 0 };
+ ::StringFromGUID2(guidValue, szGUID, 64);
+
+ USES_CONVERSION;
+ LPCTSTR lpstr = OLE2CT(szGUID);
+#ifndef _UNICODE
+ if(lpstr == NULL)
+ return E_OUTOFMEMORY;
+#endif
+ return SetStringValue(pszValueName, lpstr);
+ }
+
+ LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes)
+ {
+ ATLASSERT(m_hKey != NULL);
+ return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast(pValue), nBytes);
+ }
+
+ LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+ return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast(&dwValue), sizeof(DWORD));
+ }
+
+#ifndef _WIN32_WCE
+ LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+ return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast(&qwValue), sizeof(ULONGLONG));
+ }
+#endif
+
+ LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ)
+ {
+ ATLASSERT(m_hKey != NULL);
+ if(pszValue == NULL)
+ {
+ ATLASSERT(FALSE);
+ return ERROR_INVALID_DATA;
+ }
+ ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ));
+
+ return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast(pszValue), (lstrlen(pszValue) + 1) * sizeof(TCHAR));
+ }
+
+ LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+ if(pszValue == NULL)
+ {
+ ATLASSERT(FALSE);
+ return ERROR_INVALID_DATA;
+ }
+
+ ULONG nBytes = 0;
+ ULONG nLength = 0;
+ LPCTSTR pszTemp = pszValue;
+ do
+ {
+ nLength = lstrlen(pszTemp) + 1;
+ pszTemp += nLength;
+ nBytes += nLength * sizeof(TCHAR);
+ } while (nLength != 1);
+
+ return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast(pszValue), nBytes);
+ }
+
+ LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes)
+ {
+ ATLASSERT(m_hKey != NULL);
+ return ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast(pData), pnBytes);
+ }
+
+ LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+
+ guidValue = GUID_NULL;
+
+ TCHAR szGUID[64] = { 0 };
+ ULONG nCount = 64;
+ LONG lRes = QueryStringValue(pszValueName, szGUID, &nCount);
+
+ if (lRes != ERROR_SUCCESS)
+ return lRes;
+
+ if(szGUID[0] != _T('{'))
+ return ERROR_INVALID_DATA;
+
+ USES_CONVERSION;
+ LPOLESTR lpstr = T2OLE(szGUID);
+#ifndef _UNICODE
+ if(lpstr == NULL)
+ return E_OUTOFMEMORY;
+#endif
+
+ HRESULT hr = ::CLSIDFromString(lpstr, &guidValue);
+ if (FAILED(hr))
+ return ERROR_INVALID_DATA;
+
+ return ERROR_SUCCESS;
+ }
+
+ LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes)
+ {
+ ATLASSERT(pnBytes != NULL);
+ ATLASSERT(m_hKey != NULL);
+
+ DWORD dwType = 0;
+ LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pValue), pnBytes);
+ if (lRes != ERROR_SUCCESS)
+ return lRes;
+ if (dwType != REG_BINARY)
+ return ERROR_INVALID_DATA;
+
+ return ERROR_SUCCESS;
+ }
+
+ LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+
+ ULONG nBytes = sizeof(DWORD);
+ DWORD dwType = 0;
+ LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(&dwValue), &nBytes);
+ if (lRes != ERROR_SUCCESS)
+ return lRes;
+ if (dwType != REG_DWORD)
+ return ERROR_INVALID_DATA;
+
+ return ERROR_SUCCESS;
+ }
+
+ LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue)
+ {
+ ATLASSERT(m_hKey != NULL);
+
+ ULONG nBytes = sizeof(ULONGLONG);
+ DWORD dwType = 0;
+ LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(&qwValue), &nBytes);
+ if (lRes != ERROR_SUCCESS)
+ return lRes;
+ if (dwType != REG_QWORD)
+ return ERROR_INVALID_DATA;
+
+ return ERROR_SUCCESS;
+ }
+
+ LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
+ {
+ ATLASSERT(m_hKey != NULL);
+ ATLASSERT(pnChars != NULL);
+
+ ULONG nBytes = (*pnChars) * sizeof(TCHAR);
+ DWORD dwType = 0;
+ *pnChars = 0;
+ LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pszValue), &nBytes);
+
+ if (lRes != ERROR_SUCCESS)
+ {
+ return lRes;
+ }
+
+ if(dwType != REG_SZ && dwType != REG_EXPAND_SZ)
+ {
+ return ERROR_INVALID_DATA;
+ }
+
+ if (pszValue != NULL)
+ {
+ if(nBytes != 0)
+ {
+ if ((nBytes % sizeof(TCHAR) != 0) || (pszValue[nBytes / sizeof(TCHAR) -1] != 0))
+ return ERROR_INVALID_DATA;
+ }
+ else
+ {
+ pszValue[0] = _T('\0');
+ }
+ }
+
+ *pnChars = nBytes / sizeof(TCHAR);
+
+ return ERROR_SUCCESS;
+ }
+
+ LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
+ {
+ ATLASSERT(m_hKey != NULL);
+ ATLASSERT(pnChars != NULL);
+
+ if (pszValue != NULL && *pnChars < 2)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ ULONG nBytes = (*pnChars) * sizeof(TCHAR);
+ DWORD dwType = 0;
+ *pnChars = 0;
+ LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pszValue), &nBytes);
+ if (lRes != ERROR_SUCCESS)
+ return lRes;
+ if (dwType != REG_MULTI_SZ)
+ return ERROR_INVALID_DATA;
+ if (pszValue != NULL && (nBytes % sizeof(TCHAR) != 0 || nBytes / sizeof(TCHAR) < 1 || pszValue[nBytes / sizeof(TCHAR) - 1] != 0 || ((nBytes / sizeof(TCHAR)) > 1 && pszValue[nBytes / sizeof(TCHAR) - 2] != 0)))
+ return ERROR_INVALID_DATA;
+
+ *pnChars = nBytes / sizeof(TCHAR);
+
+ return ERROR_SUCCESS;
+ }
+};
+
+#else // !(_ATL_VER < 0x0700)
+
+typedef ATL::CRegKey CRegKeyEx;
+
+#endif // !(_ATL_VER < 0x0700)
+
+
///////////////////////////////////////////////////////////////////////////////
// CString forward reference (enables CString use in atluser.h and atlgdi.h)
@@ -1575,9 +2011,10 @@ public:
///////////////////////////////////////////////////////////////////////////////
-// General DLL version helpers (excluded from atlbase.h if _ATL_DLL is defined)
+// General DLL version helpers
+// (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed)
-#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE)
+#if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
namespace ATL
{
diff --git a/Source/3rd Party/WTL/atlcrack.h b/Source/3rd Party/WTL/atlcrack.h
index f92b35ad2..d488c1aaf 100644
--- a/Source/3rd Party/WTL/atlcrack.h
+++ b/Source/3rd Party/WTL/atlcrack.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,6 +14,10 @@
#pragma once
+#ifndef __ATLAPP_H__
+ #error atlcrack.h requires atlapp.h to be included first
+#endif
+
///////////////////////////////////////////////////////////////////////////////
// Message map macro for cracked handlers
@@ -566,7 +570,7 @@ public: \
return TRUE; \
}
-// void OnNcPaint(CRgn rgn)
+// void OnNcPaint(CRgnHandle rgn)
#define MSG_WM_NCPAINT(func) \
if (uMsg == WM_NCPAINT) \
{ \
@@ -795,7 +799,7 @@ public: \
return TRUE; \
}
-// void OnSysCommand(UINT nID, LPARAM lParam)
+// void OnSysCommand(UINT nID, CPoint point)
#define MSG_WM_SYSCOMMAND(func) \
if (uMsg == WM_SYSCOMMAND) \
{ \
@@ -850,7 +854,7 @@ public: \
return TRUE; \
}
-// void OnInitMenu(CMenu menu)
+// void OnInitMenu(CMenuHandle menu)
#define MSG_WM_INITMENU(func) \
if (uMsg == WM_INITMENU) \
{ \
@@ -861,7 +865,7 @@ public: \
return TRUE; \
}
-// void OnInitMenuPopup(CMenu menuPopup, UINT nIndex, BOOL bSysMenu)
+// void OnInitMenuPopup(CMenuHandle menuPopup, UINT nIndex, BOOL bSysMenu)
#define MSG_WM_INITMENUPOPUP(func) \
if (uMsg == WM_INITMENUPOPUP) \
{ \
@@ -872,7 +876,7 @@ public: \
return TRUE; \
}
-// void OnMenuSelect(UINT nItemID, UINT nFlags, CMenu menu)
+// void OnMenuSelect(UINT nItemID, UINT nFlags, CMenuHandle menu)
#define MSG_WM_MENUSELECT(func) \
if (uMsg == WM_MENUSELECT) \
{ \
@@ -883,7 +887,7 @@ public: \
return TRUE; \
}
-// LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenu menu)
+// LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenuHandle menu)
#define MSG_WM_MENUCHAR(func) \
if (uMsg == WM_MENUCHAR) \
{ \
@@ -1544,7 +1548,7 @@ public: \
return TRUE; \
}
-// void OnSetFont(CFont font, BOOL bRedraw)
+// void OnSetFont(CFontHandle font, BOOL bRedraw)
#define MSG_WM_SETFONT(func) \
if (uMsg == WM_SETFONT) \
{ \
@@ -1638,7 +1642,7 @@ public: \
#if(WINVER >= 0x0500)
-// void OnMenuRButtonUp(WPARAM wParam, CMenu menu)
+// void OnMenuRButtonUp(WPARAM wParam, CMenuHandle menu)
#define MSG_WM_MENURBUTTONUP(func) \
if (uMsg == WM_MENURBUTTONUP) \
{ \
@@ -1649,7 +1653,7 @@ public: \
return TRUE; \
}
-// LRESULT OnMenuDrag(WPARAM wParam, CMenu menu)
+// LRESULT OnMenuDrag(WPARAM wParam, CMenuHandle menu)
#define MSG_WM_MENUDRAG(func) \
if (uMsg == WM_MENUDRAG) \
{ \
@@ -1669,7 +1673,7 @@ public: \
return TRUE; \
}
-// void OnUnInitMenuPopup(UINT nID, CMenu menu)
+// void OnUnInitMenuPopup(UINT nID, CMenuHandle menu)
#define MSG_WM_UNINITMENUPOPUP(func) \
if (uMsg == WM_UNINITMENUPOPUP) \
{ \
@@ -1680,7 +1684,7 @@ public: \
return TRUE; \
}
-// void OnMenuCommand(WPARAM nIndex, CMenu menu)
+// void OnMenuCommand(WPARAM nIndex, CMenuHandle menu)
#define MSG_WM_MENUCOMMAND(func) \
if (uMsg == WM_MENUCOMMAND) \
{ \
diff --git a/Source/3rd Party/WTL/atlctrls.h b/Source/3rd Party/WTL/atlctrls.h
index 338f51d0b..e6aca7dee 100644
--- a/Source/3rd Party/WTL/atlctrls.h
+++ b/Source/3rd Party/WTL/atlctrls.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atlctrls.h requires atlapp.h to be included first
#endif
@@ -26,10 +22,6 @@
#error atlctrls.h requires atlwin.h to be included first
#endif
-#if (_WIN32_IE < 0x0300)
- #error atlctrls.h requires IE Version 3.0 or higher
-#endif
-
#ifndef _WIN32_WCE
#include
#include
@@ -3922,15 +3914,19 @@ public:
}
#endif // (_WIN32_WINNT >= 0x0600)
- // single-selection only
+ // Note: selects only one item
BOOL SelectItem(int nIndex)
{
ATLASSERT(::IsWindow(m_hWnd));
- ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0);
+
+ // multi-selection only: de-select all items
+ if((GetStyle() & LVS_SINGLESEL) == 0)
+ SetItemState(-1, 0, LVIS_SELECTED);
BOOL bRet = SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
if(bRet)
bRet = EnsureVisible(nIndex, FALSE);
+
return bRet;
}
};
diff --git a/Source/3rd Party/WTL/atlctrlw.h b/Source/3rd Party/WTL/atlctrlw.h
index 3bf16ee58..7f95bdfda 100644
--- a/Source/3rd Party/WTL/atlctrlw.h
+++ b/Source/3rd Party/WTL/atlctrlw.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifdef _WIN32_WCE
#error atlctrlw.h is not supported on Windows CE
#endif
@@ -3147,16 +3143,16 @@ public:
void _AddVistaBitmapsFromImageList(int nStartIndex, int nCount)
{
// Create display compatible memory DC
- HDC hDC = ::GetDC(NULL);
+ CClientDC dc(NULL);
CDC dcMem;
- dcMem.CreateCompatibleDC(hDC);
+ dcMem.CreateCompatibleDC(dc);
HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();
T* pT = static_cast(this);
// Create bitmaps for all menu items
for(int i = 0; i < nCount; i++)
{
- HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nStartIndex + i, hDC, dcMem);
+ HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nStartIndex + i, dc, dcMem);
dcMem.SelectBitmap(hBitmapSave);
m_arrVistaBitmap.Add(hBitmap);
}
@@ -3165,14 +3161,14 @@ public:
void _AddVistaBitmapFromImageList(int nIndex)
{
// Create display compatible memory DC
- HDC hDC = ::GetDC(NULL);
+ CClientDC dc(NULL);
CDC dcMem;
- dcMem.CreateCompatibleDC(hDC);
+ dcMem.CreateCompatibleDC(dc);
HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();
// Create bitmap for menu item
T* pT = static_cast(this);
- HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, hDC, dcMem);
+ HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem);
// Select saved bitmap back and add bitmap to the array
dcMem.SelectBitmap(hBitmapSave);
@@ -3186,14 +3182,14 @@ public:
::DeleteObject(m_arrVistaBitmap[nIndex]);
// Create display compatible memory DC
- HDC hDC = ::GetDC(NULL);
+ CClientDC dc(NULL);
CDC dcMem;
- dcMem.CreateCompatibleDC(hDC);
+ dcMem.CreateCompatibleDC(dc);
HBITMAP hBitmapSave = dcMem.GetCurrentBitmap();
// Create bitmap for menu item
T* pT = static_cast(this);
- HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, hDC, dcMem);
+ HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem);
// Select saved bitmap back and replace bitmap in the array
dcMem.SelectBitmap(hBitmapSave);
diff --git a/Source/3rd Party/WTL/atlctrlx.h b/Source/3rd Party/WTL/atlctrlx.h
index a1161a3ee..4189ea8d7 100644
--- a/Source/3rd Party/WTL/atlctrlx.h
+++ b/Source/3rd Party/WTL/atlctrlx.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atlctrlx.h requires atlapp.h to be included first
#endif
@@ -52,8 +48,6 @@
// CTabViewImpl
// CTabView
-#include
-
namespace WTL
{
@@ -572,7 +566,6 @@ public:
}
};
-
class CBitmapButton : public CBitmapButtonImpl
{
public:
@@ -759,14 +752,16 @@ __declspec(selectany) struct
};
#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE)
-#define HLINK_UNDERLINED 0x00000000
-#define HLINK_NOTUNDERLINED 0x00000001
-#define HLINK_UNDERLINEHOVER 0x00000002
-#define HLINK_COMMANDBUTTON 0x00000004
-#define HLINK_NOTIFYBUTTON 0x0000000C
-#define HLINK_USETAGS 0x00000010
-#define HLINK_USETAGSBOLD 0x00000030
-#define HLINK_NOTOOLTIP 0x00000040
+#define HLINK_UNDERLINED 0x00000000
+#define HLINK_NOTUNDERLINED 0x00000001
+#define HLINK_UNDERLINEHOVER 0x00000002
+#define HLINK_COMMANDBUTTON 0x00000004
+#define HLINK_NOTIFYBUTTON 0x0000000C
+#define HLINK_USETAGS 0x00000010
+#define HLINK_USETAGSBOLD 0x00000030
+#define HLINK_NOTOOLTIP 0x00000040
+#define HLINK_AUTOCREATELINKFONT 0x00000080
+#define HLINK_SINGLELINE 0x00000100
// Notes:
// - HLINK_USETAGS and HLINK_USETAGSBOLD are always left-aligned
@@ -780,7 +775,7 @@ public:
LPTSTR m_lpstrHyperLink;
HCURSOR m_hCursor;
- HFONT m_hFont;
+ HFONT m_hFontLink;
HFONT m_hFontNormal;
RECT m_rcLink;
@@ -797,16 +792,17 @@ public:
bool m_bVisited:1;
bool m_bHover:1;
bool m_bInternalLinkFont:1;
+ bool m_bInternalNormalFont:1;
// Constructor/Destructor
CHyperLinkImpl(DWORD dwExtendedStyle = HLINK_UNDERLINED) :
m_lpstrLabel(NULL), m_lpstrHyperLink(NULL),
- m_hCursor(NULL), m_hFont(NULL), m_hFontNormal(NULL),
+ m_hCursor(NULL), m_hFontLink(NULL), m_hFontNormal(NULL),
m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128)),
m_dwExtendedStyle(dwExtendedStyle),
m_bPaintLabel(true), m_bVisited(false),
- m_bHover(false), m_bInternalLinkFont(false)
+ m_bHover(false), m_bInternalLinkFont(false), m_bInternalNormalFont(false)
{
::SetRectEmpty(&m_rcLink);
}
@@ -815,8 +811,6 @@ public:
{
delete [] m_lpstrLabel;
delete [] m_lpstrHyperLink;
- if(m_bInternalLinkFont && m_hFont != NULL)
- ::DeleteObject(m_hFont);
#if (WINVER < 0x0500) && !defined(_WIN32_WCE)
// It was created, not loaded, so we have to destroy it
if(m_hCursor != NULL)
@@ -912,17 +906,21 @@ public:
HFONT GetLinkFont() const
{
- return m_hFont;
+ return m_hFontLink;
}
void SetLinkFont(HFONT hFont)
{
- if(m_bInternalLinkFont && m_hFont != NULL)
+ if(m_bInternalLinkFont)
{
- ::DeleteObject(m_hFont);
+ ::DeleteObject(m_hFontLink);
m_bInternalLinkFont = false;
}
- m_hFont = hFont;
+
+ m_hFontLink = hFont;
+
+ T* pT = static_cast(this);
+ pT->CalcLabelRect();
}
int GetIdealHeight() const
@@ -933,15 +931,17 @@ public:
if(!m_bPaintLabel)
return -1;
+ UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
+
CClientDC dc(m_hWnd);
RECT rect = { 0 };
GetClientRect(&rect);
HFONT hFontOld = dc.SelectFont(m_hFontNormal);
RECT rcText = rect;
- dc.DrawText(_T("NS"), -1, &rcText, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
- dc.SelectFont(m_hFont);
+ dc.DrawText(_T("NS"), -1, &rcText, DT_LEFT | uFormat | DT_CALCRECT);
+ dc.SelectFont(m_hFontLink);
RECT rcLink = rect;
- dc.DrawText(_T("NS"), -1, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
+ dc.DrawText(_T("NS"), -1, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
dc.SelectFont(hFontOld);
return max(rcText.bottom - rcText.top, rcLink.bottom - rcLink.top);
}
@@ -985,17 +985,19 @@ public:
pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
// get label part rects
+ UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
+
HFONT hFontOld = dc.SelectFont(m_hFontNormal);
RECT rcLeft = rcClient;
- dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
+ dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT);
- dc.SelectFont(m_hFont);
+ dc.SelectFont(m_hFontLink);
RECT rcLink = { rcLeft.right, rcLeft.top, rcClient.right, rcClient.bottom };
- dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
+ dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
dc.SelectFont(m_hFontNormal);
RECT rcRight = { rcLink.right, rcLink.top, rcClient.right, rcClient.bottom };
- dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
+ dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat | DT_CALCRECT);
dc.SelectFont(hFontOld);
@@ -1005,17 +1007,18 @@ public:
else
{
HFONT hOldFont = NULL;
- if(m_hFont != NULL)
- hOldFont = dc.SelectFont(m_hFont);
+ if(m_hFontLink != NULL)
+ hOldFont = dc.SelectFont(m_hFontLink);
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
DWORD dwStyle = GetStyle();
- int nDrawStyle = DT_LEFT;
+ UINT uFormat = DT_LEFT;
if (dwStyle & SS_CENTER)
- nDrawStyle = DT_CENTER;
+ uFormat = DT_CENTER;
else if (dwStyle & SS_RIGHT)
- nDrawStyle = DT_RIGHT;
- dc.DrawText(lpstrText, -1, &rcAll, nDrawStyle | DT_WORDBREAK | DT_CALCRECT);
- if(m_hFont != NULL)
+ uFormat = DT_RIGHT;
+ uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
+ dc.DrawText(lpstrText, -1, &rcAll, uFormat | DT_CALCRECT);
+ if(m_hFontLink != NULL)
dc.SelectFont(hOldFont);
if (dwStyle & SS_CENTER)
{
@@ -1053,6 +1056,8 @@ public:
{
ATLASSERT(m_hWnd == NULL);
ATLASSERT(::IsWindow(hWnd));
+ if(m_hFontNormal == NULL)
+ m_hFontNormal = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
#if (_MSC_VER >= 1300)
BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd);
#else // !(_MSC_VER >= 1300)
@@ -1102,6 +1107,28 @@ public:
return bRet;
}
+ void CreateLinkFontFromNormal()
+ {
+ if(m_bInternalLinkFont)
+ {
+ ::DeleteObject(m_hFontLink);
+ m_bInternalLinkFont = false;
+ }
+
+ CFontHandle font = (m_hFontNormal != NULL) ? m_hFontNormal : (HFONT)::GetStockObject(SYSTEM_FONT);
+ LOGFONT lf = { 0 };
+ font.GetLogFont(&lf);
+
+ if(IsUsingTagsBold())
+ lf.lfWeight = FW_BOLD;
+ else if(!IsNotUnderlined())
+ lf.lfUnderline = TRUE;
+
+ m_hFontLink = ::CreateFontIndirect(&lf);
+ m_bInternalLinkFont = true;
+ ATLASSERT(m_hFontLink != NULL);
+ }
+
// Message map and handlers
BEGIN_MSG_MAP(CHyperLinkImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
@@ -1147,6 +1174,21 @@ public:
m_tip.DestroyWindow();
m_tip.m_hWnd = NULL;
}
+
+ if(m_bInternalLinkFont)
+ {
+ ::DeleteObject(m_hFontLink);
+ m_hFontLink = NULL;
+ m_bInternalLinkFont = false;
+ }
+
+ if(m_bInternalNormalFont)
+ {
+ ::DeleteObject(m_hFontNormal);
+ m_hFontNormal = NULL;
+ m_bInternalNormalFont = false;
+ }
+
bHandled = FALSE;
return 1;
}
@@ -1315,12 +1357,28 @@ public:
LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
+ if(m_bInternalNormalFont)
+ {
+ ::DeleteObject(m_hFontNormal);
+ m_bInternalNormalFont = false;
+ }
+
+ bool bCreateLinkFont = m_bInternalLinkFont;
+
m_hFontNormal = (HFONT)wParam;
+
+ if(bCreateLinkFont || IsAutoCreateLinkFont())
+ CreateLinkFontFromNormal();
+
+ T* pT = static_cast(this);
+ pT->CalcLabelRect();
+
if((BOOL)lParam)
{
Invalidate();
UpdateWindow();
}
+
return 0;
}
@@ -1373,26 +1431,17 @@ public:
#endif
ATLASSERT(m_hCursor != NULL);
- // set font
+ // set fonts
if(m_bPaintLabel)
{
- ATL::CWindow wnd = GetParent();
- m_hFontNormal = wnd.GetFont();
if(m_hFontNormal == NULL)
- m_hFontNormal = (HFONT)::GetStockObject(SYSTEM_FONT);
- if(m_hFontNormal != NULL && m_hFont == NULL)
{
- LOGFONT lf = { 0 };
- CFontHandle font = m_hFontNormal;
- font.GetLogFont(&lf);
- if(IsUsingTagsBold())
- lf.lfWeight = FW_BOLD;
- else if(!IsNotUnderlined())
- lf.lfUnderline = TRUE;
- m_hFont = ::CreateFontIndirect(&lf);
- m_bInternalLinkFont = true;
- ATLASSERT(m_hFont != NULL);
+ m_hFontNormal = AtlCreateControlFont();
+ m_bInternalNormalFont = true;
}
+
+ if(m_hFontLink == NULL)
+ CreateLinkFontFromNormal();
}
#ifndef _WIN32_WCE
@@ -1407,11 +1456,9 @@ public:
int nLen = GetWindowTextLength();
if(nLen > 0)
{
- CTempBuffer buff;
- LPTSTR lpstrText = buff.Allocate(nLen + 1);
- ATLASSERT(lpstrText != NULL);
- if((lpstrText != NULL) && (GetWindowText(lpstrText, nLen + 1) > 0))
- SetLabel(lpstrText);
+ ATLTRY(m_lpstrLabel = new TCHAR[nLen + 1]);
+ if(m_lpstrLabel != NULL)
+ ATLVERIFY(GetWindowText(m_lpstrLabel, nLen + 1) > 0);
}
}
@@ -1435,20 +1482,15 @@ public:
// set link colors
if(m_bPaintLabel)
{
- ATL::CRegKey rk;
+ CRegKeyEx rk;
LONG lRet = rk.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\Settings"));
- if(lRet == 0)
+ if(lRet == ERROR_SUCCESS)
{
const int cchValue = 12;
TCHAR szValue[cchValue] = { 0 };
-#if (_ATL_VER >= 0x0700)
ULONG ulCount = cchValue;
lRet = rk.QueryStringValue(_T("Anchor Color"), szValue, &ulCount);
-#else
- DWORD dwCount = cchValue * sizeof(TCHAR);
- lRet = rk.QueryValue(szValue, _T("Anchor Color"), &dwCount);
-#endif
- if(lRet == 0)
+ if(lRet == ERROR_SUCCESS)
{
COLORREF clr = pT->_ParseColorString(szValue);
ATLASSERT(clr != CLR_INVALID);
@@ -1456,14 +1498,9 @@ public:
m_clrLink = clr;
}
-#if (_ATL_VER >= 0x0700)
ulCount = cchValue;
lRet = rk.QueryStringValue(_T("Anchor Color Visited"), szValue, &ulCount);
-#else
- dwCount = cchValue * sizeof(TCHAR);
- lRet = rk.QueryValue(szValue, _T("Anchor Color Visited"), &dwCount);
-#endif
- if(lRet == 0)
+ if(lRet == ERROR_SUCCESS)
{
COLORREF clr = pT->_ParseColorString(szValue);
ATLASSERT(clr != CLR_INVALID);
@@ -1485,7 +1522,7 @@ public:
if(*p == _T(','))
{
*p = _T('\0');
- c[i] = T::_xttoi(lpstr);
+ c[i] = MinCrtHelper::_atoi(lpstr);
lpstr = &p[1];
break;
}
@@ -1495,7 +1532,7 @@ public:
}
if(*lpstr == _T('\0'))
return CLR_INVALID;
- c[2] = T::_xttoi(lpstr);
+ c[2] = MinCrtHelper::_atoi(lpstr);
return RGB(c[0], c[1], c[2]);
}
@@ -1532,15 +1569,17 @@ public:
// get label part rects
HFONT hFontOld = dc.SelectFont(m_hFontNormal);
+ UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
+
RECT rcLeft = rcClient;
if(lpstrLeft != NULL)
- dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
+ dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT);
- dc.SelectFont(m_hFont);
+ dc.SelectFont(m_hFontLink);
RECT rcLink = rcClient;
if(lpstrLeft != NULL)
rcLink.left = rcLeft.right;
- dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
+ dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT);
dc.SelectFont(hFontOld);
@@ -1549,17 +1588,18 @@ public:
else
{
HFONT hOldFont = NULL;
- if(m_hFont != NULL)
- hOldFont = dc.SelectFont(m_hFont);
+ if(m_hFontLink != NULL)
+ hOldFont = dc.SelectFont(m_hFontLink);
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
DWORD dwStyle = GetStyle();
- int nDrawStyle = DT_LEFT;
+ UINT uFormat = DT_LEFT;
if (dwStyle & SS_CENTER)
- nDrawStyle = DT_CENTER;
+ uFormat = DT_CENTER;
else if (dwStyle & SS_RIGHT)
- nDrawStyle = DT_RIGHT;
- dc.DrawText(lpstrText, -1, &m_rcLink, nDrawStyle | DT_WORDBREAK | DT_CALCRECT);
- if(m_hFont != NULL)
+ uFormat = DT_RIGHT;
+ uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
+ dc.DrawText(lpstrText, -1, &m_rcLink, uFormat | DT_CALCRECT);
+ if(m_hFontLink != NULL)
dc.SelectFont(hOldFont);
if (dwStyle & SS_CENTER)
{
@@ -1656,23 +1696,25 @@ public:
dc.SetBkMode(TRANSPARENT);
HFONT hFontOld = dc.SelectFont(m_hFontNormal);
+ UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
+
if(lpstrLeft != NULL)
- dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | DT_WORDBREAK);
+ dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | uFormat);
COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
- if(m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
- dc.SelectFont(m_hFont);
+ if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
+ dc.SelectFont(m_hFontLink);
else
dc.SelectFont(m_hFontNormal);
- dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | DT_WORDBREAK);
+ dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | uFormat);
dc.SetTextColor(clrOld);
dc.SelectFont(m_hFontNormal);
if(lpstrRight != NULL)
{
RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom };
- dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | DT_WORDBREAK);
+ dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat);
}
if(GetFocus() == m_hWnd)
@@ -1686,21 +1728,22 @@ public:
COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT)));
HFONT hFontOld = NULL;
- if(m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
- hFontOld = dc.SelectFont(m_hFont);
+ if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover)))
+ hFontOld = dc.SelectFont(m_hFontLink);
else
hFontOld = dc.SelectFont(m_hFontNormal);
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
DWORD dwStyle = GetStyle();
- int nDrawStyle = DT_LEFT;
+ UINT uFormat = DT_LEFT;
if (dwStyle & SS_CENTER)
- nDrawStyle = DT_CENTER;
+ uFormat = DT_CENTER;
else if (dwStyle & SS_RIGHT)
- nDrawStyle = DT_RIGHT;
+ uFormat = DT_RIGHT;
+ uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK;
- dc.DrawText(lpstrText, -1, &m_rcLink, nDrawStyle | DT_WORDBREAK);
+ dc.DrawText(lpstrText, -1, &m_rcLink, uFormat);
if(GetFocus() == m_hWnd)
dc.DrawFocusRect(&m_rcLink);
@@ -1762,33 +1805,17 @@ public:
return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0);
}
- static int _xttoi(const TCHAR* nptr)
+ bool IsAutoCreateLinkFont() const
{
-#ifndef _ATL_MIN_CRT
- return _ttoi(nptr);
-#else // _ATL_MIN_CRT
- while(*nptr == _T(' ')) // skip spaces
- ++nptr;
+ return ((m_dwExtendedStyle & HLINK_AUTOCREATELINKFONT) == HLINK_AUTOCREATELINKFONT);
+ }
- int c = (int)(_TUCHAR)*nptr++;
- int sign = c; // save sign indication
- if (c == _T('-') || c == _T('+'))
- c = (int)(_TUCHAR)*nptr++; // skip sign
-
- int total = 0;
- while((TCHAR)c >= _T('0') && (TCHAR)c <= _T('9'))
- {
- total = 10 * total + ((TCHAR)c - _T('0')); // accumulate digit
- c = (int)(_TUCHAR)*nptr++; // get next char
- }
-
- // return result, negated if necessary
- return ((TCHAR)sign != _T('-')) ? total : -total;
-#endif // _ATL_MIN_CRT
+ bool IsSingleLine() const
+ {
+ return ((m_dwExtendedStyle & HLINK_SINGLELINE) == HLINK_SINGLELINE);
}
};
-
class CHyperLink : public CHyperLinkImpl
{
public:
@@ -2244,10 +2271,12 @@ public:
int m_cxyHeader;
TCHAR m_szTitle[m_cchTitle];
DWORD m_dwExtendedStyle; // Pane container specific extended styles
+ HFONT m_hFont;
+ bool m_bInternalFont;
// Constructor
- CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0)
+ CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0), m_hFont(NULL), m_bInternalFont(false)
{
m_szTitle[0] = 0;
}
@@ -2391,8 +2420,11 @@ public:
// Message map and handlers
BEGIN_MSG_MAP(CPaneContainerImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
+ MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
+ MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
+ MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
#ifndef _WIN32_WCE
@@ -2405,6 +2437,27 @@ public:
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
+ if(m_hFont == NULL)
+ {
+ // The same as AtlCreateControlFont() for horizontal pane
+#ifndef _WIN32_WCE
+ LOGFONT lf = { 0 };
+ ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
+ if(IsVertical())
+ lf.lfEscapement = 900; // 90 degrees
+ m_hFont = ::CreateFontIndirect(&lf);
+#else // CE specific
+ m_hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
+ if(IsVertical())
+ {
+ CLogFont lf(m_hFont);
+ lf.lfEscapement = 900; // 90 degrees
+ m_hFont = ::CreateFontIndirect(&lf);
+ }
+#endif // _WIN32_WCE
+ m_bInternalFont = true;
+ }
+
T* pT = static_cast(this);
pT->CalcSize();
@@ -2414,6 +2467,18 @@ public:
return 0;
}
+ LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+ {
+ if(m_bInternalFont)
+ {
+ ::DeleteObject(m_hFont);
+ m_hFont = NULL;
+ m_bInternalFont = false;
+ }
+
+ return 0;
+ }
+
LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
T* pT = static_cast(this);
@@ -2428,6 +2493,30 @@ public:
return 0;
}
+ LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+ {
+ return (LRESULT)m_hFont;
+ }
+
+ LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
+ {
+ if(m_bInternalFont)
+ {
+ ::DeleteObject(m_hFont);
+ m_bInternalFont = false;
+ }
+
+ m_hFont = (HFONT)wParam;
+
+ T* pT = static_cast(this);
+ pT->CalcSize();
+
+ if((BOOL)lParam != FALSE)
+ pT->UpdateLayout();
+
+ return 0;
+ }
+
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1; // no background needed
@@ -2624,6 +2713,8 @@ public:
{
T* pT = static_cast(this);
CFontHandle font = pT->GetTitleFont();
+ if(font.IsNull())
+ font = (HFONT)::GetStockObject(SYSTEM_FONT);
LOGFONT lf = { 0 };
font.GetLogFont(lf);
if(IsVertical())
@@ -2640,7 +2731,7 @@ public:
HFONT GetTitleFont() const
{
- return AtlGetDefaultGuiFont();
+ return m_hFont;
}
#ifndef _WIN32_WCE
@@ -2675,23 +2766,42 @@ public:
}
dc.FillRect(&rect, COLOR_3DFACE);
- if(!IsVertical()) // draw title only for horizontal pane container
+ // draw title text
+ dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
+ dc.SetBkMode(TRANSPARENT);
+ T* pT = static_cast(this);
+ HFONT hFontOld = dc.SelectFont(pT->GetTitleFont());
+#ifdef _WIN32_WCE
+ const UINT DT_END_ELLIPSIS = 0;
+#endif // _WIN32_WCE
+
+ if(IsVertical())
+ {
+ rect.top += m_cxyTextOffset;
+ rect.bottom -= m_cxyTextOffset;
+ if(m_tb.m_hWnd != NULL)
+ rect.top += m_cxToolBar;;
+
+ RECT rcCalc = { rect.left, rect.bottom, rect.right, rect.top };
+ int cxFont = dc.DrawText(m_szTitle, -1, &rcCalc, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT);
+ RECT rcText = { 0 };
+ rcText.left = (rect.right - rect.left - cxFont) / 2;
+ rcText.right = rcText.left + (rect.bottom - rect.top);
+ rcText.top = rect.bottom;
+ rcText.bottom = rect.top;
+ dc.DrawText(m_szTitle, -1, &rcText, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS);
+ }
+ else
{
- dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
- dc.SetBkMode(TRANSPARENT);
- T* pT = static_cast(this);
- HFONT hFontOld = dc.SelectFont(pT->GetTitleFont());
rect.left += m_cxyTextOffset;
rect.right -= m_cxyTextOffset;
if(m_tb.m_hWnd != NULL)
rect.right -= m_cxToolBar;;
-#ifndef _WIN32_WCE
+
dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
-#else // CE specific
- dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
-#endif // _WIN32_WCE
- dc.SelectFont(hFontOld);
}
+
+ dc.SelectFont(hFontOld);
}
// called only if pane is empty
@@ -3687,9 +3797,11 @@ public:
bool m_bActiveAsDefaultMenuItem:1;
bool m_bEmptyMenuItem:1;
bool m_bWindowsMenuItem:1;
+ bool m_bNoTabDrag:1;
// internal
bool m_bTabCapture:1;
bool m_bTabDrag:1;
+ bool m_bInternalFont:1;
// Constructor/destructor
CTabViewImpl() :
@@ -3707,8 +3819,10 @@ public:
m_bActiveAsDefaultMenuItem(false),
m_bEmptyMenuItem(false),
m_bWindowsMenuItem(false),
+ m_bNoTabDrag(false),
m_bTabCapture(false),
- m_bTabDrag(false)
+ m_bTabDrag(false),
+ m_bInternalFont(false)
{
m_ptStartDrag.x = 0;
m_ptStartDrag.y = 0;
@@ -4260,6 +4374,8 @@ public:
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
+ MESSAGE_HANDLER(WM_GETFONT, OnGetFont)
+ MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
NOTIFY_HANDLER(m_nTabID, TCN_SELCHANGE, OnTabChanged)
NOTIFY_ID_HANDLER(m_nTabID, OnTabNotification)
#ifndef _WIN32_WCE
@@ -4294,6 +4410,14 @@ public:
il.Destroy();
}
+ if(m_bInternalFont)
+ {
+ HFONT hFont = m_tab.GetFont();
+ m_tab.SetFont(NULL, FALSE);
+ ::DeleteObject(hFont);
+ m_bInternalFont = false;
+ }
+
return 0;
}
@@ -4311,6 +4435,32 @@ public:
return 0;
}
+ LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+ {
+ return m_tab.SendMessage(WM_GETFONT);
+ }
+
+ LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
+ {
+ if(m_bInternalFont)
+ {
+ HFONT hFont = m_tab.GetFont();
+ m_tab.SetFont(NULL, FALSE);
+ ::DeleteObject(hFont);
+ m_bInternalFont = false;
+ }
+
+ m_tab.SendMessage(WM_SETFONT, wParam, lParam);
+
+ T* pT = static_cast(this);
+ m_cyTabHeight = pT->CalcTabHeight();
+
+ if((BOOL)lParam != FALSE)
+ pT->UpdateLayout();
+
+ return 0;
+ }
+
LRESULT OnTabChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
{
SetActivePage(m_tab.GetCurSel());
@@ -4348,7 +4498,7 @@ public:
// Tab control message handlers
LRESULT OnTabLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
- if(m_tab.GetItemCount() > 1)
+ if(!m_bNoTabDrag && (m_tab.GetItemCount() > 1))
{
m_bTabCapture = true;
m_tab.SetCapture();
@@ -4565,7 +4715,8 @@ public:
if(m_tab.m_hWnd == NULL)
return false;
- m_tab.SetFont(AtlGetDefaultGuiFont());
+ m_tab.SetFont(AtlCreateControlFont());
+ m_bInternalFont = true;
m_tab.SetItemExtra(sizeof(TABVIEWPAGE));
@@ -4817,7 +4968,6 @@ public:
}
};
-
class CTabView : public CTabViewImpl
{
public:
diff --git a/Source/3rd Party/WTL/atlddx.h b/Source/3rd Party/WTL/atlddx.h
index ad4249a81..cc4e3bcda 100644
--- a/Source/3rd Party/WTL/atlddx.h
+++ b/Source/3rd Party/WTL/atlddx.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atlddx.h requires atlapp.h to be included first
#endif
@@ -142,6 +138,23 @@ namespace WTL
return TRUE; \
}
+// DDX support for Tab, Combo, ListBox and ListView selection index
+// Note: Specialized versions require atlctrls.h to be included first
+#if (_MSC_VER >= 1300)
+
+#define DDX_INDEX(CtrlClass, nID, var) \
+ if(nCtlID == (UINT)-1 || nCtlID == nID) \
+ DDX_Index(nID, var, bSaveAndValidate);
+
+#ifdef __ATLCTRLS_H__
+ #define DDX_TAB_INDEX(nID, var) DDX_INDEX(WTL::CTabCtrl, nID, var)
+ #define DDX_COMBO_INDEX(nID, var) DDX_INDEX(WTL::CComboBox, nID, var)
+ #define DDX_LISTBOX_INDEX(nID, var) DDX_INDEX(WTL::CListBox, nID, var)
+ #define DDX_LISTVIEW_INDEX(nID, var) DDX_INDEX(WTL::CListViewCtrl, nID, var)
+#endif // __ATLCTRLS_H__
+
+#endif // (_MSC_VER >= 1300)
+
///////////////////////////////////////////////////////////////////////////////
// CWinDataExchange - provides support for DDX
@@ -601,6 +614,54 @@ public:
while (hWndCtrl != NULL && !(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP));
}
+// DDX support for Tab, Combo, ListBox and ListView selection index
+#if (_MSC_VER >= 1300)
+ template
+ INT _getSel(TCtrl& tCtrl)
+ {
+ return tCtrl.GetCurSel();
+ }
+
+ template
+ void _setSel(TCtrl& tCtrl, INT iSel)
+ {
+ if(iSel < 0)
+ tCtrl.SetCurSel(-1);
+ else
+ tCtrl.SetCurSel(iSel);
+ }
+
+#ifdef __ATLCTRLS_H__
+ // ListViewCtrl specialization
+ template <>
+ INT _getSel(WTL::CListViewCtrl& tCtrl)
+ {
+ return tCtrl.GetSelectedIndex();
+ }
+
+ template <>
+ void _setSel(WTL::CListViewCtrl& tCtrl, INT iSel)
+ {
+ if(iSel < 0)
+ tCtrl.SelectItem(-1);
+ else
+ tCtrl.SelectItem(iSel);
+ }
+#endif // __ATLCTRLS_H__
+
+ template
+ void DDX_Index(UINT nID, INT& nVal, BOOL bSave)
+ {
+ T* pT = static_cast(this);
+ TCtrl ctrl(pT->GetDlgItem(nID));
+
+ if(bSave)
+ nVal = _getSel(ctrl);
+ else
+ _setSel(ctrl, nVal);
+ }
+#endif // (_MSC_VER >= 1300)
+
// Overrideables
void OnDataExchangeError(UINT nCtrlID, BOOL /*bSave*/)
{
diff --git a/Source/3rd Party/WTL/atldlgs.h b/Source/3rd Party/WTL/atldlgs.h
index c0fd56860..421694e50 100644
--- a/Source/3rd Party/WTL/atldlgs.h
+++ b/Source/3rd Party/WTL/atldlgs.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atldlgs.h requires atlapp.h to be included first
#endif
@@ -64,6 +60,7 @@
// CFindReplaceDialogImpl
// CFindReplaceDialog
//
+// CDialogBaseUnits
// CMemDlgTemplate
// CIndirectDialogImpl
//
@@ -151,7 +148,12 @@ public:
m_bOpenFileDialog = bOpenFileDialog;
+#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
+ m_ofn.lStructSize = bOpenFileDialog ? sizeof(m_ofn) : sizeof(OPENFILENAME);
+#else
m_ofn.lStructSize = sizeof(m_ofn);
+#endif
+
#if (_WIN32_WINNT >= 0x0500)
// adjust struct size if running on older version of Windows
if(AtlIsOldWindows())
@@ -512,7 +514,7 @@ public:
if (pStr[nLength + 1] == 0)
{
// The OFN buffer contains a single item so extract its path.
- LPCTSTR pSep = _strrchr(pStr, _T('\\'));
+ LPCTSTR pSep = MinCrtHelper::_strrchr(pStr, _T('\\'));
if (pSep != NULL)
nLength = (int)(DWORD_PTR)(pSep - pStr);
}
@@ -570,7 +572,7 @@ public:
else
{
// A single item was selected. Skip forward past the path.
- LPCTSTR pSep = _strrchr(pStr, _T('\\'));
+ LPCTSTR pSep = MinCrtHelper::_strrchr(pStr, _T('\\'));
if (pSep != NULL)
pStr = pSep + 1;
}
@@ -652,7 +654,7 @@ public:
int nRet = 0;
LPCTSTR pStr = m_pNextFile;
// Does the filename contain a backslash?
- if (_strrchr(pStr, _T('\\')) != NULL)
+ if (MinCrtHelper::_strrchr(pStr, _T('\\')) != NULL)
{
// Yes, so we'll assume it's a full path.
int nLength = lstrlen(pStr);
@@ -846,23 +848,6 @@ public:
if (nExtraChars > 0)
ATLVERIFY(ResizeFilenameBuffer(m_ofn.nMaxFile + nExtraChars));
}
-
- // Helper for _ATM_MIN_CRT
- static const TCHAR* _strrchr(const TCHAR* p, TCHAR ch)
- {
-#ifndef _ATL_MIN_CRT
- return _tcsrchr(p, ch);
-#else // _ATL_MIN_CRT
- const TCHAR* lpsz = NULL;
- while (*p != 0)
- {
- if (*p == ch)
- lpsz = p;
- p = ::CharNext(p);
- }
- return lpsz;
-#endif // _ATL_MIN_CRT
- }
};
class CMultiFileDialog : public CMultiFileDialogImpl
@@ -1538,7 +1523,7 @@ public:
ATLASSERT(m_hWnd != NULL);
USES_CONVERSION;
LPCWSTR lpstr = T2CW(lpstrOKText);
- ::SendMessage(m_hWnd, BFFM_SETOKTEXT, (WPARAM)lpstr, 0L);
+ ::SendMessage(m_hWnd, BFFM_SETOKTEXT, 0, (LPARAM)lpstr);
}
void SetExpanded(LPCITEMIDLIST pItemIDList)
@@ -2957,14 +2942,159 @@ public:
#endif // !_WIN32_WCE
-#if (_ATL_VER >= 0x800)
-typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX;
-typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX;
-#else // (_ATL_VER >= 0x800)
-typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX;
-#pragma pack(push, 4)
-struct DLGITEMTEMPLATEEX
+/////////////////////////////////////////////////////////////////////////
+// CDialogBaseUnits - Dialog Units helper
+//
+
+class CDialogBaseUnits
{
+public:
+ SIZE m_sizeUnits;
+
+// Constructors
+ CDialogBaseUnits()
+ {
+ // The base units of the out-dated System Font
+ LONG nDlgBaseUnits = ::GetDialogBaseUnits();
+ m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
+ m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
+ }
+
+ CDialogBaseUnits(HWND hWnd)
+ {
+ if(!InitDialogBaseUnits(hWnd)) {
+ LONG nDlgBaseUnits = ::GetDialogBaseUnits();
+ m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
+ m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
+ }
+ }
+
+ CDialogBaseUnits(HFONT hFont, HWND hWnd = NULL)
+ {
+ if(!InitDialogBaseUnits(hFont, hWnd)) {
+ LONG nDlgBaseUnits = ::GetDialogBaseUnits();
+ m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
+ m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
+ }
+ }
+
+ CDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL)
+ {
+ if(!InitDialogBaseUnits(lf, hWnd)) {
+ LONG nDlgBaseUnits = ::GetDialogBaseUnits();
+ m_sizeUnits.cx = LOWORD(nDlgBaseUnits);
+ m_sizeUnits.cy = HIWORD(nDlgBaseUnits);
+ }
+ }
+
+// Operations
+ BOOL InitDialogBaseUnits(HWND hWnd)
+ {
+ ATLASSERT(::IsWindow(hWnd));
+ RECT rc = { 0, 0, 4, 8 };
+ if(!::MapDialogRect(hWnd, &rc)) return FALSE;
+ m_sizeUnits.cx = rc.right;
+ m_sizeUnits.cy = rc.bottom;
+ return TRUE;
+ }
+
+ BOOL InitDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL)
+ {
+ CFont font;
+ font.CreateFontIndirect(&lf);
+ if(font.IsNull()) return FALSE;
+ return InitDialogBaseUnits(font, hWnd);
+ }
+
+ BOOL InitDialogBaseUnits(HFONT hFont, HWND hWnd = NULL)
+ {
+ ATLASSERT(hFont != NULL);
+ CWindowDC dc = hWnd;
+ TEXTMETRIC tmText = { 0 };
+ SIZE sizeText = { 0 };
+ HFONT hFontOld = dc.SelectFont(hFont);
+ dc.GetTextMetrics(&tmText);
+ m_sizeUnits.cy = tmText.tmHeight + tmText.tmExternalLeading;
+ dc.GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &sizeText);
+ m_sizeUnits.cx = (sizeText.cx + 26) / 52;
+ dc.SelectFont(hFontOld);
+ return TRUE;
+ }
+
+ SIZE GetDialogBaseUnits() const
+ {
+ return m_sizeUnits;
+ }
+
+ INT MapDialogPixelsX(INT x) const
+ {
+ return ::MulDiv(x, 4, m_sizeUnits.cx); // Pixels X to DLU
+ }
+
+ INT MapDialogPixelsY(INT y) const
+ {
+ return ::MulDiv(y, 8, m_sizeUnits.cy); // Pixels Y to DLU
+ }
+
+ POINT MapDialogPixels(POINT pt) const
+ {
+ POINT out = { MapDialogPixelsX(pt.x), MapDialogPixelsY(pt.y) };
+ return out;
+ }
+
+ SIZE MapDialogPixels(SIZE input) const
+ {
+ SIZE out = { MapDialogPixelsX(input.cx), MapDialogPixelsY(input.cy) };
+ return out;
+ }
+
+ RECT MapDialogPixels(RECT input) const
+ {
+ RECT out = { MapDialogPixelsX(input.left), MapDialogPixelsY(input.top), MapDialogPixelsX(input.right), MapDialogPixelsY(input.bottom) };
+ return out;
+ }
+
+ INT MapDialogUnitsX(INT x) const
+ {
+ return ::MulDiv(x, m_sizeUnits.cx, 4); // DLU to Pixels X
+ }
+
+ INT MapDialogUnitsY(INT y) const
+ {
+ return ::MulDiv(y, m_sizeUnits.cx, 8); // DLU to Pixels Y
+ }
+
+ POINT MapDialogUnits(POINT pt) const
+ {
+ POINT out = { MapDialogUnitsX(pt.x), MapDialogUnitsY(pt.y) };
+ return out;
+ }
+
+ SIZE MapDialogUnits(SIZE input) const
+ {
+ SIZE out = { MapDialogUnitsX(input.cx), MapDialogUnitsY(input.cy) };
+ return out;
+ }
+
+ RECT MapDialogUnits(RECT input) const
+ {
+ RECT out = { MapDialogUnitsX(input.left), MapDialogUnitsY(input.top), MapDialogUnitsX(input.right), MapDialogUnitsY(input.bottom) };
+ return out;
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX
+
+#if (_ATL_VER >= 0x800)
+ typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX;
+ typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX;
+#else // (_ATL_VER >= 0x800)
+ typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX;
+ #pragma pack(push, 4)
+ struct DLGITEMTEMPLATEEX
+ {
DWORD helpID;
DWORD exStyle;
DWORD style;
@@ -2972,15 +3102,12 @@ struct DLGITEMTEMPLATEEX
short y;
short cx;
short cy;
- WORD id;
-};
-#pragma pack(pop)
+ DWORD id;
+ };
+ #pragma pack(pop)
#endif // (_ATL_VER >= 0x800)
-///////////////////////////////////////////////////////////////////////////////
-// CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX
-
class CMemDlgTemplate
{
public:
@@ -2994,7 +3121,7 @@ public:
CTRL_COMBOBOX = 0x0085
};
- CMemDlgTemplate() : m_pData(NULL), m_pPtr(NULL), m_cAllocated(0)
+ CMemDlgTemplate() : m_hData(NULL), m_pData(NULL), m_pPtr(NULL), m_cAllocated(0)
{ }
~CMemDlgTemplate()
@@ -3024,17 +3151,30 @@ public:
void Reset()
{
- if (IsValid())
- ATLVERIFY(::GlobalFree(m_pData) == NULL);
+ if (IsValid()) {
+#ifndef UNDER_CE
+ ::GlobalUnlock(m_pData);
+#endif
+ ATLVERIFY(::GlobalFree(m_hData) == NULL);
+ }
+ m_hData = NULL;
m_pData = NULL;
m_pPtr = NULL;
m_cAllocated = 0;
}
- void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0,
- LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0,
- ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U)
+ void Create(bool bDlgEx, LPCTSTR lpszCaption, RECT rc, DWORD dwStyle = 0, DWORD dwExStyle = 0,
+ LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0,
+ ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U)
+ {
+ Create(bDlgEx, lpszCaption, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle,
+ lpstrFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName.m_lpstr, Menu.m_lpstr);
+ }
+
+ void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0,
+ LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0,
+ ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U)
{
// Should have DS_SETFONT style to set the dialog font name and size
if (lpstrFontName != NULL)
@@ -3113,6 +3253,13 @@ public:
}
}
+ void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, RECT rc, DWORD dwStyle, DWORD dwExStyle,
+ ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
+ {
+ AddControl(ClassName.m_lpstr, wId, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle,
+ Text.m_lpstr, pCreationData, nCreationData, dwHelpID);
+ }
+
void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle, DWORD dwExStyle,
ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
{
@@ -3179,24 +3326,38 @@ public:
AddControl(CtrlType, wId, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, Text, pCreationData, nCreationData, dwHelpID);
}
-protected:
void AddData(LPCVOID pData, size_t nData)
{
ATLASSERT(pData != NULL);
- const size_t ALLOCATION_INCREMENT = 1024;
+ const SIZE_T ALLOCATION_INCREMENT = 1024;
if (m_pData == NULL)
{
m_cAllocated = ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT;
- m_pPtr = m_pData = static_cast(::GlobalAlloc(GPTR, m_cAllocated));
+ m_hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, m_cAllocated);
+ ATLASSERT(m_hData != NULL);
+#ifndef UNDER_CE
+ m_pPtr = m_pData = static_cast(::GlobalLock(m_hData));
+#else
+ m_pPtr = m_pData = static_cast(m_hData);
+#endif
ATLASSERT(m_pData != NULL);
}
else if (((m_pPtr - m_pData) + nData) > m_cAllocated)
{
- size_t ptrPos = (m_pPtr - m_pData);
+ SIZE_T ptrPos = (m_pPtr - m_pData);
m_cAllocated += ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT;
- m_pData = static_cast(::GlobalReAlloc(m_pData, m_cAllocated, 0));
+#ifndef UNDER_CE
+ ::GlobalUnlock(m_pData);
+#endif
+ m_hData = ::GlobalReAlloc(m_hData, m_cAllocated, GMEM_MOVEABLE | GMEM_ZEROINIT);
+ ATLASSERT(m_hData != NULL);
+#ifndef UNDER_CE
+ m_pData = static_cast(::GlobalLock(m_hData));
+#else
+ m_pData = static_cast(m_hData);
+#endif
ATLASSERT(m_pData != NULL);
m_pPtr = m_pData + ptrPos;
}
@@ -3222,6 +3383,7 @@ protected:
}
}
+ HANDLE m_hData;
LPBYTE m_pData;
LPBYTE m_pPtr;
SIZE_T m_cAllocated;
@@ -5628,7 +5790,13 @@ inline int AtlTaskDialog(HWND hWndParent,
#ifdef _WTL_TASKDIALOG_DIRECT
USES_CONVERSION;
- HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), T2CW(WindowTitle.m_lpstr), T2CW(MainInstructionText.m_lpstr), T2CW(ContentText.m_lpstr), dwCommonButtons, T2CW(Icon.m_lpstr), &nRet);
+ HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstance(),
+ IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr),
+ IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr),
+ IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr),
+ dwCommonButtons,
+ IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr),
+ &nRet);
ATLVERIFY(SUCCEEDED(hRet));
#else
// This allows apps to run on older versions of Windows
@@ -5641,7 +5809,13 @@ inline int AtlTaskDialog(HWND hWndParent,
if(pfnTaskDialog != NULL)
{
USES_CONVERSION;
- HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), T2CW(WindowTitle.m_lpstr), T2CW(MainInstructionText.m_lpstr), T2CW(ContentText.m_lpstr), dwCommonButtons, T2CW(Icon.m_lpstr), &nRet);
+ HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::GetResourceInstance(),
+ IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr),
+ IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr),
+ IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr),
+ dwCommonButtons,
+ IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr),
+ &nRet);
ATLVERIFY(SUCCEEDED(hRet));
}
diff --git a/Source/3rd Party/WTL/atldwm.h b/Source/3rd Party/WTL/atldwm.h
new file mode 100644
index 000000000..e6377f4d9
--- /dev/null
+++ b/Source/3rd Party/WTL/atldwm.h
@@ -0,0 +1,461 @@
+// Windows Template Library - WTL version 8.1
+// 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
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
+// which can be found in the file CPL.TXT at the root of this distribution.
+// By using this software in any fashion, you are agreeing to be bound by
+// the terms of this license. You must not remove this notice, or
+// any other, from this software.
+
+#ifndef __ATLDWM_H__
+#define __ATLDWM_H__
+
+#pragma once
+
+#ifdef _WIN32_WCE
+ #error atldwm.h is not supported on Windows CE
+#endif
+
+#ifndef __ATLAPP_H__
+ #error atldwm.h requires atlapp.h to be included first
+#endif
+
+#ifndef __ATLWIN_H__
+ #error atldwm.h requires atlwin.h to be included first
+#endif
+
+#if (_WIN32_WINNT < 0x0600)
+ #error atldwm.h requires _WIN32_WINNT >= 0x0600
+#endif // (_WIN32_WINNT < 0x0600)
+
+#ifndef _DWMAPI_H_
+#include
+#endif // _DWMAPI_H_
+#pragma comment(lib, "dwmapi.lib")
+
+// Note: To create an application that also runs on older versions of Windows,
+// use delay load of dwmapi.dll and ensure that no calls to the DWM API are
+// Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib,
+// and add dwmapi.dll in the Linker.Input.Delay Loaded DLLs section of the
+// project properties.
+#if (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD)
+ #pragma comment(lib, "delayimp.lib")
+ #pragma comment(linker, "/delayload:dwmapi.dll")
+#endif // (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD)
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes in this file:
+//
+// CDwm
+// CDwmImpl
+// CDwmWindowT - CDwmWindow
+// CDwmThumbnailT
+// CDwmThumbnail
+// CDwmThumbnailHandle
+// CAeroControlImpl
+
+
+namespace WTL
+{
+
+///////////////////////////////////////////////////////////////////////////////
+// CDwm - wrapper for DWM handle
+
+class CDwm
+{
+public:
+// Data members
+ static int m_nIsDwmSupported;
+
+// Constructor
+ CDwm()
+ {
+ IsDwmSupported();
+ }
+
+// Dwm support helper
+ static bool IsDwmSupported()
+ {
+ if(m_nIsDwmSupported == -1)
+ {
+ CStaticDataInitCriticalSectionLock lock;
+ if(FAILED(lock.Lock()))
+ {
+ ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDwm::IsDwmSupported.\n"));
+ ATLASSERT(FALSE);
+ return false;
+ }
+
+ if(m_nIsDwmSupported == -1)
+ {
+ HMODULE hDwmDLL = ::LoadLibrary(_T("dwmapi.dll"));
+ m_nIsDwmSupported = (hDwmDLL != NULL) ? 1 : 0;
+ if(hDwmDLL != NULL)
+ ::FreeLibrary(hDwmDLL);
+ }
+
+ lock.Unlock();
+ }
+
+ ATLASSERT(m_nIsDwmSupported != -1);
+ return (m_nIsDwmSupported == 1);
+ }
+
+// Operations
+ BOOL DwmIsCompositionEnabled() const
+ {
+ if(!IsDwmSupported()) return FALSE;
+ BOOL bRes = FALSE;
+ return SUCCEEDED(::DwmIsCompositionEnabled(&bRes)) && bRes;
+ }
+
+ BOOL DwmEnableComposition(UINT fEnable)
+ {
+ if(!IsDwmSupported()) return FALSE;
+ return SUCCEEDED(::DwmEnableComposition(fEnable));
+ }
+
+ BOOL DwmEnableMMCSS(BOOL fEnableMMCSS)
+ {
+ if(!IsDwmSupported()) return FALSE;
+ return SUCCEEDED(::DwmEnableMMCSS(fEnableMMCSS));
+ }
+
+ HRESULT DwmGetColorizationColor(DWORD* pcrColorization, BOOL* pfOpaqueBlend)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ return ::DwmGetColorizationColor(pcrColorization, pfOpaqueBlend);
+ }
+
+ HRESULT DwmFlush()
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ return ::DwmFlush();
+ }
+};
+
+__declspec(selectany) int CDwm::m_nIsDwmSupported = -1;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CDwmImpl - DWM window support
+
+template
+class CDwmImpl : public TBase
+{
+public:
+ HRESULT DwmEnableBlurBehindWindow(const DWM_BLURBEHIND* pBB)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmEnableBlurBehindWindow(pT->m_hWnd, pBB);
+ }
+
+ HRESULT DwmExtendFrameIntoClientArea(const MARGINS* pMargins)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmExtendFrameIntoClientArea(pT->m_hWnd, pMargins);
+ }
+
+ HRESULT DwmExtendFrameIntoEntireClientArea()
+ {
+ MARGINS margins = { -1 };
+ return DwmExtendFrameIntoClientArea(&margins);
+ }
+
+ HRESULT DwmGetCompositionTimingInfo(DWM_TIMING_INFO* pTimingInfo)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmGetCompositionTimingInfo(pT->m_hWnd, pTimingInfo);
+ }
+
+ HRESULT DwmGetWindowAttribute(DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmGetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute);
+ }
+
+ HRESULT DwmModifyPreviousDxFrameDuration(INT cRefreshes, BOOL fRelative)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmModifyPreviousDxFrameDuration(pT->m_hWnd, cRefreshes, fRelative);
+ }
+
+ HRESULT DwmSetDxFrameDuration(INT cRefreshes)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmSetDxFrameDuration(pT->m_hWnd, cRefreshes);
+ }
+
+ HRESULT DwmSetPresentParameters(DWM_PRESENT_PARAMETERS* pPresentParams)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmSetPresentParameters(pT->m_hWnd, pPresentParams);
+ }
+
+ HRESULT DwmSetWindowAttribute(DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmSetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute);
+ }
+
+ HRESULT DwmAttachMilContent()
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmAttachMilContent(pT->m_hWnd);
+ }
+
+ HRESULT DwmDetachMilContent()
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ T* pT = static_cast(this);
+ ATLASSERT(::IsWindow(pT->m_hWnd));
+ return ::DwmDetachMilContent(pT->m_hWnd);
+ }
+};
+
+template
+class CDwmWindowT : public TBase, public CDwmImpl >
+{
+public:
+ CDwmWindowT(HWND hWnd = NULL) : TBase(hWnd)
+ { }
+
+ CDwmWindowT< TBase >& operator =(HWND hWnd)
+ {
+ m_hWnd = hWnd;
+ return *this;
+ }
+};
+
+typedef CDwmWindowT CDwmWindow;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CDwmThumbnail - provides DWM thumbnail support
+
+template
+class CDwmThumbnailT : public TBase
+{
+public:
+// Data members
+ HTHUMBNAIL m_hThumbnail;
+
+// Constructor
+ CDwmThumbnailT(HTHUMBNAIL hThumbnail = NULL) : m_hThumbnail(hThumbnail)
+ {
+ }
+
+ ~CDwmThumbnailT()
+ {
+ if(t_bManaged && m_hThumbnail != NULL)
+ Unregister();
+ }
+
+// Operations
+ CDwmThumbnailT& operator =(HTHUMBNAIL hThumbnail)
+ {
+ Attach(hThumbnail);
+ return *this;
+ }
+
+ void Attach(HTHUMBNAIL hThumbnailNew)
+ {
+ if(t_bManaged && m_hThumbnail != NULL && m_hThumbnail != hThumbnailNew)
+ Unregister();
+ m_hThumbnail = hThumbnailNew;
+ }
+
+ HTHUMBNAIL Detach()
+ {
+ HTHUMBNAIL hThumbnail = m_hThumbnail;
+ m_hThumbnail = NULL;
+ return hThumbnail;
+ }
+
+ HRESULT Register(HWND hwndDestination, HWND hwndSource)
+ {
+ ATLASSERT(::IsWindow(hwndDestination));
+ ATLASSERT(::IsWindow(hwndSource));
+ ATLASSERT(m_hThumbnail==NULL);
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ return ::DwmRegisterThumbnail(hwndDestination, hwndSource, &m_hThumbnail);
+ }
+
+ HRESULT Unregister()
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ if(m_hThumbnail == NULL) return S_FALSE;
+ HRESULT Hr = ::DwmUnregisterThumbnail(m_hThumbnail);
+ if(SUCCEEDED(Hr)) m_hThumbnail = NULL;
+ return Hr;
+ }
+
+ operator HTHUMBNAIL() const { return m_hThumbnail; }
+
+ bool IsNull() const { return (m_hThumbnail == NULL); }
+
+ HRESULT UpdateProperties(const DWM_THUMBNAIL_PROPERTIES* ptnProperties)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ ATLASSERT(m_hThumbnail != NULL);
+ return ::DwmUpdateThumbnailProperties(m_hThumbnail, ptnProperties);
+ }
+
+// Attributes
+ HRESULT QuerySourceSize(PSIZE pSize)
+ {
+ if(!IsDwmSupported()) return E_NOTIMPL;
+ ATLASSERT(m_hThumbnail != NULL);
+ return ::DwmQueryThumbnailSourceSize(m_hThumbnail, pSize);
+ }
+};
+
+typedef CDwmThumbnailT CDwmThumbnail;
+typedef CDwmThumbnailT CDwmThumbnailHandle;
+
+
+#ifdef __ATLTHEME_H__
+
+///////////////////////////////////////////////////////////////////////////////
+// CAeroControlImpl - Base class for controls on Glass
+
+template
+class CAeroControlImpl :
+ public CThemeImpl,
+ public CBufferedPaintImpl,
+ public ATL::CWindowImpl
+{
+public:
+ typedef CThemeImpl _themeClass;
+ typedef CBufferedPaintImpl _baseClass;
+ typedef ATL::CWindowImpl _windowClass;
+
+ CAeroControlImpl()
+ {
+ m_PaintParams.dwFlags = BPPF_ERASE;
+ }
+
+ static LPCWSTR GetThemeName()
+ {
+#ifdef _UNICODE
+ return TBase::GetWndClassName();
+#else
+ ATLASSERT(!_T("Return UNICODE string of window classname / theme class"));
+ return NULL;
+#endif // _UNICODE
+ }
+
+// Message map and handlers
+ BEGIN_MSG_MAP(CAeroControlImpl)
+ MESSAGE_HANDLER(WM_CREATE, OnCreate)
+ MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
+ CHAIN_MSG_MAP(_themeClass)
+ CHAIN_MSG_MAP(_baseClass)
+ END_MSG_MAP()
+
+ LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
+ {
+ T* pT = static_cast(this);
+ pT->Init();
+ bHandled = FALSE;
+ return 0;
+ }
+
+ LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
+ {
+ if(IsThemingSupported()) Invalidate(FALSE);
+ bHandled = FALSE;
+ return 0;
+ }
+
+// Operations
+ BOOL SubclassWindow(HWND hWnd)
+ {
+ ATLASSERT(m_hWnd == NULL);
+ ATLASSERT(::IsWindow(hWnd));
+ BOOL bRet = _windowClass::SubclassWindow(hWnd);
+ if(bRet) {
+ T* pT = static_cast(this);
+ pT->Init();
+ }
+ return bRet;
+ }
+
+// Implementation
+ LRESULT DefWindowProc()
+ {
+ const _ATL_MSG* pMsg = m_pCurrentMsg;
+ LRESULT lRes = 0;
+ if(pMsg != NULL)
+ lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
+ return lRes;
+ }
+
+ LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ T* pT = static_cast(this);
+ LRESULT lRes = 0;
+ if( ::DwmDefWindowProc(pT->m_hWnd, uMsg, wParam, lParam, &lRes) ) return lRes;
+ return _windowClass::DefWindowProc(uMsg, wParam, lParam);
+ }
+
+ void DoBufferedPaint(HDC hDC, RECT& rcPaint)
+ {
+ T* pT = static_cast(this);
+ HDC hDCPaint = NULL;
+ RECT rcClient = { 0 };
+ GetClientRect(&rcClient);
+ m_BufferedPaint.Begin(hDC, &rcClient, m_dwFormat, &m_PaintParams, &hDCPaint);
+ ATLASSERT(hDCPaint != NULL);
+ pT->DoAeroPaint(hDCPaint, rcClient, rcPaint);
+ m_BufferedPaint.End();
+ }
+
+ void DoPaint(HDC /*hdc*/, RECT& /*rcClient*/)
+ {
+ DefWindowProc();
+ }
+
+// Overridables
+ void Init()
+ {
+ T* pT = static_cast(this);
+ SetThemeClassList(pT->GetThemeName());
+ if(m_lpstrThemeClassList != NULL)
+ OpenThemeData();
+ }
+
+ void DoAeroPaint(HDC hDC, RECT& /*rcClient*/, RECT& rcPaint)
+ {
+ DefWindowProc(WM_PAINT, (WPARAM) hDC, 0L);
+ m_BufferedPaint.MakeOpaque(&rcPaint);
+ }
+};
+
+#endif // __ATLTHEME_H__
+
+
+}; // namespace WTL
+
+
+#endif // __ATLDWM_H__
diff --git a/Source/3rd Party/WTL/atlfind.h b/Source/3rd Party/WTL/atlfind.h
index a1dd52dbe..832aba204 100644
--- a/Source/3rd Party/WTL/atlfind.h
+++ b/Source/3rd Party/WTL/atlfind.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifdef _WIN32_WCE
#error atlfind.h is not supported on Windows CE
#endif
@@ -897,7 +893,7 @@ public:
}
}
- return (pT->m_bShadowBufferNeeded == TRUE);
+ return (pT->m_bShadowBufferNeeded != FALSE);
}
};
diff --git a/Source/3rd Party/WTL/atlframe.h b/Source/3rd Party/WTL/atlframe.h
index 7eb102f8a..252e50e90 100644
--- a/Source/3rd Party/WTL/atlframe.h
+++ b/Source/3rd Party/WTL/atlframe.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atlframe.h requires atlapp.h to be included first
#endif
@@ -38,6 +34,7 @@
// CUpdateUIBase
// CUpdateUI
// CDynamicUpdateUI
+// CAutoUpdateUI
// CDialogResize
// CDoubleBufferImpl
// CDoubleBufferWindowImpl
@@ -375,29 +372,6 @@ class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase,
public:
DECLARE_FRAME_WND_CLASS(NULL, 0)
-// Data members
- HWND m_hWndToolBar;
- HWND m_hWndStatusBar;
- HWND m_hWndClient;
-
- HACCEL m_hAccel;
-
-#ifdef _WIN32_WCE
- HWND m_hWndCECommandBar;
-#endif // _WIN32_WCE
-
- struct _AtlToolBarData
- {
- WORD wVersion;
- WORD wWidth;
- WORD wHeight;
- WORD wItemCount;
- //WORD aItems[wItemCount]
-
- WORD* items()
- { return (WORD*)(this+1); }
- };
-
#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
struct _ChevronMenuInfo
{
@@ -407,14 +381,25 @@ public:
};
#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
+// Data members
+ HWND m_hWndToolBar;
+ HWND m_hWndStatusBar;
+ HWND m_hWndClient;
+
+#ifdef _WIN32_WCE
+ HWND m_hWndCECommandBar;
+#endif // _WIN32_WCE
+
+ HACCEL m_hAccel;
+
// Constructor
CFrameWindowImplBase() :
-#ifdef _WIN32_WCE
- m_hWndCECommandBar(NULL),
-#endif // _WIN32_WCE
m_hWndToolBar(NULL),
m_hWndStatusBar(NULL),
m_hWndClient(NULL),
+#ifdef _WIN32_WCE
+ m_hWndCECommandBar(NULL),
+#endif // _WIN32_WCE
m_hAccel(NULL)
{ }
@@ -523,7 +508,7 @@ public:
// check if font is taller than our bitmaps
CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
if(font.IsNull())
- font = AtlGetDefaultGuiFont();
+ font = (HFONT)::GetStockObject(SYSTEM_FONT);
LOGFONT lf = { 0 };
font.GetLogFont(lf);
WORD cyFontHeight = (WORD)abs(lf.lfHeight);
@@ -825,10 +810,10 @@ public:
// resize toolbar
if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBar, GWL_STYLE) & WS_VISIBLE))
{
- if(bResizeBars)
+ if(bResizeBars != FALSE)
{
::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0);
- ::InvalidateRect(m_hWndToolBar, NULL, FALSE);
+ ::InvalidateRect(m_hWndToolBar, NULL, TRUE);
}
RECT rectTB = { 0 };
::GetWindowRect(m_hWndToolBar, &rectTB);
@@ -838,7 +823,7 @@ public:
// resize status bar
if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStatusBar, GWL_STYLE) & WS_VISIBLE))
{
- if(bResizeBars)
+ if(bResizeBars != FALSE)
::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0);
RECT rectSB = { 0 };
::GetWindowRect(m_hWndStatusBar, &rectSB);
@@ -2115,6 +2100,11 @@ public:
{
void* m_lpData;
LPTSTR m_lpstrText;
+ struct
+ {
+ WORD m_nIDFirst;
+ WORD m_nIDLast;
+ };
};
bool operator ==(const _AtlUpdateUIData& e) const
@@ -2223,7 +2213,12 @@ public:
while(pMap->m_nID != (WORD)-1)
{
if(pMap->m_wType & UPDUI_MENUPOPUP)
+ {
UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu);
+
+ if((pUIData->m_wState & UPDUI_RADIO) != 0)
+ ::CheckMenuRadioItem(hMenu, pUIData->m_nIDFirst, pUIData->m_nIDLast, pMap->m_nID, MF_BYCOMMAND);
+ }
pMap++;
pUIData++;
}
@@ -2382,6 +2377,46 @@ public:
return TRUE;
}
+ // for menu items
+ BOOL UISetRadioMenuItem(int nID, int nIDFirst, int nIDLast, BOOL bForceUpdate = FALSE)
+ {
+ const _AtlUpdateUIMap* pMap = m_pUIMap;
+ _AtlUpdateUIData* pUIData = m_pUIData;
+ if(pUIData == NULL)
+ return FALSE;
+
+ for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
+ {
+ if(nID == (int)pMap->m_nID)
+ {
+ pUIData->m_wState |= pMap->m_wType;
+ pUIData->m_wState |= UPDUI_RADIO;
+ pUIData->m_nIDFirst = (WORD)nIDFirst;
+ pUIData->m_nIDLast = (WORD)nIDLast;
+
+ if(bForceUpdate)
+ pUIData->m_wState |= pMap->m_wType;
+ if(pUIData->m_wState & pMap->m_wType)
+ m_wDirtyType |= pMap->m_wType;
+ }
+ else if(pMap->m_nID >= nIDFirst && pMap->m_nID <= nIDLast)
+ {
+ if(pUIData->m_wState & UPDUI_RADIO)
+ {
+ pUIData->m_wState &= ~pMap->m_wType;
+ pUIData->m_wState &= ~UPDUI_RADIO;
+ pUIData->m_nIDFirst = 0;
+ pUIData->m_nIDLast = 0;
+ }
+ }
+
+ if(pMap->m_nID == nIDLast)
+ break;
+ }
+
+ return TRUE;
+ }
+
BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE)
{
const _AtlUpdateUIMap* pMap = m_pUIMap;
@@ -2922,6 +2957,194 @@ public:
};
+///////////////////////////////////////////////////////////////////////////////
+// CAutoUpdateUI : Automatic mapping of UI elements
+
+template
+class CAutoUpdateUI : public CDynamicUpdateUI
+{
+public:
+ LPCTSTR UIGetText(int nID)
+ {
+ for(int i = 0; i < m_arrUIMap.GetSize(); i++)
+ {
+ if(m_arrUIMap[i].m_nID == nID)
+ return m_arrUIData[i].m_lpstrText;
+ }
+
+ return NULL;
+ }
+
+// Element
+ template
+ bool UIAddElement(UINT nID)
+ {
+ // check for existing UI map element
+ for(int i = 0; i < m_arrUIMap.GetSize(); i++)
+ {
+ if(m_arrUIMap[i].m_nID == nID)
+ {
+ // set requested type
+ m_arrUIMap[i].m_wType |= t_wType;
+ return true;
+ }
+ }
+
+ // Add element to UI map with requested type
+ return UIAddUpdateElement((WORD)nID, t_wType);
+ }
+
+ template
+ bool UIRemoveElement(UINT nID)
+ {
+ for(int i = 0; i < m_arrUIMap.GetSize(); i++)
+ {
+ if(m_arrUIMap[i].m_nID == nID) // matching UI map element
+ {
+ WORD wType = m_arrUIMap[i].m_wType & ~t_wType;
+ if (wType) // has other types
+ {
+ m_arrUIMap[i].m_wType = wType; // keep other types
+ return true;
+ }
+ else
+ {
+ return UIRemoveUpdateElement((WORD)nID);
+ }
+ }
+ }
+
+ return false;
+ }
+
+// Menu
+ bool UIAddMenu(HMENU hMenu, bool bSetText = false)
+ {
+#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
+ using ATL::GetMenuString;
+#endif
+ ATLASSERT(::IsMenu(hMenu));
+ MENUITEMINFO mii = {sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_ID | MIIM_SUBMENU};
+
+ // Complete the UI map
+ for (INT uItem = 0; CMenuHandle(hMenu).GetMenuItemInfo(uItem, TRUE, &mii); uItem++)
+ {
+ if(mii.hSubMenu)
+ {
+ // Add submenu to UI map
+ UIAddMenu(mii.hSubMenu, bSetText);
+ }
+ else if (mii.wID)
+ {
+ // Add element to UI map
+ UIAddElement(mii.wID);
+#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
+ if (bSetText)
+ {
+ TCHAR sText[64] = { 0 };
+ if (GetMenuString(hMenu, uItem, sText, 64, MF_BYPOSITION))
+ UISetText(mii.wID, sText);
+ }
+#else
+ bSetText;
+#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
+ }
+ }
+
+ return true;
+ }
+
+ bool UIAddMenu(UINT uID, bool bSetText = false)
+ {
+ CMenu menu;
+ ATLVERIFY(menu.LoadMenu(uID));
+ return UIAddMenu(menu, bSetText);
+ }
+
+// ToolBar
+#ifndef BTNS_SEP
+ #define BTNS_SEP TBSTYLE_SEP
+#endif // BTNS_SEP compatibility
+
+#if !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX))
+ bool UIAddToolBar(HWND hWndToolBar)
+ {
+ ATLASSERT(::IsWindow(hWndToolBar));
+ TBBUTTONINFO tbbi = {sizeof TBBUTTONINFO, TBIF_COMMAND | TBIF_STYLE | TBIF_BYINDEX};
+
+ // Add toolbar buttons
+ for (int uItem = 0; ::SendMessage(hWndToolBar, TB_GETBUTTONINFO, uItem, (LPARAM)&tbbi) != -1; uItem++)
+ {
+ if (tbbi.fsStyle ^ BTNS_SEP)
+ UIAddElement(tbbi.idCommand);
+ }
+
+ // Add embedded controls if any
+ if (::GetWindow(hWndToolBar, GW_CHILD))
+ UIAddChildWindowContainer(hWndToolBar);
+
+ return (CUpdateUIBase::UIAddToolBar(hWndToolBar) != FALSE);
+ }
+#endif // !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX))
+
+// Container
+ bool UIAddChildWindowContainer(HWND hWnd)
+ {
+ ATLASSERT(::IsWindow(hWnd));
+
+ // Add children controls if any
+ for (ATL::CWindow wCtl = ::GetWindow(hWnd, GW_CHILD); wCtl.IsWindow(); wCtl = wCtl.GetWindow(GW_HWNDNEXT))
+ {
+ if (int id = wCtl.GetDlgCtrlID())
+ UIAddElement(id);
+ }
+
+ return (CUpdateUIBase::UIAddChildWindowContainer(hWnd) != FALSE);
+ }
+
+// StatusBar
+ BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE)
+ {
+ if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate)
+ return TRUE;
+
+ for(int i = 0; i < m_arrUIMap.GetSize(); i++)
+ {
+ for(int e = 0; e < m_UIElements.GetSize(); e++)
+ {
+ if((m_UIElements[e].m_wType == UPDUI_STATUSBAR) &&
+ (m_arrUIMap[i].m_wType & UPDUI_STATUSBAR) &&
+ (m_arrUIData[i].m_wState & UPDUI_STATUSBAR))
+ {
+ UIUpdateStatusBarElement(m_arrUIMap[i].m_nID, &m_arrUIData[i], m_UIElements[e].m_hWnd);
+ m_arrUIData[i].m_wState &= ~UPDUI_STATUSBAR;
+ if(m_arrUIData[i].m_wState & UPDUI_TEXT)
+ m_arrUIData[i].m_wState &= ~UPDUI_TEXT;
+ }
+ }
+ }
+
+ m_wDirtyType &= ~UPDUI_STATUSBAR;
+ return TRUE;
+ }
+
+ bool UIAddStatusBar(HWND hWndStatusBar, INT nPanes = 1)
+ {
+ ATLASSERT(::IsWindow(hWndStatusBar));
+
+ // Add StatusBar panes
+ for (int iPane = 0; iPane < nPanes; iPane++)
+ UIAddElement(ID_DEFAULT_PANE + iPane);
+
+ return (CUpdateUIBase::UIAddStatusBar(hWndStatusBar) != FALSE);
+ }
+
+// UI Map used if derived class has none
+ BEGIN_UPDATE_UI_MAP(CAutoUpdateUI)
+ END_UPDATE_UI_MAP()
+};
+
+
///////////////////////////////////////////////////////////////////////////////
// CDialogResize - provides support for resizing dialog controls
// (works for any window that has child controls)
diff --git a/Source/3rd Party/WTL/atlgdi.h b/Source/3rd Party/WTL/atlgdi.h
index 49a1371ca..1e452c4d9 100644
--- a/Source/3rd Party/WTL/atlgdi.h
+++ b/Source/3rd Party/WTL/atlgdi.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atlgdi.h requires atlapp.h to be included first
#endif
@@ -411,44 +407,60 @@ public:
void SetHeight(LONG nPointSize, HDC hDC = NULL)
{
+ HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
// For MM_TEXT mapping mode
- lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC, LOGPIXELSY), 72);
+ lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC1, LOGPIXELSY), 72);
+ if(hDC == NULL)
+ ::ReleaseDC(NULL, hDC1);
}
LONG GetHeight(HDC hDC = NULL) const
{
+ HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
// For MM_TEXT mapping mode
- return ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC, LOGPIXELSY));
+ LONG nPointSize = ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC1, LOGPIXELSY));
+ if(hDC == NULL)
+ ::ReleaseDC(NULL, hDC1);
+
+ return nPointSize;
}
LONG GetDeciPointHeight(HDC hDC = NULL) const
{
+ HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
#ifndef _WIN32_WCE
POINT ptOrg = { 0, 0 };
- ::DPtoLP(hDC, &ptOrg, 1);
+ ::DPtoLP(hDC1, &ptOrg, 1);
POINT pt = { 0, 0 };
pt.y = abs(lfHeight) + ptOrg.y;
- ::LPtoDP(hDC,&pt,1);
- return ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
+ ::LPtoDP(hDC1, &pt,1);
+ LONG nDeciPoint = ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
#else // CE specific
// DP and LP are always the same on CE
- return ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
+ LONG nDeciPoint = ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
+ if(hDC == NULL)
+ ::ReleaseDC(NULL, hDC1);
+
+ return nDeciPoint;
}
void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL)
{
+ HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
#ifndef _WIN32_WCE
POINT pt = { 0, 0 };
- pt.y = ::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point
- ::DPtoLP(hDC, &pt, 1);
+ pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point
+ ::DPtoLP(hDC1, &pt, 1);
POINT ptOrg = { 0, 0 };
- ::DPtoLP(hDC, &ptOrg, 1);
+ ::DPtoLP(hDC1, &ptOrg, 1);
lfHeight = -abs(pt.y - ptOrg.y);
#else // CE specific
// DP and LP are always the same on CE
- lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point
+ lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
+ if(hDC == NULL)
+ ::ReleaseDC(NULL, hDC1);
}
#ifndef _WIN32_WCE
@@ -2321,6 +2333,31 @@ public:
ATLASSERT(m_hDC != NULL);
return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode);
}
+
+ BOOL GradientFillRect(RECT& rect, COLORREF clr1, COLORREF clr2, bool bHorizontal)
+ {
+ ATLASSERT(m_hDC != NULL);
+
+ TRIVERTEX arrTvx[2] = { { 0 }, { 0 } };
+
+ arrTvx[0].x = rect.left;
+ arrTvx[0].y = rect.top;
+ arrTvx[0].Red = MAKEWORD(0, GetRValue(clr1));
+ arrTvx[0].Green = MAKEWORD(0, GetGValue(clr1));
+ arrTvx[0].Blue = MAKEWORD(0, GetBValue(clr1));
+ arrTvx[0].Alpha = 0;
+
+ arrTvx[1].x = rect.right;
+ arrTvx[1].y = rect.bottom;
+ arrTvx[1].Red = MAKEWORD(0, GetRValue(clr2));
+ arrTvx[1].Green = MAKEWORD(0, GetGValue(clr2));
+ arrTvx[1].Blue = MAKEWORD(0, GetBValue(clr2));
+ arrTvx[1].Alpha = 0;
+
+ GRADIENT_RECT gr = { 0, 1 };
+
+ return ::GradientFill(m_hDC, arrTvx, 2, &gr, 1, bHorizontal ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V);
+ }
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
#if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
@@ -3646,7 +3683,7 @@ struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields
DWORD dw[3] = DIBINFO16_BITFIELDS ;
bmiHeader = bmih;
- memcpy(bmiColors, dw, 3 * sizeof(DWORD));
+ SecureHelper::memcpy_x(bmiColors, sizeof(bmiColors), dw, 3 * sizeof(DWORD));
}
};
@@ -3710,18 +3747,21 @@ inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih)
inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi)
{
- HBITMAP hbm = NULL;
CDC dc(NULL);
- void * pBits = NULL;
+ void* pBits = NULL;
LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD);
- if (hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL))
- memcpy(pBits, pDibBits, pbmi->bmiHeader.biSizeImage);
+ HBITMAP hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL);
+ if (hbm != NULL)
+ {
+ int cbBits = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biHeight * pbmi->bmiHeader.biBitCount / 8;
+ SecureHelper::memcpy_x(pBits, cbBits, pDibBits, pbmi->bmiHeader.biSizeImage);
+ }
return hbm;
}
-inline HBITMAP AtlCopyBitmap(HBITMAP hbm , SIZE sizeDst, bool bAsBitmap = false)
+inline HBITMAP AtlCopyBitmap(HBITMAP hbm, SIZE sizeDst, bool bAsBitmap = false)
{
CDC hdcSrc = CreateCompatibleDC(NULL);
CDC hdcDst = CreateCompatibleDC(NULL);
@@ -3786,13 +3826,13 @@ inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size)
}
}
- if((bOK == TRUE) && (AtlIsDib16(&ds.dsBmih) == TRUE) && (ds.dsBm.bmBits != NULL))
+ if((bOK != FALSE) && (AtlIsDib16(&ds.dsBmih) != FALSE) && (ds.dsBm.bmBits != NULL))
{
pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage);
if (pDib != NULL)
{
- memcpy(pDib , &ds.dsBmih, sizeof(DIBINFO16));
- memcpy(pDib + sizeof(DIBINFO16), ds.dsBm.bmBits, ds.dsBmih.biSizeImage);
+ SecureHelper::memcpy_x(pDib, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage, &ds.dsBmih, sizeof(DIBINFO16));
+ SecureHelper::memcpy_x(pDib + sizeof(DIBINFO16), ds.dsBmih.biSizeImage, ds.dsBm.bmBits, ds.dsBmih.biSizeImage);
}
}
@@ -3806,9 +3846,10 @@ inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd)
{
ATLASSERT(::IsWindow(hWnd));
BOOL bOK = OpenClipboard(hWnd);
- if (bOK == TRUE)
+ if (bOK != FALSE)
{
- if ((bOK = EmptyClipboard()) == TRUE)
+ bOK = EmptyClipboard();
+ if (bOK != FALSE)
{
HLOCAL hDib = AtlCreatePackedDib16(hbm, size);
if (hDib != NULL)
@@ -3825,14 +3866,14 @@ inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd)
CloseClipboard();
}
- return bOK == TRUE;
+ return (bOK != FALSE);
}
inline HBITMAP AtlGetClipboardDib(HWND hWnd)
{
- ATLASSERT(::IsWindow(hWnd) == TRUE);
+ ATLASSERT(::IsWindow(hWnd) != FALSE);
HBITMAP hbm = NULL;
- if (OpenClipboard(hWnd) == TRUE)
+ if (OpenClipboard(hWnd) != FALSE)
{
LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB);
if (pbmi != NULL)
diff --git a/Source/3rd Party/WTL/atlmisc.h b/Source/3rd Party/WTL/atlmisc.h
index 70c8745f9..dd760ca0b 100644
--- a/Source/3rd Party/WTL/atlmisc.h
+++ b/Source/3rd Party/WTL/atlmisc.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifndef __ATLAPP_H__
#error atlmisc.h requires atlapp.h to be included first
#endif
@@ -55,22 +51,6 @@
// CFindFile
//
// Global functions:
-// AtlLoadAccelerators()
-// AtlLoadMenu()
-// AtlLoadBitmap()
-// AtlLoadSysBitmap()
-// AtlLoadCursor()
-// AtlLoadSysCursor()
-// AtlLoadIcon()
-// AtlLoadSysIcon()
-// AtlLoadBitmapImage()
-// AtlLoadCursorImage()
-// AtlLoadIconImage()
-// AtlLoadSysBitmapImage()
-// AtlLoadSysCursorImage()
-// AtlLoadSysIconImage()
-// AtlLoadString()
-//
// AtlGetStockPen()
// AtlGetStockBrush()
// AtlGetStockFont()
@@ -2481,18 +2461,6 @@ protected:
return (*p == ch) ? p : NULL;
}
- static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
- {
- const TCHAR* lpsz = NULL;
- while (*p != 0)
- {
- if (*p == ch)
- lpsz = p;
- p = ::CharNext(p);
- }
- return lpsz;
- }
-
static TCHAR* _cstrrev(TCHAR* pStr)
{
// optimize NULL, zero-length, and single-char case
@@ -2601,20 +2569,6 @@ protected:
return (p[n] != 0) ? &p[n] : NULL;
}
- static int _cstrisdigit(TCHAR ch)
- {
- WORD type;
- GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
- return (type & C1_DIGIT) == C1_DIGIT;
- }
-
- static int _cstrisspace(TCHAR ch)
- {
- WORD type;
- GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
- return (type & C1_SPACE) == C1_SPACE;
- }
-
static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return lstrcmp(pstrOne, pstrOther);
@@ -2638,45 +2592,12 @@ protected:
ATLASSERT(nRet != 0);
return nRet - 2; // convert to strcmp convention
}
-
- static int _cstrtoi(const TCHAR* nptr)
- {
- int c; // current char
- int total; // current total
- int sign; // if '-', then negative, otherwise positive
-
- while (_cstrisspace(*nptr))
- ++nptr;
-
- c = (int)(_TUCHAR)*nptr++;
- sign = c; // save sign indication
- if (c == _T('-') || c == _T('+'))
- c = (int)(_TUCHAR)*nptr++; // skip sign
-
- total = 0;
-
- while (_cstrisdigit((TCHAR)c))
- {
- total = 10 * total + (c - '0'); // accumulate digit
- c = (int)(_TUCHAR)*nptr++; // get next char
- }
-
- if (sign == '-')
- return -total;
- else
- return total; // return result, negated if necessary
- }
#else // !_ATL_MIN_CRT
static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch)
{
return _tcschr(p, ch);
}
- static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
- {
- return _tcsrchr(p, ch);
- }
-
static TCHAR* _cstrrev(TCHAR* pStr)
{
return _tcsrev(pStr);
@@ -2702,16 +2623,6 @@ protected:
return _tcspbrk(p, lpszCharSet);
}
- static int _cstrisdigit(TCHAR ch)
- {
- return _istdigit(ch);
- }
-
- static int _cstrisspace(TCHAR ch)
- {
- return _istspace((_TUCHAR)ch);
- }
-
static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther)
{
return _tcscmp(pstrOne, pstrOther);
@@ -2733,12 +2644,27 @@ protected:
return _tcsicoll(pstrOne, pstrOther);
}
#endif // !_WIN32_WCE
+#endif // !_ATL_MIN_CRT
+
+ static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
+ {
+ return MinCrtHelper::_strrchr(p, ch);
+ }
+
+ static int _cstrisdigit(TCHAR ch)
+ {
+ return MinCrtHelper::_isdigit(ch);
+ }
+
+ static int _cstrisspace(TCHAR ch)
+ {
+ return MinCrtHelper::_isspace(ch);
+ }
static int _cstrtoi(const TCHAR* nptr)
{
- return _ttoi(nptr);
+ return MinCrtHelper::_atoi(nptr);
}
-#endif // !_ATL_MIN_CRT
static const TCHAR* _cstrchr_db(const TCHAR* p, TCHAR ch1, TCHAR ch2)
{
@@ -3066,8 +2992,8 @@ public:
BOOL ReadFromRegistry(LPCTSTR lpstrRegKey)
{
T* pT = static_cast(this);
- ATL::CRegKey rkParent;
- ATL::CRegKey rk;
+ CRegKeyEx rkParent;
+ CRegKeyEx rk;
LONG lRet = rkParent.Open(HKEY_CURRENT_USER, lpstrRegKey);
if(lRet != ERROR_SUCCESS)
@@ -3077,11 +3003,7 @@ public:
return FALSE;
DWORD dwRet = 0;
-#if (_ATL_VER >= 0x0700)
lRet = rk.QueryDWORDValue(pT->GetRegCountName(), dwRet);
-#else
- lRet = rk.QueryValue(dwRet, pT->GetRegCountName());
-#endif
if(lRet != ERROR_SUCCESS)
return FALSE;
SetMaxEntries(dwRet);
@@ -3095,13 +3017,8 @@ public:
{
TCHAR szBuff[m_cchItemNameLen] = { 0 };
SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
-#if (_ATL_VER >= 0x0700)
ULONG ulCount = t_cchItemLen;
lRet = rk.QueryStringValue(szBuff, szRetString, &ulCount);
-#else
- DWORD dwCount = t_cchItemLen * sizeof(TCHAR);
- lRet = rk.QueryValue(szRetString, szBuff, &dwCount);
-#endif
if(lRet == ERROR_SUCCESS)
{
SecureHelper::strcpy_x(de.szDocName, _countof(de.szDocName), szRetString);
@@ -3119,8 +3036,8 @@ public:
{
T* pT = static_cast(this);
pT; // avoid level 4 warning
- ATL::CRegKey rkParent;
- ATL::CRegKey rk;
+ CRegKeyEx rkParent;
+ CRegKeyEx rk;
LONG lRet = rkParent.Create(HKEY_CURRENT_USER, lpstrRegKey);
if(lRet != ERROR_SUCCESS)
@@ -3129,11 +3046,7 @@ public:
if(lRet != ERROR_SUCCESS)
return FALSE;
-#if (_ATL_VER >= 0x0700)
lRet = rk.SetDWORDValue(pT->GetRegCountName(), m_nMaxEntries);
-#else
- lRet = rk.SetValue(m_nMaxEntries, pT->GetRegCountName());
-#endif
ATLASSERT(lRet == ERROR_SUCCESS);
// set new values
@@ -3144,11 +3057,7 @@ public:
SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
TCHAR szDocName[t_cchItemLen] = { 0 };
GetFromList(t_nFirstID + nItem - 1, szDocName, t_cchItemLen);
-#if (_ATL_VER >= 0x0700)
lRet = rk.SetStringValue(szBuff, szDocName);
-#else
- lRet = rk.SetValue(szDocName, szBuff);
-#endif
ATLASSERT(lRet == ERROR_SUCCESS);
}
@@ -3367,7 +3276,7 @@ public:
return FALSE;
// find the last dot
- LPTSTR pstrDot = (LPTSTR)_cstrrchr(szBuff, _T('.'));
+ LPTSTR pstrDot = MinCrtHelper::_strrchr(szBuff, _T('.'));
if(pstrDot != NULL)
*pstrDot = 0;
@@ -3616,8 +3525,8 @@ public:
else
{
// find the last forward or backward whack
- LPTSTR pstrBack = (LPTSTR)_cstrrchr(m_lpszRoot, _T('\\'));
- LPTSTR pstrFront = (LPTSTR)_cstrrchr(m_lpszRoot, _T('/'));
+ LPTSTR pstrBack = MinCrtHelper::_strrchr(m_lpszRoot, _T('\\'));
+ LPTSTR pstrFront = MinCrtHelper::_strrchr(m_lpszRoot, _T('/'));
if(pstrFront != NULL || pstrBack != NULL)
{
@@ -3665,193 +3574,9 @@ public:
m_hFind = NULL;
}
}
-
-// Helper
- static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch)
- {
-#ifdef _ATL_MIN_CRT
- const TCHAR* lpsz = NULL;
- while (*p != 0)
- {
- if (*p == ch)
- lpsz = p;
- p = ::CharNext(p);
- }
- return lpsz;
-#else // !_ATL_MIN_CRT
- return _tcsrchr(p, ch);
-#endif // !_ATL_MIN_CRT
- }
};
-///////////////////////////////////////////////////////////////////////////////
-// Global functions for loading resources
-
-inline HACCEL AtlLoadAccelerators(ATL::_U_STRINGorID table)
-{
- return ::LoadAccelerators(ModuleHelper::GetResourceInstance(), table.m_lpstr);
-}
-
-inline HMENU AtlLoadMenu(ATL::_U_STRINGorID menu)
-{
- return ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
-}
-
-inline HBITMAP AtlLoadBitmap(ATL::_U_STRINGorID bitmap)
-{
- return ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
-}
-
-#ifdef OEMRESOURCE
-inline HBITMAP AtlLoadSysBitmap(ATL::_U_STRINGorID bitmap)
-{
-#ifdef _DEBUG
- WORD wID = (WORD)bitmap.m_lpstr;
- ATLASSERT(wID >= 32734 && wID <= 32767);
-#endif // _DEBUG
- return ::LoadBitmap(NULL, bitmap.m_lpstr);
-}
-#endif // OEMRESOURCE
-
-inline HCURSOR AtlLoadCursor(ATL::_U_STRINGorID cursor)
-{
- return ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr);
-}
-
-inline HCURSOR AtlLoadSysCursor(LPCTSTR lpCursorName)
-{
-#if (WINVER >= 0x0500)
- ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT ||
- lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE ||
- lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW ||
- lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL ||
- lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP ||
- lpCursorName == IDC_HAND);
-#else // !(WINVER >= 0x0500)
- ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT ||
- lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE ||
- lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW ||
- lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL ||
- lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP);
-#endif // !(WINVER >= 0x0500)
- return ::LoadCursor(NULL, lpCursorName);
-}
-
-inline HICON AtlLoadIcon(ATL::_U_STRINGorID icon)
-{
- return ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
-}
-
-#ifndef _WIN32_WCE
-inline HICON AtlLoadSysIcon(LPCTSTR lpIconName)
-{
-#if (WINVER >= 0x0600)
- ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION ||
- lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO ||
- lpIconName == IDI_SHIELD);
-#else // !(WINVER >= 0x0600)
- ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION ||
- lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO);
-#endif // !(WINVER >= 0x0600)
- return ::LoadIcon(NULL, lpIconName);
-}
-#endif // !_WIN32_WCE
-
-inline HBITMAP AtlLoadBitmapImage(ATL::_U_STRINGorID bitmap, UINT fuLoad = LR_DEFAULTCOLOR)
-{
- return (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, IMAGE_BITMAP, 0, 0, fuLoad);
-}
-
-inline HCURSOR AtlLoadCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
-{
- return (HCURSOR)::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
-}
-
-inline HICON AtlLoadIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
-{
- return (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
-}
-
-#ifdef OEMRESOURCE
-inline HBITMAP AtlLoadSysBitmapImage(WORD wBitmapID, UINT fuLoad = LR_DEFAULTCOLOR)
-{
- ATLASSERT(wBitmapID >= 32734 && wBitmapID <= 32767);
- ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file
- return (HBITMAP)::LoadImage(NULL, MAKEINTRESOURCE(wBitmapID), IMAGE_BITMAP, 0, 0, fuLoad);
-}
-#endif // OEMRESOURCE
-
-inline HCURSOR AtlLoadSysCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
-{
-#ifdef _DEBUG
- WORD wID = (WORD)cursor.m_lpstr;
- ATLASSERT((wID >= 32512 && wID <= 32516) || (wID >= 32640 && wID <= 32648) || (wID == 32650) || (wID == 32651));
- ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file
-#endif // _DEBUG
- return (HCURSOR)::LoadImage(NULL, cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
-}
-
-inline HICON AtlLoadSysIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
-{
-#ifdef _DEBUG
- WORD wID = (WORD)icon.m_lpstr;
- ATLASSERT(wID >= 32512 && wID <= 32517);
- ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file
-#endif // _DEBUG
- return (HICON)::LoadImage(NULL, icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
-}
-
-#if (_ATL_VER < 0x0700)
-inline int AtlLoadString(UINT uID, LPTSTR lpBuffer, int nBufferMax)
-{
- return ::LoadString(_Module.GetResourceInstance(), uID, lpBuffer, nBufferMax);
-}
-#endif // (_ATL_VER < 0x0700)
-
-#ifdef _WIN32_WCE // CE only direct access to the resource
-inline LPCTSTR AtlLoadString(UINT uID)
-{
- LPCTSTR s = (LPCTSTR)::LoadString(ModuleHelper::GetResourceInstance(), uID, NULL, 0);
-#ifdef DEBUG // Check for null-termination
- if(s != NULL)
- // Note: RC -n compiles null-terminated resource strings
- ATLASSERT(s[*((WORD*)s -1) - 1] == L'\0');
-#endif
- return s;
-}
-#endif // _WIN32_WCE
-
-inline bool AtlLoadString(UINT uID, BSTR& bstrText)
-{
- USES_CONVERSION;
- ATLASSERT(bstrText == NULL);
-
- LPTSTR lpstrText = NULL;
- int nRes = 0;
- for(int nLen = 256; ; nLen *= 2)
- {
- ATLTRY(lpstrText = new TCHAR[nLen]);
- if(lpstrText == NULL)
- break;
- nRes = ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpstrText, nLen);
- if(nRes < nLen - 1)
- break;
- delete [] lpstrText;
- lpstrText = NULL;
- }
-
- if(lpstrText != NULL)
- {
- if(nRes != 0)
- bstrText = ::SysAllocString(T2OLE(lpstrText));
- delete [] lpstrText;
- }
-
- return (bstrText != NULL) ? true : false;
-}
-
-
///////////////////////////////////////////////////////////////////////////////
// Global functions for stock GDI objects
diff --git a/Source/3rd Party/WTL/atlprint.h b/Source/3rd Party/WTL/atlprint.h
index fed9a3fba..50a7fb17d 100644
--- a/Source/3rd Party/WTL/atlprint.h
+++ b/Source/3rd Party/WTL/atlprint.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -14,10 +14,6 @@
#pragma once
-#ifndef __cplusplus
- #error ATL requires C++ compilation (use a .cpp suffix)
-#endif
-
#ifdef _WIN32_WCE
#error atlprint.h is not supported on Windows CE
#endif
diff --git a/Source/3rd Party/WTL/atlres.h b/Source/3rd Party/WTL/atlres.h
index ae058876a..22fb3e6fd 100644
--- a/Source/3rd Party/WTL/atlres.h
+++ b/Source/3rd Party/WTL/atlres.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
@@ -217,6 +217,7 @@
#define ID_VIEW_TOOLBAR 0xE800
#define ID_VIEW_STATUS_BAR 0xE801
#define ID_VIEW_REFRESH 0xE803
+#define ID_VIEW_RIBBON 0xE804 // Ribbon
///////////////////////////////////////////////////////////////////////////////
// Standard control IDs
diff --git a/Source/3rd Party/WTL/atlresce.h b/Source/3rd Party/WTL/atlresce.h
index 64346b1e5..3b2b93388 100644
--- a/Source/3rd Party/WTL/atlresce.h
+++ b/Source/3rd Party/WTL/atlresce.h
@@ -1,9 +1,9 @@
-// Windows Template Library - WTL version 8.0
+// Windows Template Library - WTL version 8.1
// 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
-// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
diff --git a/Source/3rd Party/WTL/atlribbon.h b/Source/3rd Party/WTL/atlribbon.h
new file mode 100644
index 000000000..c1dfd0f83
--- /dev/null
+++ b/Source/3rd Party/WTL/atlribbon.h
@@ -0,0 +1,3446 @@
+// Windows Template Library - WTL version 8.1
+// 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
+// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
+// which can be found in the file CPL.TXT at the root of this distribution.
+// By using this software in any fashion, you are agreeing to be bound by
+// the terms of this license. You must not remove this notice, or
+// any other, from this software.
+
+#ifndef __ATLRIBBON_H__
+#define __ATLRIBBON_H__
+
+#pragma once
+
+#if (_MSC_VER < 1500)
+ #error atlribbon.h requires Visual C++ 2008 compiler or higher
+#endif
+
+#ifndef _UNICODE
+ #error atlribbon.h requires the Unicode character set
+#endif
+
+#if !defined(NTDDI_WIN7) || (NTDDI_VERSION < NTDDI_WIN7)
+ #error atlribbon.h requires the Windows 7 SDK or higher
+#endif
+
+#ifdef _WIN32_WCE
+ #error atlribbon.h is not supported on Windows CE
+#endif
+
+#ifndef __ATLAPP_H__
+ #error atlribbon.h requires atlapp.h to be included first
+#endif
+
+#if (_ATL_VER < 0x0700)
+ #include
+ #pragma comment(lib, "shlwapi.lib")
+#endif
+
+#include // for RecentDocumentList classes
+#include // for Frame and UpdateUI classes
+#include // required for atlctrlw.h
+#include // for CCommandBarCtrl
+
+#if !defined(_WTL_USE_CSTRING) && !defined(__ATLSTR_H__)
+ #pragma warning(disable : 4530) // unwind semantics not enabled
+ #include
+ #pragma warning(default : 4530)
+#endif
+
+#include
+#pragma comment(lib, "dwmapi.lib")
+
+#include
+#include
+#pragma comment(lib, "propsys.lib")
+
+#include // for CHARFORMAT2
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes in this file:
+//
+// CRibbonUpdateUI : Automatic mapping of ribbon UI elements
+//
+// RibbonUI::Text
+// RibbonUI::CharFormat
+// RibbonUI::ICtrl
+// RibbonUI::CtrlImpl
+// RibbonUI::CommandCtrlImpl
+// RibbonUI::ItemProperty
+// RibbonUI::CollectionImplBase
+// RibbonUI::CollectionImpl
+// RibbonUI::TextCollectionImpl
+// RibbonUI::ItemCollectionImpl
+// RibbonUI::ComboCollectionImpl
+// RibbonUI::CommandCollectionImpl
+// RibbonUI::ToolbarCollectionImpl
+// RibbonUI::SimpleCollectionImpl
+// RibbonUI::CollectionCtrlImpl
+// RibbonUI::ToolbarGalleryCtrlImpl
+// RibbonUI::SimpleCollectionCtrlImpl
+// RibbonUI::RecentItemsCtrlImpl
+// RibbonUI::FontCtrlImpl
+// RibbonUI::ColorCtrlImpl
+// RibbonUI::SpinnerCtrlImpl
+//
+// RibbonUI::CRibbonImpl
+// CRibbonImpl::CRibbonComboCtrl
+// CRibbonImpl::CRibbonItemGalleryCtrl
+// CRibbonImpl::CRibbonCommandGalleryCtrl
+// CRibbonImpl::CRibbonToolbarGalleryCtrl
+// CRibbonImpl::CRibbonSimpleComboCtrl
+// CRibbonImpl::CRibbonSimpleGalleryCtrl
+// CRibbonImpl::CRibbonRecentItemsCtrl
+// CRibbonImpl::CRibbonColorCtrl
+// CRibbonImpl::CRibbonFontCtrl
+// CRibbonImpl::CRibbonSpinnerCtrl
+// CRibbonImpl::CRibbonFloatSpinnerCtrl
+// CRibbonImpl::CRibbonCommandCtrl
+//
+// CRibbonFrameWindowImplBase
+// CRibbonFrameWindowImpl
+// CRibbonMDIFrameWindowImpl
+// CRibbonPersist
+//
+// Global functions:
+// RibbonUI::SetPropertyVal()
+// RibbonUI::GetImage()
+
+
+// Constants
+
+#ifndef RIBBONUI_MAX_TEXT
+ #define RIBBONUI_MAX_TEXT 128
+#endif
+
+#define TWIPS_PER_POINT 20 // For font size
+
+
+namespace WTL
+{
+
+///////////////////////////////////////////////////////////////////////////////
+// CRibbonUpdateUI : Automatic mapping of ribbon UI elements
+
+template
+class CRibbonUpdateUI : public CAutoUpdateUI
+{
+public:
+ enum
+ {
+ UPDUI_RIBBON = 0x0080,
+ UPDUI_PERSIST = 0x0020
+ };
+
+ bool IsRibbonElement(const _AtlUpdateUIMap& UIMap)
+ {
+ return (UIMap.m_wType & UPDUI_RIBBON) != 0;
+ }
+
+ bool IsRibbonID(UINT nID)
+ {
+ for(int i = 0; i < m_arrUIMap.GetSize(); i++)
+ {
+ if(m_arrUIMap[i].m_nID == nID)
+ return IsRibbonElement(m_arrUIMap[i]);
+ }
+
+ return false;
+ }
+
+// Element
+ bool UIAddRibbonElement(UINT nID)
+ {
+ return UIAddElement(nID);
+ }
+
+ bool UIRemoveRibbonElement(UINT nID)
+ {
+ return UIRemoveElement(nID);
+ }
+
+ bool UIPersistElement(UINT nID, bool bPersist = true)
+ {
+ return bPersist ?
+ UIAddElement(nID) :
+ UIRemoveElement(nID);
+ }
+
+// methods for Ribbon elements
+ BOOL UISetText(int nID, LPCWSTR sText, BOOL bForceUpdate = FALSE)
+ {
+ T* pT = static_cast(this);
+ BOOL bRes = CUpdateUIBase::UISetText(nID, sText, bForceUpdate);
+ if (pT->IsRibbonUI() && IsRibbonID(nID))
+ bRes = SUCCEEDED(pT->InvalidateProperty(nID, UI_PKEY_Label));
+ return bRes;
+ }
+
+ BOOL UISetText(int nID, UINT uIdResource, BOOL bForceUpdate = FALSE)
+ {
+ CTempBuffer sText(RIBBONUI_MAX_TEXT);
+ return AtlLoadString(uIdResource, sText, RIBBONUI_MAX_TEXT) ?
+ UISetText(nID, sText, bForceUpdate) :
+ E_FAIL;
+ }
+
+ LPCTSTR UIGetText(int nID)
+ {
+ T* pT = static_cast(this);
+ LPCTSTR sUI = CAutoUpdateUI::UIGetText(nID);
+
+ // replace 'tab' by 'space' for RibbonUI elements
+ if (sUI && pT->IsRibbonUI() && IsRibbonID(nID) && wcschr(sUI, L'\t'))
+ {
+ static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 };
+ wcscpy_s(sText, sUI);
+ *wcschr(sText, L'\t') = L' ';
+ return sText;
+ }
+ else
+ {
+ return sUI;
+ }
+ }
+
+ BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE)
+ {
+ T* pT = static_cast(this);
+ BOOL bRes = CUpdateUIBase::UIEnable(nID, bEnable, bForceUpdate);
+ if (pT->IsRibbonUI() && IsRibbonID(nID))
+ bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_Enabled, bEnable));
+ return bRes;
+ }
+
+ BOOL UISetCheck(int nID, INT nCheck, BOOL bForceUpdate = FALSE)
+ {
+ if ((nCheck == 0) || (nCheck == 1))
+ return UISetCheck(nID, nCheck != 0, bForceUpdate);
+ else
+ return CUpdateUIBase::UISetCheck(nID, nCheck, bForceUpdate);
+ }
+
+ BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE)
+ {
+ T* pT = static_cast(this);
+ BOOL bRes = CUpdateUIBase::UISetCheck(nID, bCheck, bForceUpdate);
+ if (bRes && pT->IsRibbonUI() && IsRibbonID(nID))
+ bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_BooleanValue, bCheck));
+ return bRes;
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// RibbonUI namespace
+//
+
+namespace RibbonUI
+{
+
+// Minimal string allocation support for various PROPERTYKEY values
+#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
+ typedef _CSTRING_NS::CString Text;
+#else
+ class Text : public std::wstring
+ {
+ public:
+ Text(std::wstring& s) : std::wstring(s)
+ { }
+ Text(LPCWSTR s) : std::wstring(s)
+ { }
+ Text()
+ { }
+ bool IsEmpty()
+ {
+ return empty();
+ }
+ operator LPCWSTR()
+ {
+ return c_str();
+ }
+ Text& operator =(LPCWSTR s)
+ {
+ return static_cast(std::wstring::operator =(s));
+ }
+ };
+#endif
+
+// PROPERTYKEY enum and helpers
+enum k_KEY
+{
+ // state
+ k_Enabled = 1, k_BooleanValue = 200,
+ // text properties
+ k_LabelDescription = 2, k_Keytip = 3, k_Label = 4, k_TooltipDescription = 5, k_TooltipTitle = 6,
+ // image properties
+ k_LargeImage = 7, k_LargeHighContrastImage = 8, k_SmallImage = 9, k_SmallHighContrastImage = 10,
+ // collection properties
+ k_ItemsSource = 101, k_Categories = 102, k_SelectedItem = 104,
+ // collection item properties
+ k_CommandId = 100, k_CategoryId = 103, k_CommandType = 105, k_ItemImage = 106,
+ // combo control property
+ k_StringValue = 202,
+ // spinner control properties
+ k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces, k_FormatString, k_RepresentativeString = 208,
+ // font control properties
+ k_FontProperties = 300, k_FontProperties_Family, k_FontProperties_Size, k_FontProperties_Bold, k_FontProperties_Italic = 304,
+ k_FontProperties_Underline = 305, k_FontProperties_Strikethrough, k_FontProperties_VerticalPositioning, k_FontProperties_ForegroundColor = 308,
+ k_FontProperties_BackgroundColor = 309, k_FontProperties_ForegroundColorType, k_FontProperties_BackgroundColorType, k_FontProperties_ChangedProperties = 312,
+ k_FontProperties_DeltaSize = 313,
+ // recent items properties
+ k_RecentItems = 350, k_Pinned = 351,
+ // color control properties
+ k_Color = 400, k_ColorType = 401, k_ColorMode,
+ k_ThemeColorsCategoryLabel = 403, k_StandardColorsCategoryLabel, k_RecentColorsCategoryLabel = 405, k_AutomaticColorLabel = 406,
+ k_NoColorLabel = 407, k_MoreColorsLabel = 408,
+ k_ThemeColors = 409, k_StandardColors = 410, k_ThemeColorsTooltips = 411, k_StandardColorsTooltips = 412,
+ // Ribbon state
+ k_Viewable = 1000, k_Minimized = 1001, k_QuickAccessToolbarDock = 1002, k_ContextAvailable = 1100,
+ // Ribbon UI colors
+ k_GlobalBackgroundColor = 2000, k_GlobalHighlightColor, k_GlobalTextColor = 2002
+};
+
+inline k_KEY k_(REFPROPERTYKEY key)
+{
+ return (k_KEY)key.fmtid.Data1;
+}
+
+// PROPERTYKEY value assignment and specializations
+//
+template
+HRESULT SetPropertyVal(REFPROPERTYKEY key, V val, PROPVARIANT* ppv)
+{
+ switch (k_(key))
+ {
+ case k_Enabled:
+ case k_BooleanValue:
+ return InitPropVariantFromBoolean(val, ppv);
+ default:
+ return UIInitPropertyFromUInt32(key, val, ppv);
+ }
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DOUBLE val, PROPVARIANT* ppv)
+{
+ return SetPropertyVal(key, (LONG)val, ppv);
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUIImage* val, PROPVARIANT* ppv)
+{
+ HRESULT hr = UIInitPropertyFromImage(key, val, ppv);
+ ATLVERIFY(val->Release() == 1);
+ return hr;
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUnknown* val, PROPVARIANT* ppv)
+{
+ return UIInitPropertyFromInterface(key, val, ppv);
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IPropertyStore* val, PROPVARIANT* ppv)
+{
+ return UIInitPropertyFromInterface(key, val, ppv);
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, SAFEARRAY* val, PROPVARIANT* ppv)
+{
+ return UIInitPropertyFromIUnknownArray(key, val, ppv);
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DECIMAL* val, PROPVARIANT* ppv)
+{
+ return UIInitPropertyFromDecimal(key, *val, ppv);
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, bool val, PROPVARIANT* ppv)
+{
+ return UIInitPropertyFromBoolean(key, val, ppv);
+}
+
+inline HRESULT SetPropertyVal(REFPROPERTYKEY key, LPCWSTR val, PROPVARIANT* ppv)
+{
+ return UIInitPropertyFromString(key, val, ppv);
+}
+
+// CharFormat helper struct for RibbonUI font control
+//
+struct CharFormat : CHARFORMAT2
+{
+ // Default constructor
+ CharFormat()
+ {
+ cbSize = sizeof CHARFORMAT2;
+ Reset();
+ }
+
+ // Copy constructor
+ CharFormat(const CharFormat& cf)
+ {
+ CopyMemory(this, &cf, sizeof CHARFORMAT2);
+ }
+
+ // Assign operator
+ CharFormat& operator =(const CharFormat& cf)
+ {
+ CopyMemory(this, &cf, sizeof CHARFORMAT2);
+ return (*this);
+ }
+
+ void Reset()
+ {
+ uValue = dwMask = dwEffects = 0;
+ PropVariantInit(&propvar);
+ }
+
+ void operator <<(IPropertyStore* pStore)
+ {
+ if (pStore == NULL)
+ {
+ ATLASSERT(FALSE);
+ return;
+ }
+
+ static void (CharFormat::*Getk_[])(IPropertyStore*) =
+ {
+ &CharFormat::Getk_Family,
+ &CharFormat::Getk_FontProperties_Size,
+ &CharFormat::Getk_MaskEffect,
+ &CharFormat::Getk_MaskEffect,
+ &CharFormat::Getk_MaskEffect,
+ &CharFormat::Getk_MaskEffect,
+ &CharFormat::Getk_VerticalPositioning,
+ &CharFormat::Getk_Color,
+ &CharFormat::Getk_Color,
+ &CharFormat::Getk_ColorType,
+ &CharFormat::Getk_ColorType,
+ };
+
+ DWORD nProps = 0;
+ Reset();
+
+ ATLVERIFY(SUCCEEDED(pStore->GetCount(&nProps)));
+ for (DWORD iProp = 0; iProp < nProps; iProp++)
+ {
+ PROPERTYKEY key;
+ ATLVERIFY(SUCCEEDED(pStore->GetAt(iProp, &key)));
+ ATLASSERT(k_(key) >= k_FontProperties_Family);
+
+ if (k_(key) <= k_FontProperties_BackgroundColorType)
+ (this->*Getk_[k_(key) - k_FontProperties_Family])(pStore);
+ }
+ }
+
+ void operator >>(IPropertyStore* pStore)
+ {
+ if (pStore == NULL)
+ {
+ ATLASSERT(FALSE);
+ return;
+ }
+
+ PutFace(pStore);
+ PutSize(pStore);
+ PutMaskEffect(CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold, pStore);
+ PutMaskEffect(CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic, pStore);
+ PutMaskEffect(CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline, pStore);
+ PutMaskEffect(CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough, pStore);
+ PutVerticalPos(pStore);
+ PutColor(pStore);
+ PutBackColor(pStore);
+ }
+
+private:
+ PROPVARIANT propvar;
+ UINT uValue;
+
+ // Getk_ functions
+ void Getk_Family(IPropertyStore* pStore)
+ {
+ if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Family, &propvar)))
+ {
+ PropVariantToString(propvar, szFaceName, LF_FACESIZE);
+ if (*szFaceName)
+ dwMask |= CFM_FACE;
+ }
+ }
+
+ void Getk_FontProperties_Size(IPropertyStore* pStore)
+ {
+ if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Size, &propvar)))
+ {
+ DECIMAL decSize;
+ UIPropertyToDecimal(UI_PKEY_FontProperties_Size, propvar, &decSize);
+ DOUBLE dSize;
+ VarR8FromDec(&decSize, &dSize);
+ if (dSize > 0)
+ {
+ dwMask |= CFM_SIZE;
+ yHeight = (LONG)(dSize * TWIPS_PER_POINT);
+ }
+ }
+ }
+
+ template
+ void Getk_MaskEffect(IPropertyStore* pStore)
+ {
+ if (SUCCEEDED(pStore->GetValue(key, &propvar)))
+ {
+ UIPropertyToUInt32(key, propvar, &uValue);
+ if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE)
+ {
+ dwMask |= t_dwMask;
+ dwEffects |= ((UI_FONTPROPERTIES) uValue == UI_FONTPROPERTIES_SET) ? t_dwEffects : 0;
+ }
+ }
+ }
+
+ void Getk_VerticalPositioning(IPropertyStore* pStore)
+ {
+ if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_VerticalPositioning, &propvar)))
+ {
+ UIPropertyToUInt32(UI_PKEY_FontProperties_VerticalPositioning, propvar, &uValue);
+ UI_FONTVERTICALPOSITION uVerticalPosition = (UI_FONTVERTICALPOSITION) uValue;
+ if ((uVerticalPosition != UI_FONTVERTICALPOSITION_NOTAVAILABLE))
+ {
+ dwMask |= (CFM_SUPERSCRIPT | CFM_SUBSCRIPT);
+ if (uVerticalPosition != UI_FONTVERTICALPOSITION_NOTSET)
+ {
+ dwEffects |= (uVerticalPosition == UI_FONTVERTICALPOSITION_SUPERSCRIPT) ? CFE_SUPERSCRIPT : CFE_SUBSCRIPT;
+ }
+ }
+ }
+ }
+
+ template
+ void Getk_Color(IPropertyStore* pStore)
+ {
+ UINT32 color;
+ if (SUCCEEDED(pStore->GetValue(key, &propvar)))
+ {
+ UIPropertyToUInt32(key, propvar, &color);
+ dwMask |= t_dwMask;
+
+ if (t_dwMask == CFM_COLOR)
+ crTextColor = color;
+ else
+ crBackColor = color;
+ }
+ }
+
+ template
+ void Getk_ColorType(IPropertyStore* pStore)
+ {
+ if (SUCCEEDED(pStore->GetValue(key, &propvar)))
+ {
+ UIPropertyToUInt32(key, propvar, &uValue);
+ if (t_type == (UI_SWATCHCOLORTYPE)uValue)
+ {
+ dwMask |= t_dwMask;
+ dwEffects |= t_dwEffects;
+ }
+ }
+ }
+
+ // Put functions
+ void PutMaskEffect(WORD dwMaskVal, WORD dwEffectVal, REFPROPERTYKEY key, IPropertyStore* pStore)
+ {
+ PROPVARIANT propvar;
+ UI_FONTPROPERTIES uProp = UI_FONTPROPERTIES_NOTAVAILABLE;
+ if ((dwMask & dwMaskVal) != 0)
+ uProp = dwEffects & dwEffectVal ? UI_FONTPROPERTIES_SET : UI_FONTPROPERTIES_NOTSET;
+ SetPropertyVal(key, uProp, &propvar);
+ pStore->SetValue(key, propvar);
+ }
+
+ void PutVerticalPos(IPropertyStore* pStore)
+ {
+ PROPVARIANT propvar;
+ UI_FONTVERTICALPOSITION uProp = UI_FONTVERTICALPOSITION_NOTAVAILABLE;
+
+ if ((dwMask & CFE_SUBSCRIPT) != 0)
+ {
+ if ((dwMask & CFM_SUBSCRIPT) && (dwEffects & CFE_SUBSCRIPT))
+ uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT;
+ else
+ uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT;
+ }
+ else if ((dwMask & CFM_OFFSET) != 0)
+ {
+ if (yOffset > 0)
+ uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT;
+ else if (yOffset < 0)
+ uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT;
+ }
+
+ SetPropertyVal(UI_PKEY_FontProperties_VerticalPositioning, uProp, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_VerticalPositioning, propvar);
+ }
+
+ void PutFace(IPropertyStore* pStore)
+ {
+ PROPVARIANT propvar;
+ SetPropertyVal(UI_PKEY_FontProperties_Family,
+ dwMask & CFM_FACE ? szFaceName : L"", &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_Family, propvar);
+ }
+
+ void PutSize(IPropertyStore* pStore)
+ {
+ PROPVARIANT propvar;
+ DECIMAL decVal;
+
+ if ((dwMask & CFM_SIZE) != 0)
+ VarDecFromR8((DOUBLE)yHeight / TWIPS_PER_POINT, &decVal);
+ else
+ VarDecFromI4(0, &decVal);
+
+ SetPropertyVal(UI_PKEY_FontProperties_Size, &decVal, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_Size, propvar);
+ }
+
+ void PutColor(IPropertyStore* pStore)
+ {
+ if ((dwMask & CFM_COLOR) != 0)
+ if ((dwEffects & CFE_AUTOCOLOR) == 0)
+ {
+ SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar);
+
+ SetPropertyVal(UI_PKEY_FontProperties_ForegroundColor, crTextColor, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_ForegroundColor, propvar);
+ }
+ else
+ {
+ SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_AUTOMATIC, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar);
+ }
+ }
+
+ void PutBackColor(IPropertyStore* pStore)
+ {
+ if (((dwMask & CFM_BACKCOLOR) != 0) && ((dwEffects & CFE_AUTOBACKCOLOR) == 0))
+ {
+ SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar);
+
+ SetPropertyVal(UI_PKEY_FontProperties_BackgroundColor, crBackColor, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_BackgroundColor, propvar);
+ }
+ else
+ {
+ SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_NOCOLOR, &propvar);
+ pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar);
+ }
+ }
+};
+
+// IUIImage helper
+//
+inline IUIImage* GetImage(HBITMAP hbm, UI_OWNERSHIP owner)
+{
+ ATLASSERT(hbm);
+ IUIImage* pIUII = NULL;
+ ATL::CComPtr pIFB;
+
+ if SUCCEEDED(pIFB.CoCreateInstance(CLSID_UIRibbonImageFromBitmapFactory))
+ ATLVERIFY(SUCCEEDED(pIFB->CreateImage(hbm, owner, &pIUII)));
+
+ return pIUII;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Ribbon control classes
+
+// RibbonUI::ICtrl abstract interface of RibbonUI::CRibbonImpl and all RibbonUI control classes
+//
+struct ICtrl
+{
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* pCommandExecutionProperties) = 0;
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) = 0;
+};
+
+// RibbonUI::CtrlImpl base class for all ribbon controls
+//
+template
+class ATL_NO_VTABLE CtrlImpl : public ICtrl
+{
+protected:
+ T* m_pWndRibbon;
+
+public:
+ typedef T WndRibbon;
+
+ CtrlImpl() : m_pWndRibbon(T::pWndRibbon)
+ { }
+
+ WndRibbon& GetWndRibbon()
+ {
+ return *m_pWndRibbon;
+ }
+
+ static WORD GetID()
+ {
+ return t_ID;
+ }
+
+ Text m_sTxt[5];
+
+ // Operations
+ HRESULT Invalidate()
+ {
+ return GetWndRibbon().InvalidateCtrl(GetID());
+ }
+
+ HRESULT Invalidate(REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY)
+ {
+ return GetWndRibbon().InvalidateProperty(GetID(), key, flags);
+ }
+
+ HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sTxt, bool bUpdate = false)
+ {
+ ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription));
+
+ m_sTxt[k_(key) - k_LabelDescription] = sTxt;
+
+ return bUpdate ?
+ GetWndRibbon().InvalidateProperty(GetID(), key) :
+ S_OK;
+ }
+
+ // Implementation
+ template
+ HRESULT SetProperty(REFPROPERTYKEY key, V val)
+ {
+ return GetWndRibbon().SetProperty(GetID(), key, val);
+ }
+
+ HRESULT OnGetText(REFPROPERTYKEY key, PROPVARIANT* ppv)
+ {
+ ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription));
+
+ const INT iText = k_(key) - k_LabelDescription;
+ if (m_sTxt[iText].IsEmpty())
+ if (LPCWSTR sText = GetWndRibbon().OnRibbonQueryText(GetID(), key))
+ m_sTxt[iText] = sText;
+
+ return !m_sTxt[iText].IsEmpty() ?
+ SetPropertyVal(key, (LPCWSTR)m_sTxt[iText], ppv) :
+ S_OK;
+ }
+
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* pCommandExecutionProperties)
+ {
+ ATLASSERT(nCmdID == t_ID);
+ return GetWndRibbon().DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties);
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT(nCmdID == t_ID);
+
+ const INT iMax = k_TooltipTitle - k_LabelDescription;
+ const INT iVal = k_(key) - k_LabelDescription;
+
+ return (iVal <= iMax) && (iVal >= 0) ?
+ OnGetText(key, ppropvarNewValue) :
+ GetWndRibbon().DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ }
+};
+
+// CommandCtrlImpl base class for most ribbon controls
+//
+template
+class CommandCtrlImpl : public CtrlImpl
+{
+public:
+ CBitmap m_hbm[4];
+
+ HRESULT SetImage(REFPROPERTYKEY key, HBITMAP hbm, bool bUpdate = false)
+ {
+ ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage));
+
+ m_hbm[k_(key) - k_LargeImage].Attach(hbm);
+
+ return bUpdate ?
+ GetWndRibbon().InvalidateProperty(GetID(), key) :
+ S_OK;
+ }
+
+ HRESULT OnGetImage(REFPROPERTYKEY key, PROPVARIANT* ppv)
+ {
+ ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage));
+
+ const INT iImage = k_(key) - k_LargeImage;
+
+ if (m_hbm[iImage].IsNull())
+ m_hbm[iImage] = GetWndRibbon().OnRibbonQueryImage(GetID(), key);
+
+ return m_hbm[iImage].IsNull() ?
+ E_NOTIMPL :
+ SetPropertyVal(key, GetImage(m_hbm[iImage], UI_OWNERSHIP_COPY), ppv);
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT (nCmdID == GetID());
+
+ return (k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage) ?
+ OnGetImage(key, ppropvarNewValue) :
+ CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Ribbon collection base classes
+
+// ItemProperty class: ribbon callback for each item in a collection
+//
+template
+class ItemProperty : public IUISimplePropertySet
+{
+public:
+ ItemProperty(UINT i, TCollection* pCollection) : m_Index(i), m_pCollection(pCollection)
+ { }
+
+ const UINT m_Index;
+ TCollection* m_pCollection;
+
+ // IUISimplePropertySet method.
+ STDMETHODIMP GetValue(REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ return m_pCollection->OnGetItem(m_Index, key, value);
+ }
+
+ // IUnknown methods.
+ STDMETHODIMP_(ULONG) AddRef()
+ {
+ return 1;
+ }
+
+ STDMETHODIMP_(ULONG) Release()
+ {
+ return 1;
+ }
+
+ STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
+ {
+ if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(IUISimplePropertySet)))
+ {
+ *ppv = this;
+ return S_OK;
+ }
+ else
+ {
+ return E_NOINTERFACE;
+ }
+ }
+};
+
+
+// CollectionImplBase: base class for all RibbonUI collections
+//
+template
+class CollectionImplBase
+{
+ typedef CollectionImplBase thisClass;
+
+public:
+ CollectionImplBase()
+ {
+ for (int i = 0; i < t_size; i++)
+ m_apItems[i] = new ItemProperty(i, static_cast(this));
+ }
+
+ ~CollectionImplBase()
+ {
+ for (int i = 0; i < t_size; i++)
+ delete m_apItems[i];
+ }
+
+// Data members
+ ItemProperty* m_apItems[t_size];
+};
+
+// CollectionImpl: handles categories and collecton resizing
+//
+template
+class CollectionImpl : public CollectionImplBase, t_items + t_categories>
+{
+ typedef CollectionImpl thisClass;
+public:
+ typedef thisClass Collection;
+
+ CollectionImpl() : m_size(t_items)
+ {
+ FillMemory(m_auItemCat, sizeof m_auItemCat, 0xff); // UI_COLLECTION_INVALIDINDEX
+ }
+
+ UINT32 m_auItemCat[t_items];
+ Text m_asCatName[max(t_categories, 1)];
+ size_t m_size;
+
+// Operations
+ HRESULT SetItemCategory(UINT uItem, UINT uCat, bool bUpdate = false)
+ {
+ ATLASSERT((uItem < t_items) && (uCat < t_categories));
+
+ m_auItemCat[uItem] = uCat;
+
+ return bUpdate ? InvalidateItems() : S_OK;
+ }
+
+ HRESULT SetCategoryText(UINT uCat, LPCWSTR sText, bool bUpdate = false)
+ {
+ ATLASSERT(uCat < t_categories);
+
+ m_asCatName[uCat] = sText;
+
+ return bUpdate ? InvalidateCategories() : S_OK;
+ }
+
+ HRESULT Resize(size_t size, bool bUpdate = false)
+ {
+ ATLASSERT(size <= t_items);
+
+ m_size = size;
+
+ return bUpdate ? InvalidateItems() : S_OK;
+ }
+
+// Implementation
+ HRESULT OnGetItem(UINT uIndex, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(uIndex < t_items + t_categories);
+ TCtrl* pCtrl = static_cast(this);
+
+ return uIndex < t_items ?
+ pCtrl->DoGetItem(uIndex, key, value) :
+ pCtrl->DoGetCategory(uIndex - t_items, key, value);
+ }
+
+ HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(k_(key) == k_CategoryId);
+ UINT32 uCat = UI_COLLECTION_INVALIDINDEX;
+
+ if (t_categories != 0)
+ {
+ if (m_auItemCat[uItem] == UI_COLLECTION_INVALIDINDEX)
+ {
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ m_auItemCat[uItem] = ribbon.OnRibbonQueryItemCategory(TCtrl::GetID(), uItem);
+ }
+ uCat = m_auItemCat[uItem];
+ }
+
+ return SetPropertyVal(key, uCat, value);
+ }
+
+ HRESULT DoGetCategory(UINT uCat, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ HRESULT hr = S_OK;
+
+ switch (k_(key))
+ {
+ case k_Label:
+ if (m_asCatName[uCat].IsEmpty())
+ {
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ m_asCatName[uCat] = ribbon.OnRibbonQueryCategoryText(TCtrl::GetID(), uCat);
+ }
+ hr = SetPropertyVal(key, (LPCWSTR)m_asCatName[uCat], value);
+ break;
+ case k_CategoryId:
+ hr = SetPropertyVal(key, uCat, value);
+ break;
+ default:
+ ATLASSERT(FALSE);
+ break;
+ }
+
+ return hr;
+ }
+
+ HRESULT InvalidateItems()
+ {
+ return static_cast(this)->Invalidate(UI_PKEY_ItemsSource);
+ }
+
+ HRESULT InvalidateCategories()
+ {
+ return static_cast(this)->Invalidate(UI_PKEY_Categories);
+ }
+
+ HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* /*ppropvarNewValue*/)
+ {
+ ATLASSERT(nCmdID == TCtrl::GetID());
+ nCmdID; // avoid level 4 warning
+
+ HRESULT hr = E_NOTIMPL;
+ switch (k_(key))
+ {
+ case k_ItemsSource:
+ {
+ ATL::CComQIPtr pIUICollection(ppropvarCurrentValue->punkVal);
+ ATLASSERT(pIUICollection);
+ hr = pIUICollection->Clear();
+ for (UINT i = 0; i < m_size; i++)
+ {
+ if FAILED(hr = pIUICollection->Add(m_apItems[i]))
+ break;
+ }
+ ATLASSERT(SUCCEEDED(hr));
+ }
+ break;
+ case k_Categories:
+ if (t_categories != 0)
+ {
+ ATL::CComQIPtr pIUICategory(ppropvarCurrentValue->punkVal);
+ ATLASSERT(pIUICategory.p);
+ hr = pIUICategory->Clear();
+ for (UINT i = t_items; i < t_items + t_categories; i++)
+ {
+ if FAILED(hr = pIUICategory->Add(m_apItems[i]))
+ break;
+ }
+ ATLASSERT(SUCCEEDED(hr));
+ }
+ break;
+ }
+
+ return hr;
+ }
+};
+
+// TextCollectionImpl: handles item labels and selection
+//
+template
+class TextCollectionImpl : public CollectionImpl
+{
+ typedef TextCollectionImpl thisClass;
+public:
+ typedef thisClass TextCollection;
+
+ TextCollectionImpl() : m_uSelected(UI_COLLECTION_INVALIDINDEX)
+ { }
+
+ Text m_asText[t_items];
+ UINT m_uSelected;
+
+ // Operations
+ HRESULT SetItemText(UINT uItem, LPCWSTR sText, bool bUpdate = false)
+ {
+ ATLASSERT(uItem < t_items);
+
+ m_asText[uItem] = sText;
+
+ return bUpdate ? InvalidateItems() : S_OK;
+ }
+
+ UINT GetSelected()
+ {
+ return m_uSelected;
+ }
+
+ HRESULT Select(UINT uItem, bool bUpdate = false)
+ {
+ ATLASSERT((uItem < t_items) || (uItem == UI_COLLECTION_INVALIDINDEX));
+
+ m_uSelected = uItem;
+
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ return bUpdate ?
+ ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_SelectedItem, uItem) :
+ S_OK;
+ }
+
+// Implementation
+ HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(uItem < t_items);
+
+ if (k_(key) == k_Label)
+ {
+ if (m_asText[uItem].IsEmpty())
+ {
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ m_asText[uItem] = ribbon.OnRibbonQueryItemText(TCtrl::GetID(), uItem);
+ }
+ return SetPropertyVal(key, (LPCWSTR)m_asText[uItem], value);
+ }
+ else
+ {
+ return Collection::DoGetItem(uItem, key, value);
+ }
+ }
+
+ HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT(nCmdID == TCtrl::GetID());
+
+ if (k_(key) == k_SelectedItem)
+ {
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ UINT uSel = UI_COLLECTION_INVALIDINDEX;
+ if ((m_uSelected == UI_COLLECTION_INVALIDINDEX) &&
+ ribbon.OnRibbonQuerySelectedItem(TCtrl::GetID(), uSel))
+ m_uSelected = uSel;
+
+ return SetPropertyVal(key, m_uSelected, ppropvarNewValue);
+ }
+ else
+ {
+ return Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ }
+ }
+};
+
+// ItemCollectionImpl: handles item image
+//
+template
+class ItemCollectionImpl : public TextCollectionImpl
+{
+ typedef ItemCollectionImpl thisClass;
+public:
+ typedef thisClass ItemCollection;
+
+ ItemCollectionImpl()
+ {
+ ZeroMemory(m_aBitmap, sizeof m_aBitmap);
+ }
+
+ CBitmap m_aBitmap[t_items];
+
+ // Operations
+ HRESULT SetItemImage(UINT uIndex, HBITMAP hbm, bool bUpdate = false)
+ {
+ ATLASSERT(uIndex < t_items);
+
+ m_aBitmap[uIndex] = hbm;
+
+ return bUpdate ? InvalidateItems() : S_OK;
+ }
+
+// Implementation
+ HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(uItem < t_items);
+
+ if (k_(key) == k_ItemImage)
+ {
+ if (m_aBitmap[uItem].IsNull())
+ {
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ m_aBitmap[uItem] = ribbon.OnRibbonQueryItemImage(TCtrl::GetID(), uItem);
+ }
+ return m_aBitmap[uItem].IsNull() ?
+ E_NOTIMPL :
+ SetPropertyVal(key, GetImage(m_aBitmap[uItem], UI_OWNERSHIP_COPY), value);
+ }
+ else
+ {
+ return TextCollection::DoGetItem(uItem, key, value);
+ }
+ }
+};
+
+// ComboCollectionImpl: handles combo text
+//
+template
+class ComboCollectionImpl : public ItemCollectionImpl
+{
+ typedef ComboCollectionImpl thisClass;
+public:
+ typedef thisClass ComboCollection;
+
+ // Operations
+ HRESULT SetComboText(LPCWSTR sText)
+ {
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ return ribbon.IsRibbonUI() ?
+ ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_StringValue, sText) :
+ S_OK;
+ }
+
+ LPCWSTR GetComboText()
+ {
+ static WCHAR sCombo[RIBBONUI_MAX_TEXT] = { 0 };
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+ PROPVARIANT var;
+ if (ribbon.IsRibbonUI())
+ {
+ HRESULT hr = ribbon.GetIUIFrameworkPtr()->GetUICommandProperty(TCtrl::GetID(), UI_PKEY_StringValue, &var);
+ hr = PropVariantToString(var, sCombo, RIBBONUI_MAX_TEXT);
+ return sCombo;
+ }
+ return NULL;
+ }
+};
+
+// CommandCollectionImpl: handles RibbonUI command collection controls
+//
+template
+class CommandCollectionImpl : public CollectionImpl
+{
+ typedef CommandCollectionImpl thisClass;
+public:
+ typedef thisClass CommandCollection;
+
+ CommandCollectionImpl()
+ {
+ ZeroMemory(m_auCmd, sizeof m_auCmd);
+ ZeroMemory(m_aCmdType, sizeof m_aCmdType);
+ }
+
+ UINT32 m_auCmd[t_items];
+ BYTE m_aCmdType[t_items];
+
+ // Operations
+ HRESULT SetItemCommand(UINT uItem, UINT32 uCommandID, bool bUpdate = false)
+ {
+ ATLASSERT(uItem < t_items);
+
+ if (uCommandID == m_auCmd[uItem])
+ return S_OK;
+
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+
+ m_auCmd[uItem] = uCommandID;
+ if (uCommandID != 0)
+ ribbon.UIAddRibbonElement(uCommandID);
+
+ return bUpdate ? InvalidateItems() : S_OK;
+ }
+
+ HRESULT SetItemCommandType(UINT uItem, UI_COMMANDTYPE type, bool bUpdate = false)
+ {
+ ATLASSERT(uItem < t_items);
+
+ m_aCmdType[uItem] = (BYTE)type;
+
+ return bUpdate ? InvalidateItems() : S_OK;
+ }
+
+// Implementation
+ HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(uItem < t_items);
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+
+ HRESULT hr = E_FAIL;
+ switch (k_(key))
+ {
+ case k_CommandId:
+ if (m_auCmd[uItem] == 0)
+ SetItemCommand(uItem, ribbon.OnRibbonQueryItemCommand(TCtrl::GetID(), uItem));
+ hr = SetPropertyVal(key, m_auCmd[uItem], value);
+ break;
+ case k_CommandType:
+ if (m_aCmdType[uItem] == UI_COMMANDTYPE_UNKNOWN)
+ SetItemCommandType(uItem, ribbon.OnRibbonQueryItemCommandType(TCtrl::GetID(), uItem));
+ hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value);
+ break;
+ case k_CategoryId:
+ default:
+ hr = Collection::DoGetItem(uItem, key, value);
+ break;
+ }
+
+ return hr;
+ }
+
+ HRESULT Select(UINT /*uItem*/, bool /*bUpdate*/ = false)
+ {
+ ATLASSERT(FALSE);
+ return S_OK;
+ }
+};
+
+// SimpleCollectionImpl: collection class for ribbon simple collection controls
+//
+template
+class SimpleCollectionImpl : public CollectionImplBase, t_size>
+{
+ typedef SimpleCollectionImpl thisClass;
+public:
+ typedef CollectionImplBase CollectionBase;
+ typedef thisClass SimpleCollection;
+
+// Implementation
+ HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(uItem < t_size);
+ TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon();
+
+ HRESULT hr = E_NOTIMPL;
+ switch (k_(key))
+ {
+ case k_ItemImage:
+ if (HBITMAP hbm = ribbon.DefRibbonQueryItemImage(TCtrl::GetID(), uItem))
+ hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), value);
+ break;
+ case k_Label:
+ if (LPCWSTR sText = ribbon.DefRibbonQueryItemText(TCtrl::GetID(), uItem))
+ hr = SetPropertyVal(key, (LPCWSTR)sText, value);
+ break;
+ case k_CommandType:
+ hr = SetPropertyVal(key, t_CommandType, value);
+ break;
+ case k_CommandId:
+ hr = SetPropertyVal(key, ribbon.DefRibbonQueryItemCommand(TCtrl::GetID(), uItem), value);
+ break;
+ case k_CategoryId:
+ hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value);
+ break;
+ default:
+ ATLASSERT(FALSE);
+ break;
+ }
+
+ return hr;
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Ribbon collection control classes
+
+// CollectionCtrlImpl: specializable class for ribbon collection controls
+//
+template
+class CollectionCtrlImpl : public CommandCtrlImpl, public TCollection
+{
+ typedef CollectionCtrlImpl thisClass;
+public:
+ typedef CommandCtrlImpl CommandCtrl;
+ typedef TCollection Collection;
+
+ // Implementation
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT(nCmdID == GetID());
+ ATLASSERT(ppropvarNewValue);
+
+ HRESULT hr = Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ if FAILED(hr)
+ hr = CommandCtrl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+
+ return hr;
+ }
+
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* /*pCommandExecutionProperties*/)
+ {
+ ATLASSERT (nCmdID == GetID());
+ nCmdID; // avoid level4 warning
+
+ if (key == NULL) // gallery button pressed
+ {
+ GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX);
+ return S_OK;
+ }
+
+ ATLASSERT(k_(*key) == k_SelectedItem);
+ ATLASSERT(ppropvarValue);
+
+ HRESULT hr = S_OK;
+ UINT32 uSel = 0xffff;
+ hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel);
+
+ if (SUCCEEDED(hr))
+ {
+ if (GetWndRibbon().OnRibbonItemSelected(GetID(), verb, uSel))
+ TCollection::Select(uSel);
+ }
+
+ return hr;
+ }
+};
+
+// ToolbarGalleryCtrlImpl: base class for ribbon toolbar gallery controls
+//
+template
+class ToolbarGalleryCtrlImpl : public CollectionCtrlImpl, t_size>>
+{
+public:
+ ToolbarGalleryCtrlImpl()
+ {
+ CResource tbres;
+ ATLVERIFY(tbres.Load(RT_TOOLBAR, t_idTB));
+ _AtlToolBarData* pData = (_AtlToolBarData*)tbres.Lock();
+ ATLASSERT(pData);
+ ATLASSERT(pData->wVersion == 1);
+
+ WORD* pItems = pData->items();
+ INT j = 0;
+ for (int i = 0; (i < pData->wItemCount) && (j < t_size); i++)
+ {
+ if (pItems[i] != 0)
+ {
+ m_aCmdType[j] = UI_COMMANDTYPE_ACTION;
+ m_auCmd[j++] = pItems[i];
+ }
+ }
+
+ if (j < t_size)
+ Resize(j);
+ }
+
+ HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT(uItem < m_size);
+ ATLASSERT(m_auCmd[uItem]);
+
+ HRESULT hr = E_FAIL;
+ switch (k_(key))
+ {
+ case k_CommandId:
+ hr = SetPropertyVal(key, m_auCmd[uItem], value);
+ break;
+ case k_CommandType:
+ hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value);
+ break;
+ case k_CategoryId:
+ hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value);
+ break;
+ default:
+ ATLASSERT(FALSE);
+ break;
+ }
+
+ return hr;
+ }
+};
+
+
+// SimpleCollectionCtrlImpl: base class for simple gallery and listbox controls
+//
+template
+class SimpleCollectionCtrlImpl :
+ public CommandCtrlImpl,
+ public SimpleCollectionImpl, t_size, t_CommandType>
+{
+ typedef SimpleCollectionCtrlImpl thisClass;
+public:
+ typedef thisClass SimpleCollection;
+
+ SimpleCollectionCtrlImpl() : m_uSelected(0)
+ { }
+
+ UINT m_uSelected;
+
+ HRESULT Select(UINT uItem, bool bUpdate = false)
+ {
+ ATLASSERT((uItem < t_size) || (uItem == UI_COLLECTION_INVALIDINDEX));
+
+ m_uSelected = uItem;
+
+ return bUpdate ?
+ GetWndRibbon().SetProperty(GetID(), UI_PKEY_SelectedItem, uItem) :
+ S_OK;
+ }
+
+ // Implementation
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT(nCmdID == GetID());
+ ATLASSERT(ppropvarNewValue != NULL);
+
+ HRESULT hr = S_OK;
+ switch (k_(key))
+ {
+ case k_ItemsSource:
+ {
+ ATL::CComQIPtr pIUICollection(ppropvarCurrentValue->punkVal);
+ ATLASSERT(pIUICollection.p);
+ hr = pIUICollection->Clear();
+ for (UINT i = 0; i < t_size; i++)
+ {
+ if FAILED(hr = pIUICollection->Add(m_apItems[i]))
+ break;
+ }
+ ATLASSERT(SUCCEEDED(hr));
+ }
+ break;
+ case k_SelectedItem:
+ hr = SetPropertyVal(UI_PKEY_SelectedItem, m_uSelected, ppropvarNewValue);
+ break;
+ default:
+ hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ break;
+ }
+
+ return hr;
+ }
+
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* /*pCommandExecutionProperties*/)
+ {
+ ATLASSERT (nCmdID == GetID());
+ nCmdID; // avoid level 4 warning
+
+ HRESULT hr = S_OK;
+ if (key == NULL) // gallery button pressed
+ {
+ GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX);
+ return hr;
+ }
+ ATLASSERT(k_(*key) == k_SelectedItem);
+ ATLASSERT(ppropvarValue);
+
+ if SUCCEEDED(hr = UIPropertyToUInt32(*key, *ppropvarValue, &m_uSelected))
+ GetWndRibbon().OnRibbonItemSelected(GetID(), verb, m_uSelected);
+
+ return hr;
+ }
+};
+
+// RecentItemsCtrlImpl
+//
+template
+class RecentItemsCtrlImpl :
+ public CtrlImpl,
+ public CollectionImplBase, TDocList::m_nMaxEntries_Max>,
+ public TDocList
+{
+ typedef RecentItemsCtrlImpl thisClass;
+public:
+ typedef thisClass RecentItems;
+
+ // Implementation
+ HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value)
+ {
+ ATLASSERT((INT)uItem < GetMaxEntries());
+
+ LPCWSTR sPath = m_arrDocs[uItem].szDocName;
+ HRESULT hr = E_NOTIMPL;
+ switch (k_(key))
+ {
+ case k_Label:
+ hr = SetPropertyVal(key, GetWndRibbon().OnRibbonQueryRecentItemName(sPath), value);
+ break;
+ case k_LabelDescription:
+ hr = SetPropertyVal(key, sPath, value);
+ break;
+ default:
+ ATLASSERT(FALSE);
+ break;
+ }
+
+ return hr;
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT(nCmdID == GetID());
+ ATLASSERT(ppropvarNewValue);
+
+ HRESULT hr = S_OK;
+ switch (k_(key))
+ {
+ case k_RecentItems:
+ if (SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, m_arrDocs.GetSize()))
+ {
+ const int iLastIndex = m_arrDocs.GetSize() - 1;
+ for (LONG i = 0; i <= iLastIndex; i++)
+ SafeArrayPutElement(psa, &i, m_apItems[iLastIndex - i]); // reverse order
+
+ hr = SetPropertyVal(key, psa, ppropvarNewValue);
+ SafeArrayDestroy(psa);
+ }
+ break;
+ default:
+ hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ break;
+ }
+
+ return hr;
+ }
+
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* /*pCommandExecutionProperties*/)
+ {
+ ATLASSERT(nCmdID == GetID());
+ nCmdID; // avoid level 4 warning
+ ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE);
+ verb; // avoid level 4 warning
+ ATLASSERT((key) && (k_(*key) == k_SelectedItem));
+ ATLASSERT(ppropvarValue);
+
+ UINT32 uSel = 0xffff;
+ HRESULT hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel);
+ if SUCCEEDED(hr)
+ {
+ ATLASSERT(uSel < (UINT)GetMaxEntries());
+ GetWndRibbon().DefCommandExecute(ID_FILE_MRU_FIRST + uSel);
+ }
+
+ return hr;
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Ribbon stand-alone control classes
+
+// FontCtrlImpl
+//
+template
+class FontCtrlImpl : public CtrlImpl
+{
+public:
+
+ CharFormat m_cf;
+
+// Implementation
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* pCommandExecutionProperties)
+ {
+ ATLASSERT (nCmdID == GetID());
+ nCmdID; // avoid level 4 warning
+ ATLASSERT ((key) && (k_(*key) == k_FontProperties));
+ key; // avoid level 4 warning
+
+ HRESULT hr = E_INVALIDARG;
+ switch (verb)
+ {
+ case UI_EXECUTIONVERB_PREVIEW:
+ case UI_EXECUTIONVERB_EXECUTE:
+ ATLASSERT(pCommandExecutionProperties);
+ PROPVARIANT propvar;
+
+ if (SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &propvar)))
+ m_cf << ATL::CComQIPtr(propvar.punkVal);
+ break;
+
+ case UI_EXECUTIONVERB_CANCELPREVIEW:
+ ATLASSERT(ppropvarValue);
+ ATL::CComPtr pStore;
+
+ if (SUCCEEDED(hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarValue, &pStore)))
+ m_cf << pStore;
+ break;
+ }
+
+ if (SUCCEEDED(hr))
+ GetWndRibbon().OnRibbonFontCtrlExecute(GetID(), verb, &m_cf);
+ else
+ ATLASSERT(FALSE);
+
+ return hr;
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ if ((k_(key) == k_FontProperties) && (GetWndRibbon().OnRibbonQueryFont(t_ID, m_cf)))
+ {
+ ATL::CComQIPtr pStore(ppropvarCurrentValue->punkVal);
+ m_cf >> pStore;
+ return SetPropertyVal(key, pStore.p, ppropvarNewValue);
+ }
+ else
+ {
+ return CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ }
+ }
+};
+
+// ColorCtrlImpl
+//
+template
+class ColorCtrlImpl : public CommandCtrlImpl
+{
+public:
+ ColorCtrlImpl() : m_colorType(UI_SWATCHCOLORTYPE_NOCOLOR), m_color(0x800080) /*MAGENTA*/
+ { }
+
+ COLORREF m_color;
+ UINT32 m_colorType; // value in UI_SWATCHCOLORTYPE
+ Text m_sLabels[6]; // k_MoreColorsLabel to k_ThemeColorsCategoryLabel
+ ATL::CSimpleArray m_aColors[2];
+ ATL::CSimpleArray m_aTooltips[2];
+
+ // Operations
+ HRESULT SetColor(COLORREF color, bool bUpdate = false)
+ {
+ if (m_colorType != UI_SWATCHCOLORTYPE_RGB)
+ SetColorType(UI_SWATCHCOLORTYPE_RGB, bUpdate);
+ m_color = color;
+ return bUpdate ? SetProperty(UI_PKEY_Color, color) : S_OK;
+ }
+
+ HRESULT SetColorType(UI_SWATCHCOLORTYPE type, bool bUpdate = false)
+ {
+ m_colorType = type;
+ return bUpdate ? SetProperty(UI_PKEY_ColorType, type) : S_OK;
+ }
+
+ HRESULT SetColorLabel(REFPROPERTYKEY key, LPCWSTR sLabel, bool bUpdate = false)
+ {
+ ATLASSERT((k_(key) >= k_ThemeColorsCategoryLabel) && (k_(key) <= k_MoreColorsLabel));
+ m_sLabels[k_(key) - k_ThemeColorsCategoryLabel] = sLabel;
+ return bUpdate ? SetProperty(key, sLabel) : S_OK;
+ }
+
+ HRESULT SetColorArray(REFPROPERTYKEY key, COLORREF* pColor, bool bUpdate = false)
+ {
+ ATLASSERT((k_(key) == k_ThemeColors) || (k_(key) == k_StandardColors));
+
+ const INT ic = k_(key) - k_ThemeColors;
+ m_aColors[ic].RemoveAll();
+ while (*pColor != 0x800080) /*MAGENTA*/
+ m_aColors[ic].Add(*pColor++);
+
+ if (bUpdate)
+ {
+ PROPVARIANT var;
+ if SUCCEEDED(InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), m_aColors[ic].GetSize(), &var))
+ return SetProperty(key, var);
+ else
+ return E_INVALIDARG;
+ }
+ else
+ {
+ return S_OK;
+ }
+ }
+
+ HRESULT SetColorTooltips(REFPROPERTYKEY key, LPCWSTR* ppsTT, bool bUpdate = false)
+ {
+ ATLASSERT((k_(key) == k_ThemeColorsTooltips) || (k_(key) == k_StandardColorsTooltips));
+
+ const INT ic = k_(key) - k_ThemeColorsTooltips;
+ m_aTooltips[ic].RemoveAll();
+ while (*ppsTT)
+ m_aTooltips[ic].Add(*ppsTT++);
+
+ if (bUpdate)
+ {
+ PROPVARIANT var;
+ if SUCCEEDED(InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), m_aTooltips[ic].GetSize(), &var))
+ return SetProperty(key, var);
+ else
+ return E_INVALIDARG;
+ }
+ else
+ {
+ return S_OK;
+ }
+ }
+
+ // Implementation
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* pCommandExecutionProperties)
+ {
+ ATLASSERT (nCmdID == GetID());
+ nCmdID; // avoid level 4 warning
+ ATLASSERT (key && (k_(*key) == k_ColorType));
+ key; // avoid level 4 warning
+ ATLASSERT (ppropvarValue);
+
+ HRESULT hr = PropVariantToUInt32(*ppropvarValue, &m_colorType);
+ ATLASSERT(SUCCEEDED(hr));
+
+ if (SUCCEEDED(hr) && (m_colorType == UI_SWATCHCOLORTYPE_RGB))
+ {
+ ATLASSERT(pCommandExecutionProperties);
+ PROPVARIANT var;
+ if SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_Color, &var))
+ hr = PropVariantToUInt32(var, &m_color);
+ }
+
+ if SUCCEEDED(hr)
+ GetWndRibbon().OnRibbonColorCtrlExecute(GetID(), verb, (UI_SWATCHCOLORTYPE)m_colorType/*uType*/, m_color);
+ else
+ ATLASSERT(FALSE); // something was wrong
+
+ return hr;
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT (nCmdID == GetID());
+
+ HRESULT hr = E_NOTIMPL;
+
+ switch (k_(key))
+ {
+ case k_ColorType:
+ hr = SetPropertyVal(key, m_colorType, ppropvarNewValue);
+ break;
+ case k_Color:
+ if (m_color == 0x800080) /*MAGENTA*/
+ m_color = GetWndRibbon().OnRibbonQueryColor(GetID());
+ hr = SetPropertyVal(key, m_color, ppropvarNewValue);
+ break;
+ case k_ColorMode:
+ break;
+ case k_ThemeColorsCategoryLabel:
+ case k_StandardColorsCategoryLabel:
+ case k_RecentColorsCategoryLabel:
+ case k_AutomaticColorLabel:
+ case k_NoColorLabel:
+ case k_MoreColorsLabel:
+ {
+ const UINT iLabel = k_(key) - k_ThemeColorsCategoryLabel;
+ if (m_sLabels[iLabel].IsEmpty())
+ if (LPCWSTR psLabel = GetWndRibbon().OnRibbonQueryColorLabel(GetID(), key))
+ m_sLabels[iLabel] = psLabel;
+ if (!m_sLabels[iLabel].IsEmpty())
+ hr = SetPropertyVal(key, (LPCWSTR)m_sLabels[iLabel], ppropvarNewValue);
+ }
+ break;
+ case k_ThemeColors:
+ case k_StandardColors:
+ {
+ const INT ic = k_(key) - k_ThemeColors;
+ if (!m_aColors[ic].GetSize())
+ if (COLORREF* pColor = GetWndRibbon().OnRibbonQueryColorArray(GetID(), key))
+ SetColorArray(key, pColor);
+ if (INT iMax = m_aColors[ic].GetSize())
+ hr = InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), iMax, ppropvarNewValue);
+ }
+ break;
+ case k_ThemeColorsTooltips:
+ case k_StandardColorsTooltips:
+ {
+ const INT ic = k_(key) - k_ThemeColorsTooltips;
+ if (m_aTooltips[ic].GetSize() == 0)
+ if (LPCWSTR* ppsTT = GetWndRibbon().OnRibbonQueryColorTooltips(GetID(), key))
+ SetColorTooltips(key, ppsTT);
+ if (INT iMax = m_aTooltips[ic].GetSize())
+ hr = InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), iMax, ppropvarNewValue);
+ }
+ break;
+ default:
+ hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ break;
+ }
+
+ return hr;
+ }
+};
+
+// SpinnerCtrlImpl
+//
+template
+class SpinnerCtrlImpl : public CtrlImpl
+{
+public:
+ SpinnerCtrlImpl()
+ {
+ m_Values[0] = m_Values[2] = m_Values[4] = 0;
+ m_Values[1] = 100;
+ m_Values[3] = 1;
+ }
+
+ V m_Values[5];
+ // k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces
+
+ Text m_FormatString;
+ Text m_RepresentativeString;
+
+ // Operations
+ HRESULT SetDecimalPlaces(V vPlaces, bool bUpdate = false)
+ {
+ return SetValue(UI_PKEY_DecimalPlaces, vPlaces, bUpdate);
+ }
+
+ HRESULT SetMin(V vMin, bool bUpdate = false)
+ {
+ return SetValue(UI_PKEY_MinValue, vMin, bUpdate);
+ }
+
+ HRESULT SetMax(V vMax, bool bUpdate = false)
+ {
+ return SetValue(UI_PKEY_MaxValue, vMax, bUpdate);
+ }
+
+ HRESULT SetVal(V vVal, bool bUpdate = false)
+ {
+ return SetValue(UI_PKEY_DecimalValue, vVal, bUpdate);
+ }
+
+ HRESULT SetIncrement(V vIncrement, bool bUpdate = false)
+ {
+ return SetValue(UI_PKEY_Increment, vIncrement, bUpdate);
+ }
+
+ HRESULT SetFormatString(LPCWSTR sFormat, bool bUpdate = false)
+ {
+ return SetText(UI_PKEY_FormatString, sFormat, bUpdate);
+ }
+
+ HRESULT SetRepresentativeString(LPCWSTR sRepresentative, bool bUpdate = false)
+ {
+ return SetText(UI_PKEY_RepresentativeString, sRepresentative, bUpdate);
+ }
+
+ // Implementation
+ HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sText, bool bUpdate = false)
+ {
+ switch (k_(key))
+ {
+ case k_FormatString:
+ m_FormatString = sText;
+ break;
+ case k_RepresentativeString:
+ m_RepresentativeString = sText;
+ break;
+ default:
+ return CtrlImpl::SetText(key, sText, bUpdate);
+ }
+
+ return bUpdate ?
+ GetWndRibbon().InvalidateProperty(GetID(), key) :
+ S_OK;
+ }
+
+ HRESULT SetValue(REFPROPERTYKEY key, V val, bool bUpdate = false)
+ {
+ ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue));
+
+ const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue;
+ m_Values[iVal] = val;
+
+ if (bUpdate)
+ {
+ if(k_(key) == k_DecimalValue)
+ {
+ DECIMAL decVal;
+ InitDecimal(val, &decVal);
+ return SetProperty(key, &decVal);
+ }
+ else
+ {
+ return GetWndRibbon().InvalidateProperty(GetID(), key);
+ }
+ }
+ else
+ {
+ return S_OK;
+ }
+ }
+
+ HRESULT QueryValue(REFPROPERTYKEY key, LONG* plVal)
+ {
+ return GetWndRibbon().OnRibbonQuerySpinnerValue(GetID(), key, plVal);
+ }
+
+ HRESULT QueryValue(REFPROPERTYKEY key, DOUBLE* pdVal)
+ {
+ return GetWndRibbon().OnRibbonQueryFloatSpinnerValue(GetID(), key, pdVal);
+ }
+
+ HRESULT OnGetValue(REFPROPERTYKEY key, PROPVARIANT* ppv)
+ {
+ ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue));
+
+ const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue;
+
+ QueryValue(key, m_Values + iVal);
+
+ if (k_(key) == k_DecimalPlaces)
+ {
+ return SetPropertyVal(key, m_Values[iVal], ppv);
+ }
+ else
+ {
+ DECIMAL decVal;
+ InitDecimal(m_Values[iVal], &decVal);
+ return SetPropertyVal(key, &decVal, ppv);
+ }
+ }
+
+ HRESULT OnGetText(REFPROPERTYKEY key, Text& sVal, PROPVARIANT* ppv)
+ {
+ if (LPCWSTR sNew = GetWndRibbon().OnRibbonQueryText(GetID(), key))
+ sVal = sNew;
+ return SetPropertyVal(key, (LPCWSTR)sVal, ppv);
+ }
+
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* /*pCommandExecutionProperties*/)
+ {
+ ATLASSERT (nCmdID == GetID());
+ nCmdID; // avoid level 4 warning
+ ATLASSERT (key && (k_(*key) == k_DecimalValue));
+ key; // avoid level 4 warning
+ ATLASSERT (verb == UI_EXECUTIONVERB_EXECUTE);
+ verb; // avoid level 4 warning
+
+ DECIMAL decVal;
+
+ HRESULT hr = UIPropertyToDecimal(UI_PKEY_DecimalValue, *ppropvarValue, &decVal);
+ hr = InitVal(m_Values[0], &decVal);
+
+ GetWndRibbon().OnRibbonSpinnerCtrlExecute(GetID(), &m_Values[0]);
+
+ return hr;
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ ATLASSERT (nCmdID == GetID());
+
+ HRESULT hr = E_NOTIMPL;
+ switch (k_(key))
+ {
+ case k_DecimalPlaces:
+ case k_DecimalValue:
+ case k_Increment:
+ case k_MaxValue:
+ case k_MinValue:
+ hr = OnGetValue(key, ppropvarNewValue);
+ break;
+ case k_FormatString:
+ if (m_FormatString.IsEmpty())
+ return OnGetText(key, m_FormatString, ppropvarNewValue);
+ break;
+ case k_RepresentativeString:
+ if (m_RepresentativeString.IsEmpty())
+ return OnGetText(key, m_RepresentativeString, ppropvarNewValue);
+ break;
+ default:
+ hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ break;
+ }
+
+ return hr;
+ }
+
+ // decimal conversion helpers
+ static HRESULT InitDecimal(LONG& val, DECIMAL* pDecimal)
+ {
+ return ::VarDecFromI4(val, pDecimal);
+ }
+
+ static HRESULT InitDecimal(DOUBLE& val, DECIMAL* pDecimal)
+ {
+ return ::VarDecFromR8(val, pDecimal);
+ }
+
+ static HRESULT InitVal(LONG& val, const DECIMAL* pDecimal)
+ {
+ return ::VarI4FromDec(pDecimal, &val);
+ }
+
+ static HRESULT InitVal(DOUBLE& val, const DECIMAL* pDecimal)
+ {
+ return ::VarR8FromDec(pDecimal, &val);
+ }
+};
+
+// CRibbonImpl Ribbon implementation class
+//
+template
+class CRibbonImpl :
+ public CRibbonUpdateUI,
+ public ICtrl,
+ public IUIApplication,
+ public IUICommandHandler
+{
+ typedef CRibbonImpl thisClass;
+public:
+ typedef thisClass Ribbon;
+ typedef T WndRibbon;
+
+ CRibbonImpl() : m_bRibbonUI(false), m_hgRibbonSettings(NULL)
+ {
+#ifdef _DEBUG
+ m_cRef = 1;
+#endif
+ pWndRibbon = static_cast(this);
+ HRESULT hr = ::CoInitialize(NULL);
+ if(SUCCEEDED(hr))
+ if (RunTimeHelper::IsRibbonUIAvailable())
+ hr = m_pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework);
+ else
+ ATLTRACE(L"Ribbon UI not available\n");
+
+ if FAILED(hr)
+ ATLTRACE(L"Ribbon construction failed\n");
+
+ ATLASSERT(SUCCEEDED(hr));
+ }
+
+ ~CRibbonImpl()
+ {
+ ::GlobalFree(m_hgRibbonSettings);
+ m_pIUIFramework.Release();
+ ::CoUninitialize();
+ }
+
+ ICtrl& GetRibbonCtrl(UINT)
+ {
+ return static_cast(*this);
+ }
+
+ ATL::CComPtr m_pIUIFramework;
+ HGLOBAL m_hgRibbonSettings;
+ bool m_bRibbonUI;
+
+ bool IsRibbonUI()
+ {
+ return m_bRibbonUI;
+ }
+
+ IUIFramework* GetIUIFrameworkPtr()
+ {
+ return m_pIUIFramework;
+ }
+
+ template
+ I* GetRibbonViewPtr(UINT32 uID)
+ {
+ ATLASSERT(m_pIUIFramework);
+ ATL::CComPtr pI;
+ return m_pIUIFramework->GetView(uID, __uuidof(I), (void**) &pI) == S_OK ?
+ pI :
+ NULL;
+ }
+
+ IUIRibbon* GetRibbonPtr()
+ {
+ return GetRibbonViewPtr(0);
+ }
+
+ IUIContextualUI* GetMenuPtr(UINT32 uID)
+ {
+ ATLASSERT(uID);
+ return GetRibbonViewPtr(uID);
+ }
+
+ UINT GetRibbonHeight()
+ {
+ ATLASSERT(IsRibbonUI());
+
+ UINT32 cy = 0;
+ if (ATL::CComPtr pIUIRibbon = GetRibbonPtr())
+ pIUIRibbon->GetHeight(&cy);
+ return cy;
+ }
+
+ HRESULT CreateRibbon(LPCWSTR sResName = L"APPLICATION_RIBBON")
+ {
+ T* pT = static_cast(this);
+ ATLASSERT(GetIUIFrameworkPtr() && !IsRibbonUI());
+ ATLASSERT(pT->IsWindow());
+
+ HRESULT hr = m_pIUIFramework->Initialize(pT->m_hWnd, this);
+
+ if (hr == S_OK)
+ hr = m_pIUIFramework->LoadUI(ModuleHelper::GetResourceInstance(), sResName);
+
+ return hr;
+ }
+
+ HRESULT DestroyRibbon()
+ {
+ T* pT = static_cast(this);
+ ATLASSERT(GetIUIFrameworkPtr() && IsRibbonUI());
+ ATLASSERT(pT->IsWindow());
+
+ HRESULT hRes = m_pIUIFramework->Destroy();
+ if (!RunTimeHelper::IsWin7())
+ pT->SetWindowRgn(NULL, TRUE); // Vista Basic bug workaround
+ return hRes;
+ }
+
+// Ribbon persistency
+ HRESULT operator >>(IStream* pIStream)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(pIStream);
+
+ HRESULT hr = E_FAIL;
+ if (ATL::CComPtr pIUIRibbon = GetRibbonPtr())
+ {
+ const LARGE_INTEGER li0 = { 0 };
+ pIStream->Seek(li0, STREAM_SEEK_SET, NULL);
+ hr = pIUIRibbon->SaveSettingsToStream(pIStream);
+ pIStream->Commit(STGC_DEFAULT);
+ }
+
+ return hr;
+ }
+
+ HRESULT operator <<(IStream* pIStream)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(pIStream);
+
+ HRESULT hr = E_FAIL;
+ if (ATL::CComPtr pIUIRibbon = GetRibbonPtr())
+ {
+ const LARGE_INTEGER li0 = { 0 };
+ pIStream->Seek(li0, STREAM_SEEK_SET, NULL);
+ hr = pIUIRibbon->LoadSettingsFromStream(pIStream);
+ }
+
+ return hr;
+ }
+
+ void ResetRibbonSettings()
+ {
+ if (m_hgRibbonSettings != NULL)
+ {
+ ::GlobalFree(m_hgRibbonSettings);
+ m_hgRibbonSettings = NULL;
+ }
+ }
+
+ HRESULT SaveRibbonSettings()
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(static_cast(this)->IsWindow());
+
+ HRESULT hr = E_FAIL;
+ ATL::CComPtr pIStream;
+
+ if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream))
+ hr = *this >> pIStream;
+
+ if (SUCCEEDED(hr) && (m_hgRibbonSettings == NULL))
+ hr = ::GetHGlobalFromStream(pIStream, &m_hgRibbonSettings);
+
+ if FAILED(hr)
+ ResetRibbonSettings();
+
+ return hr;
+ }
+
+ HRESULT RestoreRibbonSettings()
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(m_hgRibbonSettings);
+ ATLASSERT(static_cast(this)->IsWindow());
+
+ HRESULT hr = E_FAIL;
+ ATL::CComPtr pIStream;
+
+ if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream))
+ hr = *this << pIStream;
+
+ if FAILED(hr)
+ ResetRibbonSettings();
+
+ return hr;
+ }
+
+// QAT dock states
+ UI_CONTROLDOCK GetQATDock()
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(IsRibbonUI());
+
+ UINT32 uDock = 0;
+ PROPVARIANT propvar;
+ ATL::CComQIPtrpIPS(GetRibbonPtr());
+
+ if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(UI_PKEY_QuickAccessToolbarDock, &propvar)) &&
+ SUCCEEDED(UIPropertyToUInt32(UI_PKEY_QuickAccessToolbarDock, propvar, &uDock)))
+ return (UI_CONTROLDOCK)uDock;
+
+ ATLASSERT(FALSE); // something was wrong
+ return (UI_CONTROLDOCK)0;
+ }
+
+ bool SetQATDock(UI_CONTROLDOCK dockState)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(IsRibbonUI());
+
+ PROPVARIANT propvar;
+ ATLVERIFY(SUCCEEDED(SetPropertyVal(UI_PKEY_QuickAccessToolbarDock, dockState, &propvar)));
+
+ ATL::CComQIPtrpIPS(GetRibbonPtr());
+ if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(UI_PKEY_QuickAccessToolbarDock, propvar)))
+ {
+ pIPS->Commit();
+ return true;
+ }
+
+ ATLASSERT(FALSE); // something was wrong
+ return false;
+ }
+
+// Ribbon display states
+ bool GetRibbonDisplayState(REFPROPERTYKEY key)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(IsRibbonUI());
+ ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized));
+
+ PROPVARIANT propvar;
+ ATL::CComQIPtrpIPS(GetRibbonPtr());
+
+ if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar)))
+ {
+ BOOL bState = FALSE;
+ if SUCCEEDED(UIPropertyToBoolean(key, propvar, &bState))
+ return (bState != FALSE);
+ }
+
+ ATLASSERT(FALSE); // something was wrong
+ return false;
+ }
+
+ bool SetRibbonDisplayState(REFPROPERTYKEY key, bool bState = true)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(IsRibbonUI());
+ ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized));
+
+ PROPVARIANT propvar;
+ ATLVERIFY(SUCCEEDED(SetPropertyVal(key, bState, &propvar)));
+
+ ATL::CComQIPtrpIPS(GetRibbonPtr());
+
+ if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar)))
+ {
+ pIPS->Commit();
+ return true;
+ }
+
+ ATLASSERT(FALSE); // something was wrong
+ return false;
+ }
+
+ bool IsRibbonMinimized()
+ {
+ return GetRibbonDisplayState(UI_PKEY_Minimized);
+ }
+
+ bool MinimizeRibbon(bool bMinimize = true)
+ {
+ return SetRibbonDisplayState(UI_PKEY_Minimized, bMinimize);
+ }
+
+ bool IsRibbonHidden()
+ {
+ return !GetRibbonDisplayState(UI_PKEY_Viewable);
+ }
+
+ bool HideRibbon(bool bHide = true)
+ {
+ return SetRibbonDisplayState(UI_PKEY_Viewable, !bHide);
+ }
+
+// Ribbon colors
+ UI_HSBCOLOR GetRibbonColor(REFPROPERTYKEY key)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(IsRibbonUI());
+ ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor));
+
+ PROPVARIANT propvar;
+ ATL::CComQIPtrpIPS(GetIUIFrameworkPtr());
+
+ if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar)))
+ {
+ UINT32 color = 0;
+ if SUCCEEDED(UIPropertyToUInt32(key, propvar, &color))
+ return color;
+ }
+
+ ATLASSERT(FALSE); // something was wrong
+ return 0;
+ }
+
+ bool SetRibbonColor(REFPROPERTYKEY key, UI_HSBCOLOR color)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+ ATLASSERT(IsRibbonUI());
+ ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor));
+
+ PROPVARIANT propvar;
+ ATLVERIFY(SUCCEEDED(SetPropertyVal(key, color, &propvar)));
+
+ ATL::CComQIPtrpIPS(GetIUIFrameworkPtr());
+
+ if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar)))
+ {
+ pIPS->Commit();
+ return true;
+ }
+
+ ATLASSERT(FALSE); // something was wrong
+ return false;
+ }
+
+// Ribbon modes
+ HRESULT SetRibbonModes(INT32 iModes)
+ {
+ ATLASSERT(IsRibbonUI());
+ return GetIUIFrameworkPtr()->SetModes(iModes);
+ }
+
+// Ribbon contextual tab
+ UI_CONTEXTAVAILABILITY GetRibbonContextAvail(UINT32 uID)
+ {
+ ATLASSERT(GetIUIFrameworkPtr());
+
+ PROPVARIANT propvar;
+ if (IsRibbonUI() &&
+ SUCCEEDED(GetIUIFrameworkPtr()->GetUICommandProperty(uID, UI_PKEY_ContextAvailable, &propvar)))
+ {
+ UINT uav;
+ if (SUCCEEDED(PropVariantToUInt32(propvar, &uav)))
+ {
+ CUpdateUIBase::UIEnable(uID, uav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE);
+ CUpdateUIBase::UISetCheck(uID, uav == UI_CONTEXTAVAILABILITY_ACTIVE);
+ return (UI_CONTEXTAVAILABILITY)uav;
+ }
+ }
+
+ return UI_CONTEXTAVAILABILITY_NOTAVAILABLE;
+ }
+
+ HRESULT SetRibbonContextAvail(UINT32 uID, UI_CONTEXTAVAILABILITY cav)
+ {
+ CUpdateUIBase::UIEnable(uID, cav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE);
+ CUpdateUIBase::UISetCheck(uID, cav == UI_CONTEXTAVAILABILITY_ACTIVE);
+
+ return SetProperty((WORD)uID, UI_PKEY_ContextAvailable, UINT32(cav));
+ }
+
+// Ribbon context menu
+ bool HasRibbonMenu(UINT32 uID)
+ {
+ ATL::CComPtr pI = GetMenuPtr(uID);
+ return pI != NULL;
+ }
+
+ HRESULT TrackRibbonMenu(UINT32 uID, INT32 x, INT32 y)
+ {
+ ATLASSERT(HasRibbonMenu(uID));
+
+ return IsRibbonUI() ?
+ ATL::CComPtr(GetMenuPtr(uID))->ShowAtLocation(x, y) :
+ E_FAIL;
+ }
+
+ HRESULT TrackRibbonMenu(UINT32 uID, LPARAM lParam)
+ {
+ return TrackRibbonMenu(uID, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ }
+
+// Overrideables
+ HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY /*key*/)
+ {
+ return DefRibbonQueryImage(nCmdID);
+ }
+
+ LPCWSTR OnRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key)
+ {
+ return DefRibbonQueryText(nCmdID, key);
+ }
+
+ bool OnRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key)
+ {
+ return DefRibbonQueryState(nCmdID, key);
+ }
+
+ UI_CONTEXTAVAILABILITY OnRibbonQueryTabAvail(UINT nCmdID)
+ {
+ DWORD dwState = UIGetState(nCmdID);
+ return ((dwState & UPDUI_DISABLED) == UPDUI_DISABLED) ?
+ UI_CONTEXTAVAILABILITY_NOTAVAILABLE :
+ (((dwState & UPDUI_CHECKED) == UPDUI_CHECKED) ?
+ UI_CONTEXTAVAILABILITY_ACTIVE :
+ UI_CONTEXTAVAILABILITY_AVAILABLE);
+ }
+
+ LPCWSTR OnRibbonQueryComboText(UINT32 /*uCtrlID*/)
+ {
+ return NULL;
+ }
+
+ LPCWSTR OnRibbonQueryCategoryText(UINT32 /*uCtrlID*/, UINT32 /*uCat*/)
+ {
+ return L"Category";
+ }
+
+ UINT32 OnRibbonQueryItemCategory(UINT32 /*uCtrlID*/, UINT32 /*uItem*/)
+ {
+ return 0;
+ }
+
+ LPCWSTR OnRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem)
+ {
+ return DefRibbonQueryItemText(uCtrlID, uItem);
+ }
+
+ bool OnRibbonQuerySelectedItem(UINT32 /*uCtrlID*/, UINT32& /*uSel*/)
+ {
+ return false;
+ }
+
+ HBITMAP OnRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem)
+ {
+ return DefRibbonQueryItemImage(uCtrlID, uItem);
+ }
+
+ UINT32 OnRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem)
+ {
+ return DefRibbonQueryItemCommand(uCtrlID, uItem);
+ }
+
+ UI_COMMANDTYPE OnRibbonQueryItemCommandType(UINT32 /*uCtrlID*/, UINT32 /*uItem*/)
+ {
+ return UI_COMMANDTYPE_ACTION;
+ }
+
+ LPCWSTR OnRibbonQueryRecentItemName(LPCWSTR sPath)
+ {
+ return ::PathFindFileName(sPath);
+ }
+
+ bool OnRibbonQueryFont(UINT /*nId*/, CHARFORMAT2& /*cf*/)
+ {
+ return false;
+ }
+
+ bool OnRibbonQuerySpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, LONG* /*pVal*/)
+ {
+ return false;
+ }
+
+ bool OnRibbonQueryFloatSpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, DOUBLE* /*pVal*/)
+ {
+ return false;
+ }
+
+ COLORREF OnRibbonQueryColor(UINT /*nCmdID*/)
+ {
+ return 0x800080; /*MAGENTA*/
+ }
+
+ LPCWSTR OnRibbonQueryColorLabel(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/)
+ {
+ return NULL;
+ }
+
+ COLORREF* OnRibbonQueryColorArray(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/)
+ {
+ return NULL;
+ }
+
+ LPCWSTR* OnRibbonQueryColorTooltips(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/)
+ {
+ return NULL;
+ }
+
+ bool OnRibbonItemSelected(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UINT32 uItem)
+ {
+ DefCommandExecute(MAKELONG(uCtrlID, verb), uItem);
+ return true;
+ }
+
+ void OnRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color)
+ {
+ DefRibbonColorCtrlExecute(uCtrlID, verb, uType, color);
+ }
+
+ void OnRibbonFontCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, CHARFORMAT2* pcf)
+ {
+ DefCommandExecute(MAKELONG(uCtrlID, verb), (LPARAM)pcf);
+ }
+
+ void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, LONG* pVal)
+ {
+ DefCommandExecute(uCtrlID, *pVal);
+ }
+
+ void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, DOUBLE* pVal)
+ {
+ DefCommandExecute(uCtrlID, (LPARAM)pVal);
+ }
+
+ void OnRibbonCommandExecute(UINT32 uCmdID)
+ {
+ DefCommandExecute(uCmdID);
+ }
+
+// Default implementations
+ HBITMAP DefRibbonQueryImage(UINT nCmdID)
+ {
+ return AtlLoadBitmapImage(nCmdID, LR_CREATEDIBSECTION);
+ }
+
+ bool DefRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key)
+ {
+ DWORD dwState = UIGetState(nCmdID);
+ bool bRet = false;
+ switch (k_(key))
+ {
+ case k_BooleanValue:
+ bRet = (dwState & UPDUI_CHECKED) == UPDUI_CHECKED;
+ break;
+ case k_Enabled:
+ bRet = (dwState & UPDUI_DISABLED) != UPDUI_DISABLED;
+ break;
+ default:
+ ATLASSERT(FALSE);
+ break;
+ }
+
+ return bRet;
+ }
+
+ LPCTSTR DefRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key)
+ {
+ static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 };
+
+ if (k_(key) == k_Label)
+ return UIGetText(nCmdID);
+
+ if (AtlLoadString(nCmdID, sText, RIBBONUI_MAX_TEXT))
+ {
+ PWCHAR pTitle = wcschr(sText, L'\n');
+ switch (k_(key))
+ {
+ case k_Keytip:
+ if (PWCHAR pAmp = wcschr(sText, L'&'))
+ pTitle = pAmp;
+ if (pTitle != NULL)
+ *(pTitle + 2) = NULL; // fall through
+ case k_TooltipTitle:
+ return pTitle ? ++pTitle : NULL;
+ case k_TooltipDescription:
+ case k_LabelDescription:
+ if (pTitle != NULL)
+ *pTitle = NULL;
+ return sText;
+ }
+ }
+
+ return NULL;
+ }
+
+ LPCWSTR DefRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem)
+ {
+ return DefRibbonQueryText(uCtrlID + 1 + uItem, UI_PKEY_LabelDescription);
+ }
+
+ HBITMAP DefRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem)
+ {
+ return DefRibbonQueryImage(uCtrlID + 1 + uItem);
+ }
+
+ UINT32 DefRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem)
+ {
+ return uCtrlID + 1 + uItem;
+ }
+
+ void DefRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color)
+ {
+ switch(uType)
+ {
+ case UI_SWATCHCOLORTYPE_RGB:
+ break;
+ case UI_SWATCHCOLORTYPE_AUTOMATIC:
+ color = ::GetSysColor(COLOR_WINDOWTEXT);
+ break;
+ case UI_SWATCHCOLORTYPE_NOCOLOR:
+ color = ::GetSysColor(COLOR_WINDOW);
+ break;
+ default:
+ ATLASSERT(FALSE);
+ break;
+ }
+
+ DefCommandExecute(MAKELONG(uCtrlID, verb), color);
+ }
+
+ void DefCommandExecute(UINT32 uCmd, LPARAM lParam = 0)
+ {
+ static_cast(this)->PostMessage(WM_COMMAND, uCmd, lParam);
+ }
+
+// Elements setting helpers
+ HRESULT InvalidateCtrl(UINT32 nID)
+ {
+ return IsRibbonUI() ?
+ GetIUIFrameworkPtr()->InvalidateUICommand(nID, UI_INVALIDATIONS_ALLPROPERTIES, NULL) :
+ E_FAIL;
+ }
+
+ HRESULT InvalidateProperty(UINT32 nID, REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY)
+ {
+ return IsRibbonUI() ?
+ GetIUIFrameworkPtr()->InvalidateUICommand(nID, flags, &key) :
+ E_FAIL;
+ }
+
+ template
+ HRESULT SetProperty(WORD wID, REFPROPERTYKEY key, V val)
+ {
+ if (IsRibbonUI())
+ {
+ PROPVARIANT var;
+ if (SUCCEEDED(RibbonUI::SetPropertyVal(key, val, &var)))
+ {
+ return SetProperty(wID, key, var);
+ }
+ return E_INVALIDARG;
+ }
+ else
+ {
+ return E_FAIL;
+ }
+ }
+
+ template <>
+ HRESULT SetProperty(WORD nID, REFPROPERTYKEY key, PROPVARIANT var)
+ {
+ return IsRibbonUI() ?
+ GetIUIFrameworkPtr()->SetUICommandProperty(nID, key, var) :
+ E_FAIL;
+ }
+
+// Interfaces
+ // IUIApplication
+ STDMETHODIMP OnViewChanged(UINT32, UI_VIEWTYPE, IUnknown*, UI_VIEWVERB verb, INT32)
+ {
+ switch (verb)
+ {
+ case UI_VIEWVERB_CREATE:
+ m_bRibbonUI = true;
+ if (m_hgRibbonSettings != NULL)
+ RestoreRibbonSettings();
+ break;
+ case UI_VIEWVERB_SIZE:
+ static_cast(this)->UpdateLayout(FALSE);
+ break;
+ case UI_VIEWVERB_DESTROY:
+ SaveRibbonSettings();
+ m_bRibbonUI = false;
+ break;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHODIMP OnCreateUICommand(UINT32 nCmdID, UI_COMMANDTYPE typeID, IUICommandHandler** ppCommandHandler)
+ {
+ UIAddRibbonElement(nCmdID);
+ if (typeID == UI_COMMANDTYPE_CONTEXT)
+ CUpdateUIBase::UIEnable(nCmdID, false);
+ *ppCommandHandler = this;
+ return S_OK;
+ }
+
+ STDMETHODIMP OnDestroyUICommand(UINT32 nCmdID, UI_COMMANDTYPE, IUICommandHandler*)
+ {
+ UIRemoveRibbonElement(nCmdID);
+ return S_OK;
+ }
+
+ // IUICommandHandler
+ STDMETHODIMP Execute(UINT nCmdID,
+ UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key,
+ const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* pCommandExecutionProperties)
+ {
+ T* pT =static_cast(this);
+ return pT->GetRibbonCtrl(nCmdID).DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties);
+ }
+
+ STDMETHODIMP UpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue)
+ {
+ T* pT =static_cast(this);
+ return pT->GetRibbonCtrl(nCmdID).DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue);
+ }
+
+#ifdef _DEBUG
+ // IUnknown methods (heavyweight)
+ STDMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+
+ STDMETHODIMP_(ULONG) Release()
+ {
+ LONG cRef = InterlockedDecrement(&m_cRef);
+ if (cRef == 0) // NoOp for breakpoint
+ {
+ cRef = 0;
+ }
+
+ return cRef;
+ }
+
+ STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
+ {
+ if (ppv == NULL)
+ {
+ return E_POINTER;
+ }
+ else if ((iid == __uuidof(IUnknown)) ||
+ (iid == __uuidof(IUICommandHandler)) ||
+ (iid == __uuidof(IUIApplication)))
+ {
+ *ppv = this;
+ AddRef();
+ return S_OK;
+ }
+ else
+ {
+ return E_NOINTERFACE;
+ }
+ }
+
+ LONG m_cRef;
+#else
+ // IUnknown methods (lightweight)
+ STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
+ {
+ if ((iid == __uuidof(IUnknown)) ||
+ (iid == __uuidof(IUICommandHandler)) ||
+ (iid == __uuidof(IUIApplication)))
+ {
+ *ppv = this;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ ULONG STDMETHODCALLTYPE AddRef()
+ {
+ return 1;
+ }
+ ULONG STDMETHODCALLTYPE Release()
+ {
+ return 1;
+ }
+#endif
+
+// CRibbonImpl ICtrl implementation
+ virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb,
+ const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue,
+ IUISimplePropertySet* /*pCommandExecutionProperties*/)
+ {
+ if (key != NULL)
+ {
+ if(k_(*key) != k_BooleanValue)
+ {
+ ATLTRACE(L"Control ID %d is not handled\n", nCmdID);
+ return E_NOTIMPL;
+ }
+ BOOL bChecked = FALSE;
+ ATLVERIFY(SUCCEEDED(PropVariantToBoolean(*ppropvarValue, &bChecked)));
+ CUpdateUIBase::UISetCheck(nCmdID, bChecked);
+ }
+
+ ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE);
+ verb; // avoid level 4 warning
+
+ static_cast(this)->OnRibbonCommandExecute(nCmdID);
+
+ return S_OK;
+ }
+
+ virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key,
+ const PROPVARIANT* /*ppropvarCurrentValue*/, PROPVARIANT* ppropvarNewValue)
+ {
+ T* pT = static_cast(this);
+ HRESULT hr = E_NOTIMPL;
+ switch (k_(key))
+ {
+ case k_LargeImage:
+ case k_LargeHighContrastImage:
+ case k_SmallImage:
+ case k_SmallHighContrastImage:
+ if (HBITMAP hbm = pT->OnRibbonQueryImage(nCmdID, key))
+ hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), ppropvarNewValue);
+ break;
+ case k_Label:
+ case k_Keytip:
+ case k_TooltipTitle:
+ case k_TooltipDescription:
+ case k_LabelDescription:
+ if (LPCWSTR sText = pT->OnRibbonQueryText(nCmdID, key))
+ hr = SetPropertyVal(key, sText, ppropvarNewValue);
+ break;
+ case k_BooleanValue:
+ case k_Enabled:
+ hr = SetPropertyVal(key, pT->OnRibbonQueryState(nCmdID, key), ppropvarNewValue);
+ break;
+ case k_ContextAvailable:
+ hr = SetPropertyVal(key, pT->OnRibbonQueryTabAvail(nCmdID), ppropvarNewValue);
+ break;
+ }
+
+ return hr;
+ }
+
+// CRibbonImpl::CRibbonXXXCtrl specialized classes
+ //CRibbonComboCtrl
+ template
+ class CRibbonComboCtrl : public CollectionCtrlImpl, t_items, t_categories>>
+ {
+ public:
+ CRibbonComboCtrl()
+ { }
+ };
+
+ // CRibbonItemGalleryCtrl
+ template
+ class CRibbonItemGalleryCtrl : public CollectionCtrlImpl, t_items, t_categories>>
+ {
+ public:
+ CRibbonItemGalleryCtrl()
+ { }
+ };
+
+ // CRibbonCommandGalleryCtrl
+ template
+ class CRibbonCommandGalleryCtrl : public CollectionCtrlImpl, t_items, t_categories>>
+ {
+ public:
+ CRibbonCommandGalleryCtrl()
+ { }
+ };
+
+ // CRibbonToolbarGalleryCtrl
+ template
+ class CRibbonToolbarGalleryCtrl : public ToolbarGalleryCtrlImpl
+ { };
+
+ // CRibbonSimpleComboCtrl
+ template
+ class CRibbonSimpleComboCtrl : public SimpleCollectionCtrlImpl
+ { };
+
+ // CRibbonSimpleGalleryCtrl
+ template
+ class CRibbonSimpleGalleryCtrl : public SimpleCollectionCtrlImpl
+ { };
+
+ //CRibbonRecentItemsCtrl
+ template
+ class CRibbonRecentItemsCtrl : public RecentItemsCtrlImpl