From 955ff2793e7f322999eaca1c06231c96072ae3f5 Mon Sep 17 00:00:00 2001 From: sdottaka Date: Thu, 6 Mar 2025 08:47:44 +0900 Subject: [PATCH] Reduce flickering when drawing the status bar (cherry picked from commit 1964e10fe26fa5cb5f16f11a6acf9aac2b524c90) --- Src/BasicFlatStatusBar.cpp | 34 ++++++++++++++++++++++++++-------- Src/MergeStatusBar.cpp | 29 +++++++++++++++++++---------- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/Src/BasicFlatStatusBar.cpp b/Src/BasicFlatStatusBar.cpp index 45f24d3db37..c2556ea61ac 100644 --- a/Src/BasicFlatStatusBar.cpp +++ b/Src/BasicFlatStatusBar.cpp @@ -63,25 +63,38 @@ void CBasicFlatStatusBar::OnPaint() { const COLORREF clr3DFace = GetSysColor(COLOR_3DFACE); const COLORREF clr3DFaceLight = LightenColor(clr3DFace, 0.5); + CPaintDC dc(this); CRect rect; GetClientRect(&rect); + CStatusBarCtrl& ctrl = GetStatusBarCtrl(); int parts[32]; const int nParts = ctrl.GetParts(32, parts); - dc.FillSolidRect(&rect, clr3DFace); - dc.SetTextColor(GetSysColor(COLOR_BTNTEXT)); - dc.SetBkMode(TRANSPARENT); + + CDC memDC; + memDC.CreateCompatibleDC(&dc); + CBitmap bmp; + bmp.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); + CBitmap* pOldBmp = memDC.SelectObject(&bmp); + + memDC.FillSolidRect(&rect, clr3DFace); + memDC.SetTextColor(GetSysColor(COLOR_BTNTEXT)); + memDC.SetBkMode(TRANSPARENT); + CFont* pFont = GetFont(); - CFont* pOldFont = pFont ? dc.SelectObject(pFont) : nullptr; - const int radius = MulDiv (3, dc.GetDeviceCaps (LOGPIXELSY), 72); + CFont* pOldFont = pFont ? memDC.SelectObject(pFont) : nullptr; + const int radius = MulDiv(3, memDC.GetDeviceCaps(LOGPIXELSY), 72); + for (int i = 0; i < nParts; i++) { const unsigned style = GetPaneStyle(i); CRect rcPart; ctrl.GetRect(i, &rcPart); + if (m_bMouseTracking && (style & SBPS_CLICKABLE) != 0 && i == m_nTrackingPane) - DrawRoundedRect(dc.m_hDC, rcPart.left, rcPart.top, rcPart.Width(), rcPart.Height(), radius, clr3DFaceLight, clr3DFace); + DrawRoundedRect(memDC.m_hDC, rcPart.left, rcPart.top, rcPart.Width(), rcPart.Height(), radius, clr3DFaceLight, clr3DFace); + const bool disabled = (style & SBPS_DISABLED) != 0; if (!disabled) { @@ -93,11 +106,16 @@ void CBasicFlatStatusBar::OnPaint() text.Trim(); text.Replace(_T("\t"), _T(" ")); } - dc.DrawText(text, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); + memDC.DrawText(text, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } } + if (pOldFont) - dc.SelectObject(pOldFont); + memDC.SelectObject(pOldFont); + + dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); + + memDC.SelectObject(pOldBmp); } BOOL CBasicFlatStatusBar::OnEraseBkgnd(CDC* pDC) diff --git a/Src/MergeStatusBar.cpp b/Src/MergeStatusBar.cpp index e06dd023b57..5ac81c9e23c 100644 --- a/Src/MergeStatusBar.cpp +++ b/Src/MergeStatusBar.cpp @@ -146,14 +146,21 @@ void CMergeStatusBar::OnPaint() const COLORREF clr3DFaceLight = LightenColor(clr3DFace, 0.5); const COLORREF clrWordDiffLight = LightenColor(m_cachedColors.clrWordDiff, 0.5); const COLORREF clrBtnText = GetSysColor(COLOR_BTNTEXT); + CPaintDC dc(this); CRect rect; GetClientRect(&rect); - dc.FillSolidRect(&rect, clr3DFace); - dc.SetBkMode(TRANSPARENT); + CBitmap bitmap; + bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); + CDC memDC; + memDC.CreateCompatibleDC(&dc); + CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); + + memDC.FillSolidRect(&rect, GetSysColor(COLOR_3DFACE)); + memDC.SetBkMode(TRANSPARENT); CFont* pFont = GetFont(); - CFont* pOldFont = pFont ? dc.SelectObject(pFont) : nullptr; - const int radius = MulDiv (3, dc.GetDeviceCaps (LOGPIXELSY), 72); + CFont* pOldFont = pFont ? memDC.SelectObject(pFont) : nullptr; + const int radius = MulDiv (3, memDC.GetDeviceCaps (LOGPIXELSY), 72); for (int i = 0; i < nParts; i++) { const unsigned style = GetPaneStyle(i); @@ -161,27 +168,29 @@ void CMergeStatusBar::OnPaint() ctrl.GetRect(i, &rcPart); const bool lighten = (m_bMouseTracking && (style & SBPS_CLICKABLE) != 0 && i == m_nTrackingPane); if (lighten) - DrawRoundedRect(dc.m_hDC, rcPart.left, rcPart.top, rcPart.Width(), rcPart.Height(), radius, clr3DFaceLight, clr3DFace); + DrawRoundedRect(memDC.m_hDC, rcPart.left, rcPart.top, rcPart.Width(), rcPart.Height(), radius, clr3DFaceLight, clr3DFace); const bool disabled = (style & SBPS_DISABLED) != 0; if (!disabled) { if (m_bDiff[i % nColumnsPerPane]) { - dc.SetTextColor(m_cachedColors.clrWordDiffText == -1 ? + memDC.SetTextColor(m_cachedColors.clrWordDiffText == -1 ? theApp.GetMainSyntaxColors()->GetColor(COLORINDEX_NORMALTEXT) : m_cachedColors.clrWordDiffText); - DrawRoundedRect(dc.m_hDC, rcPart.left, rcPart.top, rcPart.Width(), rcPart.Height(), radius, lighten ? clrWordDiffLight : m_cachedColors.clrWordDiff, clr3DFace); + DrawRoundedRect(memDC.m_hDC, rcPart.left, rcPart.top, rcPart.Width(), rcPart.Height(), radius, lighten ? clrWordDiffLight : m_cachedColors.clrWordDiff, clr3DFace); } else { - dc.SetTextColor(clrBtnText); + memDC.SetTextColor(clrBtnText); } CRect rcText = rcPart; rcText.left += radius; - dc.DrawText(ctrl.GetText(i), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); + memDC.DrawText(ctrl.GetText(i), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } } if (pOldFont) - dc.SelectObject(pOldFont); + memDC.SelectObject(pOldFont); + dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); + memDC.SelectObject(pOldBitmap); } void CMergeStatusBar::Resize(int widths[])