CMemDC::~CMemDC() { if (m_hBufferedPaint != NULL) { m_dcMem.Detach(); EndBufferedPaint(m_hBufferedPaint, TRUE); } }
LRESULT AeroControlBase::ProgressbarWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { 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); RECT rc; GetWindowRect(hWnd, &rc); MapWindowPoints(NULL, hWnd, (LPPOINT)&rc, 2); if (hdc) { PaintControl(hWnd, hdc, &ps.rcPaint, false); BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = 0L; HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rc, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { COLORREF cr = RGB(0x00, 0x00, 0x00); SetPixel(hdcPaint, 0, 0, cr); SetPixel(hdcPaint, 0, RECTHEIGHT(rc) - 1, cr); SetPixel(hdcPaint, RECTWIDTH(rc) - 1, 0, cr); SetPixel(hdcPaint, RECTWIDTH(rc) - 1, RECTHEIGHT(rc) - 1, cr); EndBufferedPaint(hBufferedPaint, TRUE); } } EndPaint(hWnd, &ps); return 0; } break; case WM_NCDESTROY: case WM_DESTROY: RemoveWindowSubclass(hWnd, SubclassProc, Static); subclassedControls.erase(hWnd); break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
HBITMAP LiferayNativityContextMenus::_IconToBitmapPARGB32(HICON hIcon) { if (!hIcon) return NULL; SIZE sizIcon; sizIcon.cx = GetSystemMetrics(SM_CXSMICON); sizIcon.cy = GetSystemMetrics(SM_CYSMICON); RECT rcIcon; SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); HBITMAP hBmp = NULL; HDC hdcDest = CreateCompatibleDC(NULL); if (hdcDest) { if (SUCCEEDED(_Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp))) { HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); if (hbmpOld) { BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = { 0 }; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = BeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL)) { // If icon did not have an alpha channel we need to convert buffer to PARGB _ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); } // This will write the buffer contents to the destination bitmap EndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); } } DeleteDC(hdcDest); } return hBmp; }
HBITMAP IconBitmapUtils::IconToBitmapPARGB32(HICON hIcon, int width, int height) { if (!hIcon) return nullptr; SIZE sizIcon; sizIcon.cx = width; sizIcon.cy = height; RECT rcIcon; SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); HDC hdcDest = CreateCompatibleDC(nullptr); if (!hdcDest) return nullptr; SCOPE_EXIT { DeleteDC(hdcDest); }; HBITMAP hBmp = nullptr; if (FAILED(Create32BitHBITMAP(hdcDest, &sizIcon, nullptr, &hBmp))) return nullptr; auto hbmpOld = static_cast<HBITMAP>(SelectObject(hdcDest, hBmp)); if (!hbmpOld) return hBmp; BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = { 0 }; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = BeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, nullptr, DI_NORMAL)) { // If icon did not have an alpha channel we need to convert buffer to PARGB ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); } // This will write the buffer contents to the destination bitmap EndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); return hBmp; }
HBITMAP ComposerShellMenu::IconToBitmap(HICON hIcon) { HBITMAP hBmp = NULL; HDC hdcDest = CreateCompatibleDC(NULL); if (hIcon && hdcDest) { long cx = GetSystemMetrics(SM_CXSMICON); long cy = GetSystemMetrics(SM_CYSMICON); RGBQUAD *bits = NULL; BITMAPINFO bmi = {0}; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biWidth = cx; bmi.bmiHeader.biHeight = cy; bmi.bmiHeader.biBitCount = 32; hBmp = CreateDIBSection(hdcDest, &bmi, DIB_RGB_COLORS, (VOID **)bits, NULL, 0); if (hBmp) { SelectObject(hdcDest, hBmp); RECT rct; SetRect(&rct, 0, 0, cx, cy); BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = {0}; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = BeginBufferedPaint(hdcDest, &rct, BPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { DrawIconEx(hdcBuffer, 0, 0, hIcon, cx, cy, 0, NULL, DI_NORMAL); // Write the buffer contents to hdcDest EndBufferedPaint(hPaintBuffer, TRUE); } } DeleteDC(hdcDest); } return hBmp; }
void AeroControlBase::PaintControl(HWND hWnd, HDC hdc, RECT* prc, bool bDrawBorder) { HDC hdcPaint = NULL; if(bDrawBorder) VERIFY(InflateRect(prc, 1, 1)); HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, prc, BPBF_TOPDOWNDIB, NULL, &hdcPaint); if (hdcPaint) { RECT rc; VERIFY(GetWindowRect(hWnd, &rc)); PatBlt(hdcPaint, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), BLACKNESS); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &rc, 0x00)); /// /// first blit white so list ctrls don't look ugly: /// VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), WHITENESS)); if(bDrawBorder) VERIFY(InflateRect(prc, -1, -1)); // Tell the control to paint itself in our memory buffer SendMessage(hWnd, WM_PRINTCLIENT, (WPARAM) hdcPaint, PRF_CLIENT|PRF_ERASEBKGND |PRF_NONCLIENT|PRF_CHECKVISIBLE); if(bDrawBorder) { VERIFY(InflateRect(prc, 1, 1)); VERIFY(FrameRect(hdcPaint, prc, (HBRUSH)GetStockObject(BLACK_BRUSH))); } // don't make a possible border opaque, only the inner part of the control VERIFY(InflateRect(prc, -2, -2)); // Make every pixel opaque VERIFY(S_OK == BufferedPaintSetAlpha(hBufferedPaint, prc, 255)); VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } }
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); }
LRESULT AeroControlBase::StaticWindowProc(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) { HDC hdcPaint = NULL; RECT rcClient; VERIFY(GetClientRect(hWnd, &rcClient)); LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE); LONG_PTR dwStyleEx = GetWindowLongPtr(hWnd, GWL_EXSTYLE); HTHEME hTheme = OpenThemeData(NULL, L"ControlPanelStyle"); if(hTheme) { HPAINTBUFFER hBufferedPaint = NULL; if (dwStyleEx & WS_EX_TRANSPARENT) { BP_PAINTPARAMS paintParams = {0}; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; BLENDFUNCTION blendf = {0}; blendf.BlendOp = AC_SRC_OVER; blendf.AlphaFormat = AC_SRC_ALPHA; blendf.SourceConstantAlpha = 255; paintParams.pBlendFunction = &blendf; hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, &paintParams, &hdcPaint); } else hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, NULL, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); LONG_PTR dwStaticStyle = dwStyle&0x1F; if(dwStaticStyle==SS_ICON || dwStaticStyle==SS_BITMAP) { bool bIcon = dwStaticStyle==SS_ICON; HANDLE hBmpIco = (HANDLE)SendMessage(hWnd, STM_GETIMAGE, bIcon ? IMAGE_ICON:IMAGE_BITMAP, NULL); if(hBmpIco) { std::unique_ptr<Bitmap> pBmp( bIcon ? new Bitmap((HICON)hBmpIco) : new Bitmap((HBITMAP)hBmpIco, NULL) ); std::unique_ptr<Graphics> myGraphics( new Graphics(hdcPaint) ); std::unique_ptr<CachedBitmap> pcbmp( new CachedBitmap(pBmp.get(), myGraphics.get()) ); VERIFY(Ok==myGraphics->DrawCachedBitmap(pcbmp.get(), 0,0)); } } else if(SS_BLACKRECT==dwStaticStyle || SS_GRAYRECT==dwStaticStyle || SS_WHITERECT==dwStaticStyle) { ARGB argb = 0L; switch (dwStaticStyle) { case SS_BLACKRECT: argb = 0xFF000000; break; case SS_GRAYRECT: argb = 0xFF808080; break; case SS_WHITERECT: argb = 0xFFFFFFFF; break; default: ASSERT(0); break; } Color clr(argb); FillRect(&rcClient, hdcPaint, clr); } else if(SS_BLACKFRAME==dwStaticStyle || SS_GRAYFRAME==dwStaticStyle || SS_WHITEFRAME==dwStaticStyle) { ARGB argb = 0L; switch (dwStaticStyle) { case SS_BLACKFRAME: argb = 0xFF000000; break; case SS_GRAYFRAME: argb = 0xFF808080; break; case SS_WHITEFRAME: argb = 0xFFFFFFFF; break; } Color clr(argb); DrawRect(&rcClient, hdcPaint, DashStyleSolid, clr, 1.0); } else { 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_WORDBREAK; switch (dwStaticStyle) { case SS_CENTER: dwFlags |= DT_CENTER; break; case SS_RIGHT: dwFlags |= DT_RIGHT; break; case SS_LEFTNOWORDWRAP: dwFlags &= ~DT_WORDBREAK; break; } if(dwStyle & SS_CENTERIMAGE) { dwFlags |= DT_VCENTER; dwFlags &= ~DT_WORDBREAK; } if(dwStyle & SS_ENDELLIPSIS) dwFlags |= DT_END_ELLIPSIS|DT_MODIFYSTRING; else if(dwStyle & SS_PATHELLIPSIS) dwFlags |= DT_PATH_ELLIPSIS|DT_MODIFYSTRING; else if(dwStyle & SS_WORDELLIPSIS) dwFlags |= DT_WORD_ELLIPSIS|DT_MODIFYSTRING; if (dwStyleEx&WS_EX_RIGHT) dwFlags |= DT_RIGHT; if(dwStyle & SS_NOPREFIX) dwFlags |= DT_NOPREFIX; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, 0, 0, szText, -1, dwFlags, &rcClient, &DttOpts)); if(dwStyle&SS_SUNKEN || dwStyle&WS_BORDER) DrawRect(&rcClient, hdcPaint, DashStyleSolid, Color(0xFF, 0,0,0), 1.0); } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } EndPaint(hWnd, &ps); return 0; } break; case WM_NCDESTROY: case WM_DESTROY: RemoveWindowSubclass(hWnd, SubclassProc, Static); subclassedControls.erase(hWnd); break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
// PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId; int wmEvent; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_ERASEBKGND: return 1; case WM_PAINT: // Let's open some theme data, and using BufferedPainting draw different fonts on glass background { RECT rcClient; GetClientRect(hWnd, &rcClient); MARGINS marGlassInset = {-1, -1, -1, -1}; // -1 means the whole window DwmExtendFrameIntoClientArea(hWnd, &marGlassInset); PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // ControlPanelStyle is declared in AeroStyle.xml HTHEME hTheme = OpenThemeData(NULL, L"ControlPanelStyle"); 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) { // Let's start with the simplest GDI default font DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED; DrawText(hdcPaint, L"This is some GDI text in the default font", -1, &rcClient, 0); // Let's look at the same text in the default theme rcClient.top += RECT_INCREMENT; DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text in the default font", -1, 0, &rcClient, &DttOpts); // Let's add some text color to add to theming attributes and draw again rcClient.top += RECT_INCREMENT; DttOpts.dwFlags |= DTT_TEXTCOLOR; DttOpts.crText = RGB(255, 255, 255); // CPANEL_TASKLINK is declared in VSStyle.h DrawThemeTextEx(hTheme, hdcPaint, CPANEL_TASKLINK, 0, L"This is some text in a themed font", -1, 0, &rcClient, &DttOpts); // Draw text on glass in a selected font DttOpts.dwFlags &= ~DTT_TEXTCOLOR; LOGFONT lgFont; HFONT hFontOld = NULL; if (SUCCEEDED(GetThemeSysFont(hTheme, TMT_CAPTIONFONT, &lgFont))) { HFONT hFont = CreateFontIndirect(&lgFont); hFontOld = (HFONT) SelectObject(hdcPaint, hFont); } rcClient.top += RECT_INCREMENT; DrawText(hdcPaint, L"This is some GDI text in the selected font", -1, &rcClient, 0); // The same selected font in themed text rcClient.top += RECT_INCREMENT; DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text in the selected font", -1, 0, &rcClient, &DttOpts); SelectObject(hdcPaint, hFontOld); rcClient.top += RECT_INCREMENT; DrawText(hdcPaint, L"This is some GDI text in the default font", -1, &rcClient, 0); // Let's add glow to our text attributes DttOpts.dwFlags |= DTT_GLOWSIZE; DttOpts.iGlowSize = 12; // Default value // CompositedWindow::Window is declared in AeroStyle.xml HTHEME hThemeWindow = OpenThemeData(NULL, L"CompositedWindow::Window"); if (hThemeWindow != NULL) { GetThemeInt(hThemeWindow, 0, 0, TMT_TEXTGLOWSIZE, &DttOpts.iGlowSize); CloseThemeData(hThemeWindow); } rcClient.top += RECT_INCREMENT; DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text with glow in the default font", -1, 0, &rcClient, &DttOpts); // Now some color(theme) and glow DttOpts.dwFlags |= DTT_TEXTCOLOR; DttOpts.crText = RGB(255, 255, 255); rcClient.top += RECT_INCREMENT; // CPANEL_TASKLINK is declared in VSStyle.h DrawThemeTextEx(hTheme, hdcPaint, CPANEL_TASKLINK, 0, L"This is some text with glow in a themed font", -1, 0, &rcClient, &DttOpts); DttOpts.dwFlags &= ~DTT_TEXTCOLOR; // Find a particular font and draw using this if (SUCCEEDED(GetThemeSysFont(hTheme, TMT_CAPTIONFONT, &lgFont))) { HFONT hFont = CreateFontIndirect(&lgFont); hFontOld = (HFONT) SelectObject(hdcPaint, hFont); } rcClient.top += RECT_INCREMENT; DrawText(hdcPaint, L"This is some GDI text in the selected font", -1, &rcClient, 0); rcClient.top += RECT_INCREMENT; DrawThemeTextEx(hTheme, hdcPaint, 0, 0, L"This is some text with glow in the selected font", -1, 0, &rcClient, &DttOpts); if (hFontOld) { SelectObject(hdcPaint, hFontOld); } EndBufferedPaint(hBufferedPaint, TRUE); } CloseThemeData(hTheme); } EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); BufferedPaintUnInit(); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
LRESULT DeskBandWindow::OnPaint(const HDC hdcIn) { if (mHwnd == NULL) return 0; HDC hdc = hdcIn; PAINTSTRUCT ps; if (!hdc) { hdc = BeginPaint(mHwnd, &ps); } if (hdc) { RECT rc; GetClientRect(mHwnd, &rc); if (m_fCompositionEnabled) { HTHEME hTheme; if (ThemeReady) { ZeroMemory(CurrentTheme, sizeof(CurrentTheme)); wcscat(CurrentTheme, Theme); wcscat(CurrentTheme, Toolbar); hTheme = OpenThemeData(mHwnd, CurrentTheme); } else { hTheme = OpenThemeData(mHwnd, L"TOOLBAR"); } if (hTheme) { HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rc, BPBF_TOPDOWNDIB, NULL, &hdcPaint); DrawThemeParentBackground(mHwnd, hdcPaint, &rc); switch (Mouse) { case Entered: DrawThemeBackground(hTheme, hdcPaint, TP_BUTTON, TS_HOT, &rc, NULL); break; case ClickDown: DrawThemeBackground(hTheme, hdcPaint, TP_BUTTON, TS_PRESSED, &rc, NULL); break; case Left: case ClickUp: break; } HICON m_iconSafe = LoadIcon(g_hDllInst, MAKEINTRESOURCE(IDI_ICON1)); DrawIconEx(hdcPaint, rc.left+(rc.right-rc.left-30)/2, rc.top+(rc.bottom-rc.top-24)/2, m_iconSafe, 30, 24, 0, NULL, DI_DEFAULTSIZE | DI_NORMAL); EndBufferedPaint(hBufferedPaint, TRUE); CloseThemeData(hTheme); } } } if (!hdcIn) { EndPaint(mHwnd, &ps); } return 0; };
// ---------------------------------------------------------------------- // Windows proc for the one and only window in this app. // // ---------------------------------------------------------------------- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HBRUSH hbrLit = NULL; static HBRUSH hbrUnlit = NULL; static HFONT hFont = NULL; static UINT_PTR nTimerId = 101; switch (message) { case WM_CREATE: { // Make BLACK the transparency color SetLayeredWindowAttributes(hWnd, RGB(0,0,0), 0, LWA_COLORKEY); // Initialize the DPI scalar. InitializeDPIScale(hWnd); // Create brushes and font that will be used in WM_PAINT hbrLit = CreateSolidBrush(RGB(0,128,255)); hbrUnlit = CreateSolidBrush(RGB(0,64,128)); hFont = CreateFont(DPIScale(64), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, 0, 0, 0, 0, 0, L"Segoe UI"); // Position at the center of the primary monitor POINT const ptZeroZero = {}; HMONITOR hMonitor = MonitorFromPoint(ptZeroZero, MONITOR_DEFAULTTOPRIMARY); MONITORINFO mi = {sizeof(mi)}; GetMonitorInfo(hMonitor, &mi); SIZE const size = { g_currentVolume.cSteps * DPIScale(10), DPIScale(60) }; POINT const pt = { mi.rcMonitor.left + (mi.rcMonitor.left + mi.rcMonitor.right - size.cx) / 2, mi.rcMonitor.top + (mi.rcMonitor.top + mi.rcMonitor.bottom - size.cy) / 2 }; SetWindowPos(hWnd, HWND_TOPMOST, pt.x, pt.y, size.cx, size.cy, SWP_SHOWWINDOW); break; } case WM_DESTROY: { DeleteObject(hbrLit); DeleteObject(hbrUnlit); DeleteObject(hFont); PostQuitMessage(0); return 0; } case WM_ERASEBKGND: { // Don't do any erasing here. It's done in WM_PAINT to avoid flicker. return 1; } case WM_VOLUMECHANGE: { // get the new volume level g_pVolumeMonitor->GetLevelInfo(&g_currentVolume); // make window visible for 2 seconds ShowWindow(hWnd, SW_SHOW); InvalidateRect(hWnd, NULL, TRUE); nTimerId = SetTimer(hWnd, 101, 2000, NULL); return 0; } case WM_ENDPOINTCHANGE: { g_pVolumeMonitor->ChangeEndpoint(); return 0; } case WM_TIMER: { // make the window go away ShowWindow(hWnd, SW_HIDE); KillTimer(hWnd, nTimerId); return 0; } case WM_PAINT: { PAINTSTRUCT ps; HPAINTBUFFER hBufferedPaint = NULL; RECT rc; GetClientRect(hWnd, &rc); HDC hdc = BeginPaint(hWnd, &ps); if (g_bDblBuffered) { // Get doublebuffered DC HDC hdcMem; hBufferedPaint = BeginBufferedPaint(hdc, &rc, BPBF_COMPOSITED, NULL, &hdcMem); if (hBufferedPaint) { hdc = hdcMem; } } // black background (transparency color) FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); // Draw LEDs for (UINT i = 0; i < (g_currentVolume.cSteps-1); i++) { RECT const rcLed = { DPIScale(i * 10), DPIScale(10), DPIScale(i * 10 + 8), rc.bottom-DPIScale(15) }; if ((i < g_currentVolume.nStep) && (!g_currentVolume.bMuted)) FillRect(hdc, &rcLed, hbrLit); else FillRect(hdc, &rcLed, hbrUnlit); } if (g_currentVolume.bMuted) { HGDIOBJ hof = SelectObject(hdc, hFont); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(255, 64, 64)); RECT rcText = rc; rcText.bottom -= DPIScale(11); DrawText(hdc, L"MUTED", -1, &rcText, DT_CENTER | DT_SINGLELINE | DT_VCENTER); SelectObject(hdc, hof); } if (hBufferedPaint) { // end painting BufferedPaintMakeOpaque(hBufferedPaint, NULL); EndBufferedPaint(hBufferedPaint, TRUE); } EndPaint(hWnd, &ps); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); }