Mercurial > foo_out_sdl
comparison foosdk/wtl/Include/atlribbon.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 // Windows Template Library - WTL version 10.0 | |
| 2 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. | |
| 3 // | |
| 4 // This file is a part of the Windows Template Library. | |
| 5 // The use and distribution terms for this software are covered by the | |
| 6 // Microsoft Public License (http://opensource.org/licenses/MS-PL) | |
| 7 // which can be found in the file MS-PL.txt at the root folder. | |
| 8 | |
| 9 #ifndef __ATLRIBBON_H__ | |
| 10 #define __ATLRIBBON_H__ | |
| 11 | |
| 12 #pragma once | |
| 13 | |
| 14 #if (_MSC_VER < 1500) | |
| 15 #error atlribbon.h requires Visual C++ 2008 compiler or higher | |
| 16 #endif | |
| 17 | |
| 18 #ifndef _UNICODE | |
| 19 #error atlribbon.h requires the Unicode character set | |
| 20 #endif | |
| 21 | |
| 22 #if !defined(NTDDI_WIN7) || (NTDDI_VERSION < NTDDI_WIN7) | |
| 23 #error atlribbon.h requires the Windows 7 SDK or higher | |
| 24 #endif | |
| 25 | |
| 26 #ifndef __ATLAPP_H__ | |
| 27 #error atlribbon.h requires atlapp.h to be included first | |
| 28 #endif | |
| 29 | |
| 30 #include <atlmisc.h> // for RecentDocumentList classes | |
| 31 #include <atlframe.h> // for Frame and UpdateUI classes | |
| 32 #include <atlctrls.h> // required for atlctrlw.h | |
| 33 #include <atlctrlw.h> // for CCommandBarCtrl | |
| 34 | |
| 35 #ifndef __ATLSTR_H__ | |
| 36 #pragma warning(push) | |
| 37 #pragma warning(disable: 4530) // unwind semantics not enabled | |
| 38 #include <string> | |
| 39 #pragma warning(pop) | |
| 40 #endif | |
| 41 | |
| 42 #include <dwmapi.h> | |
| 43 #pragma comment(lib, "dwmapi.lib") | |
| 44 | |
| 45 #include "UIRibbon.h" | |
| 46 #include "UIRibbonPropertyHelpers.h" | |
| 47 #pragma comment(lib, "propsys.lib") | |
| 48 | |
| 49 #include <Richedit.h> // for CHARFORMAT2 | |
| 50 | |
| 51 | |
| 52 /////////////////////////////////////////////////////////////////////////////// | |
| 53 // Classes in this file: | |
| 54 // | |
| 55 // CRibbonUpdateUI : Automatic mapping of ribbon UI elements | |
| 56 // | |
| 57 // RibbonUI::Text | |
| 58 // RibbonUI::CharFormat | |
| 59 // RibbonUI::ICtrl | |
| 60 // RibbonUI::CtrlImpl | |
| 61 // RibbonUI::CommandCtrlImpl | |
| 62 // RibbonUI::ItemProperty | |
| 63 // RibbonUI::CollectionImplBase | |
| 64 // RibbonUI::CollectionImpl | |
| 65 // RibbonUI::TextCollectionImpl | |
| 66 // RibbonUI::ItemCollectionImpl | |
| 67 // RibbonUI::ComboCollectionImpl | |
| 68 // RibbonUI::CommandCollectionImpl | |
| 69 // RibbonUI::ToolbarCollectionImpl | |
| 70 // RibbonUI::SimpleCollectionImpl | |
| 71 // RibbonUI::CollectionCtrlImpl | |
| 72 // RibbonUI::ToolbarGalleryCtrlImpl | |
| 73 // RibbonUI::SimpleCollectionCtrlImpl | |
| 74 // RibbonUI::RecentItemsCtrlImpl | |
| 75 // RibbonUI::FontCtrlImpl | |
| 76 // RibbonUI::ColorCtrlImpl | |
| 77 // RibbonUI::SpinnerCtrlImpl | |
| 78 // | |
| 79 // RibbonUI::CRibbonImpl | |
| 80 // CRibbonImpl::CRibbonComboCtrl | |
| 81 // CRibbonImpl::CRibbonItemGalleryCtrl | |
| 82 // CRibbonImpl::CRibbonCommandGalleryCtrl | |
| 83 // CRibbonImpl::CRibbonToolbarGalleryCtrl | |
| 84 // CRibbonImpl::CRibbonSimpleComboCtrl | |
| 85 // CRibbonImpl::CRibbonSimpleGalleryCtrl | |
| 86 // CRibbonImpl::CRibbonRecentItemsCtrl | |
| 87 // CRibbonImpl::CRibbonColorCtrl | |
| 88 // CRibbonImpl::CRibbonFontCtrl | |
| 89 // CRibbonImpl::CRibbonSpinnerCtrl | |
| 90 // CRibbonImpl::CRibbonFloatSpinnerCtrl | |
| 91 // CRibbonImpl::CRibbonCommandCtrl | |
| 92 // | |
| 93 // CRibbonFrameWindowImplBase | |
| 94 // CRibbonFrameWindowImpl | |
| 95 // CRibbonMDIFrameWindowImpl | |
| 96 // CRibbonPersist | |
| 97 // | |
| 98 // Global functions: | |
| 99 // RibbonUI::SetPropertyVal() | |
| 100 // RibbonUI::GetImage() | |
| 101 | |
| 102 | |
| 103 // Constants | |
| 104 | |
| 105 #ifndef RIBBONUI_MAX_TEXT | |
| 106 #define RIBBONUI_MAX_TEXT 128 | |
| 107 #endif | |
| 108 | |
| 109 #define TWIPS_PER_POINT 20 // For font size | |
| 110 | |
| 111 | |
| 112 namespace WTL | |
| 113 { | |
| 114 | |
| 115 /////////////////////////////////////////////////////////////////////////////// | |
| 116 // CRibbonUpdateUI : Automatic mapping of ribbon UI elements | |
| 117 | |
| 118 template <class T> | |
| 119 class CRibbonUpdateUI : public CAutoUpdateUI<T> | |
| 120 { | |
| 121 public: | |
| 122 enum | |
| 123 { | |
| 124 UPDUI_RIBBON = 0x0080, | |
| 125 UPDUI_PERSIST = 0x0020 | |
| 126 }; | |
| 127 | |
| 128 bool IsRibbonElement(const CUpdateUIBase::_AtlUpdateUIMap& UIMap) | |
| 129 { | |
| 130 return (UIMap.m_wType & UPDUI_RIBBON) != 0; | |
| 131 } | |
| 132 | |
| 133 bool IsRibbonID(UINT nID) | |
| 134 { | |
| 135 for(int i = 0; i < this->m_arrUIMap.GetSize(); i++) | |
| 136 { | |
| 137 if(this->m_arrUIMap[i].m_nID == nID) | |
| 138 return IsRibbonElement(this->m_arrUIMap[i]); | |
| 139 } | |
| 140 | |
| 141 return false; | |
| 142 } | |
| 143 | |
| 144 // Element | |
| 145 bool UIAddRibbonElement(UINT nID) | |
| 146 { | |
| 147 return this->UIAddElement<UPDUI_RIBBON>(nID); | |
| 148 } | |
| 149 | |
| 150 bool UIRemoveRibbonElement(UINT nID) | |
| 151 { | |
| 152 return this->UIRemoveElement<UPDUI_RIBBON>(nID); | |
| 153 } | |
| 154 | |
| 155 bool UIPersistElement(UINT nID, bool bPersist = true) | |
| 156 { | |
| 157 return bPersist ? | |
| 158 this->UIAddElement<UPDUI_PERSIST>(nID) : | |
| 159 this->UIRemoveElement<UPDUI_PERSIST>(nID); | |
| 160 } | |
| 161 | |
| 162 // methods for Ribbon elements | |
| 163 BOOL UISetText(int nID, LPCWSTR sText, BOOL bForceUpdate = FALSE) | |
| 164 { | |
| 165 T* pT = static_cast<T*>(this); | |
| 166 BOOL bRes = CUpdateUIBase::UISetText(nID, sText, bForceUpdate); | |
| 167 if (pT->IsRibbonUI() && IsRibbonID(nID)) | |
| 168 bRes = SUCCEEDED(pT->InvalidateProperty(nID, UI_PKEY_Label)); | |
| 169 return bRes; | |
| 170 } | |
| 171 | |
| 172 BOOL UISetText(int nID, UINT uIdResource, BOOL bForceUpdate = FALSE) | |
| 173 { | |
| 174 ATL::CTempBuffer<WCHAR> sText(RIBBONUI_MAX_TEXT); | |
| 175 int nRet = ATL::AtlLoadString(uIdResource, sText, RIBBONUI_MAX_TEXT); | |
| 176 if(nRet > 0) | |
| 177 UISetText(nID, sText, bForceUpdate); | |
| 178 return (nRet > 0) ? TRUE : FALSE; | |
| 179 } | |
| 180 | |
| 181 LPCTSTR UIGetText(int nID) | |
| 182 { | |
| 183 T* pT = static_cast<T*>(this); | |
| 184 LPCTSTR sUI = CAutoUpdateUI<T>::UIGetText(nID); | |
| 185 | |
| 186 // replace 'tab' by 'space' for RibbonUI elements | |
| 187 if (sUI && pT->IsRibbonUI() && IsRibbonID(nID) && wcschr(sUI, L'\t')) | |
| 188 { | |
| 189 static WCHAR sText[RIBBONUI_MAX_TEXT] = {}; | |
| 190 wcscpy_s(sText, sUI); | |
| 191 WCHAR* pch = wcschr(sText, L'\t'); | |
| 192 if (pch != NULL) | |
| 193 *pch = L' '; | |
| 194 return sText; | |
| 195 } | |
| 196 else | |
| 197 { | |
| 198 return sUI; | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE) | |
| 203 { | |
| 204 T* pT = static_cast<T*>(this); | |
| 205 BOOL bRes = CUpdateUIBase::UIEnable(nID, bEnable, bForceUpdate); | |
| 206 if (pT->IsRibbonUI() && IsRibbonID(nID)) | |
| 207 bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_Enabled, bEnable)); | |
| 208 return bRes; | |
| 209 } | |
| 210 | |
| 211 BOOL UISetCheck(int nID, INT nCheck, BOOL bForceUpdate = FALSE) | |
| 212 { | |
| 213 if ((nCheck == 0) || (nCheck == 1)) | |
| 214 return UISetCheck(nID, nCheck != 0, bForceUpdate); | |
| 215 else | |
| 216 return CUpdateUIBase::UISetCheck(nID, nCheck, bForceUpdate); | |
| 217 } | |
| 218 | |
| 219 BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE) | |
| 220 { | |
| 221 T* pT = static_cast<T*>(this); | |
| 222 BOOL bRes = CUpdateUIBase::UISetCheck(nID, bCheck, bForceUpdate); | |
| 223 if (bRes && pT->IsRibbonUI() && IsRibbonID(nID)) | |
| 224 bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_BooleanValue, bCheck)); | |
| 225 return bRes; | |
| 226 } | |
| 227 }; | |
| 228 | |
| 229 | |
| 230 /////////////////////////////////////////////////////////////////////////////// | |
| 231 // RibbonUI namespace | |
| 232 // | |
| 233 | |
| 234 namespace RibbonUI | |
| 235 { | |
| 236 | |
| 237 // Minimal string allocation support for various PROPERTYKEY values | |
| 238 #ifdef __ATLSTR_H__ | |
| 239 typedef ATL::CString Text; | |
| 240 #else | |
| 241 class Text : public std::wstring | |
| 242 { | |
| 243 public: | |
| 244 Text(std::wstring& s) : std::wstring(s) | |
| 245 { } | |
| 246 Text(LPCWSTR s) : std::wstring(s) | |
| 247 { } | |
| 248 Text() | |
| 249 { } | |
| 250 bool IsEmpty() | |
| 251 { | |
| 252 return empty(); | |
| 253 } | |
| 254 operator LPCWSTR() | |
| 255 { | |
| 256 return c_str(); | |
| 257 } | |
| 258 Text& operator =(LPCWSTR s) | |
| 259 { | |
| 260 return static_cast<Text&>(std::wstring::operator =(s)); | |
| 261 } | |
| 262 }; | |
| 263 #endif // __ATLSTR_H__ | |
| 264 | |
| 265 // PROPERTYKEY enum and helpers | |
| 266 enum k_KEY | |
| 267 { | |
| 268 // state | |
| 269 k_Enabled = 1, k_BooleanValue = 200, | |
| 270 // text properties | |
| 271 k_LabelDescription = 2, k_Keytip = 3, k_Label = 4, k_TooltipDescription = 5, k_TooltipTitle = 6, | |
| 272 // image properties | |
| 273 k_LargeImage = 7, k_LargeHighContrastImage = 8, k_SmallImage = 9, k_SmallHighContrastImage = 10, | |
| 274 // collection properties | |
| 275 k_ItemsSource = 101, k_Categories = 102, k_SelectedItem = 104, | |
| 276 // collection item properties | |
| 277 k_CommandId = 100, k_CategoryId = 103, k_CommandType = 105, k_ItemImage = 106, | |
| 278 // combo control property | |
| 279 k_StringValue = 202, | |
| 280 // spinner control properties | |
| 281 k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces, k_FormatString, k_RepresentativeString = 208, | |
| 282 // font control properties | |
| 283 k_FontProperties = 300, k_FontProperties_Family, k_FontProperties_Size, k_FontProperties_Bold, k_FontProperties_Italic = 304, | |
| 284 k_FontProperties_Underline = 305, k_FontProperties_Strikethrough, k_FontProperties_VerticalPositioning, k_FontProperties_ForegroundColor = 308, | |
| 285 k_FontProperties_BackgroundColor = 309, k_FontProperties_ForegroundColorType, k_FontProperties_BackgroundColorType, k_FontProperties_ChangedProperties = 312, | |
| 286 k_FontProperties_DeltaSize = 313, | |
| 287 // recent items properties | |
| 288 k_RecentItems = 350, k_Pinned = 351, | |
| 289 // color control properties | |
| 290 k_Color = 400, k_ColorType = 401, k_ColorMode, | |
| 291 k_ThemeColorsCategoryLabel = 403, k_StandardColorsCategoryLabel, k_RecentColorsCategoryLabel = 405, k_AutomaticColorLabel = 406, | |
| 292 k_NoColorLabel = 407, k_MoreColorsLabel = 408, | |
| 293 k_ThemeColors = 409, k_StandardColors = 410, k_ThemeColorsTooltips = 411, k_StandardColorsTooltips = 412, | |
| 294 // Ribbon state | |
| 295 k_Viewable = 1000, k_Minimized = 1001, k_QuickAccessToolbarDock = 1002, k_ContextAvailable = 1100, | |
| 296 // Ribbon UI colors | |
| 297 k_GlobalBackgroundColor = 2000, k_GlobalHighlightColor, k_GlobalTextColor = 2002 | |
| 298 }; | |
| 299 | |
| 300 inline k_KEY k_(REFPROPERTYKEY key) | |
| 301 { | |
| 302 return (k_KEY)key.fmtid.Data1; | |
| 303 } | |
| 304 | |
| 305 // PROPERTYKEY value assignment and specializations | |
| 306 // | |
| 307 template <typename V> | |
| 308 HRESULT SetPropertyVal(REFPROPERTYKEY key, V val, PROPVARIANT* ppv) | |
| 309 { | |
| 310 switch (k_(key)) | |
| 311 { | |
| 312 case k_Enabled: | |
| 313 case k_BooleanValue: | |
| 314 return InitPropVariantFromBoolean(val, ppv); | |
| 315 default: | |
| 316 return UIInitPropertyFromUInt32(key, val, ppv); | |
| 317 } | |
| 318 } | |
| 319 | |
| 320 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DOUBLE val, PROPVARIANT* ppv) | |
| 321 { | |
| 322 return SetPropertyVal(key, (LONG)val, ppv); | |
| 323 } | |
| 324 | |
| 325 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUIImage* val, PROPVARIANT* ppv) | |
| 326 { | |
| 327 HRESULT hr = UIInitPropertyFromImage(key, val, ppv); | |
| 328 ATLVERIFY(val->Release() == 1); | |
| 329 return hr; | |
| 330 } | |
| 331 | |
| 332 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUnknown* val, PROPVARIANT* ppv) | |
| 333 { | |
| 334 return UIInitPropertyFromInterface(key, val, ppv); | |
| 335 } | |
| 336 | |
| 337 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IPropertyStore* val, PROPVARIANT* ppv) | |
| 338 { | |
| 339 return UIInitPropertyFromInterface(key, val, ppv); | |
| 340 } | |
| 341 | |
| 342 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, SAFEARRAY* val, PROPVARIANT* ppv) | |
| 343 { | |
| 344 return UIInitPropertyFromIUnknownArray(key, val, ppv); | |
| 345 } | |
| 346 | |
| 347 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DECIMAL* val, PROPVARIANT* ppv) | |
| 348 { | |
| 349 return UIInitPropertyFromDecimal(key, *val, ppv); | |
| 350 } | |
| 351 | |
| 352 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, bool val, PROPVARIANT* ppv) | |
| 353 { | |
| 354 return UIInitPropertyFromBoolean(key, val, ppv); | |
| 355 } | |
| 356 | |
| 357 inline HRESULT SetPropertyVal(REFPROPERTYKEY key, LPCWSTR val, PROPVARIANT* ppv) | |
| 358 { | |
| 359 return UIInitPropertyFromString(key, val, ppv); | |
| 360 } | |
| 361 | |
| 362 // CharFormat helper struct for RibbonUI font control | |
| 363 // | |
| 364 struct CharFormat : CHARFORMAT2 | |
| 365 { | |
| 366 // Default constructor | |
| 367 CharFormat() | |
| 368 { | |
| 369 cbSize = sizeof(CHARFORMAT2); | |
| 370 Reset(); | |
| 371 } | |
| 372 | |
| 373 // Copy constructor | |
| 374 CharFormat(const CharFormat& cf) | |
| 375 { | |
| 376 ::CopyMemory(this, &cf, sizeof(CHARFORMAT2)); | |
| 377 } | |
| 378 | |
| 379 // Assign operator | |
| 380 CharFormat& operator =(const CharFormat& cf) | |
| 381 { | |
| 382 ::CopyMemory(this, &cf, sizeof(CHARFORMAT2)); | |
| 383 return (*this); | |
| 384 } | |
| 385 | |
| 386 void Reset() | |
| 387 { | |
| 388 uValue = dwMask = dwEffects = 0; | |
| 389 PropVariantInit(&propvar); | |
| 390 } | |
| 391 | |
| 392 void operator <<(IPropertyStore* pStore) | |
| 393 { | |
| 394 if (pStore == NULL) | |
| 395 { | |
| 396 ATLASSERT(FALSE); | |
| 397 return; | |
| 398 } | |
| 399 | |
| 400 static void (CharFormat::*Getk_[])(IPropertyStore*) = | |
| 401 { | |
| 402 &CharFormat::Getk_Family, | |
| 403 &CharFormat::Getk_FontProperties_Size, | |
| 404 &CharFormat::Getk_MaskEffectBold, | |
| 405 &CharFormat::Getk_MaskEffectItalic, | |
| 406 &CharFormat::Getk_MaskEffectUnderline, | |
| 407 &CharFormat::Getk_MaskEffectStrikeout, | |
| 408 &CharFormat::Getk_VerticalPositioning, | |
| 409 &CharFormat::Getk_Color, | |
| 410 &CharFormat::Getk_ColorBack, | |
| 411 &CharFormat::Getk_ColorType, | |
| 412 &CharFormat::Getk_ColorTypeBack, | |
| 413 }; | |
| 414 | |
| 415 DWORD nProps = 0; | |
| 416 Reset(); | |
| 417 | |
| 418 ATLVERIFY(SUCCEEDED(pStore->GetCount(&nProps))); | |
| 419 for (DWORD iProp = 0; iProp < nProps; iProp++) | |
| 420 { | |
| 421 PROPERTYKEY key; | |
| 422 ATLVERIFY(SUCCEEDED(pStore->GetAt(iProp, &key))); | |
| 423 ATLASSERT(k_(key) >= k_FontProperties_Family); | |
| 424 | |
| 425 if (k_(key) <= k_FontProperties_BackgroundColorType) | |
| 426 (this->*Getk_[k_(key) - k_FontProperties_Family])(pStore); | |
| 427 } | |
| 428 } | |
| 429 | |
| 430 void operator >>(IPropertyStore* pStore) | |
| 431 { | |
| 432 if (pStore == NULL) | |
| 433 { | |
| 434 ATLASSERT(FALSE); | |
| 435 return; | |
| 436 } | |
| 437 | |
| 438 PutFace(pStore); | |
| 439 PutSize(pStore); | |
| 440 PutMaskEffect(CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold, pStore); | |
| 441 PutMaskEffect(CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic, pStore); | |
| 442 PutMaskEffect(CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline, pStore); | |
| 443 PutMaskEffect(CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough, pStore); | |
| 444 PutVerticalPos(pStore); | |
| 445 PutColor(pStore); | |
| 446 PutBackColor(pStore); | |
| 447 } | |
| 448 | |
| 449 private: | |
| 450 PROPVARIANT propvar; | |
| 451 UINT uValue; | |
| 452 | |
| 453 // Getk_ functions | |
| 454 void Getk_Family(IPropertyStore* pStore) | |
| 455 { | |
| 456 if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Family, &propvar))) | |
| 457 { | |
| 458 PropVariantToString(propvar, szFaceName, LF_FACESIZE); | |
| 459 if (*szFaceName) | |
| 460 dwMask |= CFM_FACE; | |
| 461 } | |
| 462 } | |
| 463 | |
| 464 void Getk_FontProperties_Size(IPropertyStore* pStore) | |
| 465 { | |
| 466 if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Size, &propvar))) | |
| 467 { | |
| 468 DECIMAL decSize = {}; | |
| 469 UIPropertyToDecimal(UI_PKEY_FontProperties_Size, propvar, &decSize); | |
| 470 DOUBLE dSize = 0; | |
| 471 VarR8FromDec(&decSize, &dSize); | |
| 472 if (dSize > 0) | |
| 473 { | |
| 474 dwMask |= CFM_SIZE; | |
| 475 yHeight = (LONG)(dSize * TWIPS_PER_POINT); | |
| 476 } | |
| 477 } | |
| 478 } | |
| 479 | |
| 480 void Getk_MaskEffectBold(IPropertyStore* pStore) | |
| 481 { | |
| 482 Getk_MaskEffectAll(pStore, CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold); | |
| 483 } | |
| 484 | |
| 485 void Getk_MaskEffectItalic(IPropertyStore* pStore) | |
| 486 { | |
| 487 Getk_MaskEffectAll(pStore, CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic); | |
| 488 } | |
| 489 | |
| 490 void Getk_MaskEffectUnderline(IPropertyStore* pStore) | |
| 491 { | |
| 492 Getk_MaskEffectAll(pStore, CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline); | |
| 493 } | |
| 494 | |
| 495 void Getk_MaskEffectStrikeout(IPropertyStore* pStore) | |
| 496 { | |
| 497 Getk_MaskEffectAll(pStore, CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough); | |
| 498 } | |
| 499 | |
| 500 void Getk_MaskEffectAll(IPropertyStore* pStore, DWORD _dwMask, DWORD _dwEffects, REFPROPERTYKEY key) | |
| 501 { | |
| 502 if (SUCCEEDED(pStore->GetValue(key, &propvar))) | |
| 503 { | |
| 504 UIPropertyToUInt32(key, propvar, &uValue); | |
| 505 if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE) | |
| 506 { | |
| 507 dwMask |= _dwMask; | |
| 508 dwEffects |= ((UI_FONTPROPERTIES)uValue == UI_FONTPROPERTIES_SET) ? _dwEffects : 0; | |
| 509 } | |
| 510 } | |
| 511 } | |
| 512 | |
| 513 void Getk_VerticalPositioning(IPropertyStore* pStore) | |
| 514 { | |
| 515 if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_VerticalPositioning, &propvar))) | |
| 516 { | |
| 517 UIPropertyToUInt32(UI_PKEY_FontProperties_VerticalPositioning, propvar, &uValue); | |
| 518 UI_FONTVERTICALPOSITION uVerticalPosition = (UI_FONTVERTICALPOSITION) uValue; | |
| 519 if ((uVerticalPosition != UI_FONTVERTICALPOSITION_NOTAVAILABLE)) | |
| 520 { | |
| 521 dwMask |= (CFM_SUPERSCRIPT | CFM_SUBSCRIPT); | |
| 522 if (uVerticalPosition != UI_FONTVERTICALPOSITION_NOTSET) | |
| 523 { | |
| 524 dwEffects |= (uVerticalPosition == UI_FONTVERTICALPOSITION_SUPERSCRIPT) ? CFE_SUPERSCRIPT : CFE_SUBSCRIPT; | |
| 525 } | |
| 526 } | |
| 527 } | |
| 528 } | |
| 529 | |
| 530 void Getk_Color(IPropertyStore* pStore) | |
| 531 { | |
| 532 Getk_ColorAll(pStore, CFM_COLOR, UI_PKEY_FontProperties_ForegroundColor); | |
| 533 } | |
| 534 | |
| 535 void Getk_ColorBack(IPropertyStore* pStore) | |
| 536 { | |
| 537 Getk_ColorAll(pStore, CFM_BACKCOLOR, UI_PKEY_FontProperties_BackgroundColor); | |
| 538 } | |
| 539 | |
| 540 void Getk_ColorAll(IPropertyStore* pStore, DWORD _dwMask, REFPROPERTYKEY key) | |
| 541 { | |
| 542 UINT32 color = 0; | |
| 543 if (SUCCEEDED(pStore->GetValue(key, &propvar))) | |
| 544 { | |
| 545 UIPropertyToUInt32(key, propvar, &color); | |
| 546 dwMask |= _dwMask; | |
| 547 | |
| 548 if (_dwMask == CFM_COLOR) | |
| 549 crTextColor = color; | |
| 550 else | |
| 551 crBackColor = color; | |
| 552 } | |
| 553 } | |
| 554 | |
| 555 void Getk_ColorType(IPropertyStore* pStore) | |
| 556 { | |
| 557 Getk_ColorTypeAll(pStore, CFM_COLOR, CFE_AUTOCOLOR, UI_SWATCHCOLORTYPE_AUTOMATIC, UI_PKEY_FontProperties_ForegroundColor); | |
| 558 | |
| 559 } | |
| 560 | |
| 561 void Getk_ColorTypeBack(IPropertyStore* pStore) | |
| 562 { | |
| 563 Getk_ColorTypeAll(pStore, CFM_BACKCOLOR, CFE_AUTOBACKCOLOR, UI_SWATCHCOLORTYPE_NOCOLOR, UI_PKEY_FontProperties_BackgroundColor); | |
| 564 } | |
| 565 | |
| 566 void Getk_ColorTypeAll(IPropertyStore* pStore, DWORD _dwMask, DWORD _dwEffects, UI_SWATCHCOLORTYPE _type, REFPROPERTYKEY key) | |
| 567 { | |
| 568 if (SUCCEEDED(pStore->GetValue(key, &propvar))) | |
| 569 { | |
| 570 UIPropertyToUInt32(key, propvar, &uValue); | |
| 571 if (_type == (UI_SWATCHCOLORTYPE)uValue) | |
| 572 { | |
| 573 dwMask |= _dwMask; | |
| 574 dwEffects |= _dwEffects; | |
| 575 } | |
| 576 } | |
| 577 } | |
| 578 | |
| 579 // Put functions | |
| 580 void PutMaskEffect(WORD dwMaskVal, WORD dwEffectVal, REFPROPERTYKEY key, IPropertyStore* pStore) | |
| 581 { | |
| 582 PROPVARIANT var; | |
| 583 UI_FONTPROPERTIES uProp = UI_FONTPROPERTIES_NOTAVAILABLE; | |
| 584 if ((dwMask & dwMaskVal) != 0) | |
| 585 uProp = dwEffects & dwEffectVal ? UI_FONTPROPERTIES_SET : UI_FONTPROPERTIES_NOTSET; | |
| 586 SetPropertyVal(key, uProp, &var); | |
| 587 pStore->SetValue(key, var); | |
| 588 } | |
| 589 | |
| 590 void PutVerticalPos(IPropertyStore* pStore) | |
| 591 { | |
| 592 PROPVARIANT var; | |
| 593 UI_FONTVERTICALPOSITION uProp = UI_FONTVERTICALPOSITION_NOTAVAILABLE; | |
| 594 | |
| 595 if ((dwMask & CFE_SUBSCRIPT) != 0) | |
| 596 { | |
| 597 if ((dwMask & CFM_SUBSCRIPT) && (dwEffects & CFE_SUBSCRIPT)) | |
| 598 uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT; | |
| 599 else | |
| 600 uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT; | |
| 601 } | |
| 602 else if ((dwMask & CFM_OFFSET) != 0) | |
| 603 { | |
| 604 if (yOffset > 0) | |
| 605 uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT; | |
| 606 else if (yOffset < 0) | |
| 607 uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT; | |
| 608 } | |
| 609 | |
| 610 SetPropertyVal(UI_PKEY_FontProperties_VerticalPositioning, uProp, &var); | |
| 611 pStore->SetValue(UI_PKEY_FontProperties_VerticalPositioning, var); | |
| 612 } | |
| 613 | |
| 614 void PutFace(IPropertyStore* pStore) | |
| 615 { | |
| 616 PROPVARIANT var; | |
| 617 SetPropertyVal(UI_PKEY_FontProperties_Family, | |
| 618 dwMask & CFM_FACE ? szFaceName : L"", &var); | |
| 619 pStore->SetValue(UI_PKEY_FontProperties_Family, var); | |
| 620 } | |
| 621 | |
| 622 void PutSize(IPropertyStore* pStore) | |
| 623 { | |
| 624 PROPVARIANT var; | |
| 625 DECIMAL decVal; | |
| 626 | |
| 627 if ((dwMask & CFM_SIZE) != 0) | |
| 628 VarDecFromR8((DOUBLE)yHeight / TWIPS_PER_POINT, &decVal); | |
| 629 else | |
| 630 VarDecFromI4(0, &decVal); | |
| 631 | |
| 632 SetPropertyVal(UI_PKEY_FontProperties_Size, &decVal, &var); | |
| 633 pStore->SetValue(UI_PKEY_FontProperties_Size, var); | |
| 634 } | |
| 635 | |
| 636 void PutColor(IPropertyStore* pStore) | |
| 637 { | |
| 638 if ((dwMask & CFM_COLOR) != 0) | |
| 639 { | |
| 640 if ((dwEffects & CFE_AUTOCOLOR) == 0) | |
| 641 { | |
| 642 SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar); | |
| 643 pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar); | |
| 644 | |
| 645 SetPropertyVal(UI_PKEY_FontProperties_ForegroundColor, crTextColor, &propvar); | |
| 646 pStore->SetValue(UI_PKEY_FontProperties_ForegroundColor, propvar); | |
| 647 } | |
| 648 else | |
| 649 { | |
| 650 SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_AUTOMATIC, &propvar); | |
| 651 pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar); | |
| 652 } | |
| 653 } | |
| 654 } | |
| 655 | |
| 656 void PutBackColor(IPropertyStore* pStore) | |
| 657 { | |
| 658 if (((dwMask & CFM_BACKCOLOR) != 0) && ((dwEffects & CFE_AUTOBACKCOLOR) == 0)) | |
| 659 { | |
| 660 SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar); | |
| 661 pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar); | |
| 662 | |
| 663 SetPropertyVal(UI_PKEY_FontProperties_BackgroundColor, crBackColor, &propvar); | |
| 664 pStore->SetValue(UI_PKEY_FontProperties_BackgroundColor, propvar); | |
| 665 } | |
| 666 else | |
| 667 { | |
| 668 SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_NOCOLOR, &propvar); | |
| 669 pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar); | |
| 670 } | |
| 671 } | |
| 672 }; | |
| 673 | |
| 674 // IUIImage helper | |
| 675 // | |
| 676 inline IUIImage* GetImage(HBITMAP hbm, UI_OWNERSHIP owner) | |
| 677 { | |
| 678 ATLASSERT(hbm); | |
| 679 IUIImage* pIUII = NULL; | |
| 680 ATL::CComPtr<IUIImageFromBitmap> pIFB; | |
| 681 | |
| 682 if SUCCEEDED(pIFB.CoCreateInstance(CLSID_UIRibbonImageFromBitmapFactory)) | |
| 683 ATLVERIFY(SUCCEEDED(pIFB->CreateImage(hbm, owner, &pIUII))); | |
| 684 | |
| 685 return pIUII; | |
| 686 } | |
| 687 | |
| 688 | |
| 689 /////////////////////////////////////////////////////////////////////////////// | |
| 690 // Ribbon control classes | |
| 691 | |
| 692 // RibbonUI::ICtrl abstract interface of RibbonUI::CRibbonImpl and all RibbonUI control classes | |
| 693 // | |
| 694 struct ICtrl | |
| 695 { | |
| 696 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 697 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 698 IUISimplePropertySet* pCommandExecutionProperties) = 0; | |
| 699 | |
| 700 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 701 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) = 0; | |
| 702 }; | |
| 703 | |
| 704 // RibbonUI::CtrlImpl base class for all ribbon controls | |
| 705 // | |
| 706 template <class T, UINT t_ID> | |
| 707 class ATL_NO_VTABLE CtrlImpl : public ICtrl | |
| 708 { | |
| 709 protected: | |
| 710 T* m_pWndRibbon; | |
| 711 | |
| 712 public: | |
| 713 typedef T WndRibbon; | |
| 714 | |
| 715 CtrlImpl() : m_pWndRibbon(T::pWndRibbon) | |
| 716 { } | |
| 717 | |
| 718 virtual ~CtrlImpl() | |
| 719 { } | |
| 720 | |
| 721 WndRibbon& GetWndRibbon() | |
| 722 { | |
| 723 return *m_pWndRibbon; | |
| 724 } | |
| 725 | |
| 726 static WORD GetID() | |
| 727 { | |
| 728 return t_ID; | |
| 729 } | |
| 730 | |
| 731 Text m_sTxt[5]; | |
| 732 | |
| 733 // Operations | |
| 734 HRESULT Invalidate() | |
| 735 { | |
| 736 return GetWndRibbon().InvalidateCtrl(GetID()); | |
| 737 } | |
| 738 | |
| 739 HRESULT Invalidate(REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY) | |
| 740 { | |
| 741 return GetWndRibbon().InvalidateProperty(GetID(), key, flags); | |
| 742 } | |
| 743 | |
| 744 HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sTxt, bool bUpdate = false) | |
| 745 { | |
| 746 ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription)); | |
| 747 | |
| 748 m_sTxt[k_(key) - k_LabelDescription] = sTxt; | |
| 749 | |
| 750 return bUpdate ? | |
| 751 GetWndRibbon().InvalidateProperty(GetID(), key) : | |
| 752 S_OK; | |
| 753 } | |
| 754 | |
| 755 // Implementation | |
| 756 template <typename V> | |
| 757 HRESULT SetProperty(REFPROPERTYKEY key, V val) | |
| 758 { | |
| 759 return GetWndRibbon().SetProperty(GetID(), key, val); | |
| 760 } | |
| 761 | |
| 762 HRESULT OnGetText(REFPROPERTYKEY key, PROPVARIANT* ppv) | |
| 763 { | |
| 764 ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription)); | |
| 765 | |
| 766 const INT iText = k_(key) - k_LabelDescription; | |
| 767 if (m_sTxt[iText].IsEmpty()) | |
| 768 if (LPCWSTR sText = GetWndRibbon().OnRibbonQueryText(GetID(), key)) | |
| 769 m_sTxt[iText] = sText; | |
| 770 | |
| 771 return !m_sTxt[iText].IsEmpty() ? | |
| 772 SetPropertyVal(key, (LPCWSTR)m_sTxt[iText], ppv) : | |
| 773 S_OK; | |
| 774 } | |
| 775 | |
| 776 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 777 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 778 IUISimplePropertySet* pCommandExecutionProperties) | |
| 779 { | |
| 780 ATLASSERT(nCmdID == t_ID); | |
| 781 return GetWndRibbon().DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties); | |
| 782 } | |
| 783 | |
| 784 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 785 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 786 { | |
| 787 ATLASSERT(nCmdID == t_ID); | |
| 788 | |
| 789 const INT iMax = k_TooltipTitle - k_LabelDescription; | |
| 790 const INT iVal = k_(key) - k_LabelDescription; | |
| 791 | |
| 792 return (iVal <= iMax) && (iVal >= 0) ? | |
| 793 OnGetText(key, ppropvarNewValue) : | |
| 794 GetWndRibbon().DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 795 } | |
| 796 }; | |
| 797 | |
| 798 // CommandCtrlImpl base class for most ribbon controls | |
| 799 // | |
| 800 template <class T, UINT t_ID> | |
| 801 class CommandCtrlImpl : public CtrlImpl<T, t_ID> | |
| 802 { | |
| 803 public: | |
| 804 CBitmap m_hbm[4]; | |
| 805 | |
| 806 HRESULT SetImage(REFPROPERTYKEY key, HBITMAP hbm, bool bUpdate = false) | |
| 807 { | |
| 808 ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage)); | |
| 809 | |
| 810 m_hbm[k_(key) - k_LargeImage].Attach(hbm); | |
| 811 | |
| 812 return bUpdate ? | |
| 813 this->GetWndRibbon().InvalidateProperty(this->GetID(), key) : | |
| 814 S_OK; | |
| 815 } | |
| 816 | |
| 817 HRESULT OnGetImage(REFPROPERTYKEY key, PROPVARIANT* ppv) | |
| 818 { | |
| 819 ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage)); | |
| 820 | |
| 821 const INT iImage = k_(key) - k_LargeImage; | |
| 822 | |
| 823 if (m_hbm[iImage].IsNull()) | |
| 824 m_hbm[iImage] = this->GetWndRibbon().OnRibbonQueryImage(this->GetID(), key); | |
| 825 | |
| 826 return m_hbm[iImage].IsNull() ? | |
| 827 E_NOTIMPL : | |
| 828 SetPropertyVal(key, GetImage(m_hbm[iImage], UI_OWNERSHIP_COPY), ppv); | |
| 829 } | |
| 830 | |
| 831 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 832 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 833 { | |
| 834 ATLASSERT (nCmdID == this->GetID()); | |
| 835 | |
| 836 return (k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage) ? | |
| 837 OnGetImage(key, ppropvarNewValue) : | |
| 838 CtrlImpl<T, t_ID>::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 839 } | |
| 840 }; | |
| 841 | |
| 842 | |
| 843 /////////////////////////////////////////////////////////////////////////////// | |
| 844 // Ribbon collection base classes | |
| 845 | |
| 846 // ItemProperty class: ribbon callback for each item in a collection | |
| 847 // | |
| 848 | |
| 849 #pragma warning(push) | |
| 850 #pragma warning(disable: 4512) // assignment operator could not be generated | |
| 851 | |
| 852 template <class TCollection> | |
| 853 class ItemProperty : public IUISimplePropertySet | |
| 854 { | |
| 855 public: | |
| 856 ItemProperty(UINT i, TCollection* pCollection) : m_Index(i), m_pCollection(pCollection) | |
| 857 { } | |
| 858 | |
| 859 const UINT m_Index; | |
| 860 TCollection* m_pCollection; | |
| 861 | |
| 862 // IUISimplePropertySet method. | |
| 863 STDMETHODIMP GetValue(REFPROPERTYKEY key, PROPVARIANT *value) | |
| 864 { | |
| 865 return m_pCollection->OnGetItem(m_Index, key, value); | |
| 866 } | |
| 867 | |
| 868 // IUnknown methods. | |
| 869 STDMETHODIMP_(ULONG) AddRef() | |
| 870 { | |
| 871 return 1; | |
| 872 } | |
| 873 | |
| 874 STDMETHODIMP_(ULONG) Release() | |
| 875 { | |
| 876 return 1; | |
| 877 } | |
| 878 | |
| 879 STDMETHODIMP QueryInterface(REFIID iid, void** ppv) | |
| 880 { | |
| 881 if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(IUISimplePropertySet))) | |
| 882 { | |
| 883 *ppv = this; | |
| 884 return S_OK; | |
| 885 } | |
| 886 else | |
| 887 { | |
| 888 return E_NOINTERFACE; | |
| 889 } | |
| 890 } | |
| 891 }; | |
| 892 | |
| 893 #pragma warning(pop) | |
| 894 | |
| 895 | |
| 896 // CollectionImplBase: base class for all RibbonUI collections | |
| 897 // | |
| 898 template <class TCollection, size_t t_size> | |
| 899 class CollectionImplBase | |
| 900 { | |
| 901 typedef CollectionImplBase<TCollection, t_size> thisClass; | |
| 902 | |
| 903 public: | |
| 904 CollectionImplBase() | |
| 905 { | |
| 906 for (int i = 0; i < t_size; i++) | |
| 907 m_apItems[i] = new ItemProperty<TCollection>(i, static_cast<TCollection*>(this)); | |
| 908 } | |
| 909 | |
| 910 ~CollectionImplBase() | |
| 911 { | |
| 912 for (int i = 0; i < t_size; i++) | |
| 913 delete m_apItems[i]; | |
| 914 } | |
| 915 | |
| 916 // Data members | |
| 917 ItemProperty<TCollection>* m_apItems[t_size]; | |
| 918 }; | |
| 919 | |
| 920 // CollectionImpl: handles categories and collecton resizing | |
| 921 // | |
| 922 template <class TCtrl, size_t t_items, size_t t_categories> | |
| 923 class CollectionImpl : public CollectionImplBase<CollectionImpl<TCtrl, t_items, t_categories>, t_items + t_categories> | |
| 924 { | |
| 925 typedef CollectionImpl<TCtrl, t_items, t_categories> thisClass; | |
| 926 public: | |
| 927 typedef thisClass Collection; | |
| 928 | |
| 929 CollectionImpl() : m_size(t_items) | |
| 930 { | |
| 931 ::FillMemory(m_auItemCat, sizeof(m_auItemCat), 0xff); // UI_COLLECTION_INVALIDINDEX | |
| 932 } | |
| 933 | |
| 934 UINT32 m_auItemCat[t_items]; | |
| 935 Text m_asCatName[__max(t_categories, 1)]; | |
| 936 size_t m_size; | |
| 937 | |
| 938 // Operations | |
| 939 HRESULT SetItemCategory(UINT uItem, UINT uCat, bool bUpdate = false) | |
| 940 { | |
| 941 ATLASSERT((uItem < t_items) && (uCat < t_categories)); | |
| 942 | |
| 943 m_auItemCat[uItem] = uCat; | |
| 944 | |
| 945 return bUpdate ? InvalidateItems() : S_OK; | |
| 946 } | |
| 947 | |
| 948 HRESULT SetCategoryText(UINT uCat, LPCWSTR sText, bool bUpdate = false) | |
| 949 { | |
| 950 ATLASSERT(uCat < t_categories); | |
| 951 | |
| 952 m_asCatName[uCat] = sText; | |
| 953 | |
| 954 return bUpdate ? InvalidateCategories() : S_OK; | |
| 955 } | |
| 956 | |
| 957 HRESULT Resize(size_t size, bool bUpdate = false) | |
| 958 { | |
| 959 ATLASSERT(size <= t_items); | |
| 960 | |
| 961 m_size = size; | |
| 962 | |
| 963 return bUpdate ? InvalidateItems() : S_OK; | |
| 964 } | |
| 965 | |
| 966 // Implementation | |
| 967 HRESULT OnGetItem(UINT uIndex, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 968 { | |
| 969 ATLASSERT(uIndex < t_items + t_categories); | |
| 970 TCtrl* pCtrl = static_cast<TCtrl*>(this); | |
| 971 | |
| 972 return uIndex < t_items ? | |
| 973 pCtrl->DoGetItem(uIndex, key, value) : | |
| 974 pCtrl->DoGetCategory(uIndex - t_items, key, value); | |
| 975 } | |
| 976 | |
| 977 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 978 { | |
| 979 ATLASSERT(k_(key) == k_CategoryId); | |
| 980 UINT32 uCat = UI_COLLECTION_INVALIDINDEX; | |
| 981 | |
| 982 if (t_categories != 0) | |
| 983 { | |
| 984 if (m_auItemCat[uItem] == UI_COLLECTION_INVALIDINDEX) | |
| 985 { | |
| 986 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 987 m_auItemCat[uItem] = ribbon.OnRibbonQueryItemCategory(TCtrl::GetID(), uItem); | |
| 988 } | |
| 989 uCat = m_auItemCat[uItem]; | |
| 990 } | |
| 991 | |
| 992 return SetPropertyVal(key, uCat, value); | |
| 993 } | |
| 994 | |
| 995 HRESULT DoGetCategory(UINT uCat, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 996 { | |
| 997 HRESULT hr = S_OK; | |
| 998 | |
| 999 switch (k_(key)) | |
| 1000 { | |
| 1001 case k_Label: | |
| 1002 if (m_asCatName[uCat].IsEmpty()) | |
| 1003 { | |
| 1004 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1005 m_asCatName[uCat] = ribbon.OnRibbonQueryCategoryText(TCtrl::GetID(), uCat); | |
| 1006 } | |
| 1007 hr = SetPropertyVal(key, (LPCWSTR)m_asCatName[uCat], value); | |
| 1008 break; | |
| 1009 case k_CategoryId: | |
| 1010 hr = SetPropertyVal(key, uCat, value); | |
| 1011 break; | |
| 1012 default: | |
| 1013 ATLASSERT(FALSE); | |
| 1014 break; | |
| 1015 } | |
| 1016 | |
| 1017 return hr; | |
| 1018 } | |
| 1019 | |
| 1020 HRESULT InvalidateItems() | |
| 1021 { | |
| 1022 return static_cast<TCtrl*>(this)->Invalidate(UI_PKEY_ItemsSource); | |
| 1023 } | |
| 1024 | |
| 1025 HRESULT InvalidateCategories() | |
| 1026 { | |
| 1027 return static_cast<TCtrl*>(this)->Invalidate(UI_PKEY_Categories); | |
| 1028 } | |
| 1029 | |
| 1030 HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1031 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* /*ppropvarNewValue*/) | |
| 1032 { | |
| 1033 ATLASSERT(nCmdID == TCtrl::GetID()); | |
| 1034 (void)nCmdID; // avoid level 4 warning | |
| 1035 | |
| 1036 HRESULT hr = E_NOTIMPL; | |
| 1037 switch (k_(key)) | |
| 1038 { | |
| 1039 case k_ItemsSource: | |
| 1040 { | |
| 1041 ATL::CComQIPtr<IUICollection> pIUICollection(ppropvarCurrentValue->punkVal); | |
| 1042 ATLASSERT(pIUICollection); | |
| 1043 hr = pIUICollection->Clear(); | |
| 1044 for (UINT i = 0; i < m_size; i++) | |
| 1045 { | |
| 1046 if FAILED(hr = pIUICollection->Add(this->m_apItems[i])) | |
| 1047 break; | |
| 1048 } | |
| 1049 ATLASSERT(SUCCEEDED(hr)); | |
| 1050 } | |
| 1051 break; | |
| 1052 case k_Categories: | |
| 1053 if (t_categories != 0) | |
| 1054 { | |
| 1055 ATL::CComQIPtr<IUICollection> pIUICategory(ppropvarCurrentValue->punkVal); | |
| 1056 ATLASSERT(pIUICategory.p); | |
| 1057 hr = pIUICategory->Clear(); | |
| 1058 for (UINT i = t_items; i < (t_items + t_categories); i++) | |
| 1059 { | |
| 1060 if FAILED(hr = pIUICategory->Add(this->m_apItems[i])) | |
| 1061 break; | |
| 1062 } | |
| 1063 ATLASSERT(SUCCEEDED(hr)); | |
| 1064 } | |
| 1065 break; | |
| 1066 } | |
| 1067 | |
| 1068 return hr; | |
| 1069 } | |
| 1070 }; | |
| 1071 | |
| 1072 // TextCollectionImpl: handles item labels and selection | |
| 1073 // | |
| 1074 template <class TCtrl, size_t t_items, size_t t_categories = 0> | |
| 1075 class TextCollectionImpl : public CollectionImpl<TCtrl, t_items, t_categories> | |
| 1076 { | |
| 1077 typedef TextCollectionImpl<TCtrl, t_items, t_categories> thisClass; | |
| 1078 public: | |
| 1079 typedef thisClass TextCollection; | |
| 1080 | |
| 1081 TextCollectionImpl() : m_uSelected(UI_COLLECTION_INVALIDINDEX) | |
| 1082 { } | |
| 1083 | |
| 1084 Text m_asText[t_items]; | |
| 1085 UINT m_uSelected; | |
| 1086 | |
| 1087 // Operations | |
| 1088 HRESULT SetItemText(UINT uItem, LPCWSTR sText, bool bUpdate = false) | |
| 1089 { | |
| 1090 ATLASSERT(uItem < t_items); | |
| 1091 | |
| 1092 m_asText[uItem] = sText; | |
| 1093 | |
| 1094 return bUpdate ? this->InvalidateItems() : S_OK; | |
| 1095 } | |
| 1096 | |
| 1097 UINT GetSelected() | |
| 1098 { | |
| 1099 return m_uSelected; | |
| 1100 } | |
| 1101 | |
| 1102 HRESULT Select(UINT uItem, bool bUpdate = false) | |
| 1103 { | |
| 1104 ATLASSERT((uItem < t_items) || (uItem == UI_COLLECTION_INVALIDINDEX)); | |
| 1105 | |
| 1106 m_uSelected = uItem; | |
| 1107 | |
| 1108 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1109 return bUpdate ? | |
| 1110 ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_SelectedItem, uItem) : | |
| 1111 S_OK; | |
| 1112 } | |
| 1113 | |
| 1114 // Implementation | |
| 1115 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 1116 { | |
| 1117 ATLASSERT(uItem < t_items); | |
| 1118 | |
| 1119 if (k_(key) == k_Label) | |
| 1120 { | |
| 1121 if (m_asText[uItem].IsEmpty()) | |
| 1122 { | |
| 1123 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1124 m_asText[uItem] = ribbon.OnRibbonQueryItemText(TCtrl::GetID(), uItem); | |
| 1125 } | |
| 1126 return SetPropertyVal(key, (LPCWSTR)m_asText[uItem], value); | |
| 1127 } | |
| 1128 else | |
| 1129 { | |
| 1130 return CollectionImpl<TCtrl, t_items, t_categories>::Collection::DoGetItem(uItem, key, value); | |
| 1131 } | |
| 1132 } | |
| 1133 | |
| 1134 HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1135 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 1136 { | |
| 1137 ATLASSERT(nCmdID == TCtrl::GetID()); | |
| 1138 | |
| 1139 if (k_(key) == k_SelectedItem) | |
| 1140 { | |
| 1141 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1142 UINT uSel = UI_COLLECTION_INVALIDINDEX; | |
| 1143 if ((m_uSelected == UI_COLLECTION_INVALIDINDEX) && | |
| 1144 ribbon.OnRibbonQuerySelectedItem(TCtrl::GetID(), uSel)) | |
| 1145 m_uSelected = uSel; | |
| 1146 | |
| 1147 return SetPropertyVal(key, m_uSelected, ppropvarNewValue); | |
| 1148 } | |
| 1149 else | |
| 1150 { | |
| 1151 return CollectionImpl<TCtrl, t_items, t_categories>::Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1152 } | |
| 1153 } | |
| 1154 }; | |
| 1155 | |
| 1156 // ItemCollectionImpl: handles item image | |
| 1157 // | |
| 1158 template <class TCtrl, size_t t_items, size_t t_categories = 0> | |
| 1159 class ItemCollectionImpl : public TextCollectionImpl<TCtrl, t_items, t_categories> | |
| 1160 { | |
| 1161 typedef ItemCollectionImpl<TCtrl, t_items, t_categories> thisClass; | |
| 1162 public: | |
| 1163 typedef thisClass ItemCollection; | |
| 1164 | |
| 1165 ItemCollectionImpl() | |
| 1166 { | |
| 1167 ::ZeroMemory(m_aBitmap, sizeof(m_aBitmap)); | |
| 1168 } | |
| 1169 | |
| 1170 CBitmap m_aBitmap[t_items]; | |
| 1171 | |
| 1172 // Operations | |
| 1173 HRESULT SetItemImage(UINT uIndex, HBITMAP hbm, bool bUpdate = false) | |
| 1174 { | |
| 1175 ATLASSERT(uIndex < t_items); | |
| 1176 | |
| 1177 m_aBitmap[uIndex] = hbm; | |
| 1178 | |
| 1179 return bUpdate ? this->InvalidateItems() : S_OK; | |
| 1180 } | |
| 1181 | |
| 1182 // Implementation | |
| 1183 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 1184 { | |
| 1185 ATLASSERT(uItem < t_items); | |
| 1186 | |
| 1187 if (k_(key) == k_ItemImage) | |
| 1188 { | |
| 1189 if (m_aBitmap[uItem].IsNull()) | |
| 1190 { | |
| 1191 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1192 m_aBitmap[uItem] = ribbon.OnRibbonQueryItemImage(TCtrl::GetID(), uItem); | |
| 1193 } | |
| 1194 return m_aBitmap[uItem].IsNull() ? | |
| 1195 E_NOTIMPL : | |
| 1196 SetPropertyVal(key, GetImage(m_aBitmap[uItem], UI_OWNERSHIP_COPY), value); | |
| 1197 } | |
| 1198 else | |
| 1199 { | |
| 1200 return TextCollectionImpl<TCtrl, t_items, t_categories>::TextCollection::DoGetItem(uItem, key, value); | |
| 1201 } | |
| 1202 } | |
| 1203 }; | |
| 1204 | |
| 1205 // ComboCollectionImpl: handles combo text | |
| 1206 // | |
| 1207 template <class TCtrl, size_t t_items, size_t t_categories = 0> | |
| 1208 class ComboCollectionImpl : public ItemCollectionImpl<TCtrl, t_items, t_categories> | |
| 1209 { | |
| 1210 typedef ComboCollectionImpl<TCtrl, t_items, t_categories> thisClass; | |
| 1211 public: | |
| 1212 typedef thisClass ComboCollection; | |
| 1213 | |
| 1214 // Operations | |
| 1215 HRESULT SetComboText(LPCWSTR sText) | |
| 1216 { | |
| 1217 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1218 return ribbon.IsRibbonUI() ? | |
| 1219 ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_StringValue, sText) : | |
| 1220 S_OK; | |
| 1221 } | |
| 1222 | |
| 1223 LPCWSTR GetComboText() | |
| 1224 { | |
| 1225 static WCHAR sCombo[RIBBONUI_MAX_TEXT] = {}; | |
| 1226 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1227 PROPVARIANT var; | |
| 1228 if (ribbon.IsRibbonUI()) | |
| 1229 { | |
| 1230 HRESULT hr = ribbon.GetIUIFrameworkPtr()->GetUICommandProperty(TCtrl::GetID(), UI_PKEY_StringValue, &var); | |
| 1231 hr = PropVariantToString(var, sCombo, RIBBONUI_MAX_TEXT); | |
| 1232 return sCombo; | |
| 1233 } | |
| 1234 return NULL; | |
| 1235 } | |
| 1236 }; | |
| 1237 | |
| 1238 // CommandCollectionImpl: handles RibbonUI command collection controls | |
| 1239 // | |
| 1240 template <class TCtrl, size_t t_items, size_t t_categories = 0> | |
| 1241 class CommandCollectionImpl : public CollectionImpl<TCtrl, t_items, t_categories> | |
| 1242 { | |
| 1243 typedef CommandCollectionImpl<TCtrl, t_items, t_categories> thisClass; | |
| 1244 public: | |
| 1245 typedef thisClass CommandCollection; | |
| 1246 | |
| 1247 CommandCollectionImpl() | |
| 1248 { | |
| 1249 ::ZeroMemory(m_auCmd, sizeof(m_auCmd)); | |
| 1250 ::ZeroMemory(m_aCmdType, sizeof(m_aCmdType)); | |
| 1251 } | |
| 1252 | |
| 1253 UINT32 m_auCmd[t_items]; | |
| 1254 BYTE m_aCmdType[t_items]; | |
| 1255 | |
| 1256 // Operations | |
| 1257 HRESULT SetItemCommand(UINT uItem, UINT32 uCommandID, bool bUpdate = false) | |
| 1258 { | |
| 1259 ATLASSERT(uItem < t_items); | |
| 1260 | |
| 1261 if (uCommandID == m_auCmd[uItem]) | |
| 1262 return S_OK; | |
| 1263 | |
| 1264 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1265 | |
| 1266 m_auCmd[uItem] = uCommandID; | |
| 1267 if (uCommandID != 0) | |
| 1268 ribbon.UIAddRibbonElement(uCommandID); | |
| 1269 | |
| 1270 return bUpdate ? this->InvalidateItems() : S_OK; | |
| 1271 } | |
| 1272 | |
| 1273 HRESULT SetItemCommandType(UINT uItem, UI_COMMANDTYPE type, bool bUpdate = false) | |
| 1274 { | |
| 1275 ATLASSERT(uItem < t_items); | |
| 1276 | |
| 1277 m_aCmdType[uItem] = (BYTE)type; | |
| 1278 | |
| 1279 return bUpdate ? this->InvalidateItems() : S_OK; | |
| 1280 } | |
| 1281 | |
| 1282 // Implementation | |
| 1283 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 1284 { | |
| 1285 ATLASSERT(uItem < t_items); | |
| 1286 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1287 | |
| 1288 HRESULT hr = E_FAIL; | |
| 1289 switch (k_(key)) | |
| 1290 { | |
| 1291 case k_CommandId: | |
| 1292 if (m_auCmd[uItem] == 0) | |
| 1293 SetItemCommand(uItem, ribbon.OnRibbonQueryItemCommand(TCtrl::GetID(), uItem)); | |
| 1294 hr = SetPropertyVal(key, m_auCmd[uItem], value); | |
| 1295 break; | |
| 1296 case k_CommandType: | |
| 1297 if (m_aCmdType[uItem] == UI_COMMANDTYPE_UNKNOWN) | |
| 1298 SetItemCommandType(uItem, ribbon.OnRibbonQueryItemCommandType(TCtrl::GetID(), uItem)); | |
| 1299 hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value); | |
| 1300 break; | |
| 1301 case k_CategoryId: | |
| 1302 default: | |
| 1303 hr = CollectionImpl<TCtrl, t_items, t_categories>::Collection::DoGetItem(uItem, key, value); | |
| 1304 break; | |
| 1305 } | |
| 1306 | |
| 1307 return hr; | |
| 1308 } | |
| 1309 | |
| 1310 HRESULT Select(UINT /*uItem*/, bool /*bUpdate*/ = false) | |
| 1311 { | |
| 1312 ATLASSERT(FALSE); | |
| 1313 return S_OK; | |
| 1314 } | |
| 1315 }; | |
| 1316 | |
| 1317 // SimpleCollectionImpl: collection class for ribbon simple collection controls | |
| 1318 // | |
| 1319 template <class TCtrl, size_t t_size, UI_COMMANDTYPE t_CommandType = UI_COMMANDTYPE_ACTION> | |
| 1320 class SimpleCollectionImpl : public CollectionImplBase<SimpleCollectionImpl<TCtrl, t_size>, t_size> | |
| 1321 { | |
| 1322 typedef SimpleCollectionImpl<TCtrl, t_size, t_CommandType> thisClass; | |
| 1323 public: | |
| 1324 typedef CollectionImplBase<thisClass, t_size> CollectionBase; | |
| 1325 typedef thisClass SimpleCollection; | |
| 1326 | |
| 1327 // Implementation | |
| 1328 HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 1329 { | |
| 1330 ATLASSERT(uItem < t_size); | |
| 1331 typename TCtrl::WndRibbon& ribbon = static_cast<TCtrl*>(this)->GetWndRibbon(); | |
| 1332 | |
| 1333 HRESULT hr = E_NOTIMPL; | |
| 1334 switch (k_(key)) | |
| 1335 { | |
| 1336 case k_ItemImage: | |
| 1337 if (HBITMAP hbm = ribbon.DefRibbonQueryItemImage(TCtrl::GetID(), uItem)) | |
| 1338 hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), value); | |
| 1339 break; | |
| 1340 case k_Label: | |
| 1341 if (LPCWSTR sText = ribbon.DefRibbonQueryItemText(TCtrl::GetID(), uItem)) | |
| 1342 hr = SetPropertyVal(key, (LPCWSTR)sText, value); | |
| 1343 break; | |
| 1344 case k_CommandType: | |
| 1345 hr = SetPropertyVal(key, t_CommandType, value); | |
| 1346 break; | |
| 1347 case k_CommandId: | |
| 1348 hr = SetPropertyVal(key, ribbon.DefRibbonQueryItemCommand(TCtrl::GetID(), uItem), value); | |
| 1349 break; | |
| 1350 case k_CategoryId: | |
| 1351 hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value); | |
| 1352 break; | |
| 1353 default: | |
| 1354 ATLASSERT(FALSE); | |
| 1355 break; | |
| 1356 } | |
| 1357 | |
| 1358 return hr; | |
| 1359 } | |
| 1360 }; | |
| 1361 | |
| 1362 | |
| 1363 /////////////////////////////////////////////////////////////////////////////// | |
| 1364 // Ribbon collection control classes | |
| 1365 | |
| 1366 // CollectionCtrlImpl: specializable class for ribbon collection controls | |
| 1367 // | |
| 1368 template <class T, UINT t_ID, class TCollection> | |
| 1369 class CollectionCtrlImpl : public CommandCtrlImpl<T, t_ID>, public TCollection | |
| 1370 { | |
| 1371 typedef CollectionCtrlImpl<T, t_ID, TCollection> thisClass; | |
| 1372 public: | |
| 1373 typedef CommandCtrlImpl<T, t_ID> CommandCtrl; | |
| 1374 typedef TCollection Collection; | |
| 1375 | |
| 1376 // Implementation | |
| 1377 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1378 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 1379 { | |
| 1380 ATLASSERT(nCmdID == this->GetID()); | |
| 1381 ATLASSERT(ppropvarNewValue); | |
| 1382 | |
| 1383 HRESULT hr = Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1384 if FAILED(hr) | |
| 1385 hr = CommandCtrl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1386 | |
| 1387 return hr; | |
| 1388 } | |
| 1389 | |
| 1390 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 1391 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 1392 IUISimplePropertySet* /*pCommandExecutionProperties*/) | |
| 1393 { | |
| 1394 ATLASSERT (nCmdID == this->GetID()); | |
| 1395 (void)nCmdID; // avoid level4 warning | |
| 1396 | |
| 1397 if (key == NULL) // gallery button pressed | |
| 1398 { | |
| 1399 this->GetWndRibbon().OnRibbonItemSelected(this->GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX); | |
| 1400 return S_OK; | |
| 1401 } | |
| 1402 | |
| 1403 ATLASSERT(k_(*key) == k_SelectedItem); | |
| 1404 ATLASSERT(ppropvarValue); | |
| 1405 | |
| 1406 HRESULT hr = S_OK; | |
| 1407 UINT32 uSel = 0xffff; | |
| 1408 hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel); | |
| 1409 | |
| 1410 if (SUCCEEDED(hr)) | |
| 1411 { | |
| 1412 if (this->GetWndRibbon().OnRibbonItemSelected(this->GetID(), verb, uSel)) | |
| 1413 TCollection::Select(uSel); | |
| 1414 } | |
| 1415 | |
| 1416 return hr; | |
| 1417 } | |
| 1418 }; | |
| 1419 | |
| 1420 // ToolbarGalleryCtrlImpl: base class for ribbon toolbar gallery controls | |
| 1421 // | |
| 1422 template <class T, UINT t_ID, UINT t_idTB, size_t t_size> | |
| 1423 class ToolbarGalleryCtrlImpl : public CollectionCtrlImpl<T, t_ID, CommandCollectionImpl<ToolbarGalleryCtrlImpl<T, t_ID, t_idTB, t_size>, t_size>> | |
| 1424 { | |
| 1425 public: | |
| 1426 ToolbarGalleryCtrlImpl() | |
| 1427 { | |
| 1428 CResource tbres; | |
| 1429 ATLVERIFY(tbres.Load(RT_TOOLBAR, t_idTB)); | |
| 1430 _AtlToolBarData* pData = (_AtlToolBarData*)tbres.Lock(); | |
| 1431 ATLASSERT(pData); | |
| 1432 ATLASSERT(pData->wVersion == 1); | |
| 1433 | |
| 1434 WORD* pItems = pData->items(); | |
| 1435 INT j = 0; | |
| 1436 for (int i = 0; (i < pData->wItemCount) && (j < t_size); i++) | |
| 1437 { | |
| 1438 if (pItems[i] != 0) | |
| 1439 { | |
| 1440 this->m_aCmdType[j] = UI_COMMANDTYPE_ACTION; | |
| 1441 this->m_auCmd[j++] = pItems[i]; | |
| 1442 } | |
| 1443 } | |
| 1444 | |
| 1445 if (j < t_size) | |
| 1446 this->Resize(j); | |
| 1447 } | |
| 1448 | |
| 1449 HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 1450 { | |
| 1451 ATLASSERT(uItem < this->m_size); | |
| 1452 ATLASSERT(this->m_auCmd[uItem]); | |
| 1453 | |
| 1454 HRESULT hr = E_FAIL; | |
| 1455 switch (k_(key)) | |
| 1456 { | |
| 1457 case k_CommandId: | |
| 1458 hr = SetPropertyVal(key, this->m_auCmd[uItem], value); | |
| 1459 break; | |
| 1460 case k_CommandType: | |
| 1461 hr = SetPropertyVal(key, UINT32(this->m_aCmdType[uItem]), value); | |
| 1462 break; | |
| 1463 case k_CategoryId: | |
| 1464 hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value); | |
| 1465 break; | |
| 1466 default: | |
| 1467 ATLASSERT(FALSE); | |
| 1468 break; | |
| 1469 } | |
| 1470 | |
| 1471 return hr; | |
| 1472 } | |
| 1473 }; | |
| 1474 | |
| 1475 | |
| 1476 // SimpleCollectionCtrlImpl: base class for simple gallery and listbox controls | |
| 1477 // | |
| 1478 template <class T, UINT t_ID, size_t t_size, UI_COMMANDTYPE t_CommandType = UI_COMMANDTYPE_ACTION> | |
| 1479 class SimpleCollectionCtrlImpl : | |
| 1480 public CommandCtrlImpl<T, t_ID>, | |
| 1481 public SimpleCollectionImpl<SimpleCollectionCtrlImpl<T, t_ID, t_size, t_CommandType>, t_size, t_CommandType> | |
| 1482 { | |
| 1483 typedef SimpleCollectionCtrlImpl<T, t_ID, t_size, t_CommandType> thisClass; | |
| 1484 public: | |
| 1485 typedef thisClass SimpleCollection; | |
| 1486 | |
| 1487 SimpleCollectionCtrlImpl() : m_uSelected(0) | |
| 1488 { } | |
| 1489 | |
| 1490 UINT m_uSelected; | |
| 1491 | |
| 1492 HRESULT Select(UINT uItem, bool bUpdate = false) | |
| 1493 { | |
| 1494 ATLASSERT((uItem < t_size) || (uItem == UI_COLLECTION_INVALIDINDEX)); | |
| 1495 | |
| 1496 m_uSelected = uItem; | |
| 1497 | |
| 1498 return bUpdate ? | |
| 1499 this->GetWndRibbon().SetProperty(this->GetID(), UI_PKEY_SelectedItem, uItem) : | |
| 1500 S_OK; | |
| 1501 } | |
| 1502 | |
| 1503 // Implementation | |
| 1504 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1505 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 1506 { | |
| 1507 ATLASSERT(nCmdID == this->GetID()); | |
| 1508 ATLASSERT(ppropvarNewValue != NULL); | |
| 1509 | |
| 1510 HRESULT hr = S_OK; | |
| 1511 switch (k_(key)) | |
| 1512 { | |
| 1513 case k_ItemsSource: | |
| 1514 { | |
| 1515 ATL::CComQIPtr<IUICollection> pIUICollection(ppropvarCurrentValue->punkVal); | |
| 1516 ATLASSERT(pIUICollection.p); | |
| 1517 hr = pIUICollection->Clear(); | |
| 1518 for (UINT i = 0; i < t_size; i++) | |
| 1519 { | |
| 1520 if FAILED(hr = pIUICollection->Add(this->m_apItems[i])) | |
| 1521 break; | |
| 1522 } | |
| 1523 ATLASSERT(SUCCEEDED(hr)); | |
| 1524 } | |
| 1525 break; | |
| 1526 case k_SelectedItem: | |
| 1527 hr = SetPropertyVal(UI_PKEY_SelectedItem, m_uSelected, ppropvarNewValue); | |
| 1528 break; | |
| 1529 default: | |
| 1530 hr = CommandCtrlImpl<T, t_ID>::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1531 break; | |
| 1532 } | |
| 1533 | |
| 1534 return hr; | |
| 1535 } | |
| 1536 | |
| 1537 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 1538 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 1539 IUISimplePropertySet* /*pCommandExecutionProperties*/) | |
| 1540 { | |
| 1541 ATLASSERT (nCmdID == this->GetID()); | |
| 1542 (void)nCmdID; // avoid level 4 warning | |
| 1543 | |
| 1544 HRESULT hr = S_OK; | |
| 1545 if (key == NULL) // gallery button pressed | |
| 1546 { | |
| 1547 this->GetWndRibbon().OnRibbonItemSelected(this->GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX); | |
| 1548 return hr; | |
| 1549 } | |
| 1550 ATLASSERT(k_(*key) == k_SelectedItem); | |
| 1551 ATLASSERT(ppropvarValue); | |
| 1552 | |
| 1553 if SUCCEEDED(hr = UIPropertyToUInt32(*key, *ppropvarValue, &m_uSelected)) | |
| 1554 this->GetWndRibbon().OnRibbonItemSelected(this->GetID(), verb, m_uSelected); | |
| 1555 | |
| 1556 return hr; | |
| 1557 } | |
| 1558 }; | |
| 1559 | |
| 1560 // RecentItemsCtrlImpl | |
| 1561 // | |
| 1562 template <class T, UINT t_ID, class TDocList = CRecentDocumentList> | |
| 1563 class RecentItemsCtrlImpl : | |
| 1564 public CtrlImpl<T, t_ID>, | |
| 1565 public CollectionImplBase<RecentItemsCtrlImpl<T, t_ID, TDocList>, TDocList::m_nMaxEntries_Max>, | |
| 1566 public TDocList | |
| 1567 { | |
| 1568 typedef RecentItemsCtrlImpl<T, t_ID, TDocList> thisClass; | |
| 1569 public: | |
| 1570 typedef thisClass RecentItems; | |
| 1571 | |
| 1572 // Implementation | |
| 1573 HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) | |
| 1574 { | |
| 1575 ATLASSERT((INT)uItem < this->GetMaxEntries()); | |
| 1576 | |
| 1577 LPCWSTR sPath = this->m_arrDocs[uItem].szDocName; | |
| 1578 HRESULT hr = E_NOTIMPL; | |
| 1579 switch (k_(key)) | |
| 1580 { | |
| 1581 case k_Label: | |
| 1582 hr = SetPropertyVal(key, this->GetWndRibbon().OnRibbonQueryRecentItemName(sPath), value); | |
| 1583 break; | |
| 1584 case k_LabelDescription: | |
| 1585 hr = SetPropertyVal(key, sPath, value); | |
| 1586 break; | |
| 1587 default: | |
| 1588 ATLASSERT(FALSE); | |
| 1589 break; | |
| 1590 } | |
| 1591 | |
| 1592 return hr; | |
| 1593 } | |
| 1594 | |
| 1595 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1596 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 1597 { | |
| 1598 ATLASSERT(nCmdID == this->GetID()); | |
| 1599 ATLASSERT(ppropvarNewValue); | |
| 1600 | |
| 1601 HRESULT hr = S_OK; | |
| 1602 switch (k_(key)) | |
| 1603 { | |
| 1604 case k_RecentItems: | |
| 1605 if (SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, this->m_arrDocs.GetSize())) | |
| 1606 { | |
| 1607 const int iLastIndex = this->m_arrDocs.GetSize() - 1; | |
| 1608 for (LONG i = 0; i <= iLastIndex; i++) | |
| 1609 SafeArrayPutElement(psa, &i, this->m_apItems[iLastIndex - i]); // reverse order | |
| 1610 | |
| 1611 hr = SetPropertyVal(key, psa, ppropvarNewValue); | |
| 1612 SafeArrayDestroy(psa); | |
| 1613 } | |
| 1614 break; | |
| 1615 default: | |
| 1616 hr = CtrlImpl<T, t_ID>::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1617 break; | |
| 1618 } | |
| 1619 | |
| 1620 return hr; | |
| 1621 } | |
| 1622 | |
| 1623 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 1624 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 1625 IUISimplePropertySet* /*pCommandExecutionProperties*/) | |
| 1626 { | |
| 1627 ATLASSERT(nCmdID == this->GetID()); | |
| 1628 (void)nCmdID; // avoid level 4 warning | |
| 1629 ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE); | |
| 1630 (void)verb; // avoid level 4 warning | |
| 1631 ATLASSERT((key) && (k_(*key) == k_SelectedItem)); | |
| 1632 ATLASSERT(ppropvarValue); | |
| 1633 | |
| 1634 UINT32 uSel = 0xffff; | |
| 1635 HRESULT hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel); | |
| 1636 if SUCCEEDED(hr) | |
| 1637 { | |
| 1638 ATLASSERT(uSel < (UINT)this->GetMaxEntries()); | |
| 1639 this->GetWndRibbon().DefCommandExecute(ID_FILE_MRU_FIRST + uSel); | |
| 1640 } | |
| 1641 | |
| 1642 return hr; | |
| 1643 } | |
| 1644 }; | |
| 1645 | |
| 1646 | |
| 1647 /////////////////////////////////////////////////////////////////////////////// | |
| 1648 // Ribbon stand-alone control classes | |
| 1649 | |
| 1650 // FontCtrlImpl | |
| 1651 // | |
| 1652 template <class T, UINT t_ID> | |
| 1653 class FontCtrlImpl : public CtrlImpl<T, t_ID> | |
| 1654 { | |
| 1655 public: | |
| 1656 | |
| 1657 CharFormat m_cf; | |
| 1658 | |
| 1659 // Implementation | |
| 1660 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 1661 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 1662 IUISimplePropertySet* pCommandExecutionProperties) | |
| 1663 { | |
| 1664 ATLASSERT (nCmdID == this->GetID()); | |
| 1665 (void)nCmdID; // avoid level 4 warning | |
| 1666 ATLASSERT ((key) && (k_(*key) == k_FontProperties)); | |
| 1667 (void)key; // avoid level 4 warning | |
| 1668 | |
| 1669 HRESULT hr = E_INVALIDARG; | |
| 1670 switch (verb) | |
| 1671 { | |
| 1672 case UI_EXECUTIONVERB_PREVIEW: | |
| 1673 case UI_EXECUTIONVERB_EXECUTE: | |
| 1674 ATLASSERT(pCommandExecutionProperties); | |
| 1675 PROPVARIANT propvar; | |
| 1676 | |
| 1677 if (SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &propvar))) | |
| 1678 m_cf << ATL::CComQIPtr<IPropertyStore>(propvar.punkVal); | |
| 1679 break; | |
| 1680 | |
| 1681 case UI_EXECUTIONVERB_CANCELPREVIEW: | |
| 1682 ATLASSERT(ppropvarValue); | |
| 1683 ATL::CComPtr<IPropertyStore> pStore; | |
| 1684 | |
| 1685 if (SUCCEEDED(hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarValue, &pStore))) | |
| 1686 m_cf << pStore; | |
| 1687 break; | |
| 1688 } | |
| 1689 | |
| 1690 if (SUCCEEDED(hr)) | |
| 1691 this->GetWndRibbon().OnRibbonFontCtrlExecute(this->GetID(), verb, &m_cf); | |
| 1692 else | |
| 1693 ATLASSERT(FALSE); | |
| 1694 | |
| 1695 return hr; | |
| 1696 } | |
| 1697 | |
| 1698 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1699 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 1700 { | |
| 1701 if ((k_(key) == k_FontProperties) && (this->GetWndRibbon().OnRibbonQueryFont(t_ID, m_cf))) | |
| 1702 { | |
| 1703 ATL::CComQIPtr<IPropertyStore> pStore(ppropvarCurrentValue->punkVal); | |
| 1704 m_cf >> pStore; | |
| 1705 return SetPropertyVal(key, pStore.p, ppropvarNewValue); | |
| 1706 } | |
| 1707 else | |
| 1708 { | |
| 1709 return CtrlImpl<T, t_ID>::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1710 } | |
| 1711 } | |
| 1712 }; | |
| 1713 | |
| 1714 // ColorCtrlImpl | |
| 1715 // | |
| 1716 template <class T, UINT t_ID> | |
| 1717 class ColorCtrlImpl : public CommandCtrlImpl<T, t_ID> | |
| 1718 { | |
| 1719 public: | |
| 1720 ColorCtrlImpl() : m_colorType(UI_SWATCHCOLORTYPE_NOCOLOR), m_color(0x800080) /*MAGENTA*/ | |
| 1721 { } | |
| 1722 | |
| 1723 UINT32 m_colorType; // value in UI_SWATCHCOLORTYPE | |
| 1724 COLORREF m_color; | |
| 1725 Text m_sLabels[6]; // k_MoreColorsLabel to k_ThemeColorsCategoryLabel | |
| 1726 ATL::CSimpleArray<COLORREF> m_aColors[2]; | |
| 1727 ATL::CSimpleArray<LPCWSTR> m_aTooltips[2]; | |
| 1728 | |
| 1729 // Operations | |
| 1730 HRESULT SetColor(COLORREF color, bool bUpdate = false) | |
| 1731 { | |
| 1732 if (m_colorType != UI_SWATCHCOLORTYPE_RGB) | |
| 1733 SetColorType(UI_SWATCHCOLORTYPE_RGB, bUpdate); | |
| 1734 m_color = color; | |
| 1735 return bUpdate ? this->SetProperty(UI_PKEY_Color, color) : S_OK; | |
| 1736 } | |
| 1737 | |
| 1738 HRESULT SetColorType(UI_SWATCHCOLORTYPE type, bool bUpdate = false) | |
| 1739 { | |
| 1740 m_colorType = type; | |
| 1741 return bUpdate ? this->SetProperty(UI_PKEY_ColorType, type) : S_OK; | |
| 1742 } | |
| 1743 | |
| 1744 HRESULT SetColorLabel(REFPROPERTYKEY key, LPCWSTR sLabel, bool bUpdate = false) | |
| 1745 { | |
| 1746 ATLASSERT((k_(key) >= k_ThemeColorsCategoryLabel) && (k_(key) <= k_MoreColorsLabel)); | |
| 1747 m_sLabels[k_(key) - k_ThemeColorsCategoryLabel] = sLabel; | |
| 1748 return bUpdate ? this->SetProperty(key, sLabel) : S_OK; | |
| 1749 } | |
| 1750 | |
| 1751 HRESULT SetColorArray(REFPROPERTYKEY key, COLORREF* pColor, bool bUpdate = false) | |
| 1752 { | |
| 1753 ATLASSERT((k_(key) == k_ThemeColors) || (k_(key) == k_StandardColors)); | |
| 1754 | |
| 1755 const INT ic = k_(key) - k_ThemeColors; | |
| 1756 m_aColors[ic].RemoveAll(); | |
| 1757 while (*pColor != 0x800080) /*MAGENTA*/ | |
| 1758 m_aColors[ic].Add(*pColor++); | |
| 1759 | |
| 1760 if (bUpdate) | |
| 1761 { | |
| 1762 PROPVARIANT var; | |
| 1763 if SUCCEEDED(InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), m_aColors[ic].GetSize(), &var)) | |
| 1764 return this->SetProperty(key, var); | |
| 1765 else | |
| 1766 return E_INVALIDARG; | |
| 1767 } | |
| 1768 else | |
| 1769 { | |
| 1770 return S_OK; | |
| 1771 } | |
| 1772 } | |
| 1773 | |
| 1774 HRESULT SetColorTooltips(REFPROPERTYKEY key, LPCWSTR* ppsTT, bool bUpdate = false) | |
| 1775 { | |
| 1776 ATLASSERT((k_(key) == k_ThemeColorsTooltips) || (k_(key) == k_StandardColorsTooltips)); | |
| 1777 | |
| 1778 const INT ic = k_(key) - k_ThemeColorsTooltips; | |
| 1779 m_aTooltips[ic].RemoveAll(); | |
| 1780 while (*ppsTT) | |
| 1781 m_aTooltips[ic].Add(*ppsTT++); | |
| 1782 | |
| 1783 if (bUpdate) | |
| 1784 { | |
| 1785 PROPVARIANT var; | |
| 1786 if SUCCEEDED(InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), m_aTooltips[ic].GetSize(), &var)) | |
| 1787 return this->SetProperty(key, var); | |
| 1788 else | |
| 1789 return E_INVALIDARG; | |
| 1790 } | |
| 1791 else | |
| 1792 { | |
| 1793 return S_OK; | |
| 1794 } | |
| 1795 } | |
| 1796 | |
| 1797 // Implementation | |
| 1798 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 1799 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 1800 IUISimplePropertySet* pCommandExecutionProperties) | |
| 1801 { | |
| 1802 ATLASSERT (nCmdID == this->GetID()); | |
| 1803 (void)nCmdID; // avoid level 4 warning | |
| 1804 ATLASSERT (key && (k_(*key) == k_ColorType)); | |
| 1805 (void)key; // avoid level 4 warning | |
| 1806 ATLASSERT (ppropvarValue); | |
| 1807 | |
| 1808 HRESULT hr = PropVariantToUInt32(*ppropvarValue, &m_colorType); | |
| 1809 ATLASSERT(SUCCEEDED(hr)); | |
| 1810 | |
| 1811 if (SUCCEEDED(hr) && (m_colorType == UI_SWATCHCOLORTYPE_RGB)) | |
| 1812 { | |
| 1813 ATLASSERT(pCommandExecutionProperties); | |
| 1814 PROPVARIANT var; | |
| 1815 if SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_Color, &var)) | |
| 1816 hr = PropVariantToUInt32(var, &m_color); | |
| 1817 } | |
| 1818 | |
| 1819 if SUCCEEDED(hr) | |
| 1820 this->GetWndRibbon().OnRibbonColorCtrlExecute(this->GetID(), verb, (UI_SWATCHCOLORTYPE)m_colorType/*uType*/, m_color); | |
| 1821 else | |
| 1822 ATLASSERT(FALSE); // something was wrong | |
| 1823 | |
| 1824 return hr; | |
| 1825 } | |
| 1826 | |
| 1827 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 1828 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 1829 { | |
| 1830 ATLASSERT (nCmdID == this->GetID()); | |
| 1831 | |
| 1832 HRESULT hr = E_NOTIMPL; | |
| 1833 | |
| 1834 switch (k_(key)) | |
| 1835 { | |
| 1836 case k_ColorType: | |
| 1837 hr = SetPropertyVal(key, m_colorType, ppropvarNewValue); | |
| 1838 break; | |
| 1839 case k_Color: | |
| 1840 if (m_color == 0x800080) /*MAGENTA*/ | |
| 1841 m_color = this->GetWndRibbon().OnRibbonQueryColor(this->GetID()); | |
| 1842 hr = SetPropertyVal(key, m_color, ppropvarNewValue); | |
| 1843 break; | |
| 1844 case k_ColorMode: | |
| 1845 break; | |
| 1846 case k_ThemeColorsCategoryLabel: | |
| 1847 case k_StandardColorsCategoryLabel: | |
| 1848 case k_RecentColorsCategoryLabel: | |
| 1849 case k_AutomaticColorLabel: | |
| 1850 case k_NoColorLabel: | |
| 1851 case k_MoreColorsLabel: | |
| 1852 { | |
| 1853 const UINT iLabel = k_(key) - k_ThemeColorsCategoryLabel; | |
| 1854 if (m_sLabels[iLabel].IsEmpty()) | |
| 1855 if (LPCWSTR psLabel = this->GetWndRibbon().OnRibbonQueryColorLabel(this->GetID(), key)) | |
| 1856 m_sLabels[iLabel] = psLabel; | |
| 1857 if (!m_sLabels[iLabel].IsEmpty()) | |
| 1858 hr = SetPropertyVal(key, (LPCWSTR)m_sLabels[iLabel], ppropvarNewValue); | |
| 1859 } | |
| 1860 break; | |
| 1861 case k_ThemeColors: | |
| 1862 case k_StandardColors: | |
| 1863 { | |
| 1864 const INT ic = k_(key) - k_ThemeColors; | |
| 1865 if (!m_aColors[ic].GetSize()) | |
| 1866 if (COLORREF* pColor = this->GetWndRibbon().OnRibbonQueryColorArray(this->GetID(), key)) | |
| 1867 SetColorArray(key, pColor); | |
| 1868 if (INT iMax = m_aColors[ic].GetSize()) | |
| 1869 hr = InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), iMax, ppropvarNewValue); | |
| 1870 } | |
| 1871 break; | |
| 1872 case k_ThemeColorsTooltips: | |
| 1873 case k_StandardColorsTooltips: | |
| 1874 { | |
| 1875 const INT ic = k_(key) - k_ThemeColorsTooltips; | |
| 1876 if (m_aTooltips[ic].GetSize() == 0) | |
| 1877 if (LPCWSTR* ppsTT = this->GetWndRibbon().OnRibbonQueryColorTooltips(this->GetID(), key)) | |
| 1878 SetColorTooltips(key, ppsTT); | |
| 1879 if (INT iMax = m_aTooltips[ic].GetSize()) | |
| 1880 hr = InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), iMax, ppropvarNewValue); | |
| 1881 } | |
| 1882 break; | |
| 1883 default: | |
| 1884 hr = CommandCtrlImpl<T, t_ID>::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 1885 break; | |
| 1886 } | |
| 1887 | |
| 1888 return hr; | |
| 1889 } | |
| 1890 }; | |
| 1891 | |
| 1892 // SpinnerCtrlImpl | |
| 1893 // | |
| 1894 template <class T, UINT t_ID, typename V = LONG> | |
| 1895 class SpinnerCtrlImpl : public CtrlImpl<T, t_ID> | |
| 1896 { | |
| 1897 public: | |
| 1898 SpinnerCtrlImpl() | |
| 1899 { | |
| 1900 m_Values[0] = m_Values[2] = m_Values[4] = 0; | |
| 1901 m_Values[1] = 100; | |
| 1902 m_Values[3] = 1; | |
| 1903 } | |
| 1904 | |
| 1905 V m_Values[5]; | |
| 1906 // k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces | |
| 1907 | |
| 1908 Text m_FormatString; | |
| 1909 Text m_RepresentativeString; | |
| 1910 | |
| 1911 // Operations | |
| 1912 HRESULT SetDecimalPlaces(V vPlaces, bool bUpdate = false) | |
| 1913 { | |
| 1914 return SetValue(UI_PKEY_DecimalPlaces, vPlaces, bUpdate); | |
| 1915 } | |
| 1916 | |
| 1917 HRESULT SetMin(V vMin, bool bUpdate = false) | |
| 1918 { | |
| 1919 return SetValue(UI_PKEY_MinValue, vMin, bUpdate); | |
| 1920 } | |
| 1921 | |
| 1922 HRESULT SetMax(V vMax, bool bUpdate = false) | |
| 1923 { | |
| 1924 return SetValue(UI_PKEY_MaxValue, vMax, bUpdate); | |
| 1925 } | |
| 1926 | |
| 1927 HRESULT SetVal(V vVal, bool bUpdate = false) | |
| 1928 { | |
| 1929 return SetValue(UI_PKEY_DecimalValue, vVal, bUpdate); | |
| 1930 } | |
| 1931 | |
| 1932 HRESULT SetIncrement(V vIncrement, bool bUpdate = false) | |
| 1933 { | |
| 1934 return SetValue(UI_PKEY_Increment, vIncrement, bUpdate); | |
| 1935 } | |
| 1936 | |
| 1937 HRESULT SetFormatString(LPCWSTR sFormat, bool bUpdate = false) | |
| 1938 { | |
| 1939 return SetText(UI_PKEY_FormatString, sFormat, bUpdate); | |
| 1940 } | |
| 1941 | |
| 1942 HRESULT SetRepresentativeString(LPCWSTR sRepresentative, bool bUpdate = false) | |
| 1943 { | |
| 1944 return SetText(UI_PKEY_RepresentativeString, sRepresentative, bUpdate); | |
| 1945 } | |
| 1946 | |
| 1947 // Implementation | |
| 1948 HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sText, bool bUpdate = false) | |
| 1949 { | |
| 1950 switch (k_(key)) | |
| 1951 { | |
| 1952 case k_FormatString: | |
| 1953 m_FormatString = sText; | |
| 1954 break; | |
| 1955 case k_RepresentativeString: | |
| 1956 m_RepresentativeString = sText; | |
| 1957 break; | |
| 1958 default: | |
| 1959 return CtrlImpl::SetText(key, sText, bUpdate); | |
| 1960 } | |
| 1961 | |
| 1962 return bUpdate ? | |
| 1963 this->GetWndRibbon().InvalidateProperty(this->GetID(), key) : | |
| 1964 S_OK; | |
| 1965 } | |
| 1966 | |
| 1967 HRESULT SetValue(REFPROPERTYKEY key, V val, bool bUpdate = false) | |
| 1968 { | |
| 1969 ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue)); | |
| 1970 | |
| 1971 const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue; | |
| 1972 m_Values[iVal] = val; | |
| 1973 | |
| 1974 if (bUpdate) | |
| 1975 { | |
| 1976 if(k_(key) == k_DecimalValue) | |
| 1977 { | |
| 1978 DECIMAL decVal; | |
| 1979 InitDecimal(val, &decVal); | |
| 1980 return this->SetProperty(key, &decVal); | |
| 1981 } | |
| 1982 else | |
| 1983 { | |
| 1984 return this->GetWndRibbon().InvalidateProperty(this->GetID(), key); | |
| 1985 } | |
| 1986 } | |
| 1987 else | |
| 1988 { | |
| 1989 return S_OK; | |
| 1990 } | |
| 1991 } | |
| 1992 | |
| 1993 HRESULT QueryValue(REFPROPERTYKEY key, LONG* plVal) | |
| 1994 { | |
| 1995 return this->GetWndRibbon().OnRibbonQuerySpinnerValue(this->GetID(), key, plVal) ? S_OK : S_FALSE; | |
| 1996 } | |
| 1997 | |
| 1998 HRESULT QueryValue(REFPROPERTYKEY key, DOUBLE* pdVal) | |
| 1999 { | |
| 2000 return this->GetWndRibbon().OnRibbonQueryFloatSpinnerValue(this->GetID(), key, pdVal) ? S_OK : S_FALSE; | |
| 2001 } | |
| 2002 | |
| 2003 HRESULT OnGetValue(REFPROPERTYKEY key, PROPVARIANT* ppv) | |
| 2004 { | |
| 2005 ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue)); | |
| 2006 | |
| 2007 const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue; | |
| 2008 | |
| 2009 QueryValue(key, m_Values + iVal); | |
| 2010 | |
| 2011 if (k_(key) == k_DecimalPlaces) | |
| 2012 { | |
| 2013 return SetPropertyVal(key, m_Values[iVal], ppv); | |
| 2014 } | |
| 2015 else | |
| 2016 { | |
| 2017 DECIMAL decVal; | |
| 2018 InitDecimal(m_Values[iVal], &decVal); | |
| 2019 return SetPropertyVal(key, &decVal, ppv); | |
| 2020 } | |
| 2021 } | |
| 2022 | |
| 2023 HRESULT OnGetText(REFPROPERTYKEY key, Text& sVal, PROPVARIANT* ppv) | |
| 2024 { | |
| 2025 if (LPCWSTR sNew = this->GetWndRibbon().OnRibbonQueryText(this->GetID(), key)) | |
| 2026 sVal = sNew; | |
| 2027 return SetPropertyVal(key, (LPCWSTR)sVal, ppv); | |
| 2028 } | |
| 2029 | |
| 2030 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 2031 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 2032 IUISimplePropertySet* /*pCommandExecutionProperties*/) | |
| 2033 { | |
| 2034 ATLASSERT (nCmdID == this->GetID()); | |
| 2035 (void)nCmdID; // avoid level 4 warning | |
| 2036 ATLASSERT (key && (k_(*key) == k_DecimalValue)); | |
| 2037 (void)key; // avoid level 4 warning | |
| 2038 ATLASSERT (verb == UI_EXECUTIONVERB_EXECUTE); | |
| 2039 (void)verb; // avoid level 4 warning | |
| 2040 | |
| 2041 DECIMAL decVal; | |
| 2042 | |
| 2043 HRESULT hr = UIPropertyToDecimal(UI_PKEY_DecimalValue, *ppropvarValue, &decVal); | |
| 2044 hr = InitVal(m_Values[0], &decVal); | |
| 2045 | |
| 2046 this->GetWndRibbon().OnRibbonSpinnerCtrlExecute(this->GetID(), &m_Values[0]); | |
| 2047 | |
| 2048 return hr; | |
| 2049 } | |
| 2050 | |
| 2051 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 2052 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 2053 { | |
| 2054 ATLASSERT (nCmdID == this->GetID()); | |
| 2055 | |
| 2056 HRESULT hr = E_NOTIMPL; | |
| 2057 switch (k_(key)) | |
| 2058 { | |
| 2059 case k_DecimalPlaces: | |
| 2060 case k_DecimalValue: | |
| 2061 case k_Increment: | |
| 2062 case k_MaxValue: | |
| 2063 case k_MinValue: | |
| 2064 hr = OnGetValue(key, ppropvarNewValue); | |
| 2065 break; | |
| 2066 case k_FormatString: | |
| 2067 if (m_FormatString.IsEmpty()) | |
| 2068 return OnGetText(key, m_FormatString, ppropvarNewValue); | |
| 2069 break; | |
| 2070 case k_RepresentativeString: | |
| 2071 if (m_RepresentativeString.IsEmpty()) | |
| 2072 return OnGetText(key, m_RepresentativeString, ppropvarNewValue); | |
| 2073 break; | |
| 2074 default: | |
| 2075 hr = CtrlImpl<T, t_ID>::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 2076 break; | |
| 2077 } | |
| 2078 | |
| 2079 return hr; | |
| 2080 } | |
| 2081 | |
| 2082 // decimal conversion helpers | |
| 2083 static HRESULT InitDecimal(LONG& val, DECIMAL* pDecimal) | |
| 2084 { | |
| 2085 return ::VarDecFromI4(val, pDecimal); | |
| 2086 } | |
| 2087 | |
| 2088 static HRESULT InitDecimal(DOUBLE& val, DECIMAL* pDecimal) | |
| 2089 { | |
| 2090 return ::VarDecFromR8(val, pDecimal); | |
| 2091 } | |
| 2092 | |
| 2093 static HRESULT InitVal(LONG& val, const DECIMAL* pDecimal) | |
| 2094 { | |
| 2095 return ::VarI4FromDec(pDecimal, &val); | |
| 2096 } | |
| 2097 | |
| 2098 static HRESULT InitVal(DOUBLE& val, const DECIMAL* pDecimal) | |
| 2099 { | |
| 2100 return ::VarR8FromDec(pDecimal, &val); | |
| 2101 } | |
| 2102 }; | |
| 2103 | |
| 2104 // CRibbonImpl Ribbon implementation class | |
| 2105 // | |
| 2106 template <class T> | |
| 2107 class CRibbonImpl : | |
| 2108 public CRibbonUpdateUI<T>, | |
| 2109 public ICtrl, | |
| 2110 public IUIApplication, | |
| 2111 public IUICommandHandler | |
| 2112 { | |
| 2113 typedef CRibbonImpl<T> thisClass; | |
| 2114 public: | |
| 2115 typedef thisClass Ribbon; | |
| 2116 typedef T WndRibbon; | |
| 2117 | |
| 2118 CRibbonImpl() : m_bRibbonUI(false), m_hgRibbonSettings(NULL) | |
| 2119 { | |
| 2120 #ifdef _DEBUG | |
| 2121 m_cRef = 1; | |
| 2122 #endif | |
| 2123 pWndRibbon = static_cast<T*>(this); | |
| 2124 HRESULT hr = ::CoInitialize(NULL); | |
| 2125 if(SUCCEEDED(hr)) | |
| 2126 if (RunTimeHelper::IsRibbonUIAvailable()) | |
| 2127 hr = m_pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework); | |
| 2128 else | |
| 2129 ATLTRACE2(atlTraceUI, 0, _T("Ribbon UI not available\n")); | |
| 2130 | |
| 2131 if FAILED(hr) | |
| 2132 ATLTRACE2(atlTraceUI, 0, _T("Ribbon construction failed\n")); | |
| 2133 | |
| 2134 ATLASSERT(SUCCEEDED(hr)); | |
| 2135 } | |
| 2136 | |
| 2137 virtual ~CRibbonImpl() | |
| 2138 { | |
| 2139 ::GlobalFree(m_hgRibbonSettings); | |
| 2140 m_pIUIFramework.Release(); | |
| 2141 ::CoUninitialize(); | |
| 2142 } | |
| 2143 | |
| 2144 ICtrl& GetRibbonCtrl(UINT) | |
| 2145 { | |
| 2146 return static_cast<ICtrl&>(*this); | |
| 2147 } | |
| 2148 | |
| 2149 ATL::CComPtr<IUIFramework> m_pIUIFramework; | |
| 2150 bool m_bRibbonUI; | |
| 2151 HGLOBAL m_hgRibbonSettings; | |
| 2152 | |
| 2153 bool IsRibbonUI() | |
| 2154 { | |
| 2155 return m_bRibbonUI; | |
| 2156 } | |
| 2157 | |
| 2158 IUIFramework* GetIUIFrameworkPtr() | |
| 2159 { | |
| 2160 return m_pIUIFramework; | |
| 2161 } | |
| 2162 | |
| 2163 template <typename I> | |
| 2164 I* GetRibbonViewPtr(UINT32 uID) | |
| 2165 { | |
| 2166 ATLASSERT(m_pIUIFramework); | |
| 2167 ATL::CComPtr<I> pI; | |
| 2168 return m_pIUIFramework->GetView(uID, __uuidof(I), (void**) &pI) == S_OK ? | |
| 2169 pI : | |
| 2170 NULL; | |
| 2171 } | |
| 2172 | |
| 2173 IUIRibbon* GetRibbonPtr() | |
| 2174 { | |
| 2175 return GetRibbonViewPtr<IUIRibbon>(0); | |
| 2176 } | |
| 2177 | |
| 2178 IUIContextualUI* GetMenuPtr(UINT32 uID) | |
| 2179 { | |
| 2180 ATLASSERT(uID); | |
| 2181 return GetRibbonViewPtr<IUIContextualUI>(uID); | |
| 2182 } | |
| 2183 | |
| 2184 UINT GetRibbonHeight() | |
| 2185 { | |
| 2186 ATLASSERT(IsRibbonUI()); | |
| 2187 | |
| 2188 UINT32 cy = 0; | |
| 2189 if (ATL::CComPtr<IUIRibbon> pIUIRibbon = GetRibbonPtr()) | |
| 2190 pIUIRibbon->GetHeight(&cy); | |
| 2191 return cy; | |
| 2192 } | |
| 2193 | |
| 2194 HRESULT CreateRibbon(LPCWSTR sResName = L"APPLICATION_RIBBON") | |
| 2195 { | |
| 2196 T* pT = static_cast<T*>(this); | |
| 2197 ATLASSERT(GetIUIFrameworkPtr() && !IsRibbonUI()); | |
| 2198 ATLASSERT(pT->IsWindow()); | |
| 2199 | |
| 2200 HRESULT hr = m_pIUIFramework->Initialize(pT->m_hWnd, this); | |
| 2201 | |
| 2202 if (hr == S_OK) | |
| 2203 hr = m_pIUIFramework->LoadUI(ModuleHelper::GetResourceInstance(), sResName); | |
| 2204 | |
| 2205 return hr; | |
| 2206 } | |
| 2207 | |
| 2208 HRESULT DestroyRibbon() | |
| 2209 { | |
| 2210 T* pT = static_cast<T*>(this); | |
| 2211 ATLASSERT(GetIUIFrameworkPtr() && IsRibbonUI()); | |
| 2212 ATLASSERT(pT->IsWindow()); | |
| 2213 | |
| 2214 HRESULT hRes = m_pIUIFramework->Destroy(); | |
| 2215 if (!RunTimeHelper::IsWin7()) | |
| 2216 pT->SetWindowRgn(NULL, TRUE); // Vista Basic bug workaround | |
| 2217 return hRes; | |
| 2218 } | |
| 2219 | |
| 2220 // Ribbon persistency | |
| 2221 HRESULT operator >>(IStream* pIStream) | |
| 2222 { | |
| 2223 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2224 ATLASSERT(pIStream); | |
| 2225 | |
| 2226 HRESULT hr = E_FAIL; | |
| 2227 if (ATL::CComPtr<IUIRibbon> pIUIRibbon = GetRibbonPtr()) | |
| 2228 { | |
| 2229 const LARGE_INTEGER li0 = {}; | |
| 2230 pIStream->Seek(li0, STREAM_SEEK_SET, NULL); | |
| 2231 hr = pIUIRibbon->SaveSettingsToStream(pIStream); | |
| 2232 pIStream->Commit(STGC_DEFAULT); | |
| 2233 } | |
| 2234 | |
| 2235 return hr; | |
| 2236 } | |
| 2237 | |
| 2238 HRESULT operator <<(IStream* pIStream) | |
| 2239 { | |
| 2240 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2241 ATLASSERT(pIStream); | |
| 2242 | |
| 2243 HRESULT hr = E_FAIL; | |
| 2244 if (ATL::CComPtr<IUIRibbon> pIUIRibbon = GetRibbonPtr()) | |
| 2245 { | |
| 2246 const LARGE_INTEGER li0 = {}; | |
| 2247 pIStream->Seek(li0, STREAM_SEEK_SET, NULL); | |
| 2248 hr = pIUIRibbon->LoadSettingsFromStream(pIStream); | |
| 2249 } | |
| 2250 | |
| 2251 return hr; | |
| 2252 } | |
| 2253 | |
| 2254 void ResetRibbonSettings() | |
| 2255 { | |
| 2256 if (m_hgRibbonSettings != NULL) | |
| 2257 { | |
| 2258 ::GlobalFree(m_hgRibbonSettings); | |
| 2259 m_hgRibbonSettings = NULL; | |
| 2260 } | |
| 2261 } | |
| 2262 | |
| 2263 HRESULT SaveRibbonSettings() | |
| 2264 { | |
| 2265 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2266 ATLASSERT(static_cast<T*>(this)->IsWindow()); | |
| 2267 | |
| 2268 HRESULT hr = E_FAIL; | |
| 2269 ATL::CComPtr<IStream> pIStream; | |
| 2270 | |
| 2271 if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream)) | |
| 2272 hr = *this >> pIStream; | |
| 2273 | |
| 2274 if (SUCCEEDED(hr) && (m_hgRibbonSettings == NULL)) | |
| 2275 hr = ::GetHGlobalFromStream(pIStream, &m_hgRibbonSettings); | |
| 2276 | |
| 2277 if FAILED(hr) | |
| 2278 ResetRibbonSettings(); | |
| 2279 | |
| 2280 return hr; | |
| 2281 } | |
| 2282 | |
| 2283 HRESULT RestoreRibbonSettings() | |
| 2284 { | |
| 2285 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2286 ATLASSERT(m_hgRibbonSettings); | |
| 2287 ATLASSERT(static_cast<T*>(this)->IsWindow()); | |
| 2288 | |
| 2289 HRESULT hr = E_FAIL; | |
| 2290 ATL::CComPtr<IStream> pIStream; | |
| 2291 | |
| 2292 if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream)) | |
| 2293 hr = *this << pIStream; | |
| 2294 | |
| 2295 if FAILED(hr) | |
| 2296 ResetRibbonSettings(); | |
| 2297 | |
| 2298 return hr; | |
| 2299 } | |
| 2300 | |
| 2301 // QAT dock states | |
| 2302 UI_CONTROLDOCK GetQATDock() | |
| 2303 { | |
| 2304 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2305 ATLASSERT(IsRibbonUI()); | |
| 2306 | |
| 2307 UINT32 uDock = 0; | |
| 2308 PROPVARIANT propvar; | |
| 2309 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr()); | |
| 2310 | |
| 2311 if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(UI_PKEY_QuickAccessToolbarDock, &propvar)) && | |
| 2312 SUCCEEDED(UIPropertyToUInt32(UI_PKEY_QuickAccessToolbarDock, propvar, &uDock))) | |
| 2313 return (UI_CONTROLDOCK)uDock; | |
| 2314 | |
| 2315 ATLASSERT(FALSE); // something was wrong | |
| 2316 return (UI_CONTROLDOCK)0; | |
| 2317 } | |
| 2318 | |
| 2319 bool SetQATDock(UI_CONTROLDOCK dockState) | |
| 2320 { | |
| 2321 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2322 ATLASSERT(IsRibbonUI()); | |
| 2323 | |
| 2324 PROPVARIANT propvar; | |
| 2325 ATLVERIFY(SUCCEEDED(SetPropertyVal(UI_PKEY_QuickAccessToolbarDock, dockState, &propvar))); | |
| 2326 | |
| 2327 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr()); | |
| 2328 if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(UI_PKEY_QuickAccessToolbarDock, propvar))) | |
| 2329 { | |
| 2330 pIPS->Commit(); | |
| 2331 return true; | |
| 2332 } | |
| 2333 | |
| 2334 ATLASSERT(FALSE); // something was wrong | |
| 2335 return false; | |
| 2336 } | |
| 2337 | |
| 2338 // Ribbon display states | |
| 2339 bool GetRibbonDisplayState(REFPROPERTYKEY key) | |
| 2340 { | |
| 2341 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2342 ATLASSERT(IsRibbonUI()); | |
| 2343 ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized)); | |
| 2344 | |
| 2345 PROPVARIANT propvar; | |
| 2346 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr()); | |
| 2347 | |
| 2348 if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar))) | |
| 2349 { | |
| 2350 BOOL bState = FALSE; | |
| 2351 if SUCCEEDED(UIPropertyToBoolean(key, propvar, &bState)) | |
| 2352 return (bState != FALSE); | |
| 2353 } | |
| 2354 | |
| 2355 ATLASSERT(FALSE); // something was wrong | |
| 2356 return false; | |
| 2357 } | |
| 2358 | |
| 2359 bool SetRibbonDisplayState(REFPROPERTYKEY key, bool bState = true) | |
| 2360 { | |
| 2361 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2362 ATLASSERT(IsRibbonUI()); | |
| 2363 ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized)); | |
| 2364 | |
| 2365 PROPVARIANT propvar; | |
| 2366 ATLVERIFY(SUCCEEDED(SetPropertyVal(key, bState, &propvar))); | |
| 2367 | |
| 2368 ATL::CComQIPtr<IPropertyStore>pIPS(GetRibbonPtr()); | |
| 2369 | |
| 2370 if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar))) | |
| 2371 { | |
| 2372 pIPS->Commit(); | |
| 2373 return true; | |
| 2374 } | |
| 2375 | |
| 2376 ATLASSERT(FALSE); // something was wrong | |
| 2377 return false; | |
| 2378 } | |
| 2379 | |
| 2380 bool IsRibbonMinimized() | |
| 2381 { | |
| 2382 return GetRibbonDisplayState(UI_PKEY_Minimized); | |
| 2383 } | |
| 2384 | |
| 2385 bool MinimizeRibbon(bool bMinimize = true) | |
| 2386 { | |
| 2387 return SetRibbonDisplayState(UI_PKEY_Minimized, bMinimize); | |
| 2388 } | |
| 2389 | |
| 2390 bool IsRibbonHidden() | |
| 2391 { | |
| 2392 return !GetRibbonDisplayState(UI_PKEY_Viewable); | |
| 2393 } | |
| 2394 | |
| 2395 bool HideRibbon(bool bHide = true) | |
| 2396 { | |
| 2397 return SetRibbonDisplayState(UI_PKEY_Viewable, !bHide); | |
| 2398 } | |
| 2399 | |
| 2400 // Ribbon colors | |
| 2401 UI_HSBCOLOR GetRibbonColor(REFPROPERTYKEY key) | |
| 2402 { | |
| 2403 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2404 ATLASSERT(IsRibbonUI()); | |
| 2405 ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor)); | |
| 2406 | |
| 2407 PROPVARIANT propvar; | |
| 2408 ATL::CComQIPtr<IPropertyStore>pIPS(GetIUIFrameworkPtr()); | |
| 2409 | |
| 2410 if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar))) | |
| 2411 { | |
| 2412 UINT32 color = 0; | |
| 2413 if SUCCEEDED(UIPropertyToUInt32(key, propvar, &color)) | |
| 2414 return color; | |
| 2415 } | |
| 2416 | |
| 2417 ATLASSERT(FALSE); // something was wrong | |
| 2418 return 0; | |
| 2419 } | |
| 2420 | |
| 2421 bool SetRibbonColor(REFPROPERTYKEY key, UI_HSBCOLOR color) | |
| 2422 { | |
| 2423 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2424 ATLASSERT(IsRibbonUI()); | |
| 2425 ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor)); | |
| 2426 | |
| 2427 PROPVARIANT propvar; | |
| 2428 ATLVERIFY(SUCCEEDED(SetPropertyVal(key, color, &propvar))); | |
| 2429 | |
| 2430 ATL::CComQIPtr<IPropertyStore>pIPS(GetIUIFrameworkPtr()); | |
| 2431 | |
| 2432 if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar))) | |
| 2433 { | |
| 2434 pIPS->Commit(); | |
| 2435 return true; | |
| 2436 } | |
| 2437 | |
| 2438 ATLASSERT(FALSE); // something was wrong | |
| 2439 return false; | |
| 2440 } | |
| 2441 | |
| 2442 // Ribbon modes | |
| 2443 HRESULT SetRibbonModes(INT32 iModes) | |
| 2444 { | |
| 2445 ATLASSERT(IsRibbonUI()); | |
| 2446 return GetIUIFrameworkPtr()->SetModes(iModes); | |
| 2447 } | |
| 2448 | |
| 2449 // Ribbon contextual tab | |
| 2450 UI_CONTEXTAVAILABILITY GetRibbonContextAvail(UINT32 uID) | |
| 2451 { | |
| 2452 ATLASSERT(GetIUIFrameworkPtr()); | |
| 2453 | |
| 2454 PROPVARIANT propvar; | |
| 2455 if (IsRibbonUI() && | |
| 2456 SUCCEEDED(GetIUIFrameworkPtr()->GetUICommandProperty(uID, UI_PKEY_ContextAvailable, &propvar))) | |
| 2457 { | |
| 2458 UINT uav; | |
| 2459 if (SUCCEEDED(PropVariantToUInt32(propvar, &uav))) | |
| 2460 { | |
| 2461 CUpdateUIBase::UIEnable(uID, uav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE); | |
| 2462 CUpdateUIBase::UISetCheck(uID, uav == UI_CONTEXTAVAILABILITY_ACTIVE); | |
| 2463 return (UI_CONTEXTAVAILABILITY)uav; | |
| 2464 } | |
| 2465 } | |
| 2466 | |
| 2467 return UI_CONTEXTAVAILABILITY_NOTAVAILABLE; | |
| 2468 } | |
| 2469 | |
| 2470 HRESULT SetRibbonContextAvail(UINT32 uID, UI_CONTEXTAVAILABILITY cav) | |
| 2471 { | |
| 2472 CUpdateUIBase::UIEnable(uID, cav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE); | |
| 2473 CUpdateUIBase::UISetCheck(uID, cav == UI_CONTEXTAVAILABILITY_ACTIVE); | |
| 2474 | |
| 2475 return SetProperty((WORD)uID, UI_PKEY_ContextAvailable, UINT32(cav)); | |
| 2476 } | |
| 2477 | |
| 2478 // Ribbon context menu | |
| 2479 bool HasRibbonMenu(UINT32 uID) | |
| 2480 { | |
| 2481 ATL::CComPtr<IUIContextualUI> pI = GetMenuPtr(uID); | |
| 2482 return pI != NULL; | |
| 2483 } | |
| 2484 | |
| 2485 HRESULT TrackRibbonMenu(UINT32 uID, INT32 x, INT32 y) | |
| 2486 { | |
| 2487 ATLASSERT(HasRibbonMenu(uID)); | |
| 2488 | |
| 2489 return IsRibbonUI() ? | |
| 2490 ATL::CComPtr<IUIContextualUI>(GetMenuPtr(uID))->ShowAtLocation(x, y) : | |
| 2491 E_FAIL; | |
| 2492 } | |
| 2493 | |
| 2494 HRESULT TrackRibbonMenu(UINT32 uID, LPARAM lParam) | |
| 2495 { | |
| 2496 return TrackRibbonMenu(uID, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); | |
| 2497 } | |
| 2498 | |
| 2499 // Overrideables | |
| 2500 HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY /*key*/) | |
| 2501 { | |
| 2502 return DefRibbonQueryImage(nCmdID); | |
| 2503 } | |
| 2504 | |
| 2505 LPCWSTR OnRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key) | |
| 2506 { | |
| 2507 return DefRibbonQueryText(nCmdID, key); | |
| 2508 } | |
| 2509 | |
| 2510 bool OnRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key) | |
| 2511 { | |
| 2512 return DefRibbonQueryState(nCmdID, key); | |
| 2513 } | |
| 2514 | |
| 2515 UI_CONTEXTAVAILABILITY OnRibbonQueryTabAvail(UINT nCmdID) | |
| 2516 { | |
| 2517 DWORD dwState = this->UIGetState(nCmdID); | |
| 2518 return ((dwState & CUpdateUIBase::UPDUI_DISABLED) == CUpdateUIBase::UPDUI_DISABLED) ? | |
| 2519 UI_CONTEXTAVAILABILITY_NOTAVAILABLE : | |
| 2520 (((dwState & CUpdateUIBase::UPDUI_CHECKED) == CUpdateUIBase::UPDUI_CHECKED) ? | |
| 2521 UI_CONTEXTAVAILABILITY_ACTIVE : | |
| 2522 UI_CONTEXTAVAILABILITY_AVAILABLE); | |
| 2523 } | |
| 2524 | |
| 2525 LPCWSTR OnRibbonQueryComboText(UINT32 /*uCtrlID*/) | |
| 2526 { | |
| 2527 return NULL; | |
| 2528 } | |
| 2529 | |
| 2530 LPCWSTR OnRibbonQueryCategoryText(UINT32 /*uCtrlID*/, UINT32 /*uCat*/) | |
| 2531 { | |
| 2532 return L"Category"; | |
| 2533 } | |
| 2534 | |
| 2535 UINT32 OnRibbonQueryItemCategory(UINT32 /*uCtrlID*/, UINT32 /*uItem*/) | |
| 2536 { | |
| 2537 return 0; | |
| 2538 } | |
| 2539 | |
| 2540 LPCWSTR OnRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem) | |
| 2541 { | |
| 2542 return DefRibbonQueryItemText(uCtrlID, uItem); | |
| 2543 } | |
| 2544 | |
| 2545 bool OnRibbonQuerySelectedItem(UINT32 /*uCtrlID*/, UINT32& /*uSel*/) | |
| 2546 { | |
| 2547 return false; | |
| 2548 } | |
| 2549 | |
| 2550 HBITMAP OnRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem) | |
| 2551 { | |
| 2552 return DefRibbonQueryItemImage(uCtrlID, uItem); | |
| 2553 } | |
| 2554 | |
| 2555 UINT32 OnRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem) | |
| 2556 { | |
| 2557 return DefRibbonQueryItemCommand(uCtrlID, uItem); | |
| 2558 } | |
| 2559 | |
| 2560 UI_COMMANDTYPE OnRibbonQueryItemCommandType(UINT32 /*uCtrlID*/, UINT32 /*uItem*/) | |
| 2561 { | |
| 2562 return UI_COMMANDTYPE_ACTION; | |
| 2563 } | |
| 2564 | |
| 2565 LPCWSTR OnRibbonQueryRecentItemName(LPCWSTR sPath) | |
| 2566 { | |
| 2567 return ::PathFindFileName(sPath); | |
| 2568 } | |
| 2569 | |
| 2570 bool OnRibbonQueryFont(UINT /*nId*/, CHARFORMAT2& /*cf*/) | |
| 2571 { | |
| 2572 return false; | |
| 2573 } | |
| 2574 | |
| 2575 bool OnRibbonQuerySpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, LONG* /*pVal*/) | |
| 2576 { | |
| 2577 return false; | |
| 2578 } | |
| 2579 | |
| 2580 bool OnRibbonQueryFloatSpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, DOUBLE* /*pVal*/) | |
| 2581 { | |
| 2582 return false; | |
| 2583 } | |
| 2584 | |
| 2585 COLORREF OnRibbonQueryColor(UINT /*nCmdID*/) | |
| 2586 { | |
| 2587 return 0x800080; /*MAGENTA*/ | |
| 2588 } | |
| 2589 | |
| 2590 LPCWSTR OnRibbonQueryColorLabel(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) | |
| 2591 { | |
| 2592 return NULL; | |
| 2593 } | |
| 2594 | |
| 2595 COLORREF* OnRibbonQueryColorArray(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) | |
| 2596 { | |
| 2597 return NULL; | |
| 2598 } | |
| 2599 | |
| 2600 LPCWSTR* OnRibbonQueryColorTooltips(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) | |
| 2601 { | |
| 2602 return NULL; | |
| 2603 } | |
| 2604 | |
| 2605 bool OnRibbonItemSelected(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UINT32 uItem) | |
| 2606 { | |
| 2607 DefCommandExecute(MAKELONG(uCtrlID, verb), uItem); | |
| 2608 return true; | |
| 2609 } | |
| 2610 | |
| 2611 void OnRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color) | |
| 2612 { | |
| 2613 DefRibbonColorCtrlExecute(uCtrlID, verb, uType, color); | |
| 2614 } | |
| 2615 | |
| 2616 void OnRibbonFontCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, CHARFORMAT2* pcf) | |
| 2617 { | |
| 2618 DefCommandExecute(MAKELONG(uCtrlID, verb), (LPARAM)pcf); | |
| 2619 } | |
| 2620 | |
| 2621 void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, LONG* pVal) | |
| 2622 { | |
| 2623 DefCommandExecute(uCtrlID, *pVal); | |
| 2624 } | |
| 2625 | |
| 2626 void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, DOUBLE* pVal) | |
| 2627 { | |
| 2628 DefCommandExecute(uCtrlID, (LPARAM)pVal); | |
| 2629 } | |
| 2630 | |
| 2631 void OnRibbonCommandExecute(UINT32 uCmdID) | |
| 2632 { | |
| 2633 DefCommandExecute(uCmdID); | |
| 2634 } | |
| 2635 | |
| 2636 // Default implementations | |
| 2637 HBITMAP DefRibbonQueryImage(UINT nCmdID) | |
| 2638 { | |
| 2639 return AtlLoadBitmapImage(nCmdID, LR_CREATEDIBSECTION); | |
| 2640 } | |
| 2641 | |
| 2642 bool DefRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key) | |
| 2643 { | |
| 2644 DWORD dwState = this->UIGetState(nCmdID); | |
| 2645 bool bRet = false; | |
| 2646 switch (k_(key)) | |
| 2647 { | |
| 2648 case k_BooleanValue: | |
| 2649 bRet = (dwState & CUpdateUIBase::UPDUI_CHECKED) == CUpdateUIBase::UPDUI_CHECKED; | |
| 2650 break; | |
| 2651 case k_Enabled: | |
| 2652 bRet = (dwState & CUpdateUIBase::UPDUI_DISABLED) != CUpdateUIBase::UPDUI_DISABLED; | |
| 2653 break; | |
| 2654 default: | |
| 2655 ATLASSERT(FALSE); | |
| 2656 break; | |
| 2657 } | |
| 2658 | |
| 2659 return bRet; | |
| 2660 } | |
| 2661 | |
| 2662 LPCTSTR DefRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key) | |
| 2663 { | |
| 2664 static WCHAR sText[RIBBONUI_MAX_TEXT] = {}; | |
| 2665 | |
| 2666 if (k_(key) == k_Label) | |
| 2667 return this->UIGetText(nCmdID); | |
| 2668 | |
| 2669 if (ATL::AtlLoadString(nCmdID, sText, RIBBONUI_MAX_TEXT)) | |
| 2670 { | |
| 2671 PWCHAR pTitle = wcschr(sText, L'\n'); | |
| 2672 switch (k_(key)) | |
| 2673 { | |
| 2674 case k_Keytip: | |
| 2675 if (PWCHAR pAmp = wcschr(sText, L'&')) | |
| 2676 pTitle = pAmp; | |
| 2677 if (pTitle != NULL) | |
| 2678 *(pTitle + 2) = NULL; // fall through | |
| 2679 case k_TooltipTitle: | |
| 2680 return pTitle ? ++pTitle : NULL; | |
| 2681 case k_TooltipDescription: | |
| 2682 case k_LabelDescription: | |
| 2683 if (pTitle != NULL) | |
| 2684 *pTitle = NULL; | |
| 2685 return sText; | |
| 2686 } | |
| 2687 } | |
| 2688 | |
| 2689 return NULL; | |
| 2690 } | |
| 2691 | |
| 2692 LPCWSTR DefRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem) | |
| 2693 { | |
| 2694 return DefRibbonQueryText(uCtrlID + 1 + uItem, UI_PKEY_LabelDescription); | |
| 2695 } | |
| 2696 | |
| 2697 HBITMAP DefRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem) | |
| 2698 { | |
| 2699 return DefRibbonQueryImage(uCtrlID + 1 + uItem); | |
| 2700 } | |
| 2701 | |
| 2702 UINT32 DefRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem) | |
| 2703 { | |
| 2704 return uCtrlID + 1 + uItem; | |
| 2705 } | |
| 2706 | |
| 2707 void DefRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color) | |
| 2708 { | |
| 2709 switch(uType) | |
| 2710 { | |
| 2711 case UI_SWATCHCOLORTYPE_RGB: | |
| 2712 break; | |
| 2713 case UI_SWATCHCOLORTYPE_AUTOMATIC: | |
| 2714 color = ::GetSysColor(COLOR_WINDOWTEXT); | |
| 2715 break; | |
| 2716 case UI_SWATCHCOLORTYPE_NOCOLOR: | |
| 2717 color = ::GetSysColor(COLOR_WINDOW); | |
| 2718 break; | |
| 2719 default: | |
| 2720 ATLASSERT(FALSE); | |
| 2721 break; | |
| 2722 } | |
| 2723 | |
| 2724 DefCommandExecute(MAKELONG(uCtrlID, verb), color); | |
| 2725 } | |
| 2726 | |
| 2727 void DefCommandExecute(UINT32 uCmd, LPARAM lParam = 0) | |
| 2728 { | |
| 2729 static_cast<T*>(this)->PostMessage(WM_COMMAND, uCmd, lParam); | |
| 2730 } | |
| 2731 | |
| 2732 // Elements setting helpers | |
| 2733 HRESULT InvalidateCtrl(UINT32 nID) | |
| 2734 { | |
| 2735 return IsRibbonUI() ? | |
| 2736 GetIUIFrameworkPtr()->InvalidateUICommand(nID, UI_INVALIDATIONS_ALLPROPERTIES, NULL) : | |
| 2737 E_FAIL; | |
| 2738 } | |
| 2739 | |
| 2740 HRESULT InvalidateProperty(UINT32 nID, REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY) | |
| 2741 { | |
| 2742 return IsRibbonUI() ? | |
| 2743 GetIUIFrameworkPtr()->InvalidateUICommand(nID, flags, &key) : | |
| 2744 E_FAIL; | |
| 2745 } | |
| 2746 | |
| 2747 template <typename V> | |
| 2748 HRESULT SetProperty(WORD wID, REFPROPERTYKEY key, V val) | |
| 2749 { | |
| 2750 if (IsRibbonUI()) | |
| 2751 { | |
| 2752 PROPVARIANT var; | |
| 2753 if (SUCCEEDED(RibbonUI::SetPropertyVal(key, val, &var))) | |
| 2754 { | |
| 2755 return SetProperty(wID, key, var); | |
| 2756 } | |
| 2757 return E_INVALIDARG; | |
| 2758 } | |
| 2759 else | |
| 2760 { | |
| 2761 return E_FAIL; | |
| 2762 } | |
| 2763 } | |
| 2764 | |
| 2765 template <> | |
| 2766 HRESULT SetProperty(WORD nID, REFPROPERTYKEY key, PROPVARIANT var) | |
| 2767 { | |
| 2768 return IsRibbonUI() ? | |
| 2769 GetIUIFrameworkPtr()->SetUICommandProperty(nID, key, var) : | |
| 2770 E_FAIL; | |
| 2771 } | |
| 2772 | |
| 2773 // Interfaces | |
| 2774 // IUIApplication | |
| 2775 STDMETHODIMP OnViewChanged(UINT32, UI_VIEWTYPE, IUnknown*, UI_VIEWVERB verb, INT32) | |
| 2776 { | |
| 2777 switch (verb) | |
| 2778 { | |
| 2779 case UI_VIEWVERB_CREATE: | |
| 2780 m_bRibbonUI = true; | |
| 2781 if (m_hgRibbonSettings != NULL) | |
| 2782 RestoreRibbonSettings(); | |
| 2783 break; | |
| 2784 case UI_VIEWVERB_SIZE: | |
| 2785 static_cast<T*>(this)->UpdateLayout(FALSE); | |
| 2786 break; | |
| 2787 case UI_VIEWVERB_DESTROY: | |
| 2788 SaveRibbonSettings(); | |
| 2789 m_bRibbonUI = false; | |
| 2790 break; | |
| 2791 } | |
| 2792 | |
| 2793 return S_OK; | |
| 2794 } | |
| 2795 | |
| 2796 STDMETHODIMP OnCreateUICommand(UINT32 nCmdID, UI_COMMANDTYPE typeID, IUICommandHandler** ppCommandHandler) | |
| 2797 { | |
| 2798 this->UIAddRibbonElement(nCmdID); | |
| 2799 if (typeID == UI_COMMANDTYPE_CONTEXT) | |
| 2800 CUpdateUIBase::UIEnable(nCmdID, false); | |
| 2801 *ppCommandHandler = this; | |
| 2802 return S_OK; | |
| 2803 } | |
| 2804 | |
| 2805 STDMETHODIMP OnDestroyUICommand(UINT32 nCmdID, UI_COMMANDTYPE, IUICommandHandler*) | |
| 2806 { | |
| 2807 this->UIRemoveRibbonElement(nCmdID); | |
| 2808 return S_OK; | |
| 2809 } | |
| 2810 | |
| 2811 // IUICommandHandler | |
| 2812 STDMETHODIMP Execute(UINT nCmdID, | |
| 2813 UI_EXECUTIONVERB verb, | |
| 2814 const PROPERTYKEY* key, | |
| 2815 const PROPVARIANT* ppropvarValue, | |
| 2816 IUISimplePropertySet* pCommandExecutionProperties) | |
| 2817 { | |
| 2818 T* pT =static_cast<T*>(this); | |
| 2819 return pT->GetRibbonCtrl(nCmdID).DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties); | |
| 2820 } | |
| 2821 | |
| 2822 STDMETHODIMP UpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 2823 const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) | |
| 2824 { | |
| 2825 T* pT =static_cast<T*>(this); | |
| 2826 return pT->GetRibbonCtrl(nCmdID).DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); | |
| 2827 } | |
| 2828 | |
| 2829 #ifdef _DEBUG | |
| 2830 // IUnknown methods (heavyweight) | |
| 2831 STDMETHODIMP_(ULONG) AddRef() | |
| 2832 { | |
| 2833 return InterlockedIncrement(&m_cRef); | |
| 2834 } | |
| 2835 | |
| 2836 STDMETHODIMP_(ULONG) Release() | |
| 2837 { | |
| 2838 LONG cRef = InterlockedDecrement(&m_cRef); | |
| 2839 if (cRef == 0) // NoOp for breakpoint | |
| 2840 { | |
| 2841 cRef = 0; | |
| 2842 } | |
| 2843 | |
| 2844 return cRef; | |
| 2845 } | |
| 2846 | |
| 2847 STDMETHODIMP QueryInterface(REFIID iid, void** ppv) | |
| 2848 { | |
| 2849 if (ppv == NULL) | |
| 2850 { | |
| 2851 return E_POINTER; | |
| 2852 } | |
| 2853 else if ((iid == __uuidof(IUnknown)) || | |
| 2854 (iid == __uuidof(IUICommandHandler)) || | |
| 2855 (iid == __uuidof(IUIApplication))) | |
| 2856 { | |
| 2857 *ppv = this; | |
| 2858 AddRef(); | |
| 2859 return S_OK; | |
| 2860 } | |
| 2861 else | |
| 2862 { | |
| 2863 return E_NOINTERFACE; | |
| 2864 } | |
| 2865 } | |
| 2866 | |
| 2867 LONG m_cRef; | |
| 2868 #else | |
| 2869 // IUnknown methods (lightweight) | |
| 2870 STDMETHODIMP QueryInterface(REFIID iid, void** ppv) | |
| 2871 { | |
| 2872 if ((iid == __uuidof(IUnknown)) || | |
| 2873 (iid == __uuidof(IUICommandHandler)) || | |
| 2874 (iid == __uuidof(IUIApplication))) | |
| 2875 { | |
| 2876 *ppv = this; | |
| 2877 return S_OK; | |
| 2878 } | |
| 2879 return E_NOINTERFACE; | |
| 2880 } | |
| 2881 ULONG STDMETHODCALLTYPE AddRef() | |
| 2882 { | |
| 2883 return 1; | |
| 2884 } | |
| 2885 ULONG STDMETHODCALLTYPE Release() | |
| 2886 { | |
| 2887 return 1; | |
| 2888 } | |
| 2889 #endif | |
| 2890 | |
| 2891 // CRibbonImpl ICtrl implementation | |
| 2892 virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, | |
| 2893 const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, | |
| 2894 IUISimplePropertySet* /*pCommandExecutionProperties*/) | |
| 2895 { | |
| 2896 if (key != NULL) | |
| 2897 { | |
| 2898 if(k_(*key) != k_BooleanValue) | |
| 2899 { | |
| 2900 ATLTRACE2(atlTraceUI, 0, _T("Control ID %d is not handled\n"), nCmdID); | |
| 2901 return E_NOTIMPL; | |
| 2902 } | |
| 2903 BOOL bChecked = FALSE; | |
| 2904 ATLVERIFY(SUCCEEDED(PropVariantToBoolean(*ppropvarValue, &bChecked))); | |
| 2905 CUpdateUIBase::UISetCheck(nCmdID, bChecked); | |
| 2906 } | |
| 2907 | |
| 2908 ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE); | |
| 2909 (void)verb; // avoid level 4 warning | |
| 2910 | |
| 2911 static_cast<T*>(this)->OnRibbonCommandExecute(nCmdID); | |
| 2912 | |
| 2913 return S_OK; | |
| 2914 } | |
| 2915 | |
| 2916 virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, | |
| 2917 const PROPVARIANT* /*ppropvarCurrentValue*/, PROPVARIANT* ppropvarNewValue) | |
| 2918 { | |
| 2919 T* pT = static_cast<T*>(this); | |
| 2920 HRESULT hr = E_NOTIMPL; | |
| 2921 switch (k_(key)) | |
| 2922 { | |
| 2923 case k_LargeImage: | |
| 2924 case k_LargeHighContrastImage: | |
| 2925 case k_SmallImage: | |
| 2926 case k_SmallHighContrastImage: | |
| 2927 if (HBITMAP hbm = pT->OnRibbonQueryImage(nCmdID, key)) | |
| 2928 hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), ppropvarNewValue); | |
| 2929 break; | |
| 2930 case k_Label: | |
| 2931 case k_Keytip: | |
| 2932 case k_TooltipTitle: | |
| 2933 case k_TooltipDescription: | |
| 2934 case k_LabelDescription: | |
| 2935 if (LPCWSTR sText = pT->OnRibbonQueryText(nCmdID, key)) | |
| 2936 hr = SetPropertyVal(key, sText, ppropvarNewValue); | |
| 2937 break; | |
| 2938 case k_BooleanValue: | |
| 2939 case k_Enabled: | |
| 2940 hr = SetPropertyVal(key, pT->OnRibbonQueryState(nCmdID, key), ppropvarNewValue); | |
| 2941 break; | |
| 2942 case k_ContextAvailable: | |
| 2943 hr = SetPropertyVal(key, pT->OnRibbonQueryTabAvail(nCmdID), ppropvarNewValue); | |
| 2944 break; | |
| 2945 } | |
| 2946 | |
| 2947 return hr; | |
| 2948 } | |
| 2949 | |
| 2950 // CRibbonImpl::CRibbonXXXCtrl specialized classes | |
| 2951 //CRibbonComboCtrl | |
| 2952 template <UINT t_ID, size_t t_items, size_t t_categories = 0> | |
| 2953 class CRibbonComboCtrl : public CollectionCtrlImpl<T, t_ID, ComboCollectionImpl<CRibbonComboCtrl<t_ID, t_items, t_categories>, t_items, t_categories>> | |
| 2954 { | |
| 2955 public: | |
| 2956 CRibbonComboCtrl() | |
| 2957 { } | |
| 2958 }; | |
| 2959 | |
| 2960 // CRibbonItemGalleryCtrl | |
| 2961 template <UINT t_ID, size_t t_items, size_t t_categories = 0> | |
| 2962 class CRibbonItemGalleryCtrl : public CollectionCtrlImpl<T, t_ID, ItemCollectionImpl<CRibbonItemGalleryCtrl<t_ID, t_items, t_categories>, t_items, t_categories>> | |
| 2963 { | |
| 2964 public: | |
| 2965 CRibbonItemGalleryCtrl() | |
| 2966 { } | |
| 2967 }; | |
| 2968 | |
| 2969 // CRibbonCommandGalleryCtrl | |
| 2970 template <UINT t_ID, size_t t_items, size_t t_categories = 0> | |
| 2971 class CRibbonCommandGalleryCtrl : public CollectionCtrlImpl<T, t_ID, CommandCollectionImpl<CRibbonCommandGalleryCtrl<t_ID, t_items, t_categories>, t_items, t_categories>> | |
| 2972 { | |
| 2973 public: | |
| 2974 CRibbonCommandGalleryCtrl() | |
| 2975 { } | |
| 2976 }; | |
| 2977 | |
| 2978 // CRibbonToolbarGalleryCtrl | |
| 2979 template <UINT t_ID, UINT t_idTB, size_t t_size> | |
| 2980 class CRibbonToolbarGalleryCtrl : public ToolbarGalleryCtrlImpl<T, t_ID, t_idTB, t_size> | |
| 2981 { }; | |
| 2982 | |
| 2983 // CRibbonSimpleComboCtrl | |
| 2984 template <UINT t_ID, size_t t_size> | |
| 2985 class CRibbonSimpleComboCtrl : public SimpleCollectionCtrlImpl<T, t_ID, t_size> | |
| 2986 { }; | |
| 2987 | |
| 2988 // CRibbonSimpleGalleryCtrl | |
| 2989 template <UINT t_ID, size_t t_size, UI_COMMANDTYPE t_CommandType = UI_COMMANDTYPE_ACTION> | |
| 2990 class CRibbonSimpleGalleryCtrl : public SimpleCollectionCtrlImpl<T, t_ID, t_size, t_CommandType> | |
| 2991 { }; | |
| 2992 | |
| 2993 //CRibbonRecentItemsCtrl | |
| 2994 template <UINT t_ID, class TDocList = CRecentDocumentList> | |
| 2995 class CRibbonRecentItemsCtrl : public RecentItemsCtrlImpl<T, t_ID, TDocList> | |
| 2996 { | |
| 2997 public: | |
| 2998 CRibbonRecentItemsCtrl() | |
| 2999 { } | |
| 3000 }; | |
| 3001 | |
| 3002 // CRibbonColorCtrl | |
| 3003 template <UINT t_ID> | |
| 3004 class CRibbonColorCtrl : public ColorCtrlImpl<T, t_ID> | |
| 3005 { | |
| 3006 public: | |
| 3007 CRibbonColorCtrl() | |
| 3008 { } | |
| 3009 }; | |
| 3010 | |
| 3011 //CRibbonFontCtrl | |
| 3012 template <UINT t_ID> | |
| 3013 class CRibbonFontCtrl : public FontCtrlImpl<T, t_ID> | |
| 3014 { | |
| 3015 public: | |
| 3016 CRibbonFontCtrl() | |
| 3017 { } | |
| 3018 }; | |
| 3019 | |
| 3020 // CRibbonSpinnerCtrl | |
| 3021 template <UINT t_ID> | |
| 3022 class CRibbonSpinnerCtrl : public SpinnerCtrlImpl<T, t_ID, LONG> | |
| 3023 { | |
| 3024 public: | |
| 3025 CRibbonSpinnerCtrl() | |
| 3026 { } | |
| 3027 }; | |
| 3028 | |
| 3029 // CRibbonFloatSpinnerCtrl | |
| 3030 template <UINT t_ID> | |
| 3031 class CRibbonFloatSpinnerCtrl : public SpinnerCtrlImpl<T, t_ID, DOUBLE> | |
| 3032 { | |
| 3033 public: | |
| 3034 CRibbonFloatSpinnerCtrl() | |
| 3035 { | |
| 3036 this->m_Values[4] = 1; // 1 decimal | |
| 3037 } | |
| 3038 }; | |
| 3039 | |
| 3040 // CRibbonCommandCtrl | |
| 3041 template <UINT t_ID> | |
| 3042 class CRibbonCommandCtrl : public CommandCtrlImpl<T, t_ID> | |
| 3043 { | |
| 3044 public: | |
| 3045 CRibbonCommandCtrl() | |
| 3046 { } | |
| 3047 }; | |
| 3048 | |
| 3049 // Control classes access to T instance (re-initialized in constructor) | |
| 3050 static T* pWndRibbon; | |
| 3051 }; | |
| 3052 | |
| 3053 template <class T> | |
| 3054 __declspec(selectany) T* CRibbonImpl<T>::pWndRibbon; | |
| 3055 | |
| 3056 // Control map element | |
| 3057 #pragma warning(push) | |
| 3058 #pragma warning(disable: 4510 610 4512) // missing default constructor, can't be instatiated, assignment operator could not be generated | |
| 3059 typedef struct | |
| 3060 { | |
| 3061 UINT uID; | |
| 3062 ICtrl& ctrl; | |
| 3063 } _ribbonCtrl; | |
| 3064 #pragma warning(pop) | |
| 3065 | |
| 3066 } // namespace RibbonUI | |
| 3067 | |
| 3068 | |
| 3069 /////////////////////////////////////////////////////////////////////////////// | |
| 3070 // RibbonUI Control map | |
| 3071 | |
| 3072 // Control map macros | |
| 3073 #define BEGIN_RIBBON_CONTROL_MAP(theClass) \ | |
| 3074 WTL::RibbonUI::ICtrl& GetRibbonCtrl(UINT id) \ | |
| 3075 { \ | |
| 3076 WTL::RibbonUI::_ribbonCtrl _ctrls[] = \ | |
| 3077 { | |
| 3078 | |
| 3079 #define RIBBON_CONTROL(member) {member.GetID(), static_cast<WTL::RibbonUI::ICtrl&>(member)}, | |
| 3080 | |
| 3081 #define END_RIBBON_CONTROL_MAP() \ | |
| 3082 {0, *this} \ | |
| 3083 }; \ | |
| 3084 int i = 0; \ | |
| 3085 for(; i < _countof(_ctrls) - 1; i++) \ | |
| 3086 if (_ctrls[i].uID == id) \ | |
| 3087 break; \ | |
| 3088 return _ctrls[i].ctrl; \ | |
| 3089 } | |
| 3090 | |
| 3091 // Control message map macros | |
| 3092 #define RIBBON_GALLERY_CONTROL_HANDLER(id, func) \ | |
| 3093 if((uMsg == WM_COMMAND) && (id == LOWORD(wParam))) \ | |
| 3094 { \ | |
| 3095 bHandled = TRUE; \ | |
| 3096 lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (UINT)lParam, bHandled); \ | |
| 3097 if(bHandled) \ | |
| 3098 return TRUE; \ | |
| 3099 } | |
| 3100 | |
| 3101 #define RIBBON_COMBO_CONTROL_HANDLER(id, func) \ | |
| 3102 RIBBON_GALLERY_CONTROL_HANDLER(id, func) | |
| 3103 | |
| 3104 #define RIBBON_FONT_CONTROL_HANDLER(id, func) \ | |
| 3105 if((uMsg == WM_COMMAND) && (id == LOWORD(wParam))) \ | |
| 3106 { \ | |
| 3107 bHandled = TRUE; \ | |
| 3108 lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (CHARFORMAT2*)lParam, bHandled); \ | |
| 3109 if(bHandled) \ | |
| 3110 return TRUE; \ | |
| 3111 } | |
| 3112 | |
| 3113 #define RIBBON_COLOR_CONTROL_HANDLER(id, func) \ | |
| 3114 if((uMsg == WM_COMMAND) && (id == LOWORD(wParam))) \ | |
| 3115 { \ | |
| 3116 bHandled = TRUE; \ | |
| 3117 lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (COLORREF)lParam, bHandled); \ | |
| 3118 if(bHandled) \ | |
| 3119 return TRUE; \ | |
| 3120 } | |
| 3121 | |
| 3122 #define RIBBON_SPINNER_CONTROL_HANDLER(id, func) \ | |
| 3123 if((uMsg == WM_COMMAND) && (id == wParam)) \ | |
| 3124 { \ | |
| 3125 bHandled = TRUE; \ | |
| 3126 lResult = func((WORD)wParam, (LONG)lParam, bHandled); \ | |
| 3127 if(bHandled) \ | |
| 3128 return TRUE; \ | |
| 3129 } | |
| 3130 | |
| 3131 #define RIBBON_FLOATSPINNER_CONTROL_HANDLER(id, func) \ | |
| 3132 if((uMsg == WM_COMMAND) && (id == wParam)) \ | |
| 3133 { \ | |
| 3134 bHandled = TRUE; \ | |
| 3135 lResult = func((WORD)wParam, (DOUBLE*)lParam, bHandled); \ | |
| 3136 if(bHandled) \ | |
| 3137 return TRUE; \ | |
| 3138 } | |
| 3139 | |
| 3140 // Handler prototypes | |
| 3141 /* | |
| 3142 LRESULT OnRibbonGalleryCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled); | |
| 3143 LRESULT OnRibbonComboCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled); | |
| 3144 LRESULT OnRibbonFontCtrl(UI_EXECUTIONVERB verb, WORD wID, CHARFORMAT2* pcf, BOOL& bHandled); | |
| 3145 LRESULT OnRibbonColorCtrl(UI_EXECUTIONVERB verb, WORD wID, COLORREF color, BOOL& bHandled); | |
| 3146 LRESULT OnRibbonSpinnerCtrl(WORD wID, LONG lVal, BOOL& bHandled); | |
| 3147 LRESULT OnRibbonFloatSpinnerCtrl(WORD wID, DOUBLE* pdVal, BOOL& bHandled); | |
| 3148 */ | |
| 3149 | |
| 3150 | |
| 3151 /////////////////////////////////////////////////////////////////////////////// | |
| 3152 // Ribbon frame classes | |
| 3153 | |
| 3154 // CRibbonFrameWindowImplBase | |
| 3155 // | |
| 3156 template <class T, class TFrameImpl> | |
| 3157 class ATL_NO_VTABLE CRibbonFrameWindowImplBase : public TFrameImpl, public RibbonUI::CRibbonImpl<T> | |
| 3158 { | |
| 3159 typedef TFrameImpl baseFrame; | |
| 3160 bool m_bUseCommandBarBitmaps; | |
| 3161 bool m_bWin7Fix; | |
| 3162 | |
| 3163 public: | |
| 3164 // Construction | |
| 3165 CRibbonFrameWindowImplBase(bool bUseCommandBarBitmaps = true) : | |
| 3166 m_bUseCommandBarBitmaps(bUseCommandBarBitmaps), m_bWin7Fix(false) | |
| 3167 { | |
| 3168 __if_not_exists(T::m_CmdBar) | |
| 3169 { | |
| 3170 m_bUseCommandBarBitmaps = false; | |
| 3171 } | |
| 3172 } | |
| 3173 | |
| 3174 // Win7 Aero fix helpers | |
| 3175 void ResetFrame() | |
| 3176 { | |
| 3177 const MARGINS margins = { 0, 0, 0, 0 }; | |
| 3178 ::DwmExtendFrameIntoClientArea(this->m_hWnd, &margins); | |
| 3179 } | |
| 3180 | |
| 3181 INT CalcWin7Fix() | |
| 3182 { | |
| 3183 ResetFrame(); | |
| 3184 RECT rc = {}; | |
| 3185 ::AdjustWindowRectEx(&rc, T::GetWndStyle(0), this->GetMenu() != NULL, T::GetWndExStyle(0)); | |
| 3186 return -rc.top; | |
| 3187 } | |
| 3188 | |
| 3189 bool NeedWin7Fix() | |
| 3190 { | |
| 3191 BOOL bComp = FALSE; | |
| 3192 return m_bWin7Fix && RunTimeHelper::IsWin7() && SUCCEEDED(DwmIsCompositionEnabled(&bComp)) && bComp; | |
| 3193 } | |
| 3194 | |
| 3195 // Operations | |
| 3196 bool UseCommandBarBitmaps(bool bUse) | |
| 3197 { | |
| 3198 __if_exists(T::m_CmdBar) | |
| 3199 { | |
| 3200 return m_bUseCommandBarBitmaps = bUse; | |
| 3201 } | |
| 3202 __if_not_exists(T::m_CmdBar) | |
| 3203 { | |
| 3204 (void)bUse; // avoid level 4 warning | |
| 3205 return false; | |
| 3206 } | |
| 3207 } | |
| 3208 | |
| 3209 bool ShowRibbonUI(bool bShow, INT32 imodes = UI_MAKEAPPMODE(0), LPCWSTR sResName = L"APPLICATION_RIBBON") | |
| 3210 { | |
| 3211 if (!RunTimeHelper::IsRibbonUIAvailable()) | |
| 3212 return false; | |
| 3213 | |
| 3214 ATLASSERT(this->GetIUIFrameworkPtr()); | |
| 3215 | |
| 3216 if (this->IsRibbonUI() == bShow) | |
| 3217 return bShow; | |
| 3218 | |
| 3219 bool bVisible = (this->IsWindowVisible() != FALSE); | |
| 3220 if(bVisible && !bShow) | |
| 3221 this->SetRedraw(FALSE); | |
| 3222 | |
| 3223 if (bShow && ::IsWindow(this->m_hWndToolBar)) | |
| 3224 { | |
| 3225 ::ShowWindow(this->m_hWndToolBar, SW_HIDE); | |
| 3226 UpdateLayout(); | |
| 3227 } | |
| 3228 | |
| 3229 m_bWin7Fix = !bShow; | |
| 3230 | |
| 3231 HRESULT hr = bShow ? this->CreateRibbon(sResName) : this->DestroyRibbon(); | |
| 3232 | |
| 3233 m_bWin7Fix = SUCCEEDED(hr) && !bShow; | |
| 3234 | |
| 3235 if (SUCCEEDED(hr)) | |
| 3236 { | |
| 3237 if(::IsWindow(this->m_hWndToolBar) && !bShow) | |
| 3238 { | |
| 3239 ::ShowWindow(this->m_hWndToolBar, SW_SHOWNA); | |
| 3240 UpdateLayout(); | |
| 3241 } | |
| 3242 else if (bShow) | |
| 3243 { | |
| 3244 this->PostMessage(WM_SIZE); | |
| 3245 this->SetRibbonModes(imodes); | |
| 3246 } | |
| 3247 } | |
| 3248 | |
| 3249 if(bVisible && !bShow) | |
| 3250 { | |
| 3251 this->SetRedraw(TRUE); | |
| 3252 this->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); | |
| 3253 } | |
| 3254 | |
| 3255 return SUCCEEDED(hr) ? bShow : !bShow; | |
| 3256 } | |
| 3257 | |
| 3258 // Overrideables | |
| 3259 HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY key) | |
| 3260 { | |
| 3261 if ((key == UI_PKEY_SmallImage) && m_bUseCommandBarBitmaps) | |
| 3262 { | |
| 3263 if (HBITMAP hbm = GetCommandBarBitmap(nCmdID)) | |
| 3264 return (HBITMAP)::CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); | |
| 3265 } | |
| 3266 | |
| 3267 return this->DefRibbonQueryImage(nCmdID); | |
| 3268 } | |
| 3269 | |
| 3270 BEGIN_MSG_MAP(CRibbonFrameWindowImplBase) | |
| 3271 if (!this->IsRibbonUI() && NeedWin7Fix()) | |
| 3272 { | |
| 3273 MESSAGE_HANDLER(WM_SIZING, OnSizing) | |
| 3274 MESSAGE_HANDLER(WM_SIZE, OnSize) | |
| 3275 MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) | |
| 3276 MESSAGE_HANDLER(WM_NCCALCSIZE, OnNCCalcSize) | |
| 3277 } | |
| 3278 CHAIN_MSG_MAP(CRibbonUpdateUI<T>) | |
| 3279 CHAIN_MSG_MAP(baseFrame) | |
| 3280 END_MSG_MAP() | |
| 3281 | |
| 3282 // Message handlers for Win7 Aero | |
| 3283 LRESULT OnSizing(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) | |
| 3284 { | |
| 3285 switch (wParam) | |
| 3286 { | |
| 3287 case WMSZ_TOP: | |
| 3288 case WMSZ_TOPLEFT: | |
| 3289 case WMSZ_TOPRIGHT: | |
| 3290 this->SetWindowPos(NULL, (LPRECT)lParam, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); | |
| 3291 break; | |
| 3292 default: | |
| 3293 this->DefWindowProc(); | |
| 3294 break; | |
| 3295 } | |
| 3296 | |
| 3297 return 1; // handled | |
| 3298 } | |
| 3299 | |
| 3300 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) | |
| 3301 { | |
| 3302 if (wParam != SIZE_MINIMIZED) | |
| 3303 this->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); | |
| 3304 | |
| 3305 bHandled = FALSE; | |
| 3306 return 1; | |
| 3307 } | |
| 3308 | |
| 3309 LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) | |
| 3310 { | |
| 3311 if(wParam != WA_INACTIVE) | |
| 3312 this->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); | |
| 3313 | |
| 3314 bHandled = FALSE; | |
| 3315 return 1; | |
| 3316 } | |
| 3317 | |
| 3318 LRESULT OnNCCalcSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) | |
| 3319 { | |
| 3320 ATLASSERT(!this->IsRibbonUI() && NeedWin7Fix()); | |
| 3321 | |
| 3322 LRESULT lRet = this->DefWindowProc(); | |
| 3323 | |
| 3324 if(wParam) | |
| 3325 { | |
| 3326 LPNCCALCSIZE_PARAMS pParams = (LPNCCALCSIZE_PARAMS)lParam; | |
| 3327 pParams->rgrc[0].top = pParams->rgrc[1].top + CalcWin7Fix(); | |
| 3328 } | |
| 3329 | |
| 3330 return lRet; | |
| 3331 } | |
| 3332 | |
| 3333 // Overrides | |
| 3334 void UpdateLayout(BOOL bResizeBars = TRUE) | |
| 3335 { | |
| 3336 RECT rect = {}; | |
| 3337 this->GetClientRect(&rect); | |
| 3338 | |
| 3339 if (this->IsRibbonUI() && !this->IsRibbonHidden()) | |
| 3340 { | |
| 3341 rect.top += this->GetRibbonHeight(); | |
| 3342 } | |
| 3343 else if (!this->IsRibbonUI() && NeedWin7Fix()) | |
| 3344 { | |
| 3345 ResetFrame(); | |
| 3346 } | |
| 3347 | |
| 3348 // position bars and offset their dimensions | |
| 3349 this->UpdateBarsPosition(rect, bResizeBars); | |
| 3350 | |
| 3351 // resize client window | |
| 3352 if(this->m_hWndClient != NULL) | |
| 3353 ::SetWindowPos(this->m_hWndClient, NULL, rect.left, rect.top, | |
| 3354 rect.right - rect.left, rect.bottom - rect.top, | |
| 3355 SWP_NOZORDER | SWP_NOACTIVATE); | |
| 3356 } | |
| 3357 | |
| 3358 // Implementation | |
| 3359 HBITMAP GetCommandBarBitmap(UINT nCmdID) | |
| 3360 { | |
| 3361 __if_exists (T::m_CmdBar) | |
| 3362 { | |
| 3363 ATLASSERT(RunTimeHelper::IsVista()); | |
| 3364 T* pT =static_cast<T*>(this); | |
| 3365 int nIndex = pT->m_CmdBar.m_arrCommand.Find((WORD&)nCmdID); | |
| 3366 return (nIndex == -1) ? NULL : pT->m_CmdBar.m_arrVistaBitmap[nIndex]; | |
| 3367 } | |
| 3368 __if_not_exists (T::m_CmdBar) | |
| 3369 { | |
| 3370 (void)nCmdID; // avoid level 4 warning | |
| 3371 return NULL; | |
| 3372 } | |
| 3373 } | |
| 3374 }; | |
| 3375 | |
| 3376 // CRibbonFrameWindowImpl | |
| 3377 // | |
| 3378 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits> | |
| 3379 class ATL_NO_VTABLE CRibbonFrameWindowImpl : public CRibbonFrameWindowImplBase<T, CFrameWindowImpl<T, TBase, TWinTraits>> | |
| 3380 { }; | |
| 3381 | |
| 3382 // CRibbonMDIFrameWindowImpl | |
| 3383 // | |
| 3384 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CFrameWinTraits> | |
| 3385 class ATL_NO_VTABLE CRibbonMDIFrameWindowImpl : public CRibbonFrameWindowImplBase<T, CMDIFrameWindowImpl<T, TBase, TWinTraits>> | |
| 3386 { }; | |
| 3387 | |
| 3388 | |
| 3389 /////////////////////////////////////////////////////////////////////////////// | |
| 3390 // CRibbonPersist helper for RibbonUI persistency | |
| 3391 | |
| 3392 class CRibbonPersist | |
| 3393 { | |
| 3394 public: | |
| 3395 CRibbonPersist(LPCWSTR sAppKey) | |
| 3396 { | |
| 3397 ATLASSERT(sAppKey && *sAppKey); | |
| 3398 m_Key.Create(HKEY_CURRENT_USER, sAppKey); | |
| 3399 ATLASSERT(m_Key.m_hKey); | |
| 3400 } | |
| 3401 | |
| 3402 ATL::CRegKey m_Key; | |
| 3403 | |
| 3404 LONG Save(bool bRibbonUI, HGLOBAL hgSettings = NULL) | |
| 3405 { | |
| 3406 ATL::CRegKey key; | |
| 3407 const DWORD dwUI = bRibbonUI; | |
| 3408 | |
| 3409 LONG lRet = key.Create(m_Key, L"Ribbon"); | |
| 3410 if(lRet != ERROR_SUCCESS) | |
| 3411 return lRet; | |
| 3412 | |
| 3413 lRet = key.SetDWORDValue(L"UI", dwUI); | |
| 3414 if(lRet != ERROR_SUCCESS) | |
| 3415 return lRet; | |
| 3416 | |
| 3417 if (hgSettings != NULL) | |
| 3418 { | |
| 3419 LPBYTE pVal = (LPBYTE)::GlobalLock(hgSettings); | |
| 3420 if (pVal != NULL) | |
| 3421 { | |
| 3422 lRet = key.SetBinaryValue(L"Settings", pVal, (ULONG)::GlobalSize(hgSettings)); | |
| 3423 ::GlobalUnlock(hgSettings); | |
| 3424 } | |
| 3425 else | |
| 3426 { | |
| 3427 lRet = GetLastError(); | |
| 3428 } | |
| 3429 } | |
| 3430 | |
| 3431 return lRet; | |
| 3432 } | |
| 3433 | |
| 3434 LONG Restore(bool& bRibbonUI, HGLOBAL& hgSettings) | |
| 3435 { | |
| 3436 ATLASSERT(hgSettings == NULL); | |
| 3437 | |
| 3438 ATL::CRegKey key; | |
| 3439 | |
| 3440 LONG lRet = key.Open(m_Key, L"Ribbon"); | |
| 3441 if(lRet != ERROR_SUCCESS) | |
| 3442 return lRet; | |
| 3443 | |
| 3444 DWORD dwUI = 0xffff; | |
| 3445 lRet = key.QueryDWORDValue(L"UI", dwUI); | |
| 3446 if(lRet == ERROR_SUCCESS) | |
| 3447 bRibbonUI = dwUI == 1; | |
| 3448 else | |
| 3449 return lRet; | |
| 3450 | |
| 3451 ULONG ulSize = 0; | |
| 3452 lRet = key.QueryBinaryValue(L"Settings", NULL, &ulSize); | |
| 3453 if (lRet == ERROR_SUCCESS) | |
| 3454 { | |
| 3455 ATLASSERT(ulSize != 0); | |
| 3456 | |
| 3457 hgSettings = ::GlobalAlloc(GHND, ulSize); | |
| 3458 if (hgSettings != NULL) | |
| 3459 { | |
| 3460 LPBYTE pData = (LPBYTE)::GlobalLock(hgSettings); | |
| 3461 if (pData != NULL) | |
| 3462 { | |
| 3463 lRet = key.QueryBinaryValue(L"Settings", pData, &ulSize); | |
| 3464 } | |
| 3465 else | |
| 3466 { | |
| 3467 lRet = GetLastError(); | |
| 3468 ::GlobalFree(hgSettings); | |
| 3469 hgSettings = NULL; | |
| 3470 } | |
| 3471 } | |
| 3472 else | |
| 3473 { | |
| 3474 lRet = GetLastError(); | |
| 3475 } | |
| 3476 } | |
| 3477 return lRet; | |
| 3478 } | |
| 3479 | |
| 3480 LONG Delete() | |
| 3481 { | |
| 3482 return m_Key.DeleteSubKey(L"Ribbon"); | |
| 3483 } | |
| 3484 }; | |
| 3485 | |
| 3486 } // namespace WTL | |
| 3487 | |
| 3488 #endif // __ATLRIBBON_H__ |
