// Draws the 'x' close button in regular state or onhover state // Tries to mimic visual style of Chrome tab close button static void DrawCloseButton(HDC hdc, LabelWithCloseWnd *w) { Graphics g(hdc); g.SetCompositingQuality(CompositingQualityHighQuality); g.SetSmoothingMode(SmoothingModeAntiAlias); g.SetPageUnit(UnitPixel); // GDI+ doesn't pick up the window's orientation through the device context, // so we have to explicitly mirror all rendering horizontally if (IsRtl(w->hwnd)) { g.ScaleTransform(-1, 1); g.TranslateTransform((REAL)ClientRect(w->hwnd).dx, 0, MatrixOrderAppend); } Color c; RectI &r = w->closeBtnPos; // in onhover state, background is a red-ish circle bool onHover = IsMouseOverClose(w); if (onHover) { c.SetFromCOLORREF(COL_CLOSE_HOVER_BG); SolidBrush b(c); g.FillEllipse(&b, r.x, r.y, r.dx - 2, r.dy - 2); } // draw 'x' c.SetFromCOLORREF(onHover ? COL_CLOSE_X_HOVER : COL_CLOSE_X); g.TranslateTransform((float)r.x, (float)r.y); Pen p(c, 2); if (onHover) { g.DrawLine(&p, Point(4, 4), Point(r.dx - 6, r.dy - 6)); g.DrawLine(&p, Point(r.dx - 6, 4), Point(4, r.dy - 6)); } else { g.DrawLine(&p, Point(4, 5), Point(r.dx - 6, r.dy - 5)); g.DrawLine(&p, Point(r.dx - 6, 5), Point(4, r.dy - 5)); } }
static void PaintHDC(LabelWithCloseWnd *w, HDC hdc, const PAINTSTRUCT& ps) { HBRUSH br = CreateSolidBrush(w->bgCol); FillRect(hdc, &ps.rcPaint, br); ClientRect cr(w->hwnd); int x = win::DpiAdjust(w->hwnd, w->padL); int y = win::DpiAdjust(w->hwnd, w->padT); UINT opts = ETO_OPAQUE; if (IsRtl(w->hwnd)) { opts = opts | ETO_RTLREADING; } HGDIOBJ prevFont = NULL; if (w->font) { prevFont = SelectObject(hdc, w->font); } SetTextColor(hdc, w->txtCol); SetBkColor(hdc, w->bgCol); WCHAR *s = win::GetText(w->hwnd); ExtTextOut(hdc, x, y, opts, NULL, s, (UINT)str::Len(s), NULL); free(s); // Text might be too long and invade close button area. We just re-paint // the background, which is not the pretties but works. // A better way would be to intelligently truncate text or shrink the font // size (within reason) x = w->closeBtnPos.x - win::DpiAdjust(w->hwnd, LABEL_BUTTON_SPACE_DX); RectI ri(x, 0, cr.dx - x, cr.dy); RECT r = ri.ToRECT(); FillRect(hdc, &r, br); DrawCloseButton(hdc, w->closeBtnPos, IsMouseOverClose(w)); DeleteObject(br); if (w->font) { SelectObject(hdc, prevFont); } }