toolbarButton.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include "main.h"
  2. #include "./toolbarButton.h"
  3. #include "./toolbar.h"
  4. #include "./graphics.h"
  5. #include "./resource.h"
  6. #include "../Plugins/General/gen_ml/ml_ipc_0313.h"
  7. #include <strsafe.h>
  8. #define CMDLINK_SPACECX_UNITS 2
  9. ToolbarButton::ToolbarButton(LPCSTR pszName, INT nCommand, UINT nStyle, INT nIcon, LPCWSTR pszText, LPCWSTR pszDescription) :
  10. ToolbarItem(pszName, nStyle, nIcon, pszText, pszDescription),
  11. commandId(nCommand), offsetX(0), offsetY(0), rgbText(0), rgbHilite(0)
  12. {
  13. }
  14. ToolbarItem* CALLBACK ToolbarButton::CreateInstance(ToolbarItem::Template *item)
  15. {
  16. if (NULL == item)
  17. return NULL;
  18. return new ToolbarButton( (NULL != item->name) ? item->name : TOOLCLS_BUTTON,
  19. item->commandId,
  20. item->style,
  21. item->iconId,
  22. item->text,
  23. item->description);
  24. }
  25. static LPCTSTR ToolbarButton_GetResourceString(LPCTSTR pszResource, LPTSTR pszBuffer, INT cchBufferMax)
  26. {
  27. if (IS_INTRESOURCE(pszResource))
  28. {
  29. Plugin_LoadString((INT)(INT_PTR)pszResource, pszBuffer, cchBufferMax);
  30. return pszBuffer;
  31. }
  32. return pszResource;
  33. }
  34. static BOOL ToolbarButton_GetTextSise(HWND hToolbar, LPCWSTR pszText, INT cchText, SIZE *textSize, TEXTMETRIC *ptm)
  35. {
  36. if (NULL == textSize)
  37. return FALSE;
  38. if (cchText < 0)
  39. cchText = lstrlenW(pszText);
  40. HDC hdc = GetDCEx(hToolbar, NULL, DCX_CACHE | DCX_NORESETATTRS);
  41. if (NULL == hdc) return FALSE;
  42. BOOL result = FALSE;
  43. HFONT font = (HFONT)SendMessage(hToolbar, WM_GETFONT, 0, 0L);
  44. HFONT originalFont = (HFONT)SelectObject(hdc, font);
  45. if (NULL != ptm && !GetTextMetrics(hdc, ptm))
  46. ZeroMemory(ptm, sizeof(TEXTMETRIC));
  47. if (0 != cchText)
  48. {
  49. if (GetTextExtentPoint32(hdc, pszText, cchText, textSize))
  50. result = TRUE;
  51. }
  52. else
  53. ZeroMemory(textSize, sizeof(SIZE));
  54. SelectObject(hdc, originalFont);
  55. ReleaseDC(hToolbar, hdc);
  56. return result;
  57. }
  58. BOOL ToolbarButton::AdjustRect(HWND hToolbar, RECT *proposedRect)
  59. {
  60. if (0 != (ToolbarButton::styleCommandLink & style))
  61. {
  62. SIZE linkSize = {0};
  63. LPCTSTR pszText;
  64. WCHAR szBuffer[128] = {0};
  65. TOOLBARTEXTMETRIC ttm = {0};
  66. pszText = ToolbarButton_GetResourceString(text, szBuffer, ARRAYSIZE(szBuffer));
  67. if (!ToolbarButton_GetTextSise(hToolbar, pszText, -1, &linkSize, NULL))
  68. ZeroMemory(&linkSize, sizeof(SIZE));
  69. if (!Toolbar_GetTextMetrics(hToolbar, &ttm))
  70. ZeroMemory(&ttm, sizeof(TOOLBARTEXTMETRIC));
  71. offsetX = MulDiv(CMDLINK_SPACECX_UNITS, ttm.aveCharWidth, 4);
  72. offsetY = ttm.baseY;
  73. proposedRect->right = proposedRect->left + linkSize.cx + 2 * offsetX + ttm.overhang;
  74. proposedRect->top = ttm.origY;
  75. proposedRect->bottom = proposedRect->top + ttm.height;
  76. return TRUE;
  77. }
  78. SIZE iconSize;
  79. if (!Toolbar_GetIconSize(hToolbar, iconId, &iconSize))
  80. ZeroMemory(&iconSize, sizeof(SIZE));
  81. proposedRect->right = proposedRect->left + iconSize.cx;
  82. INT offsetY = (proposedRect->bottom - proposedRect->top) - iconSize.cy;
  83. if (0 != offsetY)
  84. {
  85. proposedRect->top += offsetY/2;
  86. if (0 != (offsetY%2)) proposedRect->top++;
  87. }
  88. proposedRect->bottom = proposedRect->top + iconSize.cy;
  89. return TRUE;
  90. }
  91. void ToolbarButton::UpdateSkin(HWND hToolbar)
  92. {
  93. rgbText = Toolbar_GetTextColor(hToolbar);
  94. rgbHilite = Toolbar_GetHiliteColor(hToolbar);
  95. }
  96. BOOL ToolbarButton::Paint(HWND hToolbar, HDC hdc, const RECT *paintRect, UINT state)
  97. {
  98. if (statePressed == ((statePressed | stateHighlighted) & state))
  99. state &= ~statePressed;
  100. if (0 != (ToolbarButton::styleCommandLink & style))
  101. {
  102. LPCTSTR pszText;
  103. WCHAR szBuffer[256] = {0};
  104. pszText = ToolbarButton_GetResourceString(text, szBuffer, ARRAYSIZE(szBuffer));
  105. INT cchText = lstrlen(pszText);
  106. if (0 == cchText)
  107. return FALSE;
  108. COLORREF originalFg = GetTextColor(hdc);
  109. COLORREF rgbFg = (0 == (stateHighlighted & style)) ? rgbText : rgbHilite;
  110. SetTextColor(hdc, rgbFg);
  111. INT originalMode = SetBkMode(hdc, TRANSPARENT);
  112. UINT originalAlign = SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
  113. ExtTextOut(hdc, rect.left + offsetX, rect.top + offsetY, ETO_CLIPPED | ETO_OPAQUE, &rect, pszText, cchText, NULL);
  114. if (TRANSPARENT != originalMode) SetBkMode(hdc, originalMode);
  115. if ((TA_LEFT | TA_BASELINE) != originalAlign) SetTextAlign(hdc, originalAlign);
  116. if (0 != (stateHighlighted & style))
  117. {
  118. COLORREF originalBk = SetBkColor(hdc, rgbFg);
  119. RECT partRect;
  120. ::SetRect(&partRect, rect.left + offsetX, rect.top + offsetY + 1, rect.right - offsetX, rect.top + offsetY + 2);
  121. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &partRect, NULL, 0, NULL);
  122. SetBkColor(hdc, originalBk);
  123. }
  124. if (rgbFg != originalFg)
  125. SetTextColor(hdc, originalFg);
  126. return TRUE;
  127. }
  128. TOOLBARDRAWICONPARAM param;
  129. param.hdcDst = hdc;
  130. param.iconIndex = iconId;
  131. param.x = rect.left;
  132. param.y = rect.top;
  133. param.cx = rect.right - rect.left;
  134. param.cy = rect.bottom - rect.top;
  135. param.itemState = state;
  136. if (Toolbar_DrawIcon(hToolbar, &param))
  137. {
  138. if (stateFocused == ((stateFocused | stateNoFocusRect) & state))
  139. {
  140. RECT focusRect;
  141. CopyRect(&focusRect, &rect);
  142. focusRect.left += 1;
  143. focusRect.top += 2;
  144. focusRect.bottom -= 1;
  145. COLORREF origBk = SetBkColor(hdc, 0x00000000);
  146. COLORREF origFg = SetTextColor(hdc, 0x00FFFFFF);
  147. DrawFocusRect(hdc, &focusRect);
  148. if (origBk != 0x00000000) SetBkColor(hdc, origBk);
  149. if (origFg != 0x00FFFFFF) SetTextColor(hdc, origFg);
  150. }
  151. return TRUE;
  152. }
  153. return FALSE;
  154. }
  155. INT ToolbarButton::GetTip(LPTSTR pszBuffer, INT cchBufferMax)
  156. {
  157. if (IS_INTRESOURCE(description))
  158. {
  159. if (NULL == pszBuffer || cchBufferMax < 1)
  160. return 0;
  161. Plugin_LoadString((INT)(INT_PTR)description, pszBuffer, cchBufferMax);
  162. return lstrlen(pszBuffer);
  163. }
  164. size_t remaining;
  165. HRESULT hr = StringCchCopyEx(pszBuffer, cchBufferMax, description, NULL, &remaining, STRSAFE_IGNORE_NULLS);
  166. return SUCCEEDED(hr) ? (cchBufferMax - (INT)remaining) : 0;
  167. }
  168. BOOL ToolbarButton::PtInItem(POINT pt)
  169. {
  170. return (pt.x >= (rect.left + offsetX) && pt.x < (rect.right - offsetX) && rect.bottom != rect.top);
  171. }
  172. INT ToolbarButton::GetCommandId()
  173. {
  174. return commandId;
  175. }
  176. void ToolbarButton::MouseMove(HWND hToolbar, UINT mouseFlags, POINT pt)
  177. {
  178. UINT styleNew = (PtInItem(pt)) ? stateHighlighted : 0;
  179. SetStyle(hToolbar, styleNew, stateHighlighted);
  180. }
  181. void ToolbarButton::MouseLeave(HWND hToolbar)
  182. {
  183. if (0 != (stateHighlighted & style))
  184. {
  185. SetStyle(hToolbar, 0, stateHighlighted);
  186. }
  187. }
  188. void ToolbarButton::LButtonDown(HWND hToolbar, UINT mouseFlags, POINT pt)
  189. {
  190. SetStyle(hToolbar, statePressed, statePressed);
  191. }
  192. void ToolbarButton::LButtonUp(HWND hToolbar, UINT mouseFlags, POINT pt)
  193. {
  194. SetStyle(hToolbar, 0, statePressed);
  195. }
  196. void ToolbarButton::Click(HWND hToolbar, UINT mouseFlags, POINT pt)
  197. {
  198. if (0 != commandId)
  199. {
  200. Toolbar_SendCommand(hToolbar, commandId);
  201. }
  202. }
  203. BOOL ToolbarButton::FillMenuInfo(HWND hToolbar, MENUITEMINFO *pmii, LPWSTR pszBuffer, INT cchBufferMax)
  204. {
  205. pmii->fMask = MIIM_STRING | MIIM_ID | MIIM_STATE;
  206. pmii->wID = commandId;
  207. pmii->fState = MFS_UNHILITE;
  208. pmii->fState |= ((0 == (stateDisabled & style)) ? MFS_ENABLED : MFS_DISABLED);
  209. pmii->dwTypeData = pszBuffer;
  210. if (IS_INTRESOURCE(text))
  211. {
  212. Plugin_LoadString((INT)(INT_PTR)text, pszBuffer, cchBufferMax);
  213. }
  214. else
  215. {
  216. if (FAILED(StringCchCopyEx(pszBuffer, cchBufferMax, text, NULL, NULL, STRSAFE_IGNORE_NULLS)))
  217. pszBuffer[0] = L'\0';
  218. }
  219. return TRUE;
  220. }
  221. BOOL ToolbarButton::KeyDown(HWND hToolbar, INT vKey, UINT flags)
  222. {
  223. switch(vKey)
  224. {
  225. case VK_SPACE:
  226. case VK_RETURN:
  227. SetStyle(hToolbar, statePressed | stateHighlighted, statePressed | stateHighlighted);
  228. return TRUE;
  229. }
  230. return FALSE;
  231. }
  232. BOOL ToolbarButton::KeyUp(HWND hToolbar, INT vKey, UINT flags)
  233. {
  234. switch(vKey)
  235. {
  236. case VK_SPACE:
  237. case VK_RETURN:
  238. if (0 != (statePressed & style))
  239. {
  240. SetStyle(hToolbar, 0, (statePressed | stateHighlighted));
  241. if (0 != commandId)
  242. Toolbar_SendCommand(hToolbar, commandId);
  243. }
  244. return TRUE;
  245. }
  246. return FALSE;
  247. }
  248. void ToolbarButton::SetFocus(HWND hToolbar, ToolbarItem *focusItem, BOOL fSet)
  249. {
  250. InvalidateRect(hToolbar, &rect, FALSE);
  251. }