1
0

ratingMenuCustomizer.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "main.h"
  2. #include "./ratingMenuCustomizer.h"
  3. #include "./ifc_skinhelper.h"
  4. #include "./ifc_skinnedrating.h"
  5. #include "../Plugins/General/gen_ml/ml_ipc_0313.h"
  6. #define RATING_MINSPACECX 16
  7. RatingMenuCustomizer::RatingMenuCustomizer(HMENU hMenu, ifc_skinnedrating *skinnedRating)
  8. : ref(1), menu(hMenu), skin(skinnedRating)
  9. {
  10. if (NULL != skin)
  11. skin->AddRef();
  12. }
  13. RatingMenuCustomizer::~RatingMenuCustomizer()
  14. {
  15. if (NULL != skin)
  16. skin->Release();
  17. }
  18. HRESULT RatingMenuCustomizer::CreateInstance(HMENU hMenu, ifc_skinnedrating *skinnedRating, RatingMenuCustomizer **instance)
  19. {
  20. if (NULL == instance) return E_POINTER;
  21. *instance = NULL;
  22. if (NULL == hMenu || NULL == skinnedRating) return E_INVALIDARG;
  23. *instance = new RatingMenuCustomizer(hMenu, skinnedRating);
  24. if (NULL == *instance) return E_OUTOFMEMORY;
  25. return S_OK;
  26. }
  27. size_t RatingMenuCustomizer::AddRef()
  28. {
  29. return InterlockedIncrement((LONG*)&ref);
  30. }
  31. size_t RatingMenuCustomizer::Release()
  32. {
  33. if (0 == ref)
  34. return ref;
  35. LONG r = InterlockedDecrement((LONG*)&ref);
  36. if (0 == r)
  37. delete(this);
  38. return r;
  39. }
  40. int RatingMenuCustomizer::QueryInterface(GUID interface_guid, void **object)
  41. {
  42. if (NULL == object) return E_POINTER;
  43. if (IsEqualIID(interface_guid, IFC_MenuCustomizer))
  44. *object = static_cast<ifc_menucustomizer*>(this);
  45. else
  46. {
  47. *object = NULL;
  48. return E_NOINTERFACE;
  49. }
  50. if (NULL == *object)
  51. return E_UNEXPECTED;
  52. AddRef();
  53. return S_OK;
  54. }
  55. INT RatingMenuCustomizer::CustomDraw(HMENU menuInstance, INT action, HDC hdc, LPARAM param)
  56. {
  57. if (menuInstance != menu)
  58. return FALSE;
  59. switch(action)
  60. {
  61. case MLMENU_ACTION_MEASUREITEM: return MeasureRating(hdc, (MEASUREITEMSTRUCT*)param);
  62. case MLMENU_ACTION_DRAWITEM: return MLMENU_WANT_DRAWPART;
  63. case MLMENU_ACTION_DRAWBACK: break;
  64. case MLMENU_ACTION_DRAWICON: break;
  65. case MLMENU_ACTION_DRAWTEXT: return DrawRating(hdc, (DRAWITEMSTRUCT*)param);
  66. }
  67. return FALSE;
  68. }
  69. HRESULT RatingMenuCustomizer::GetValue(INT itemId, INT *valueOut)
  70. {
  71. if (NULL == menu) return E_UNEXPECTED;
  72. WCHAR szBuffer[32] = {0};
  73. INT cchBuffer = GetMenuStringW(menu, itemId, szBuffer, ARRAYSIZE(szBuffer), MF_BYCOMMAND);
  74. if (cchBuffer < 1 || cchBuffer > 5)
  75. return E_INVALIDARG;
  76. for (INT i = 1; i < cchBuffer; i++)
  77. {
  78. if (szBuffer[i -1] != szBuffer[i])
  79. return E_INVALIDARG;
  80. }
  81. if (NULL != valueOut)
  82. *valueOut = cchBuffer;
  83. return S_OK;
  84. }
  85. INT RatingMenuCustomizer::MeasureRating(HDC hdc, MEASUREITEMSTRUCT *pmis)
  86. {
  87. RECT rect;
  88. if (NULL == skin || NULL == hdc ||
  89. FAILED(GetValue(pmis->itemID, NULL)) ||
  90. FAILED(skin->CalcMinRect(5, &rect)))
  91. {
  92. return FALSE;
  93. }
  94. pmis->itemHeight = rect.bottom - rect.top + 6;
  95. TEXTMETRIC tm;
  96. if (GetTextMetrics(hdc, &tm) &&
  97. (UINT)(tm.tmHeight + 2) > pmis->itemHeight)
  98. {
  99. pmis->itemHeight = tm.tmHeight + 2;
  100. }
  101. INT spaceCX = (pmis->itemHeight > RATING_MINSPACECX) ? pmis->itemHeight : RATING_MINSPACECX;
  102. pmis->itemWidth = rect.right - rect.left + (2 * spaceCX) - (GetSystemMetrics(SM_CXMENUCHECK) - 1);
  103. return TRUE;
  104. }
  105. INT RatingMenuCustomizer::DrawRating(HDC hdc, DRAWITEMSTRUCT *pdis)
  106. {
  107. INT value;
  108. if (NULL == skin || NULL == hdc || FAILED(GetValue(pdis->itemID, &value)))
  109. return FALSE;
  110. INT spaceCX = ((pdis->rcItem.bottom - pdis->rcItem.top) > RATING_MINSPACECX) ?
  111. (pdis->rcItem.bottom - pdis->rcItem.top) :
  112. RATING_MINSPACECX;
  113. RECT rect;
  114. CopyRect(&rect, &pdis->rcItem);
  115. rect.left += spaceCX;
  116. UINT menuState = GetMenuState(menu, pdis->itemID, MF_BYCOMMAND);
  117. UINT trackingValue = (0 == ((MF_DISABLED | MF_GRAYED) & menuState)) ? value : 0;
  118. return SUCCEEDED(skin->Draw(hdc, 5, value, trackingValue, &rect, RDS_LEFT | RDS_VCENTER | RDS_HOT));
  119. }
  120. #define CBCLASS RatingMenuCustomizer
  121. START_DISPATCH;
  122. CB(API_CUSTOMDRAW, CustomDraw);
  123. END_DISPATCH;
  124. #undef CBCLASS