static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) { static const int states[] = { PBS_NORMAL, PBS_DISABLED, PBS_HOT, PBS_PRESSED, PBS_DEFAULTED }; RECT bgRect, textRect; HFONT font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; int state = states[ drawState ]; WCHAR *text = get_button_text(hwnd); GetClientRect(hwnd, &bgRect); GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect, &textRect); if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state)) DrawThemeParentBackground(hwnd, hDC, NULL); DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL); if (text) { DrawThemeText(theme, hDC, BP_PUSHBUTTON, state, text, lstrlenW(text), dtFlags, 0, &textRect); HeapFree(GetProcessHeap(), 0, text); } if (focused) { MARGINS margins; RECT focusRect = bgRect; GetThemeMargins(theme, hDC, BP_PUSHBUTTON, state, TMT_CONTENTMARGINS, NULL, &margins); focusRect.left += margins.cxLeftWidth; focusRect.top += margins.cyTopHeight; focusRect.right -= margins.cxRightWidth; focusRect.bottom -= margins.cyBottomHeight; DrawFocusRect( hDC, &focusRect ); } if (hPrevFont) SelectObject(hDC, hPrevFont); }
/******************************************** GetMargins Purpose This wraps the GetThemeMargins call, which returns the margins of the area which will be taken up by drawing the theme edge. Params hwnd - the window to draw to, often NULL hdc - the HDC to draw to type - the cell type to draw state - the state of the cell ( selected, current, etc ) propId - the margin type to return prc - the rect to draw to XPMARGINS - an internal struct which copies the MARGINS struct, so this code will work if the XPThemes header files are available or not. Return A bool to indicate success or failure. *********************************************/ bool UGXPThemes::GetMargins(HWND hwnd, HDC hdc, UGXPCellType type, UGXPThemeState state, int propID, RECT *prc, XPMARGINS *pMargins) { bool success = false; if (useThemes) { UGThemeData * td = LookupThemeData(type, state); if (!td) { return false; } HANDLE themeHandle = OpenThemeData(hwnd, td->GetThemeName()); if (!themeHandle) return false; success = SUCCEEDED(GetThemeMargins(themeHandle, hdc, td->GetPartID(), td->GetStateID(), propID, prc, pMargins)); } return success; }
static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused, LPARAM prfFlag) { static const int states[] = { PBS_NORMAL, PBS_HOT, PBS_PRESSED, PBS_DISABLED, PBS_DEFAULTED }; RECT bgRect, textRect; HFONT font = get_button_font(hwnd); HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; int state = states[ drawState ]; WCHAR *text; PBUTTON_DATA pdata = _GetButtonData(hwnd); HWND parent; DWORD cdrf; GetClientRect(hwnd, &bgRect); GetThemeBackgroundContentRect(theme, hDC, BP_PUSHBUTTON, state, &bgRect, &textRect); if (prfFlag == 0) { if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state)) DrawThemeParentBackground(hwnd, hDC, NULL); } parent = GetParent(hwnd); if (!parent) parent = hwnd; SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd ); cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREERASE, &bgRect); if (cdrf == CDRF_SKIPDEFAULT) goto cleanup; DrawThemeBackground(theme, hDC, BP_PUSHBUTTON, state, &bgRect, NULL); if (cdrf == CDRF_NOTIFYPOSTERASE) BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTERASE, &bgRect); cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREPAINT, &bgRect); if (cdrf == CDRF_SKIPDEFAULT) goto cleanup; BUTTON_DrawIml(hDC, &pdata->imlData, &textRect, FALSE, drawState); text = get_button_text(hwnd); if (text) { DrawThemeText(theme, hDC, BP_PUSHBUTTON, state, text, lstrlenW(text), dtFlags, 0, &textRect); HeapFree(GetProcessHeap(), 0, text); } if (focused) { MARGINS margins; RECT focusRect = bgRect; GetThemeMargins(theme, hDC, BP_PUSHBUTTON, state, TMT_CONTENTMARGINS, NULL, &margins); focusRect.left += margins.cxLeftWidth; focusRect.top += margins.cyTopHeight; focusRect.right -= margins.cxRightWidth; focusRect.bottom -= margins.cyBottomHeight; DrawFocusRect( hDC, &focusRect ); } if (cdrf == CDRF_NOTIFYPOSTPAINT) BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTPAINT, &bgRect); cleanup: if (hPrevFont) SelectObject(hDC, hPrevFont); }
static void on_draw_item(HWND hDlg, WPARAM wParam, LPARAM lParam) { static HBRUSH black_brush = 0; LPDRAWITEMSTRUCT draw_info = (LPDRAWITEMSTRUCT)lParam; if (!black_brush) black_brush = CreateSolidBrush(0); if (draw_info->CtlID == IDC_SYSPARAM_COLOR) { UINT state; HTHEME theme; RECT buttonrect; theme = OpenThemeData(NULL, WC_BUTTONW); if (theme) { MARGINS margins; if (draw_info->itemState & ODS_DISABLED) state = PBS_DISABLED; else if (draw_info->itemState & ODS_SELECTED) state = PBS_PRESSED; else state = PBS_NORMAL; if (IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, state)) DrawThemeParentBackground(draw_info->hwndItem, draw_info->hDC, NULL); DrawThemeBackground(theme, draw_info->hDC, BP_PUSHBUTTON, state, &draw_info->rcItem, NULL); buttonrect = draw_info->rcItem; GetThemeMargins(theme, draw_info->hDC, BP_PUSHBUTTON, state, TMT_CONTENTMARGINS, &draw_info->rcItem, &margins); buttonrect.left += margins.cxLeftWidth; buttonrect.top += margins.cyTopHeight; buttonrect.right -= margins.cxRightWidth; buttonrect.bottom -= margins.cyBottomHeight; if (draw_info->itemState & ODS_FOCUS) DrawFocusRect(draw_info->hDC, &buttonrect); CloseThemeData(theme); } else { state = DFCS_ADJUSTRECT | DFCS_BUTTONPUSH; if (draw_info->itemState & ODS_DISABLED) state |= DFCS_INACTIVE; else state |= draw_info->itemState & ODS_SELECTED ? DFCS_PUSHED : 0; DrawFrameControl(draw_info->hDC, &draw_info->rcItem, DFC_BUTTON, state); buttonrect = draw_info->rcItem; } if (!(draw_info->itemState & ODS_DISABLED)) { HBRUSH brush; int index = SendDlgItemMessageW(hDlg, IDC_SYSPARAM_COMBO, CB_GETCURSEL, 0, 0); index = SendDlgItemMessageW(hDlg, IDC_SYSPARAM_COMBO, CB_GETITEMDATA, index, 0); brush = CreateSolidBrush(metrics[index].color); InflateRect(&buttonrect, -1, -1); FrameRect(draw_info->hDC, &buttonrect, black_brush); InflateRect(&buttonrect, -1, -1); FillRect(draw_info->hDC, &buttonrect, brush); DeleteObject(brush); } } }