/** * name: PaintThemeButton * desc: Draws the themed button * param: ctl - BTNCTRL structure for the button * hdcMem - device context to draw to * rcClient - rectangle of the whole button * return: nothing **/ static void __fastcall PaintThemeButton(BTNCTRL *ctl, HDC hdcMem, LPRECT rcClient) { RECT rcText = { 0, 0, 0, 0 }; WCHAR wszText[MAX_PATH] = { 0 }; WORD ccText; // Draw the flat button if ((ctl->dwStyle & MBS_FLAT) && ctl->hThemeToolbar) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { if (SUCCEEDED(DrawThemeParentBackground(ctl->hwnd, hdcMem, rcClient))) DrawThemeParentBackground(GetParent(ctl->hwnd), hdcMem, rcClient); } DrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), rcClient, rcClient); } else { // draw themed button background if (ctl->hThemeButton) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { if (SUCCEEDED(DrawThemeParentBackground(ctl->hwnd, hdcMem, rcClient))) DrawThemeParentBackground(GetParent(ctl->hwnd), hdcMem, rcClient); } DrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, rcClient, rcClient); } } // calculate text rect { RECT sizeText; HFONT hOldFont; ccText = GetWindowTextW(ctl->hwnd, wszText, _countof(wszText)); if (ccText > 0) { hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); GetThemeTextExtent( ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, wszText, ccText, DST_PREFIXTEXT, NULL, &sizeText); if (ctl->cHot) { RECT rcHot; GetThemeTextExtent(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, L"&", 1, DST_PREFIXTEXT, NULL, &rcHot); sizeText.right -= (rcHot.right - rcHot.left); } SelectObject(hdcMem, hOldFont); rcText.left = (ctl->hIcon) ? 0 : (rcClient->right - rcClient->left - (sizeText.right - sizeText.left)) / 2; rcText.top = (rcClient->bottom - rcClient->top - (sizeText.bottom - sizeText.top)) / 2; rcText.right = rcText.left + (sizeText.right - sizeText.left); rcText.bottom = rcText.top + (sizeText.bottom - sizeText.top); if (ctl->stateId == PBS_PRESSED) { OffsetRect(&rcText, 1, 1); } } } PaintIcon(ctl, hdcMem, &ccText, rcClient, &rcText); // draw text if (ccText > 0 && ctl->hThemeButton) { HFONT hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); DrawThemeText(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, wszText, ccText, DST_PREFIXTEXT, 0, &rcText); SelectObject(hdcMem, hOldFont); } }
/** * paints the background for a switchbar item. It can paint aero, visual styles, skins or * classic buttons (depending on os and current plugin settings). * * @param hdc HDC: target device context * @param rc RECT*: target rectangle * @param stateId the state identifier (normal, pressed, hot, disabled etc.) */ void __fastcall CSideBar::m_DefaultBackgroundRenderer(const HDC hdc, const RECT *rc, const CSideBarButton *item) { UINT id = item->getID(); int stateId = item->m_buttonControl->stateId; bool fIsActiveItem = (item->m_sideBar->getActiveItem() == item); if (CSkin::m_skinEnabled) { TContainerData *pContainer = const_cast<TContainerData *>(item->m_sideBar->getContainer()); int ctrlId = stateId == PBS_PRESSED || fIsActiveItem ? ID_EXTBKBUTTONSPRESSED : (stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : ID_EXTBKBUTTONSNPRESSED); CSkinItem *skinItem = &SkinItems[ctrlId]; HWND hwnd = item->m_buttonControl->hwnd; CSkin::SkinDrawBG(hwnd, pContainer->hwnd, pContainer, const_cast<RECT *>(rc), hdc); CSkin::DrawItem(hdc, rc, skinItem); } else if (M.isAero() || PluginConfig.m_fillColor) { if (id == IDC_SIDEBARUP || id == IDC_SIDEBARDOWN) { if (M.isAero()) ::FillRect(hdc, const_cast<RECT *>(rc), CSkin::m_BrushBack); else CSkin::FillBack(hdc, const_cast<RECT *>(rc)); if (stateId == PBS_HOT || stateId == PBS_PRESSED) DrawAlpha(hdc, const_cast<RECT *>(rc), 0xf0f0f0, 70, 0x000000, 0, 9, 31, 4, 0); else DrawAlpha(hdc, const_cast<RECT *>(rc), 0xf0f0f0, 30, 0x707070, 0, 9, 31, 4, 0); } else { if (PluginConfig.m_fillColor) FillTabBackground(hdc, stateId, item->getDat(), const_cast<RECT *>(rc)); CSkin::m_switchBarItem->setAlphaFormat(AC_SRC_ALPHA, (stateId == PBS_HOT && !fIsActiveItem) ? 250 : (fIsActiveItem || stateId == PBS_PRESSED ? 250 : 230)); CSkin::m_switchBarItem->Render(hdc, rc, true); if (stateId == PBS_HOT || stateId == PBS_PRESSED || fIsActiveItem) { RECT rcGlow = *rc; rcGlow.top += 1; rcGlow.bottom -= 2; CSkin::m_tabGlowTop->setAlphaFormat(AC_SRC_ALPHA, (stateId == PBS_PRESSED || fIsActiveItem) ? 180 : 100); CSkin::m_tabGlowTop->Render(hdc, &rcGlow, true); } } } else if (M.isVSThemed()) { RECT *rcDraw = const_cast<RECT *>(rc); if (id == IDC_SIDEBARUP || id == IDC_SIDEBARDOWN) { ::FillRect(hdc, rc, stateId == PBS_HOT ? ::GetSysColorBrush(COLOR_HOTLIGHT) : ::GetSysColorBrush(COLOR_3DFACE)); ::InflateRect(rcDraw, -2, 0); ::DrawEdge(hdc, rcDraw, EDGE_ETCHED, BF_SOFT | BF_RECT | BF_FLAT); } else { CSkin::FillBack(hdc, rcDraw); if (IsThemeBackgroundPartiallyTransparent(item->m_buttonControl->hThemeToolbar, TP_BUTTON, stateId)) DrawThemeParentBackground(item->getHwnd(), hdc, rcDraw); if (M.isAero() || PluginConfig.m_WinVerMajor >= 6) { stateId = (fIsActiveItem ? PBS_PRESSED : PBS_HOT); DrawThemeBackground(item->m_buttonControl->hThemeToolbar, hdc, 8, RBStateConvert2Flat(stateId), rcDraw, rcDraw); } else { stateId = (fIsActiveItem ? PBS_PRESSED : PBS_HOT); DrawThemeBackground(item->m_buttonControl->hThemeToolbar, hdc, TP_BUTTON, TBStateConvert2Flat(stateId), rcDraw, rcDraw); } } } else { RECT *rcDraw = const_cast<RECT *>(rc); if (!(id == IDC_SIDEBARUP || id == IDC_SIDEBARDOWN)) { HBRUSH br = (stateId == PBS_HOT && !fIsActiveItem) ? ::GetSysColorBrush(COLOR_BTNSHADOW) : (fIsActiveItem || stateId == PBS_PRESSED ? ::GetSysColorBrush(COLOR_HOTLIGHT) : ::GetSysColorBrush(COLOR_3DFACE)); ::FillRect(hdc, rc, br); ::DrawEdge(hdc, rcDraw, (stateId == PBS_HOT && !fIsActiveItem) ? EDGE_ETCHED : (fIsActiveItem || stateId == PBS_PRESSED) ? EDGE_BUMP : EDGE_ETCHED, BF_RECT | BF_SOFT | BF_FLAT); } else { ::FillRect(hdc, rc, stateId == PBS_HOT ? ::GetSysColorBrush(COLOR_HOTLIGHT) : ::GetSysColorBrush(COLOR_3DFACE)); ::InflateRect(rcDraw, -2, 0); ::DrawEdge(hdc, rcDraw, EDGE_ETCHED, BF_SOFT | BF_RECT | BF_FLAT); } } }
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if(hdcPaint) { HDC hdcMem; RECT rcClient, rcBp; HFONT hOldFont = 0; int xOffset = 0; HANDLE hbp = 0; GetClientRect(ctl->hwnd, &rcClient); #ifndef _USE_D2D rcBp = rcClient; INIT_PAINT(hdcPaint, rcBp, hdcMem); #else hdcMem = cfg::dat.hdcBg; MapWindowPoints(ctl->hwnd, pcli->hwndContactList, reinterpret_cast<POINT *>(&rcClient), 2); #endif hOldFont = reinterpret_cast<HFONT>(SelectObject(hdcMem, ctl->hFont)); // If its a push button, check to see if it should stay pressed if(ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; // Draw the flat button if(ctl->flatBtn) { if(ctl->hThemeToolbar && ctl->bThemed) { RECT rc = rcClient; int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; Gfx::drawBGFromSurface(ctl->hwnd, rc, hdcMem); if(Api::pfnIsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { Api::pfnDrawThemeParentBackground(ctl->hwnd, hdcMem, &rc); } Api::pfnDrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rc, &rc); } else { HBRUSH hbr; RECT rc = rcClient; if(ctl->buttonItem) { RECT rcParent; POINT pt; TImageItem *imgItem = ctl->stateId == PBS_HOT ? ctl->buttonItem->imgHover : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->imgPressed : ctl->buttonItem->imgNormal); LONG *glyphMetrics = ctl->stateId == PBS_HOT ? ctl->buttonItem->hoverGlyphMetrics : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->pressedGlyphMetrics : ctl->buttonItem->normalGlyphMetrics); #ifndef _USE_D2D GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); Gfx::drawBGFromSurface(ctl->hwnd, rc, hdcMem); #endif if(imgItem) Gfx::renderSkinItem(hdcMem, &rc, imgItem); if(Skin::glyphItem) { Api::pfnAlphaBlend(hdcMem, (rc.right - glyphMetrics[2]) / 2, (rc.bottom - glyphMetrics[3]) / 2, glyphMetrics[2], glyphMetrics[3], Skin::glyphItem->hdc, glyphMetrics[0], glyphMetrics[1], glyphMetrics[2], glyphMetrics[3], Skin::glyphItem->bf); } } else if(ctl->bSkinned) { // skinned RECT rcParent; TStatusItem *item; int item_id; GetWindowRect(ctl->hwnd, &rcParent); Gfx::drawBGFromSurface(ctl->hwnd, rc, hdcMem); item_id = ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED); item = &Skin::statusItems[item_id]; Gfx::setTextColor(item->TEXTCOLOR); if(item->IGNORED) FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); else { rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM; rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT; Gfx::renderSkinItem(hdcMem, &rc, item->imageItem); } } else { if(ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DFACE); else { HDC dc; HWND hwndParent; hwndParent = GetParent(ctl->hwnd); dc = GetDC(hwndParent); hbr = (HBRUSH) SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM) dc, (LPARAM) hwndParent); ReleaseDC(hwndParent, dc); } if(hbr) { FillRect(hdcMem, &rc, hbr); DeleteObject(hbr); } } if(!ctl->bSkinned && ctl->buttonItem == 0) { if(ctl->stateId == PBS_HOT || ctl->focus) { if(ctl->pbState) DrawEdge(hdcMem, &rc, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, &rc, BDR_RAISEDOUTER, BF_RECT | BF_SOFT); } else if(ctl->stateId == PBS_PRESSED) DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } } } else { // Draw background/border if(ctl->hThemeButton && ctl->bThemed) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; POINT pt; RECT rcParent; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY); if(Api::pfnIsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { Api::pfnDrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } Api::pfnDrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); } else { UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); if(ctl->defbutton && ctl->stateId == PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); } // Draw focus rectangle if button has focus if(ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // If we have an icon or a bitmap, ignore text and only draw the image on the button if(ctl->hIcon || ctl->hIconPrivate || ctl->iIcon) { int ix = (rcClient.right - rcClient.left) / 2 - (CXSMICON / 2); int iy = (rcClient.bottom - rcClient.top) / 2 - (CXSMICON / 2); HICON hIconNew = ctl->hIconPrivate != 0 ? ctl->hIconPrivate : ctl->hIcon; if(lstrlen(ctl->szText) == 0) { if(ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, CXSMICON, CYSMICON, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, CXSMICON, CYSMICON, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); ctl->sLabel.cx = ctl->sLabel.cy = 0; } else { GetTextExtentPoint32(hdcMem, ctl->szText, lstrlen(ctl->szText), &ctl->sLabel); if(CXSMICON + ctl->sLabel.cx + 8 > rcClient.right - rcClient.left) ctl->sLabel.cx = (rcClient.right - rcClient.left) - CXSMICON - 8; else ctl->sLabel.cx += 4; ix = (rcClient.right - rcClient.left) / 2 - ((CXSMICON + ctl->sLabel.cx) / 2); if(ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, CXSMICON, CYSMICON, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, CXSMICON, CYSMICON, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); xOffset = ix + CXSMICON + 4; } } else if(ctl->hBitmap) { BITMAP bminfo; int ix, iy; GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); ix = (rcClient.right - rcClient.left) / 2 - (bminfo.bmWidth / 2); iy = (rcClient.bottom - rcClient.top) / 2 - (bminfo.bmHeight / 2); if(ctl->stateId == PBS_PRESSED) { ix++; iy++; } DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->hBitmap, 0, ix, iy, bminfo.bmWidth, bminfo.bmHeight, IsWindowEnabled(ctl->hwnd) ? DST_BITMAP : DST_BITMAP | DSS_DISABLED); } if(GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow RECT rcText; CopyRect(&rcText, &rcClient); SetBkMode(hdcMem, TRANSPARENT); if(!ctl->bSkinned) Gfx::setTextColor(IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); if(ctl->arrow) { DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->arrow, 0, rcClient.right - rcClient.left - 5 - CXSMICON + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), (rcClient.bottom - rcClient.top) / 2 - CYSMICON / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), CXSMICON, CYSMICON, IsWindowEnabled(ctl->hwnd) ? DST_ICON : DST_ICON | DSS_DISABLED); rcText.left += (4 + CXSMICON); } if(xOffset) rcText.left += (4 + CXSMICON); Gfx::renderText(hdcMem, ctl->hThemeButton, ctl->szText, &rcText, DT_VCENTER | DT_CENTER | DT_SINGLELINE, 0); } if(hOldFont) SelectObject(hdcMem, hOldFont); #ifndef _USE_D2D FINALIZE_PAINT(hbp, &rcBp, 0); #endif } }
static void PaintWorker(TBBUTTONDATA *bct, HDC hdcPaint, POINT *pOffset) { if (!hdcPaint) return; //early exit POINT offset; if (pOffset) offset = *pOffset; else offset.x = offset.y = 0; RECT rcClient; GetClientRect(bct->hwnd, &rcClient); int width = rcClient.right - rcClient.left; int height = rcClient.bottom - rcClient.top; HBITMAP hbmMem = NULL; HBITMAP hbmOld = NULL; HDC hdcMem = pOffset ? hdcPaint : CreateCompatibleDC(hdcPaint); HFONT hOldFont = (HFONT)SelectObject(hdcMem, bct->hFont); if (!pOffset) { hbmMem = ske_CreateDIB32(width, height); hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem); } else OffsetRect(&rcClient, offset.x, offset.y); if (!g_CluiData.fDisableSkinEngine) { char szRequest[128]; /* painting */ mir_snprintf(szRequest, "Button,ID=%s,Hovered=%s,Pressed=%s,Focused=%s", bct->szButtonID, // ID b2str(bct->stateId == PBS_HOT), // Hovered b2str(bct->stateId == PBS_PRESSED || bct->bIsPushed == TRUE), // Pressed b2str(bct->bFocused)); // Focused SkinDrawGlyph(hdcMem, &rcClient, &rcClient, szRequest); } else if (xpt_IsThemed(bct->hThemeToolbar)) { RECT *rc = &rcClient; int state = IsWindowEnabled(bct->hwnd) ? /*(bct->stateId == PBS_PRESSED || bct->bIsPushed == TRUE) ? PBS_PRESSED :*/ (bct->stateId == PBS_NORMAL && bct->bIsDefault ? PBS_DEFAULTED : bct->stateId) : PBS_DISABLED; xpt_DrawTheme(bct->hThemeToolbar, bct->hwnd, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), rc, rc); } else { HBRUSH hbr = NULL; if (bct->stateId == PBS_PRESSED || bct->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DLIGHT); else { RECT btnRect; POINT pt = { 0 }; int ret; HWND hwndParent = GetParent(bct->hwnd); HDC dc = CreateCompatibleDC(NULL); HBITMAP memBM, oldBM; GetWindowRect(hwndParent, &btnRect); memBM = ske_CreateDIB32(btnRect.right - btnRect.left, btnRect.bottom - btnRect.top); oldBM = (HBITMAP)SelectObject(dc, memBM); ret = SendMessage(hwndParent, WM_ERASEBKGND, (WPARAM)dc, 0); GetWindowRect(bct->hwnd, &btnRect); ClientToScreen(hwndParent, &pt); OffsetRect(&btnRect, -pt.x, -pt.y); if (ret) BitBlt(hdcMem, 0, 0, btnRect.right - btnRect.left, btnRect.bottom - btnRect.top, dc, btnRect.left, btnRect.top, SRCCOPY); oldBM = (HBITMAP)SelectObject(dc, oldBM); DeleteObject(memBM); DeleteDC(dc); if (!ret) { //WM_ERASEBKG return false need to paint HDC pdc = GetDC(hwndParent); HBRUSH oldBrush = (HBRUSH)GetCurrentObject(pdc, OBJ_BRUSH); hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)pdc, (LPARAM)hwndParent); SelectObject(pdc, oldBrush); ReleaseDC(hwndParent, pdc); } } if (hbr) { FillRect(hdcMem, &rcClient, hbr); DeleteObject(hbr); } if (bct->stateId == PBS_HOT || bct->bFocused) { if (bct->bIsPushed) DrawEdge(hdcMem, &rcClient, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, &rcClient, BDR_RAISEDOUTER, BF_RECT | BF_SOFT | BF_FLAT); } else if (bct->stateId == PBS_PRESSED) DrawEdge(hdcMem, &rcClient, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } RECT rcTemp = rcClient; //content rect bool bPressed = (bct->stateId == PBS_PRESSED || bct->bIsPushed == TRUE); bool bHasText = (bct->szText[0] != '\0'); /* formatter */ if (!g_CluiData.fDisableSkinEngine) { /* correct rect according to rcMargins */ rcTemp.left += bct->rcMargins.left; rcTemp.top += bct->rcMargins.top; rcTemp.bottom -= bct->rcMargins.bottom; rcTemp.right -= bct->rcMargins.right; } /* reposition button items */ RECT rcIcon = rcTemp, rcText = rcTemp; if (bct->hIcon) { if (bHasText) { rcIcon.right = rcIcon.left + 16; /* CXSM_ICON */ rcText.left = rcIcon.right + 2; } else { rcIcon.left += (rcIcon.right - rcIcon.left) / 2 - 8; rcIcon.right = rcIcon.left + 16; } } /* Check sizes*/ if (bct->hIcon && (rcIcon.right > rcTemp.right || rcIcon.bottom > rcTemp.bottom || rcIcon.left < rcTemp.left || rcIcon.top < rcTemp.top)) bct->hIcon = NULL; if (bHasText && (rcText.right > rcTemp.right || rcText.bottom > rcTemp.bottom || rcText.left < rcTemp.left || rcText.top < rcTemp.top)) bHasText = FALSE; if (bct->hIcon) { /* center icon vertically */ rcIcon.top += (rcClient.bottom - rcClient.top) / 2 - 8; /* CYSM_ICON/2 */ rcIcon.bottom = rcIcon.top + 16; /* CYSM_ICON */ /* draw it */ ske_DrawIconEx(hdcMem, rcIcon.left + bPressed, rcIcon.top + bPressed, bct->hIcon, 16, 16, 0, NULL, DI_NORMAL); } if (bHasText) { BOOL bCentered = TRUE; SetBkMode(hdcMem, TRANSPARENT); if (bct->nFontID >= 0) g_clcPainter.ChangeToFont(hdcMem, NULL, bct->nFontID, NULL); RECT TextRequiredRect = rcText; ske_DrawText(hdcMem, bct->szText, -1, &TextRequiredRect, DT_CENTER | DT_VCENTER | DT_CALCRECT | DT_SINGLELINE); if (TextRequiredRect.right - TextRequiredRect.left > rcText.right - rcText.left) bCentered = FALSE; ske_DrawText(hdcMem, bct->szText, -1, &rcText, (bCentered ? DT_CENTER : 0) | DT_VCENTER | DT_SINGLELINE); ske_ResetTextEffect(hdcMem); } if (!pOffset) BitBlt(hdcPaint, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY); // better to use try/finally but looks like last one is Microsoft specific SelectObject(hdcMem, hOldFont); if (!pOffset) { SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); } }
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if (hdcPaint) { HDC hdcMem; HBITMAP hbmMem; HDC hOld; RECT rcClient; GetClientRect(ctl->hwnd, &rcClient); hdcMem = CreateCompatibleDC(hdcPaint); hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); hOld = ( HDC )SelectObject(hdcMem, hbmMem); // If its a push button, check to see if it should stay pressed if (ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; // Draw the flat button if (ctl->flatBtn) { if (ctl->hThemeToolbar) { int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId==PBS_NORMAL&&ctl->defbutton?PBS_DEFAULTED:ctl->stateId):PBS_DISABLED; if (isThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { drawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } drawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rcClient, &rcClient); } else { HBRUSH hbr; if (ctl->stateId==PBS_PRESSED||ctl->stateId==PBS_HOT) hbr = GetSysColorBrush(COLOR_3DLIGHT); else { HWND hwndParent = GetParent(ctl->hwnd); HDC dc = GetDC(hwndParent); HBRUSH oldBrush = (HBRUSH)GetCurrentObject( dc, OBJ_BRUSH ); hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent); SelectObject(dc,oldBrush); ReleaseDC(hwndParent,dc); } if (hbr) { FillRect(hdcMem, &rcClient, hbr); DeleteObject(hbr); } if (ctl->stateId==PBS_HOT||ctl->focus) { if (ctl->pbState) DrawEdge(hdcMem,&rcClient, EDGE_ETCHED,BF_RECT|BF_SOFT); else DrawEdge(hdcMem,&rcClient, BDR_RAISEDOUTER,BF_RECT|BF_SOFT|BF_FLAT); } else if (ctl->stateId==PBS_PRESSED) DrawEdge(hdcMem, &rcClient, BDR_SUNKENOUTER,BF_RECT|BF_SOFT); } } else { // Draw background/border if (ctl->hThemeButton) { int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId==PBS_NORMAL&&ctl->defbutton?PBS_DEFAULTED:ctl->stateId):PBS_DISABLED; if (isThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { drawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } drawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); } else { UINT uState = DFCS_BUTTONPUSH|((ctl->stateId==PBS_HOT)?DFCS_HOT:0)|((ctl->stateId == PBS_PRESSED)?DFCS_PUSHED:0); if (ctl->defbutton&&ctl->stateId==PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); } // Draw focus rectangle if button has focus if (ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // If we have an icon or a bitmap, ignore text and only draw the image on the button if (ctl->hIcon) { int ix = (rcClient.right-rcClient.left)/2 - (GetSystemMetrics(SM_CXSMICON)/2); int iy = (rcClient.bottom-rcClient.top)/2 - (GetSystemMetrics(SM_CYSMICON)/2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } { HIMAGELIST hImageList; HICON hIconNew; hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), IsWinVerXPPlus()? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0); ImageList_AddIcon(hImageList, ctl->hIcon); hIconNew = ImageList_GetIcon(hImageList, 0, ILD_NORMAL); DrawState(hdcMem,NULL,NULL,(LPARAM)hIconNew,0,ix,iy,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),IsWindowEnabled(ctl->hwnd)?DST_ICON|DSS_NORMAL:DST_ICON|DSS_DISABLED); ImageList_RemoveAll(hImageList); ImageList_Destroy(hImageList); DestroyIcon(hIconNew); } } else if (ctl->hBitmap) { BITMAP bminfo; int ix,iy; GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); ix = (rcClient.right-rcClient.left)/2 - (bminfo.bmWidth/2); iy = (rcClient.bottom-rcClient.top)/2 - (bminfo.bmHeight/2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } DrawState(hdcMem,NULL,NULL,(LPARAM)ctl->hBitmap,0,ix,iy,bminfo.bmWidth,bminfo.bmHeight,IsWindowEnabled(ctl->hwnd)?DST_BITMAP:DST_BITMAP|DSS_DISABLED); } else if (GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow TCHAR szText[MAX_PATH]; SIZE sz; RECT rcText; HFONT hOldFont; CopyRect(&rcText, &rcClient); GetWindowText(ctl->hwnd, szText, SIZEOF(szText)); SetBkMode(hdcMem, TRANSPARENT); hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so. SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd)||!ctl->hThemeButton?GetSysColor(COLOR_BTNTEXT):GetSysColor(COLOR_GRAYTEXT)); GetTextExtentPoint32(hdcMem, szText, lstrlen(szText), &sz); if (ctl->cHot) { SIZE szHot; GetTextExtentPoint32 (hdcMem, _T("&"), 1, &szHot); sz.cx -= szHot.cx; } if (ctl->arrow) { DrawState(hdcMem,NULL,NULL,(LPARAM)ctl->arrow,0,rcClient.right-rcClient.left-5-GetSystemMetrics(SM_CXSMICON)+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),(rcClient.bottom-rcClient.top)/2-GetSystemMetrics(SM_CYSMICON)/2+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),IsWindowEnabled(ctl->hwnd)?DST_ICON:DST_ICON|DSS_DISABLED); } SelectObject(hdcMem, ctl->hFont); DrawState(hdcMem,NULL,NULL,(LPARAM)szText,0,(rcText.right-rcText.left-sz.cx)/2+(!ctl->hThemeButton&&ctl->stateId==PBS_PRESSED?1:0),ctl->hThemeButton?(rcText.bottom-rcText.top-sz.cy)/2:(rcText.bottom-rcText.top-sz.cy)/2-(ctl->stateId==PBS_PRESSED?0:1),sz.cx,sz.cy,IsWindowEnabled(ctl->hwnd)||ctl->hThemeButton?DST_PREFIXTEXT|DSS_NORMAL:DST_PREFIXTEXT|DSS_DISABLED); SelectObject(hdcMem, hOldFont); } BitBlt(hdcPaint, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hOld); DeleteObject(hbmMem); DeleteDC(hdcMem); } }
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if (hdc_buttonglyph == 0) { hdc_buttonglyph = CreateCompatibleDC(hdcPaint); hbm_buttonglyph = CreateCompatibleBitmap(hdcPaint, 16, 16); hbm_buttonglyph_old = (HBITMAP)SelectObject(hdc_buttonglyph, hbm_buttonglyph); bf_buttonglyph.BlendFlags = 0; bf_buttonglyph.SourceConstantAlpha = 120; bf_buttonglyph.BlendOp = AC_SRC_OVER; bf_buttonglyph.AlphaFormat = 0; } if (hdcPaint) { HDC hdcMem; HBITMAP hbmMem, hOld; RECT rcClient; RECT rcContent; bool fAero = M->isAero(); bool fVSThemed = (!CSkin::m_skinEnabled && M->isVSThemed()); HANDLE hbp = 0; TWindowData *dat = (TWindowData *)GetWindowLongPtr(GetParent(ctl->hwnd), GWLP_USERDATA); GetClientRect(ctl->hwnd, const_cast<RECT *>(&rcClient)); CopyRect(&rcContent, &rcClient); if(CMimAPI::m_haveBufferedPaint) hbp = CMimAPI::m_pfnBeginBufferedPaint(hdcPaint, &rcContent, BPBF_TOPDOWNDIB, NULL, &hdcMem); else { hdcMem = CreateCompatibleDC(hdcPaint); hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); hOld = (HBITMAP)SelectObject(hdcMem, hbmMem); } CSkin::FillBack(hdcMem, &rcContent); if (ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; if (ctl->flatBtn) { if (ctl->pContainer && CSkin::m_skinEnabled) { CSkinItem *item, *realItem = 0; if (ctl->bTitleButton) item = &SkinItems[ctl->stateId == PBS_NORMAL ? ID_EXTBKTITLEBUTTON : (ctl->stateId == PBS_HOT ? ID_EXTBKTITLEBUTTONMOUSEOVER : ID_EXTBKTITLEBUTTONPRESSED)]; else { item = &SkinItems[(ctl->stateId == PBS_NORMAL || ctl->stateId == PBS_DISABLED) ? ID_EXTBKBUTTONSNPRESSED : (ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : ID_EXTBKBUTTONSPRESSED)]; realItem = item; } CSkin::SkinDrawBG(ctl->hwnd, ctl->pContainer->hwnd, ctl->pContainer, &rcContent, hdcMem); if (!item->IGNORED) { RECT rc1 = rcClient; rc1.left += item->MARGIN_LEFT; rc1.right -= item->MARGIN_RIGHT; rc1.top += item->MARGIN_TOP; rc1.bottom -= item->MARGIN_BOTTOM; CSkin::DrawItem(hdcMem, &rc1, item); } else goto flat_themed; } else { flat_themed: int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; if (ctl->bToolbarButton) { if(dat) { RECT rcWin; GetWindowRect(ctl->hwnd, &rcWin); POINT pt; pt.x = rcWin.left; ScreenToClient(dat->hwnd, &pt); BitBlt(hdcMem, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, dat->pContainer->cachedToolbarDC, pt.x, 1, SRCCOPY); } } if (ctl->hThemeToolbar && ctl->bThemed && 1 == dat->pContainer->bTBRenderingMode) { if(fAero || PluginConfig.m_WinVerMajor >= 6) CMimAPI::m_pfnDrawThemeBackground(ctl->hThemeToolbar, hdcMem, 8, RBStateConvert2Flat(state), &rcClient, &rcClient); else CMimAPI::m_pfnDrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rcClient, &rcClient); } else { CSkin::m_switchBarItem->setAlphaFormat(AC_SRC_ALPHA, state == PBS_HOT ? 220 : 180); if(state == PBS_HOT || state == PBS_PRESSED) { if(state == PBS_PRESSED) { RECT rc = rcClient; InflateRect(&rc, -1, -1); HBRUSH bBack = CreateSolidBrush(PluginConfig.m_tbBackgroundLow ? PluginConfig.m_tbBackgroundLow : GetSysColor(COLOR_3DDKSHADOW)); FillRect(hdcMem, &rc, bBack); DeleteObject(bBack); } CSkin::m_switchBarItem->Render(hdcMem, &rcClient, true); } } } } else { if (ctl->pContainer && CSkin::m_skinEnabled) { CSkinItem *item, *realItem = 0; if (ctl->bTitleButton) item = &SkinItems[ctl->stateId == PBS_NORMAL ? ID_EXTBKTITLEBUTTON : (ctl->stateId == PBS_HOT ? ID_EXTBKTITLEBUTTONMOUSEOVER : ID_EXTBKTITLEBUTTONPRESSED)]; else { item = &SkinItems[(ctl->stateId == PBS_NORMAL || ctl->stateId == PBS_DISABLED) ? ID_EXTBKBUTTONSNPRESSED : (ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : ID_EXTBKBUTTONSPRESSED)]; realItem = item; } CSkin::SkinDrawBG(ctl->hwnd, ctl->pContainer->hwnd, ctl->pContainer, &rcClient, hdcMem); if (!item->IGNORED) { RECT rc1 = rcClient; rc1.left += item->MARGIN_LEFT; rc1.right -= item->MARGIN_RIGHT; rc1.top += item->MARGIN_TOP; rc1.bottom -= item->MARGIN_BOTTOM; CSkin::DrawItem(hdcMem, &rc1, item); } else goto nonflat_themed; } else { nonflat_themed: int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; if (ctl->hThemeButton && ctl->bThemed && 0 == PluginConfig.m_fillColor) { CMimAPI::m_pfnDrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); CMimAPI::m_pfnGetThemeBackgroundContentRect(ctl->hThemeToolbar, hdcMem, BP_PUSHBUTTON, PBS_NORMAL, &rcClient, &rcContent); } else { CSkin::m_switchBarItem->setAlphaFormat(AC_SRC_ALPHA, state == PBS_NORMAL ? 140 : 240); if(state == PBS_PRESSED) { RECT rc = rcClient; InflateRect(&rc, -1, -1); HBRUSH bBack = CreateSolidBrush(PluginConfig.m_tbBackgroundLow ? PluginConfig.m_tbBackgroundLow : GetSysColor(COLOR_3DDKSHADOW)); FillRect(hdcMem, &rc, bBack); DeleteObject(bBack); } CSkin::m_switchBarItem->Render(hdcMem, &rcClient, true); } // Draw focus rectangle if button has focus if (ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } } /* * render content */ if (ctl->arrow) { rcContent.top += 2; rcContent.bottom -= 2; rcContent.left = rcClient.right - 12; rcContent.right = rcContent.left; DrawIconEx(hdcMem, rcClient.right - 15, (rcClient.bottom - rcClient.top) / 2 - (PluginConfig.m_smcyicon / 2), PluginConfig.g_buttonBarIcons[ICON_DEFAULT_PULLDOWN], 16, 16, 0, 0, DI_NORMAL); } if (ctl->hIcon || ctl->hIconPrivate) { int ix = (rcClient.right - rcClient.left) / 2 - 8; int iy = (rcClient.bottom - rcClient.top) / 2 - 8; HICON hIconNew = ctl->hIconPrivate != 0 ? ctl->hIconPrivate : ctl->hIcon; if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } if (ctl->arrow) ix -= 4; if (ctl->dimmed && PluginConfig.m_IdleDetect) CSkin::DrawDimmedIcon(hdcMem, ix, iy, PluginConfig.m_smcxicon, PluginConfig.m_smcyicon, hIconNew, 180); else { if (ctl->stateId != PBS_DISABLED || CMimAPI::m_MyAlphaBlend == 0) { DrawIconEx(hdcMem, ix, iy, hIconNew, 16, 16, 0, 0, DI_NORMAL); if(ctl->overlay) DrawIconEx(hdcMem, ix, iy, ctl->overlay, 16, 16, 0, 0, DI_NORMAL); } else { BitBlt(hdc_buttonglyph, 0, 0, 16, 16, hdcMem, ix, iy, SRCCOPY); DrawIconEx(hdc_buttonglyph, 0, 0, hIconNew, 16, 16, 0, 0, DI_NORMAL); if(ctl->overlay) DrawIconEx(hdc_buttonglyph, 0, 0, ctl->overlay, 16, 16, 0, 0, DI_NORMAL); CMimAPI::m_MyAlphaBlend(hdcMem, ix, iy, PluginConfig.m_smcxicon, PluginConfig.m_smcyicon, hdc_buttonglyph, 0, 0, 16, 16, bf_buttonglyph); } } } else if (GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow TCHAR szText[MAX_PATH]; SIZE sz; RECT rcText; HFONT hOldFont; CopyRect(&rcText, &rcClient); GetWindowText(ctl->hwnd, szText, MAX_PATH - 1); SetBkMode(hdcMem, TRANSPARENT); hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); if (ctl->pContainer && CSkin::m_skinEnabled) SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) ? CSkin::m_DefaultFontColor : GetSysColor(COLOR_GRAYTEXT)); else { if(PluginConfig.m_genericTxtColor) SetTextColor(hdcMem, PluginConfig.m_genericTxtColor); else SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); } GetTextExtentPoint32(hdcMem, szText, lstrlen(szText), &sz); if (ctl->cHot) { SIZE szHot; GetTextExtentPoint32A(hdcMem, "&", 1, &szHot); sz.cx -= szHot.cx; } if (ctl->arrow) DrawState(hdcMem, NULL, NULL, (LPARAM)ctl->arrow, 0, rcClient.right - rcClient.left - 5 - PluginConfig.m_smcxicon + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), (rcClient.bottom - rcClient.top) / 2 - PluginConfig.m_smcyicon / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), PluginConfig.m_smcxicon, PluginConfig.m_smcyicon, IsWindowEnabled(ctl->hwnd) ? DST_ICON : DST_ICON | DSS_DISABLED); SelectObject(hdcMem, ctl->hFont); DrawState(hdcMem, NULL, NULL, (LPARAM)szText, lstrlen(szText), (rcText.right - rcText.left - sz.cx) / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->hThemeButton ? (rcText.bottom - rcText.top - sz.cy) / 2 : (rcText.bottom - rcText.top - sz.cy) / 2 - (ctl->stateId == PBS_PRESSED ? 0 : 1), sz.cx, sz.cy, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); SelectObject(hdcMem, hOldFont); } if(hbp) CMimAPI::m_pfnEndBufferedPaint(hbp, TRUE); else { BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hOld); DeleteObject(hbmMem); DeleteDC(hdcMem); } } }
static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) { if (hdcPaint) { HDC hdcMem; HBITMAP hbmMem; HBITMAP hbmOld = 0; RECT rcClient; HFONT hOldFont = 0; int xOffset = 0; GetClientRect(ctl->hwnd, &rcClient); hdcMem = CreateCompatibleDC(hdcPaint); hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); hbmOld = SelectObject(hdcMem, hbmMem); hOldFont = SelectObject(hdcMem, ctl->hFont); // If its a push button, check to see if it should stay pressed if (ctl->pushBtn && ctl->pbState) ctl->stateId = PBS_PRESSED; // Draw the flat button if (ctl->flatBtn) { if (ctl->hThemeToolbar && ctl->bThemed) { RECT rc = rcClient; int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; SkinDrawBg(ctl->hwnd, hdcMem); if (MyIsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { MyDrawThemeParentBackground(ctl->hwnd, hdcMem, &rc); } MyDrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rc, &rc); } else { HBRUSH hbr; RECT rc = rcClient; if(ctl->buttonItem) { RECT rcParent; POINT pt; HWND hwndParent = pcli->hwndContactList; ImageItem *imgItem = ctl->stateId == PBS_HOT ? ctl->buttonItem->imgHover : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->imgPressed : ctl->buttonItem->imgNormal); LONG *glyphMetrics = ctl->stateId == PBS_HOT ? ctl->buttonItem->hoverGlyphMetrics : (ctl->stateId == PBS_PRESSED ? ctl->buttonItem->pressedGlyphMetrics : ctl->buttonItem->normalGlyphMetrics); //if(ctl->stateId == PBS_HOT && glyphMetrics[2] <= 1 && glyphMetrics[3] <= 1) // glyphMetrics = ctl->lastGlyphMetrics; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); if(imgItem) DrawAlpha(hdcMem, &rc, 0, 0, 0, 0, 0, 0, 0, imgItem); if(g_glyphItem) { AlphaBlend(hdcMem, (rc.right - glyphMetrics[2]) / 2, (rc.bottom - glyphMetrics[3]) / 2, glyphMetrics[2], glyphMetrics[3], g_glyphItem->hdc, glyphMetrics[0], glyphMetrics[1], glyphMetrics[2], glyphMetrics[3], g_glyphItem->bf); //CopyMemory(ctl->lastGlyphMetrics, glyphMetrics, 4 * sizeof(LONG)); } } else if(ctl->bSkinned) { // skinned RECT rcParent; POINT pt; HWND hwndParent = pcli->hwndContactList; StatusItems_t *item; int item_id; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); if(HIWORD(ctl->bSkinned)) item_id = ctl->stateId == PBS_HOT ? ID_EXTBKTBBUTTONMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED); //GetItemByStatus(ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKTBBUTTONSPRESSED : ID_EXTBKTBBUTTONSNPRESSED), &item); else item_id = ctl->stateId == PBS_HOT ? ID_EXTBKBUTTONSMOUSEOVER : (ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED); item = &StatusItems[item_id - ID_STATUS_OFFLINE]; //GetItemByStatus(ctl->stateId == PBS_PRESSED ? ID_EXTBKBUTTONSPRESSED : ID_EXTBKBUTTONSNPRESSED, &item); SetTextColor(hdcMem, item->TEXTCOLOR); if(item->IGNORED) { if(pt.y < 10 || g_CluiData.bWallpaperMode) //SkinDrawBg(ctl->hwnd, hdcMem); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); else FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); } else { if(pt.y < 10 || g_CluiData.bWallpaperMode) //SkinDrawBg(ctl->hwnd, hdcMem); BitBlt(hdcMem, 0, 0, rc.right, rc.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); else FillRect(hdcMem, &rc, GetSysColorBrush(COLOR_3DFACE)); rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM; rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT; DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem); } } else { if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) hbr = GetSysColorBrush(COLOR_3DFACE); else { HDC dc; HWND hwndParent; hwndParent = GetParent(ctl->hwnd); dc = GetDC(hwndParent); hbr = (HBRUSH) SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM) dc, (LPARAM) hwndParent); ReleaseDC(hwndParent, dc); } if (hbr) { FillRect(hdcMem, &rc, hbr); DeleteObject(hbr); } } if(!ctl->bSkinned && ctl->buttonItem == 0) { if (ctl->stateId == PBS_HOT || ctl->focus) { if (ctl->pbState) DrawEdge(hdcMem, &rc, EDGE_ETCHED, BF_RECT | BF_SOFT); else DrawEdge(hdcMem, &rc, BDR_RAISEDOUTER, BF_RECT | BF_SOFT); } else if (ctl->stateId == PBS_PRESSED) DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT | BF_SOFT); } } } else { // Draw background/border if (ctl->hThemeButton && ctl->bThemed) { int state = IsWindowEnabled(ctl->hwnd) ? (ctl->stateId == PBS_NORMAL && ctl->defbutton ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; POINT pt; RECT rcParent; GetWindowRect(ctl->hwnd, &rcParent); pt.x = rcParent.left; pt.y = rcParent.top; ScreenToClient(pcli->hwndContactList, &pt); BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, g_CluiData.hdcBg, pt.x, pt.y, SRCCOPY); if (MyIsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { MyDrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); } MyDrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); } else { UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); if (ctl->defbutton && ctl->stateId == PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); } // Draw focus rectangle if button has focus if (ctl->focus) { RECT focusRect = rcClient; InflateRect(&focusRect, -3, -3); DrawFocusRect(hdcMem, &focusRect); } } // If we have an icon or a bitmap, ignore text and only draw the image on the button if (ctl->hIcon || ctl->hIconPrivate || ctl->iIcon) { int ix = (rcClient.right - rcClient.left) / 2 - (g_cxsmIcon / 2); int iy = (rcClient.bottom - rcClient.top) / 2 - (g_cxsmIcon / 2); HICON hIconNew = ctl->hIconPrivate != 0 ? ctl->hIconPrivate : ctl->hIcon; if (lstrlen(ctl->szText) == 0) { if (ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); ctl->sLabel.cx = ctl->sLabel.cy = 0; } else { GetTextExtentPoint32(hdcMem, ctl->szText, lstrlen(ctl->szText), &ctl->sLabel); if(g_cxsmIcon + ctl->sLabel.cx + 8 > rcClient.right - rcClient.left) ctl->sLabel.cx = (rcClient.right - rcClient.left) - g_cxsmIcon - 8; else ctl->sLabel.cx += 4; ix = (rcClient.right - rcClient.left) / 2 - ((g_cxsmIcon + ctl->sLabel.cx) / 2); if (ctl->iIcon) ImageList_DrawEx(ctl->hIml, ctl->iIcon, hdcMem, ix, iy, g_cxsmIcon, g_cysmIcon, CLR_NONE, CLR_NONE, ILD_NORMAL); else DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); xOffset = ix + g_cxsmIcon + 4; } } else if (ctl->hBitmap) { BITMAP bminfo; int ix, iy; GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); ix = (rcClient.right - rcClient.left) / 2 - (bminfo.bmWidth / 2); iy = (rcClient.bottom - rcClient.top) / 2 - (bminfo.bmHeight / 2); if (ctl->stateId == PBS_PRESSED) { ix++; iy++; } DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->hBitmap, 0, ix, iy, bminfo.bmWidth, bminfo.bmHeight, IsWindowEnabled(ctl->hwnd) ? DST_BITMAP : DST_BITMAP | DSS_DISABLED); } if (GetWindowTextLength(ctl->hwnd)) { // Draw the text and optinally the arrow RECT rcText; CopyRect(&rcText, &rcClient); SetBkMode(hdcMem, TRANSPARENT); // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so. if(!ctl->bSkinned) SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_GRAYTEXT)); if (ctl->arrow) DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->arrow, 0, rcClient.right - rcClient.left - 5 - g_cxsmIcon + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), (rcClient.bottom - rcClient.top) / 2 - g_cysmIcon / 2 + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), g_cxsmIcon, g_cysmIcon, IsWindowEnabled(ctl->hwnd) ? DST_ICON : DST_ICON | DSS_DISABLED); DrawState(hdcMem, NULL, NULL, (LPARAM) ctl->szText, 0, xOffset + (!ctl->hThemeButton && ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->hThemeButton ? (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + 1 : (rcText.bottom - rcText.top - ctl->sLabel.cy) / 2 + (ctl->stateId == PBS_PRESSED ? 1 : 0), ctl->sLabel.cx, ctl->sLabel.cy, IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); } if (hOldFont) SelectObject(hdcMem, hOldFont); BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); DeleteObject(hbmOld); } }