Exemple #1
0
/**
 * 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);
    }
}
Exemple #2
0
/**
 * 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);
		}
	}
}
Exemple #3
0
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);
	}
}
Exemple #5
0
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);

	}
}
Exemple #6
0
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);
    }
}