OSDN Git Service

0b547b5f05f19b4d37f0b9fa2e79adf76249e169
[winmerge-jp/winmerge-jp.git] / Src / Common / scbarcf.cpp
1 /////////////////////////////////////////////////////////////////////////
2 //
3 // CSizingControlBarCF          Version 2.44
4 // 
5 // Created: Dec 21, 1998        Last Modified: March 31, 2002
6 //
7 // See the official site at www.datamekanix.com for documentation and
8 // the latest news.
9 //
10 /////////////////////////////////////////////////////////////////////////
11 // Copyright (C) 1998-2002 by Cristi Posea. All rights reserved.
12 //
13 // This code is free for personal and commercial use, providing this 
14 // notice remains intact in the source files and all eventual changes are
15 // clearly marked with comments.
16 //
17 // You must obtain the author's consent before you can include this code
18 // in a software library.
19 //
20 // No warrantee of any kind, express or implied, is included with this
21 // software; use at your own risk, responsibility for damages (if any) to
22 // anyone resulting from the use of this software rests entirely with the
23 // user.
24 //
25 // Send bug reports, bug fixes, enhancements, requests, flames, etc. to
26 // cristi@datamekanix.com or post them at the message board at the site.
27 /////////////////////////////////////////////////////////////////////////
28
29 #include "StdAfx.h"
30 #include "scbarcf.h"
31
32 /////////////////////////////////////////////////////////////////////////
33 // CSizingControlBarCF
34
35 IMPLEMENT_DYNAMIC(CSizingControlBarCF, baseCSizingControlBarCF);
36
37 int CALLBACK EnumFontFamProc(ENUMLOGFONT FAR *lpelf,
38                              NEWTEXTMETRIC FAR *lpntm,
39                              int FontType,
40                              LPARAM lParam)
41 {
42     UNUSED_ALWAYS(lpelf);
43     UNUSED_ALWAYS(lpntm);
44     UNUSED_ALWAYS(FontType);
45     UNUSED_ALWAYS(lParam);
46
47     return 0;
48 }
49  
50 CSizingControlBarCF::CSizingControlBarCF()
51 {
52     m_bActive = false;
53
54     CDC dc;
55     dc.CreateCompatibleDC(nullptr);
56
57     m_sFontFace = (::EnumFontFamilies(dc.m_hDC,
58         _T("Tahoma"), (FONTENUMPROC) EnumFontFamProc, 0) == 0) ?
59         _T("Tahoma") : _T("Arial");
60 }
61
62 BEGIN_MESSAGE_MAP(CSizingControlBarCF, baseCSizingControlBarCF)
63     //{{AFX_MSG_MAP(CSizingControlBarCF)
64     //}}AFX_MSG_MAP
65     ON_MESSAGE(WM_SETTEXT, OnSetText)
66 END_MESSAGE_MAP()
67
68 void CSizingControlBarCF::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
69 {
70     baseCSizingControlBarCF::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
71
72     if (!HasGripper())
73         return;
74
75     bool bNeedPaint = false;
76
77     CWnd* pFocus = GetFocus();
78     bool bActiveOld = m_bActive;
79
80     m_bActive = (pFocus && pFocus->GetSafeHwnd() && IsChild(pFocus));
81
82     if (m_bActive != bActiveOld)
83         bNeedPaint = true;
84
85     if (bNeedPaint)
86         SendMessage(WM_NCPAINT);
87 }
88
89 void CSizingControlBarCF::NcPaintGripper(CDC* pDC, const CRect& rcClient)
90 {
91     if (!HasGripper())
92         return;
93
94     // compute the caption rectangle
95     bool bHorz = IsHorzDocked();
96     CRect rcGrip = rcClient;
97     const int lpx = pDC->GetDeviceCaps(LOGPIXELSX);
98     auto pointToPixel = [lpx](double point) { return static_cast<int>(point * lpx / 72); };
99     CRect rcBtn(m_biHide.ptOrg, CSize(pointToPixel(m_biHide.dblBoxSize), pointToPixel(m_biHide.dblBoxSize)));
100     if (bHorz)
101     {   // right side gripper
102         rcGrip.left -= pointToPixel(m_dblGripper + 0.75);
103         rcGrip.right = rcGrip.left + pointToPixel(8.25);
104                 rcGrip.top = rcBtn.bottom + pointToPixel(2.25);
105     }
106     else
107     {   // gripper at top
108         rcGrip.top -= pointToPixel(m_dblGripper + 0.75);
109         rcGrip.bottom = rcGrip.top + pointToPixel(8.25);
110         rcGrip.right = rcBtn.left - pointToPixel(2.25);
111     }
112     rcGrip.InflateRect(bHorz ? pointToPixel(0.75) : 0, bHorz ? 0 : pointToPixel(0.75));
113
114     // draw the caption background
115     //CBrush br;
116     COLORREF clrCptn = m_bActive ?
117         ::GetSysColor(COLOR_ACTIVECAPTION) :
118         ::GetSysColor(COLOR_INACTIVECAPTION);
119
120     // query gradient info (usually TRUE for Win98/Win2k)
121     BOOL bGradient = FALSE;
122     ::SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0);
123     
124     if (!bGradient)
125         pDC->FillSolidRect(&rcGrip, clrCptn); // solid color
126     else
127     {
128         // gradient from left to right or from bottom to top
129         // get second gradient color (the right end)
130         COLORREF clrCptnRight = m_bActive ?
131             ::GetSysColor(COLOR_GRADIENTACTIVECAPTION) :
132             ::GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
133
134         // this will make 2^6 = 64 fountain steps
135         int nShift = 6;
136         int nSteps = 1 << nShift;
137
138         for (int i = 0; i < nSteps; i++)
139         {
140             // do a little alpha blending
141             int nR = (GetRValue(clrCptn) * (nSteps - i) +
142                       GetRValue(clrCptnRight) * i) >> nShift;
143             int nG = (GetGValue(clrCptn) * (nSteps - i) +
144                       GetGValue(clrCptnRight) * i) >> nShift;
145             int nB = (GetBValue(clrCptn) * (nSteps - i) +
146                       GetBValue(clrCptnRight) * i) >> nShift;
147
148             COLORREF cr = RGB(nR, nG, nB);
149
150             // then paint with the resulting color
151             CRect r2 = rcGrip;
152             if (bHorz)
153             {
154                 r2.bottom = rcGrip.bottom - 
155                     ((i * rcGrip.Height()) >> nShift);
156                 r2.top = rcGrip.bottom - 
157                     (((i + 1) * rcGrip.Height()) >> nShift);
158                 if (r2.Height() > 0)
159                     pDC->FillSolidRect(r2, cr);
160             }
161             else
162             {
163                 r2.left = rcGrip.left + 
164                     ((i * rcGrip.Width()) >> nShift);
165                 r2.right = rcGrip.left + 
166                     (((i + 1) * rcGrip.Width()) >> nShift);
167                 if (r2.Width() > 0)
168                     pDC->FillSolidRect(r2, cr);
169             }
170         }
171     }
172
173     // draw the caption text - first select a font
174     CFont font;
175     LOGFONT lf;
176     bool bFont = !!font.CreatePointFont(85/*8.5 points*/, m_sFontFace);
177     if (bFont)
178     {
179         // get the text color
180         COLORREF clrCptnText = m_bActive ?
181             ::GetSysColor(COLOR_CAPTIONTEXT) :
182             ::GetSysColor(COLOR_INACTIVECAPTIONTEXT);
183
184         int nOldBkMode = pDC->SetBkMode(TRANSPARENT);
185         COLORREF clrOldText = pDC->SetTextColor(clrCptnText);
186
187         if (bHorz)
188         {
189             // rotate text 90 degrees CCW if horizontally docked
190             font.GetLogFont(&lf);
191             font.DeleteObject();
192             lf.lfEscapement = 900;
193             font.CreateFontIndirect(&lf);
194         }
195         
196         CFont* pOldFont = pDC->SelectObject(&font);
197         CString sTitle;
198         GetWindowText(sTitle);
199
200         CPoint ptOrg = bHorz ?
201             CPoint(rcGrip.left - pointToPixel(0.75), rcGrip.bottom - pointToPixel(2.25)) :
202             CPoint(rcGrip.left + pointToPixel(2.25), rcGrip.top - pointToPixel(0.75));
203
204         pDC->ExtTextOut(ptOrg.x, ptOrg.y,
205             ETO_CLIPPED, rcGrip, sTitle, nullptr);
206
207         pDC->SelectObject(pOldFont);
208         pDC->SetBkMode(nOldBkMode);
209         pDC->SetTextColor(clrOldText);
210     }
211
212     // draw the button
213     m_biHide.Paint(pDC);
214 }
215
216 LRESULT CSizingControlBarCF::OnSetText(WPARAM wParam, LPARAM lParam)
217 {
218     LRESULT lResult = baseCSizingControlBarCF::OnSetText(wParam, lParam);
219
220     SendMessage(WM_NCPAINT);
221
222     return lResult;
223 }