CRect CPropPageFrameDefault::CalcCaptionArea() { CRect rect; GetClientRect(rect); if (IsAppThemed()) { HTHEME hTheme = OpenThemeData(m_hWnd, L"Tab"); if (hTheme) { CRect rectContent; CDC *pDc = GetDC(); GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent); ReleaseDC(pDc); CloseThemeData(hTheme); if (GetShowCaption()) rectContent.bottom = rect.top+GetCaptionHeight(); else rectContent.bottom = rectContent.top; rect = rectContent; } } else { if (GetShowCaption()) rect.bottom = rect.top+GetCaptionHeight(); else rect.bottom = rect.top; } return rect; }
static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) { static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL }; RECT bgRect, textRect, contentRect; int state = states[ drawState ]; WCHAR *text = get_button_text(hwnd); LOGFONTW lf; HFONT font, hPrevFont = NULL; BOOL created_font = FALSE; HRESULT hr = GetThemeFont(theme, hDC, BP_GROUPBOX, state, TMT_FONT, &lf); if (SUCCEEDED(hr)) { font = CreateFontIndirectW(&lf); if (!font) TRACE("Failed to create font\n"); else { hPrevFont = SelectObject(hDC, font); created_font = TRUE; } } else { font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); hPrevFont = SelectObject(hDC, font); } GetClientRect(hwnd, &bgRect); textRect = bgRect; if (text) { SIZE textExtent; GetTextExtentPoint32W(hDC, text, lstrlenW(text), &textExtent); bgRect.top += (textExtent.cy / 2); textRect.left += 10; textRect.bottom = textRect.top + textExtent.cy; textRect.right = textRect.left + textExtent.cx + 4; ExcludeClipRect(hDC, textRect.left, textRect.top, textRect.right, textRect.bottom); } GetThemeBackgroundContentRect(theme, hDC, BP_GROUPBOX, state, &bgRect, &contentRect); ExcludeClipRect(hDC, contentRect.left, contentRect.top, contentRect.right, contentRect.bottom); if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state)) DrawThemeParentBackground(hwnd, hDC, NULL); DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL); SelectClipRgn(hDC, NULL); if (text) { InflateRect(&textRect, -2, 0); DrawThemeText(theme, hDC, BP_GROUPBOX, state, text, lstrlenW(text), 0, 0, &textRect); HeapFree(GetProcessHeap(), 0, text); } if (created_font) DeleteObject(font); if (hPrevFont) SelectObject(hDC, hPrevFont); }
static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags) { static const int cb_states[3][5] = { { CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL }, { CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL }, { CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL } }; static const int rb_states[2][5] = { { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL }, { RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL } }; static const int cb_size = 13; RECT bgRect, textRect; HFONT font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); HFONT hPrevFont = font ? SelectObject(hDC, font) : NULL; LRESULT checkState = SendMessageW(hwnd, BM_GETCHECK, 0, 0); DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); int part = ((dwStyle & BUTTON_TYPE) == BS_RADIOBUTTON) || ((dwStyle & BUTTON_TYPE) == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX; int state = (part == BP_CHECKBOX) ? cb_states[ checkState ][ drawState ] : rb_states[ checkState ][ drawState ]; WCHAR *text = get_button_text(hwnd); GetClientRect(hwnd, &bgRect); GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect); if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */ bgRect.top = bgRect.top + (textRect.bottom - textRect.top - cb_size) / 2; /* adjust for the check/radio marker */ bgRect.bottom = bgRect.top + cb_size; bgRect.right = bgRect.left + cb_size; textRect.left = bgRect.right + 6; if (IsThemeBackgroundPartiallyTransparent(theme, part, state)) DrawThemeParentBackground(hwnd, hDC, NULL); DrawThemeBackground(theme, hDC, part, state, &bgRect, NULL); if (text) { DrawThemeText(theme, hDC, part, state, text, lstrlenW(text), dtFlags, 0, &textRect); HeapFree(GetProcessHeap(), 0, text); } if (hPrevFont) SelectObject(hDC, hPrevFont); }
/* Get client rect. Takes into account that theming needs no adjustment. */ static inline void get_client_rect (HWND hwnd, RECT* rect) { HTHEME theme = GetWindowTheme (hwnd); GetClientRect (hwnd, rect); if (!theme) InflateRect(rect, -1, -1); else { DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR; GetThemeBackgroundContentRect (theme, 0, part, 0, rect, rect); } }
void ColourButton::OnCustomDraw(NMHDR* nmhdr, LRESULT* result) { NMCUSTOMDRAW* nmcd = (NMCUSTOMDRAW*)nmhdr; *result = CDRF_DODEFAULT; switch (nmcd->dwDrawStage) { case CDDS_PREPAINT: { CDC* dc = CDC::FromHandle(nmcd->hdc); CRect r(nmcd->rc); bool selected = ((nmcd->uItemState & CDIS_SELECTED) != 0); bool disabled = ((nmcd->uItemState & CDIS_DISABLED) != 0); bool focus = ((nmcd->uItemState & CDIS_FOCUS) != 0); if (SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) focus = false; if (IsAppThemed()) { HTHEME theme = OpenThemeData(this,L"Button"); if (theme) { // Get the area to draw into GetThemeBackgroundContentRect(theme,dc,BP_PUSHBUTTON,PBS_NORMAL,r); CloseThemeData(theme); } } else { UINT state = DFCS_BUTTONPUSH|DFCS_ADJUSTRECT; if (disabled) state |= DFCS_INACTIVE; if (selected) state |= DFCS_PUSHED; dc->DrawFrameControl(r,DFC_BUTTON,state); if (selected) r.OffsetRect(1,1); } DrawControl(dc,r,disabled,focus); *result = CDRF_SKIPDEFAULT; } break; } }
static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags) { static const int states[] = { GBS_NORMAL, GBS_DISABLED, GBS_NORMAL, GBS_NORMAL, GBS_NORMAL }; RECT bgRect, textRect, contentRect; 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); textRect = bgRect; if (text) { SIZE textExtent; GetTextExtentPoint32W(hDC, text, lstrlenW(text), &textExtent); bgRect.top += (textExtent.cy / 2); textRect.left += 10; textRect.bottom = textRect.top + textExtent.cy; textRect.right = textRect.left + textExtent.cx + 4; ExcludeClipRect(hDC, textRect.left, textRect.top, textRect.right, textRect.bottom); } GetThemeBackgroundContentRect(theme, hDC, BP_GROUPBOX, state, &bgRect, &contentRect); ExcludeClipRect(hDC, contentRect.left, contentRect.top, contentRect.right, contentRect.bottom); if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state)) DrawThemeParentBackground(hwnd, hDC, NULL); DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL); SelectClipRgn(hDC, NULL); if (text) { textRect.left += 2; textRect.right -= 2; DrawThemeText(theme, hDC, BP_GROUPBOX, state, text, lstrlenW(text), 0, 0, &textRect); HeapFree(GetProcessHeap(), 0, text); } if (hPrevFont) SelectObject(hDC, hPrevFont); }
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); }
static void PB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags) { 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 (hPrevFont) SelectObject(hDC, hPrevFont); }
static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) #endif { static const int states[] = { GBS_NORMAL, GBS_NORMAL, GBS_NORMAL, GBS_DISABLED, GBS_NORMAL }; RECT bgRect, textRect, contentRect; int state = states[ drawState ]; WCHAR *text = get_button_text(hwnd); LOGFONTW lf; HFONT font, hPrevFont = NULL; BOOL created_font = FALSE; #ifdef __REACTOS__ /* r74406 */ HWND parent; HBRUSH hBrush; RECT clientRect; #endif HRESULT hr = GetThemeFont(theme, hDC, BP_GROUPBOX, state, TMT_FONT, &lf); if (SUCCEEDED(hr)) { font = CreateFontIndirectW(&lf); if (!font) TRACE("Failed to create font\n"); else { hPrevFont = SelectObject(hDC, font); created_font = TRUE; } } else { #ifdef __REACTOS__ /* r73885 */ font = get_button_font(hwnd); #else font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); #endif hPrevFont = SelectObject(hDC, font); } GetClientRect(hwnd, &bgRect); textRect = bgRect; if (text) { SIZE textExtent; GetTextExtentPoint32W(hDC, text, lstrlenW(text), &textExtent); bgRect.top += (textExtent.cy / 2); textRect.left += 10; textRect.bottom = textRect.top + textExtent.cy; textRect.right = textRect.left + textExtent.cx + 4; ExcludeClipRect(hDC, textRect.left, textRect.top, textRect.right, textRect.bottom); } GetThemeBackgroundContentRect(theme, hDC, BP_GROUPBOX, state, &bgRect, &contentRect); ExcludeClipRect(hDC, contentRect.left, contentRect.top, contentRect.right, contentRect.bottom); #ifdef __REACTOS__ /* r73885 & r74149 */ if (prfFlag == 0) { if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state)) DrawThemeParentBackground(hwnd, hDC, NULL); } #else if (IsThemeBackgroundPartiallyTransparent(theme, BP_GROUPBOX, state)) DrawThemeParentBackground(hwnd, hDC, NULL); #endif #ifdef __REACTOS__ /* r74406 */ parent = GetParent(hwnd); if (!parent) parent = hwnd; hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd); if (!hBrush) /* did the app forget to call defwindowproc ? */ hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd ); GetClientRect(hwnd, &clientRect); FillRect( hDC, &clientRect, hBrush ); #endif DrawThemeBackground(theme, hDC, BP_GROUPBOX, state, &bgRect, NULL); SelectClipRgn(hDC, NULL); if (text) { InflateRect(&textRect, -2, 0); DrawThemeText(theme, hDC, BP_GROUPBOX, state, text, lstrlenW(text), 0, 0, &textRect); HeapFree(GetProcessHeap(), 0, text); } if (created_font) DeleteObject(font); if (hPrevFont) SelectObject(hDC, hPrevFont); }
static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused, LPARAM prfFlag) { static const int cb_states[3][5] = { { CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDNORMAL }, { CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED, CBS_CHECKEDNORMAL }, { CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED, CBS_MIXEDNORMAL } }; static const int rb_states[2][5] = { { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDNORMAL }, { RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDDISABLED, RBS_CHECKEDNORMAL } }; SIZE sz; RECT bgRect, textRect; HFONT font, hPrevFont = NULL; LRESULT checkState = get_button_state(hwnd) & 3; DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); int part = ((dwStyle & BUTTON_TYPE) == BS_RADIOBUTTON) || ((dwStyle & BUTTON_TYPE) == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX; int state = (part == BP_CHECKBOX) ? cb_states[ checkState ][ drawState ] : rb_states[ checkState ][ drawState ]; WCHAR *text; LOGFONTW lf; BOOL created_font = FALSE; HWND parent; HBRUSH hBrush; DWORD cdrf; HRESULT hr = GetThemeFont(theme, hDC, part, state, TMT_FONT, &lf); if (SUCCEEDED(hr)) { font = CreateFontIndirectW(&lf); if (!font) TRACE("Failed to create font\n"); else { TRACE("font = %s\n", debugstr_w(lf.lfFaceName)); hPrevFont = SelectObject(hDC, font); created_font = TRUE; } } else { font = get_button_font(hwnd); hPrevFont = SelectObject(hDC, font); } if (FAILED(GetThemePartSize(theme, hDC, part, state, NULL, TS_DRAW, &sz))) sz.cx = sz.cy = 13; GetClientRect(hwnd, &bgRect); if (prfFlag == 0) { DrawThemeParentBackground(hwnd, hDC, NULL); } parent = GetParent(hwnd); if (!parent) parent = hwnd; hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd); if (!hBrush) /* did the app forget to call defwindowproc ? */ hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, (WPARAM)hDC, (LPARAM)hwnd ); FillRect( hDC, &bgRect, hBrush ); cdrf = BUTTON_SendCustomDraw(hwnd, hDC, CDDS_PREERASE, &bgRect); if (cdrf == CDRF_SKIPDEFAULT) goto cleanup; GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect); if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */ bgRect.top = bgRect.top + (textRect.bottom - textRect.top - sz.cy) / 2; /* adjust for the check/radio marker */ bgRect.bottom = bgRect.top + sz.cy; bgRect.right = bgRect.left + sz.cx; textRect.left = bgRect.right + 6; DrawThemeBackground(theme, hDC, part, 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; text = get_button_text(hwnd); if (text) { DrawThemeText(theme, hDC, part, state, text, lstrlenW(text), dtFlags, 0, &textRect); if (focused) { RECT focusRect; focusRect = textRect; DrawTextW(hDC, text, lstrlenW(text), &focusRect, dtFlags | DT_CALCRECT); if (focusRect.right < textRect.right) focusRect.right++; focusRect.bottom = textRect.bottom; DrawFocusRect( hDC, &focusRect ); } HeapFree(GetProcessHeap(), 0, text); } if (cdrf == CDRF_NOTIFYPOSTPAINT) BUTTON_SendCustomDraw(hwnd, hDC, CDDS_POSTPAINT, &bgRect); cleanup: if (created_font) DeleteObject(font); if (hPrevFont) SelectObject(hDC, hPrevFont); }
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 LRESULT CALLBACK OptionsFilterSubclassProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message != WM_PAINT && message != WM_PRINT) return mir_callNextSubclass(hWnd, OptionsFilterSubclassProc, message, wParam, lParam); if (GetFocus() == hWnd || GetWindowTextLength(hWnd)) return mir_callNextSubclass(hWnd, OptionsFilterSubclassProc, message, wParam, lParam); RECT rc; GetClientRect(hWnd, &rc); HDC hdc; PAINTSTRUCT paint; if (message == WM_PAINT) hdc = BeginPaint(hWnd, &paint); else hdc = (HDC)wParam; TCHAR buf[255]; if (bSearchState == 1 && FilterLoadProgress < 100 && FilterLoadProgress > 0) mir_sntprintf(buf, SIZEOF(buf), TranslateT("Loading... %d%%"), FilterLoadProgress); else mir_sntprintf(buf, SIZEOF(buf), TranslateT("Search")); BOOL bDrawnByTheme = FALSE; int oldMode = SetBkMode(hdc, TRANSPARENT); HTHEME hTheme = OpenThemeData(hWnd, L"EDIT"); if (hTheme) { if (IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) DrawThemeParentBackground(hWnd, hdc, &rc); RECT rc2; GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &rc, &rc2); rc2.top = 2 * rc.top - rc2.top; rc2.left = 2 * rc.left - rc2.left; rc2.bottom = 2 * rc.bottom - rc2.bottom; rc2.right = 2 * rc.right - rc2.right; DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &rc2, &rc); HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); HFONT oldFont = (HFONT)SelectObject(hdc, hFont); wchar_t *bufW = mir_t2u(buf); DrawThemeText(hTheme, hdc, EP_EDITTEXT, ETS_DISABLED, bufW, -1, 0, 0, &rc); mir_free(bufW); SelectObject(hdc, oldFont); CloseThemeData(hTheme); bDrawnByTheme = TRUE; } SetBkMode(hdc, oldMode); if (!bDrawnByTheme) { HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); HFONT oldFont = (HFONT)SelectObject(hdc, hFont); SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); int oldMode = SetBkMode(hdc, TRANSPARENT); DrawText(hdc, buf, -1, &rc, 0); SetBkMode(hdc, oldMode); SelectObject(hdc, oldFont); } if (message == WM_PAINT) EndPaint(hWnd, &paint); return 0; }
LRESULT AeroControlBase::ButtonWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_SETTEXT: case WM_ENABLE: case WM_STYLECHANGED: { LRESULT res = DefSubclassProc(hWnd, uMsg, wParam, lParam); InvalidateRgn(hWnd, NULL, FALSE); return res; } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); if(hdc) { LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE); LONG_PTR dwButtonStyle = LOWORD(dwStyle); LONG_PTR dwButtonType = dwButtonStyle&0xF; RECT rcClient; VERIFY(GetClientRect(hWnd, &rcClient)); if((dwButtonType&BS_GROUPBOX)==BS_GROUPBOX) { /// /// it must be a group box /// HTHEME hTheme = OpenThemeData(hWnd, L"Button"); if(hTheme) { BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; RECT rcExclusion = rcClient; params.prcExclude = &rcExclusion; /// /// We have to calculate the exclusion rect and therefore /// calculate the font height. We select the control's font /// into the DC and fake a drawing operation: /// HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdc, hFontOld); RECT rcDraw = rcClient; DWORD dwFlags = DT_SINGLELINE; /// /// we use uppercase A to determine the height of text, so we /// can draw the upper line of the groupbox: /// DrawTextW(hdc, L"A", -1, &rcDraw, dwFlags|DT_CALCRECT); if (hFontOld) { SelectObject(hdc, hFontOld); hFontOld = NULL; } VERIFY(InflateRect(&rcExclusion, -1, -1*RECTHEIGHT(rcDraw))); HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { /// /// now we again retrieve the font, but this time we select it into /// the buffered DC: /// hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); int iPartId = BP_GROUPBOX; int iState = GetStateFromBtnState(dwStyle, FALSE, FALSE, 0L, iPartId, FALSE); DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); COLORREF cr = RGB(0x00, 0x00, 0x00); VERIFY(GetEditBorderColor(hWnd, &cr)); /// /// add the alpha value: /// cr |= 0xff000000; std::unique_ptr<Pen> myPen( new Pen(Color(cr), 1) ); std::unique_ptr<Graphics> myGraphics( new Graphics(hdcPaint) ); int iY = RECTHEIGHT(rcDraw)/2; Rect rr = Rect(rcClient.left, rcClient.top+iY, RECTWIDTH(rcClient), RECTHEIGHT(rcClient)-iY-1); GraphicsPath path; GetRoundRectPath(&path, rr, 10); myGraphics->DrawPath(myPen.get(), &path); //myGraphics->DrawRectangle(myPen, rcClient.left, rcClient.top + iY, // RECTWIDTH(rcClient)-1, RECTHEIGHT(rcClient) - iY-1); myGraphics.reset(); myPen.reset(); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { int iX = RECTWIDTH(rcDraw); rcDraw = rcClient; rcDraw.left += iX; DrawTextW(hdcPaint, szText, -1, &rcDraw, dwFlags|DT_CALCRECT); VERIFY(PatBlt(hdcPaint, rcDraw.left, rcDraw.top , RECTWIDTH(rcDraw) + 3, RECTHEIGHT(rcDraw), BLACKNESS)); rcDraw.left++; rcDraw.right++; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1, dwFlags, &rcDraw, &DttOpts)); } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } else if(dwButtonType==BS_CHECKBOX || dwButtonType==BS_AUTOCHECKBOX || dwButtonType==BS_3STATE || dwButtonType==BS_AUTO3STATE || dwButtonType==BS_RADIOBUTTON || dwButtonType==BS_AUTORADIOBUTTON) { HTHEME hTheme = OpenThemeData(hWnd, L"Button"); if(hTheme) { HDC hdcPaint = NULL; BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); LRESULT dwCheckState = SendMessage(hWnd, BM_GETCHECK, 0, NULL); POINT pt; RECT rc; GetWindowRect(hWnd, &rc); GetCursorPos(&pt); BOOL bHot = PtInRect(&rc, pt); BOOL bFocus = GetFocus()==hWnd; int iPartId = BP_CHECKBOX; if(dwButtonType==BS_RADIOBUTTON || dwButtonType==BS_AUTORADIOBUTTON) iPartId = BP_RADIOBUTTON; int iState = GetStateFromBtnState(dwStyle, bHot, bFocus, dwCheckState, iPartId, FALSE); int bmWidth = int(ceil(13.0 * GetDeviceCaps(hdcPaint, LOGPIXELSX) / 96.0)); UINT uiHalfWidth = (RECTWIDTH(rcClient) - bmWidth)/2; /// /// we have to use the whole client area, otherwise we get only partially /// drawn areas: /// RECT rcPaint = rcClient; if(dwButtonStyle & BS_LEFTTEXT) { rcPaint.left += uiHalfWidth; rcPaint.right += uiHalfWidth; } else { rcPaint.left -= uiHalfWidth; rcPaint.right -= uiHalfWidth; } /// /// we assume that bmWidth is both the horizontal and the vertical /// dimension of the control bitmap and that it is square. bm.bmHeight /// seems to be the height of a striped bitmap because it is an absurdly /// high dimension value /// if((dwButtonStyle&BS_VCENTER)==BS_VCENTER) /// BS_VCENTER is BS_TOP|BS_BOTTOM { int h = RECTHEIGHT(rcPaint); rcPaint.top = (h - bmWidth) / 2; rcPaint.bottom = rcPaint.top + bmWidth; } else if(dwButtonStyle&BS_TOP) { rcPaint.bottom = rcPaint.top + bmWidth; } else if(dwButtonStyle&BS_BOTTOM) { rcPaint.top = rcPaint.bottom - bmWidth; } else // default: center the checkbox/radiobutton vertically { int h = RECTHEIGHT(rcPaint); rcPaint.top = (h - bmWidth) / 2; rcPaint.bottom = rcPaint.top + bmWidth; } VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL)); rcPaint = rcClient; VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc)); if(dwButtonStyle & BS_LEFTTEXT) rc.right -= bmWidth + 2 * GetSystemMetrics(SM_CXEDGE); else rc.left += bmWidth + 2 * GetSystemMetrics(SM_CXEDGE); DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { DWORD dwFlags = DT_SINGLELINE /*|DT_VCENTER*/; if(dwButtonStyle&BS_MULTILINE) { dwFlags|=DT_WORDBREAK; dwFlags&= ~(DT_SINGLELINE |DT_VCENTER); } if((dwButtonStyle&BS_CENTER)==BS_CENTER) /// BS_CENTER is BS_LEFT|BS_RIGHT dwFlags|=DT_CENTER; else if(dwButtonStyle&BS_LEFT) dwFlags|=DT_LEFT; else if(dwButtonStyle&BS_RIGHT) dwFlags|=DT_RIGHT; if((dwButtonStyle&BS_VCENTER)==BS_VCENTER) /// BS_VCENTER is BS_TOP|BS_BOTTOM dwFlags|=DT_VCENTER; else if(dwButtonStyle&BS_TOP) dwFlags|=DT_TOP; else if(dwButtonStyle&BS_BOTTOM) dwFlags|=DT_BOTTOM; else dwFlags|=DT_VCENTER; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1, dwFlags, &rc, &DttOpts)); /// /// if our control has the focus, we also have to draw the focus rectangle: /// if(bFocus) { /// /// now calculate the text size: /// RECT rcDraw = rc; /// /// we use GDI's good old DrawText, because it returns much more /// accurate data than DrawThemeTextEx, which takes the glow /// into account which we don't want: /// VERIFY(DrawTextW(hdcPaint, szText, -1, &rcDraw, dwFlags|DT_CALCRECT)); if(dwFlags&DT_SINGLELINE) { dwFlags &= ~DT_VCENTER; RECT rcDrawTop; DrawTextW(hdcPaint, szText, -1, &rcDrawTop, dwFlags|DT_CALCRECT); rcDraw.top = rcDraw.bottom - RECTHEIGHT(rcDrawTop); } if(dwFlags & DT_RIGHT) { int iWidth = RECTWIDTH(rcDraw); rcDraw.right = rc.right; rcDraw.left = rcDraw.right - iWidth; } RECT rcFocus; VERIFY(IntersectRect(&rcFocus, &rc, &rcDraw)); DrawFocusRect(&rcFocus, hdcPaint); } } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } else if(BS_PUSHBUTTON==dwButtonType || BS_DEFPUSHBUTTON==dwButtonType) { /// /// it is a push button /// HTHEME hTheme = OpenThemeData(hWnd, L"Button"); if(hTheme) { HDC hdcPaint = NULL; BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); LRESULT dwCheckState = SendMessage(hWnd, BM_GETCHECK, 0, NULL); POINT pt; RECT rc; GetWindowRect(hWnd, &rc); GetCursorPos(&pt); BOOL bHot = PtInRect(&rc, pt); BOOL bFocus = GetFocus()==hWnd; int iPartId = BP_PUSHBUTTON; if(dwButtonStyle==BS_RADIOBUTTON || dwButtonStyle==BS_AUTORADIOBUTTON) iPartId = BP_RADIOBUTTON; int iState = GetStateFromBtnState(dwStyle, bHot, bFocus, dwCheckState, iPartId, GetCapture()==hWnd); /// /// we have to use the whole client area, otherwise we get only partially /// drawn areas: /// RECT rcPaint = rcClient; VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL)); VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc)); DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { DWORD dwFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1, dwFlags, &rc, &DttOpts)); /// /// if our control has the focus, we also have to draw the focus rectangle: /// if(bFocus) { RECT rcDraw = rcClient; VERIFY(InflateRect(&rcDraw, -3, -3)); DrawFocusRect(&rcDraw, hdcPaint); } } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } else //PaintControl(hWnd, hdc, &ps.rcPaint, (m_dwFlags & WD_DRAW_BORDER)!=0); PaintControl(hWnd, hdc, &ps.rcPaint, false); } EndPaint(hWnd, &ps); return 0; } break; case WM_DESTROY: case WM_NCDESTROY: RemoveWindowSubclass(hWnd, SubclassProc, Button); subclassedControls.erase(hWnd); break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UINT dtFlags, BOOL focused) { static const int cb_states[3][5] = { { CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDNORMAL }, { CBS_CHECKEDNORMAL, CBS_CHECKEDDISABLED, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDNORMAL }, { CBS_MIXEDNORMAL, CBS_MIXEDDISABLED, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDNORMAL } }; static const int rb_states[2][5] = { { RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDNORMAL }, { RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL } }; static const int cb_size = 13; RECT bgRect, textRect; HFONT font, hPrevFont = NULL; LRESULT checkState = SendMessageW(hwnd, BM_GETCHECK, 0, 0); DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); int part = ((dwStyle & BUTTON_TYPE) == BS_RADIOBUTTON) || ((dwStyle & BUTTON_TYPE) == BS_AUTORADIOBUTTON) ? BP_RADIOBUTTON : BP_CHECKBOX; int state = (part == BP_CHECKBOX) ? cb_states[ checkState ][ drawState ] : rb_states[ checkState ][ drawState ]; WCHAR *text = get_button_text(hwnd); LOGFONTW lf; BOOL created_font = FALSE; HRESULT hr = GetThemeFont(theme, hDC, part, state, TMT_FONT, &lf); if (SUCCEEDED(hr)) { font = CreateFontIndirectW(&lf); if (!font) TRACE("Failed to create font\n"); else { TRACE("font = %s\n", debugstr_w(lf.lfFaceName)); hPrevFont = SelectObject(hDC, font); created_font = TRUE; } } else font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); GetClientRect(hwnd, &bgRect); GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect); if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */ bgRect.top = bgRect.top + (textRect.bottom - textRect.top - cb_size) / 2; /* adjust for the check/radio marker */ bgRect.bottom = bgRect.top + cb_size; bgRect.right = bgRect.left + cb_size; textRect.left = bgRect.right + 6; DrawThemeParentBackground(hwnd, hDC, NULL); DrawThemeBackground(theme, hDC, part, state, &bgRect, NULL); if (text) { DrawThemeText(theme, hDC, part, state, text, lstrlenW(text), dtFlags, 0, &textRect); if (focused) { RECT focusRect; focusRect = textRect; DrawTextW(hDC, text, lstrlenW(text), &focusRect, dtFlags | DT_CALCRECT); if (focusRect.right < textRect.right) focusRect.right++; focusRect.bottom = textRect.bottom; DrawFocusRect( hDC, &focusRect ); } HeapFree(GetProcessHeap(), 0, text); } if (created_font) DeleteObject(font); if (hPrevFont) SelectObject(hDC, hPrevFont); }
static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { TRichUtil *ru = NULL, tru; int idx; LRESULT ret; tru.hwnd = hwnd; { mir_cslock lck(csRich); if (List_GetIndex(&sListInt, &tru, &idx)) ru = (TRichUtil *)sListInt.items[idx]; } switch (msg) { case WM_THEMECHANGED: case WM_STYLECHANGED: RichUtil_ClearUglyBorder(ru); break; case WM_NCPAINT: ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); if (ru->hasUglyBorder && IsThemeActive()) { HANDLE hTheme = OpenThemeData(ru->hwnd, L"EDIT"); if (hTheme) { RECT rcBorder; RECT rcClient; int nState; HDC hdc = GetWindowDC(ru->hwnd); GetWindowRect(hwnd, &rcBorder); rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top; rcBorder.left = rcBorder.top = 0; CopyRect(&rcClient, &rcBorder); rcClient.left += ru->rect.left; rcClient.top += ru->rect.top; rcClient.right -= ru->rect.right; rcClient.bottom -= ru->rect.bottom; ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if (IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) DrawThemeParentBackground(hwnd, hdc, &rcBorder); if (!IsWindowEnabled(hwnd)) nState = ETS_DISABLED; else if (SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY) nState = ETS_READONLY; else nState = ETS_NORMAL; DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL); CloseThemeData(hTheme); ReleaseDC(hwnd, hdc); return 0; } } return ret; case WM_NCCALCSIZE: { ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS *)lParam; if (ru->hasUglyBorder && IsThemeActive()) { HANDLE hTheme = OpenThemeData(hwnd, L"EDIT"); if (hTheme) { RECT rcClient = {0}; HDC hdc = GetDC(GetParent(hwnd)); if (GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) { ru->rect.left = rcClient.left - ncsParam->rgrc[0].left; ru->rect.top = rcClient.top - ncsParam->rgrc[0].top; ru->rect.right = ncsParam->rgrc[0].right - rcClient.right; ru->rect.bottom = ncsParam->rgrc[0].bottom - rcClient.bottom; ncsParam->rgrc[0] = rcClient; CloseThemeData(hTheme); ReleaseDC(GetParent(hwnd), hdc); return WVR_REDRAW; } ReleaseDC(GetParent(hwnd), hdc); CloseThemeData(hTheme); } } } return ret; case WM_ENABLE: RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME); break; case WM_GETDLGCODE: return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam) & ~DLGC_HASSETSEL; case WM_NCDESTROY: ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); { mir_cslock lck(csRich); List_Remove(&sListInt, idx); } mir_free(ru); return ret; } return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); }
static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { TRichUtil *ru; EnterCriticalSection(&csRich); ru = rlist_find(slist, hwnd); LeaveCriticalSection(&csRich); switch(msg) { case WM_THEMECHANGED: case WM_STYLECHANGED: RichUtil_ClearUglyBorder(ru); break; case WM_NCPAINT: { LRESULT ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); if (ru->hasUglyBorder && IsThemeActive()) { HANDLE hTheme = OpenThemeData(ru->hwnd, L"EDIT"); if (hTheme) { RECT rcBorder; RECT rcClient; int nState; HDC hdc = GetWindowDC(ru->hwnd); GetWindowRect(hwnd, &rcBorder); rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top; rcBorder.left = rcBorder.top = 0; CopyRect(&rcClient, &rcBorder); rcClient.left += ru->rect.left; rcClient.top += ru->rect.top; rcClient.right -= ru->rect.right; rcClient.bottom -= ru->rect.bottom; ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if(IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) DrawThemeParentBackground(hwnd, hdc, &rcBorder); if (!IsWindowEnabled(hwnd)) nState = ETS_DISABLED; else if(SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY) nState = ETS_READONLY; else nState = ETS_NORMAL; DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL); CloseThemeData(hTheme); ReleaseDC(hwnd, hdc); return 0; } } return ret; } case WM_NCCALCSIZE: { LRESULT ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam; if (ru->hasUglyBorder && IsThemeActive()) { HANDLE hTheme = OpenThemeData(hwnd, L"EDIT"); if (hTheme) { RECT rcClient; HDC hdc = GetDC(GetParent(hwnd)); ZeroMemory(&rcClient, sizeof(RECT)); if(GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) { ru->rect.left = rcClient.left-ncsParam->rgrc[0].left; ru->rect.top = rcClient.top-ncsParam->rgrc[0].top; ru->rect.right = ncsParam->rgrc[0].right-rcClient.right; ru->rect.bottom = ncsParam->rgrc[0].bottom-rcClient.bottom; CopyRect(&ncsParam->rgrc[0], &rcClient); CloseThemeData(hTheme); ReleaseDC(GetParent(hwnd), hdc); return WVR_REDRAW; } ReleaseDC(GetParent(hwnd), hdc); CloseThemeData(hTheme); } } return ret; } case WM_ENABLE: RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_UPDATENOW|RDW_FRAME); break; case WM_DESTROY: { LRESULT ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); EnterCriticalSection(&csRich); slist = rlist_remove(slist, ru); LeaveCriticalSection(&csRich); if (ru) free(ru); return ret; } } return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam); }
static HRESULT drawProgressBarPart(HRESULT hr, struct drawState *s) { int progress; LONG indeterminatePos; HTHEME theme; RECT r; RECT rBorder, rFill[2]; int i, nFill; TEXTMETRICW tm; int sysColor; if (hr != S_OK) return hr; if (s->p->progressBarModelColumn == -1) return S_OK; progress = uiprivTableProgress(s->t, s->iItem, s->iSubItem, s->p->progressBarModelColumn, &indeterminatePos); theme = OpenThemeData(s->t->hwnd, L"PROGRESS"); if (GetTextMetricsW(s->dc, &tm) == 0) { logLastError(L"GetTextMetricsW()"); hr = E_FAIL; goto fail; } r = s->m->subitemBounds; // this sets the height of the progressbar and vertically centers it in one fell swoop r.top += (r.bottom - tm.tmHeight - r.top) / 2; r.bottom = r.top + tm.tmHeight; // TODO check errors rBorder = r; InflateRect(&rBorder, -1, -1); if (theme != NULL) { RECT crect; hr = GetThemeBackgroundContentRect(theme, s->dc, PP_TRANSPARENTBAR, PBBS_NORMAL, &rBorder, &crect); if (hr != S_OK) { logHRESULT(L"GetThemeBackgroundContentRect()", hr); goto fail; } hr = DrawThemeBackground(theme, s->dc, PP_TRANSPARENTBAR, PBBS_NORMAL, &crect, NULL); if (hr != S_OK) { logHRESULT(L"DrawThemeBackground() border", hr); goto fail; } } else { HPEN pen, prevPen; HBRUSH brush, prevBrush; sysColor = COLOR_HIGHLIGHT; if (s->m->selected) sysColor = COLOR_HIGHLIGHTTEXT; // TODO check errors everywhere pen = CreatePen(PS_SOLID, 1, GetSysColor(sysColor)); prevPen = (HPEN) SelectObject(s->dc, pen); brush = (HBRUSH) GetStockObject(NULL_BRUSH); prevBrush = (HBRUSH) SelectObject(s->dc, brush); Rectangle(s->dc, rBorder.left, rBorder.top, rBorder.right, rBorder.bottom); SelectObject(s->dc, prevBrush); SelectObject(s->dc, prevPen); DeleteObject(pen); } nFill = 1; rFill[0] = r; // TODO check error InflateRect(&rFill[0], -1, -1); if (progress != -1) rFill[0].right -= (rFill[0].right - rFill[0].left) * (100 - progress) / 100; else { LONG barWidth; LONG pieceWidth; // TODO explain all this // TODO this should really start the progressbar scrolling into view instead of already on screen when first set rFill[1] = rFill[0]; // save in case we need it barWidth = rFill[0].right - rFill[0].left; pieceWidth = barWidth / indeterminateSegments; rFill[0].left += indeterminatePos % barWidth; if ((rFill[0].left + pieceWidth) >= rFill[0].right) { // make this piece wrap back around nFill++; rFill[1].right = rFill[1].left + (pieceWidth - (rFill[0].right - rFill[0].left)); } else rFill[0].right = rFill[0].left + pieceWidth; } for (i = 0; i < nFill; i++) if (theme != NULL) { hr = DrawThemeBackground(theme, s->dc, PP_FILL, PBFS_NORMAL, &rFill[i], NULL); if (hr != S_OK) { logHRESULT(L"DrawThemeBackground() fill", hr); goto fail; } } else // TODO check errors FillRect(s->dc, &rFill[i], GetSysColorBrush(sysColor)); hr = S_OK; fail: // TODO check errors if (theme != NULL) CloseThemeData(theme); return hr; }