High DPI optimizations
[TortoiseGit.git] / src / Utils / MiscUI / HintCtrl.h
blob585dd1c55e27958376545349eb3efdad6aaabca9
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2011, 2013, 2015, 2018 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #pragma once
20 #include "MyMemDC.h"
22 /**
23 * \ingroup Utils
24 * Allows to show a hint text on a control, basically hiding the control
25 * content. Can be used for example during lengthy operations (showing "please wait")
26 * or to indicate why the control is empty (showing "no data available").
28 template <typename BaseType> class CHintCtrl : public BaseType
30 public:
31 CHintCtrl() : BaseType(), m_uiFont(nullptr)
33 NONCLIENTMETRICS metrics = { 0 };
34 metrics.cbSize = sizeof(NONCLIENTMETRICS);
35 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrics, FALSE);
36 m_uiFont = CreateFontIndirect(&metrics.lfMessageFont);
38 virtual ~CHintCtrl()
40 if (m_uiFont)
41 DeleteObject(m_uiFont);
44 void ShowText(const CString& sText, bool forceupdate = false)
46 m_sText = sText;
47 Invalidate();
48 if (forceupdate)
49 UpdateWindow();
52 void ClearText()
54 m_sText.Empty();
55 Invalidate();
58 bool HasText() const {return !m_sText.IsEmpty();}
60 DECLARE_MESSAGE_MAP()
62 protected:
63 afx_msg void CHintCtrl::OnPaint()
65 LRESULT defres = Default();
66 if (!m_sText.IsEmpty())
68 COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);
69 COLORREF clrTextBk;
70 if (IsWindowEnabled())
71 clrTextBk = ::GetSysColor(COLOR_WINDOW);
72 else
73 clrTextBk = ::GetSysColor(COLOR_3DFACE);
75 CRect rc;
76 GetClientRect(&rc);
77 bool bIsEmpty = false;
78 CListCtrl * pListCtrl = dynamic_cast<CListCtrl*>(this);
79 if (pListCtrl)
81 CHeaderCtrl* pHC;
82 pHC = pListCtrl->GetHeaderCtrl();
83 if (pHC)
85 CRect rcH;
86 rcH.SetRectEmpty();
87 pHC->GetItemRect(0, &rcH);
88 rc.top += rcH.bottom;
90 bIsEmpty = pListCtrl->GetItemCount() == 0;
92 CDC* pDC = GetDC();
94 CMyMemDC memDC(pDC, &rc);
96 memDC.SetTextColor(clrText);
97 memDC.SetBkColor(clrTextBk);
98 if (bIsEmpty)
99 memDC.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), pDC, rc.left, rc.top, SRCCOPY);
100 else
101 memDC.FillSolidRect(rc, clrTextBk);
102 rc.top += 10;
103 CGdiObject* oldfont = memDC.SelectObject(CGdiObject::FromHandle(m_uiFont));
104 memDC.DrawText(m_sText, rc, DT_CENTER | DT_VCENTER |
105 DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
106 memDC.SelectObject(oldfont);
108 ReleaseDC(pDC);
110 if (defres)
112 // the Default() call did not process the WM_PAINT message!
113 // Validate the update region ourselves to avoid
114 // an endless loop repainting
115 CRect rc;
116 GetUpdateRect(&rc, FALSE);
117 if (!rc.IsRectEmpty())
118 ValidateRect(rc);
122 private:
123 CString m_sText;
124 HFONT m_uiFont;
127 BEGIN_TEMPLATE_MESSAGE_MAP(CHintCtrl, BaseType, BaseType)
128 ON_WM_PAINT()
129 END_MESSAGE_MAP()