#include "main.h" #include "./toolbarButton.h" #include "./toolbar.h" #include "./graphics.h" #include "./resource.h" #include "../Plugins/General/gen_ml/ml_ipc_0313.h" #include #define CMDLINK_SPACECX_UNITS 2 ToolbarButton::ToolbarButton(LPCSTR pszName, INT nCommand, UINT nStyle, INT nIcon, LPCWSTR pszText, LPCWSTR pszDescription) : ToolbarItem(pszName, nStyle, nIcon, pszText, pszDescription), commandId(nCommand), offsetX(0), offsetY(0), rgbText(0), rgbHilite(0) { } ToolbarItem* CALLBACK ToolbarButton::CreateInstance(ToolbarItem::Template *item) { if (NULL == item) return NULL; return new ToolbarButton( (NULL != item->name) ? item->name : TOOLCLS_BUTTON, item->commandId, item->style, item->iconId, item->text, item->description); } static LPCTSTR ToolbarButton_GetResourceString(LPCTSTR pszResource, LPTSTR pszBuffer, INT cchBufferMax) { if (IS_INTRESOURCE(pszResource)) { Plugin_LoadString((INT)(INT_PTR)pszResource, pszBuffer, cchBufferMax); return pszBuffer; } return pszResource; } static BOOL ToolbarButton_GetTextSise(HWND hToolbar, LPCWSTR pszText, INT cchText, SIZE *textSize, TEXTMETRIC *ptm) { if (NULL == textSize) return FALSE; if (cchText < 0) cchText = lstrlenW(pszText); HDC hdc = GetDCEx(hToolbar, NULL, DCX_CACHE | DCX_NORESETATTRS); if (NULL == hdc) return FALSE; BOOL result = FALSE; HFONT font = (HFONT)SendMessage(hToolbar, WM_GETFONT, 0, 0L); HFONT originalFont = (HFONT)SelectObject(hdc, font); if (NULL != ptm && !GetTextMetrics(hdc, ptm)) ZeroMemory(ptm, sizeof(TEXTMETRIC)); if (0 != cchText) { if (GetTextExtentPoint32(hdc, pszText, cchText, textSize)) result = TRUE; } else ZeroMemory(textSize, sizeof(SIZE)); SelectObject(hdc, originalFont); ReleaseDC(hToolbar, hdc); return result; } BOOL ToolbarButton::AdjustRect(HWND hToolbar, RECT *proposedRect) { if (0 != (ToolbarButton::styleCommandLink & style)) { SIZE linkSize = {0}; LPCTSTR pszText; WCHAR szBuffer[128] = {0}; TOOLBARTEXTMETRIC ttm = {0}; pszText = ToolbarButton_GetResourceString(text, szBuffer, ARRAYSIZE(szBuffer)); if (!ToolbarButton_GetTextSise(hToolbar, pszText, -1, &linkSize, NULL)) ZeroMemory(&linkSize, sizeof(SIZE)); if (!Toolbar_GetTextMetrics(hToolbar, &ttm)) ZeroMemory(&ttm, sizeof(TOOLBARTEXTMETRIC)); offsetX = MulDiv(CMDLINK_SPACECX_UNITS, ttm.aveCharWidth, 4); offsetY = ttm.baseY; proposedRect->right = proposedRect->left + linkSize.cx + 2 * offsetX + ttm.overhang; proposedRect->top = ttm.origY; proposedRect->bottom = proposedRect->top + ttm.height; return TRUE; } SIZE iconSize; if (!Toolbar_GetIconSize(hToolbar, iconId, &iconSize)) ZeroMemory(&iconSize, sizeof(SIZE)); proposedRect->right = proposedRect->left + iconSize.cx; INT offsetY = (proposedRect->bottom - proposedRect->top) - iconSize.cy; if (0 != offsetY) { proposedRect->top += offsetY/2; if (0 != (offsetY%2)) proposedRect->top++; } proposedRect->bottom = proposedRect->top + iconSize.cy; return TRUE; } void ToolbarButton::UpdateSkin(HWND hToolbar) { rgbText = Toolbar_GetTextColor(hToolbar); rgbHilite = Toolbar_GetHiliteColor(hToolbar); } BOOL ToolbarButton::Paint(HWND hToolbar, HDC hdc, const RECT *paintRect, UINT state) { if (statePressed == ((statePressed | stateHighlighted) & state)) state &= ~statePressed; if (0 != (ToolbarButton::styleCommandLink & style)) { LPCTSTR pszText; WCHAR szBuffer[256] = {0}; pszText = ToolbarButton_GetResourceString(text, szBuffer, ARRAYSIZE(szBuffer)); INT cchText = lstrlen(pszText); if (0 == cchText) return FALSE; COLORREF originalFg = GetTextColor(hdc); COLORREF rgbFg = (0 == (stateHighlighted & style)) ? rgbText : rgbHilite; SetTextColor(hdc, rgbFg); INT originalMode = SetBkMode(hdc, TRANSPARENT); UINT originalAlign = SetTextAlign(hdc, TA_LEFT | TA_BASELINE); ExtTextOut(hdc, rect.left + offsetX, rect.top + offsetY, ETO_CLIPPED | ETO_OPAQUE, &rect, pszText, cchText, NULL); if (TRANSPARENT != originalMode) SetBkMode(hdc, originalMode); if ((TA_LEFT | TA_BASELINE) != originalAlign) SetTextAlign(hdc, originalAlign); if (0 != (stateHighlighted & style)) { COLORREF originalBk = SetBkColor(hdc, rgbFg); RECT partRect; ::SetRect(&partRect, rect.left + offsetX, rect.top + offsetY + 1, rect.right - offsetX, rect.top + offsetY + 2); ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &partRect, NULL, 0, NULL); SetBkColor(hdc, originalBk); } if (rgbFg != originalFg) SetTextColor(hdc, originalFg); return TRUE; } TOOLBARDRAWICONPARAM param; param.hdcDst = hdc; param.iconIndex = iconId; param.x = rect.left; param.y = rect.top; param.cx = rect.right - rect.left; param.cy = rect.bottom - rect.top; param.itemState = state; if (Toolbar_DrawIcon(hToolbar, ¶m)) { if (stateFocused == ((stateFocused | stateNoFocusRect) & state)) { RECT focusRect; CopyRect(&focusRect, &rect); focusRect.left += 1; focusRect.top += 2; focusRect.bottom -= 1; COLORREF origBk = SetBkColor(hdc, 0x00000000); COLORREF origFg = SetTextColor(hdc, 0x00FFFFFF); DrawFocusRect(hdc, &focusRect); if (origBk != 0x00000000) SetBkColor(hdc, origBk); if (origFg != 0x00FFFFFF) SetTextColor(hdc, origFg); } return TRUE; } return FALSE; } INT ToolbarButton::GetTip(LPTSTR pszBuffer, INT cchBufferMax) { if (IS_INTRESOURCE(description)) { if (NULL == pszBuffer || cchBufferMax < 1) return 0; Plugin_LoadString((INT)(INT_PTR)description, pszBuffer, cchBufferMax); return lstrlen(pszBuffer); } size_t remaining; HRESULT hr = StringCchCopyEx(pszBuffer, cchBufferMax, description, NULL, &remaining, STRSAFE_IGNORE_NULLS); return SUCCEEDED(hr) ? (cchBufferMax - (INT)remaining) : 0; } BOOL ToolbarButton::PtInItem(POINT pt) { return (pt.x >= (rect.left + offsetX) && pt.x < (rect.right - offsetX) && rect.bottom != rect.top); } INT ToolbarButton::GetCommandId() { return commandId; } void ToolbarButton::MouseMove(HWND hToolbar, UINT mouseFlags, POINT pt) { UINT styleNew = (PtInItem(pt)) ? stateHighlighted : 0; SetStyle(hToolbar, styleNew, stateHighlighted); } void ToolbarButton::MouseLeave(HWND hToolbar) { if (0 != (stateHighlighted & style)) { SetStyle(hToolbar, 0, stateHighlighted); } } void ToolbarButton::LButtonDown(HWND hToolbar, UINT mouseFlags, POINT pt) { SetStyle(hToolbar, statePressed, statePressed); } void ToolbarButton::LButtonUp(HWND hToolbar, UINT mouseFlags, POINT pt) { SetStyle(hToolbar, 0, statePressed); } void ToolbarButton::Click(HWND hToolbar, UINT mouseFlags, POINT pt) { if (0 != commandId) { Toolbar_SendCommand(hToolbar, commandId); } } BOOL ToolbarButton::FillMenuInfo(HWND hToolbar, MENUITEMINFO *pmii, LPWSTR pszBuffer, INT cchBufferMax) { pmii->fMask = MIIM_STRING | MIIM_ID | MIIM_STATE; pmii->wID = commandId; pmii->fState = MFS_UNHILITE; pmii->fState |= ((0 == (stateDisabled & style)) ? MFS_ENABLED : MFS_DISABLED); pmii->dwTypeData = pszBuffer; if (IS_INTRESOURCE(text)) { Plugin_LoadString((INT)(INT_PTR)text, pszBuffer, cchBufferMax); } else { if (FAILED(StringCchCopyEx(pszBuffer, cchBufferMax, text, NULL, NULL, STRSAFE_IGNORE_NULLS))) pszBuffer[0] = L'\0'; } return TRUE; } BOOL ToolbarButton::KeyDown(HWND hToolbar, INT vKey, UINT flags) { switch(vKey) { case VK_SPACE: case VK_RETURN: SetStyle(hToolbar, statePressed | stateHighlighted, statePressed | stateHighlighted); return TRUE; } return FALSE; } BOOL ToolbarButton::KeyUp(HWND hToolbar, INT vKey, UINT flags) { switch(vKey) { case VK_SPACE: case VK_RETURN: if (0 != (statePressed & style)) { SetStyle(hToolbar, 0, (statePressed | stateHighlighted)); if (0 != commandId) Toolbar_SendCommand(hToolbar, commandId); } return TRUE; } return FALSE; } void ToolbarButton::SetFocus(HWND hToolbar, ToolbarItem *focusItem, BOOL fSet) { InvalidateRect(hToolbar, &rect, FALSE); }