OSDN Git Service

Show Ignore Sub Menu
[tortoisegit/TortoiseGitJp.git] / src / Utils / TreePropSheet / PropPageFrameDefault.cpp
1 /********************************************************************\r
2 *\r
3 * Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>\r
4 *\r
5 * You can use this and modify this in any way you want,\r
6 * BUT LEAVE THIS HEADER INTACT.\r
7 *\r
8 * Redistribution is appreciated.\r
9 *\r
10 * $Workfile:$\r
11 * $Revision:$\r
12 * $Modtime:$\r
13 * $Author:$\r
14 *\r
15 * Revision History:\r
16 *       $History:$\r
17 *\r
18 *********************************************************************/\r
19 \r
20 #include "stdafx.h"\r
21 #include "PropPageFrameDefault.h"\r
22 #include "ExtTextOutFL.h"\r
23 \r
24 namespace TreePropSheet\r
25 {\r
26 \r
27 \r
28 //uncomment the following line, if you don't have installed the\r
29 //new platform SDK\r
30 #define XPSUPPORT\r
31 \r
32 #ifdef XPSUPPORT\r
33 #include <uxtheme.h>\r
34 #include <tmschema.h>\r
35 #endif\r
36 \r
37 #ifdef _DEBUG\r
38 #define new DEBUG_NEW\r
39 #undef THIS_FILE\r
40 static char THIS_FILE[] = __FILE__;\r
41 #endif\r
42 \r
43 //-------------------------------------------------------------------\r
44 // class CThemeLib\r
45 //-------------------------------------------------------------------\r
46 \r
47 #define THEMEAPITYPE(f)                                 typedef HRESULT (__stdcall *_##f)\r
48 #define THEMEAPITYPE_(t, f)                     typedef t (__stdcall *_##f)\r
49 #define THEMEAPIPTR(f)                                  _##f m_p##f\r
50 \r
51 #ifdef XPSUPPORT\r
52         #define THEMECALL(f)                                            return (*m_p##f)\r
53         #define GETTHEMECALL(f)                                 m_p##f = (_##f)GetProcAddress(m_hThemeLib, #f)\r
54 #else\r
55         void ThemeDummy(...) {ASSERT(FALSE);}\r
56         #define HTHEME                                                                  void*\r
57         #define TABP_PANE                                                               0\r
58         #define THEMECALL(f)                                            return 0; ThemeDummy\r
59         #define GETTHEMECALL(f)                                 m_p##f = NULL\r
60 #endif\r
61 \r
62 \r
63 /**\r
64 Helper class for loading the uxtheme DLL and providing their \r
65 functions.\r
66 \r
67 One global object of this class exists.\r
68 \r
69 @author Sven Wiegand\r
70 */\r
71 class CThemeLib\r
72 {\r
73 // construction/destruction\r
74 public:\r
75         CThemeLib();\r
76         ~CThemeLib();\r
77 \r
78 // operations\r
79 public:\r
80         /**\r
81         Returns TRUE if the call wrappers are available, FALSE otherwise.\r
82         */\r
83         BOOL IsAvailable() const;\r
84 \r
85 // call wrappers\r
86 public:\r
87         BOOL IsThemeActive() \r
88         {THEMECALL(IsThemeActive)();}\r
89 \r
90         HTHEME OpenThemeData(HWND hwnd, LPCWSTR pszClassList) \r
91         {THEMECALL(OpenThemeData)(hwnd, pszClassList);}\r
92 \r
93         HRESULT CloseThemeData(HTHEME hTheme) \r
94         {THEMECALL(CloseThemeData)(hTheme);}\r
95 \r
96         HRESULT GetThemeBackgroundContentRect(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect, OUT RECT *pContentRect)\r
97         {THEMECALL(GetThemeBackgroundContentRect)(hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect);}\r
98 \r
99         HRESULT DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)\r
100         {THEMECALL(DrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);}\r
101 \r
102 // function pointers\r
103 private:\r
104 #ifdef XPSUPPORT\r
105         THEMEAPITYPE_(BOOL, IsThemeActive)();\r
106         THEMEAPIPTR(IsThemeActive);\r
107 \r
108         THEMEAPITYPE_(HTHEME, OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);\r
109         THEMEAPIPTR(OpenThemeData);\r
110 \r
111         THEMEAPITYPE(CloseThemeData)(HTHEME hTheme);\r
112         THEMEAPIPTR(CloseThemeData);\r
113 \r
114         THEMEAPITYPE(GetThemeBackgroundContentRect)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect, OUT RECT *pContentRect);\r
115         THEMEAPIPTR(GetThemeBackgroundContentRect);\r
116 \r
117         THEMEAPITYPE(DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);\r
118         THEMEAPIPTR(DrawThemeBackground);\r
119 #endif\r
120 \r
121 // properties\r
122 private:\r
123         /** instance handle to the library or NULL. */\r
124         HINSTANCE m_hThemeLib;\r
125 };\r
126 \r
127 /**\r
128 One and only instance of CThemeLib.\r
129 */\r
130 static CThemeLib g_ThemeLib;\r
131 \r
132 \r
133 CThemeLib::CThemeLib()\r
134 :       m_hThemeLib(NULL)\r
135 {\r
136 #ifdef XPSUPPORT\r
137         m_hThemeLib = LoadLibrary(_T("uxtheme.dll"));\r
138         if (!m_hThemeLib)\r
139                 return;\r
140 \r
141         GETTHEMECALL(IsThemeActive);\r
142         GETTHEMECALL(OpenThemeData);\r
143         GETTHEMECALL(CloseThemeData);\r
144         GETTHEMECALL(GetThemeBackgroundContentRect);\r
145         GETTHEMECALL(DrawThemeBackground);\r
146 #endif\r
147 }\r
148 \r
149 \r
150 CThemeLib::~CThemeLib()\r
151 {\r
152         if (m_hThemeLib)\r
153                 FreeLibrary(m_hThemeLib);\r
154 }\r
155 \r
156 \r
157 BOOL CThemeLib::IsAvailable() const\r
158 {\r
159         return m_hThemeLib!=NULL;\r
160 }\r
161 \r
162 \r
163 //-------------------------------------------------------------------\r
164 // class CPropPageFrameDefault\r
165 //-------------------------------------------------------------------\r
166 \r
167 BEGIN_MESSAGE_MAP(CPropPageFrameDefault, CWnd)\r
168         //{{AFX_MSG_MAP(CPropPageFrameDefault)\r
169         ON_WM_PAINT()\r
170         ON_WM_ERASEBKGND()\r
171         //}}AFX_MSG_MAP\r
172 END_MESSAGE_MAP()\r
173 \r
174 \r
175 CPropPageFrameDefault::CPropPageFrameDefault()\r
176 {\r
177 }\r
178 \r
179 \r
180 CPropPageFrameDefault::~CPropPageFrameDefault()\r
181 {\r
182         if (m_Images.GetSafeHandle())\r
183                 m_Images.DeleteImageList();\r
184 }\r
185 \r
186 \r
187 /////////////////////////////////////////////////////////////////////\r
188 // Overridings\r
189 \r
190 BOOL CPropPageFrameDefault::Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID)\r
191 {\r
192         return CWnd::Create(\r
193                 AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), GetSysColorBrush(COLOR_3DFACE)),\r
194                 _T("Page Frame"),\r
195                 dwWindowStyle, rect, pwndParent, nID);\r
196 }\r
197 \r
198 \r
199 CWnd* CPropPageFrameDefault::GetWnd()\r
200 {\r
201         return static_cast<CWnd*>(this);\r
202 }\r
203 \r
204 \r
205 void CPropPageFrameDefault::SetCaption(LPCTSTR lpszCaption, HICON hIcon /*= NULL*/)\r
206 {\r
207         CPropPageFrame::SetCaption(lpszCaption, hIcon);\r
208 \r
209         // build image list\r
210         if (m_Images.GetSafeHandle())\r
211                 m_Images.DeleteImageList();\r
212         if (hIcon)\r
213         {\r
214                 ICONINFO        ii;\r
215                 if (!GetIconInfo(hIcon, &ii))\r
216                         return;\r
217 \r
218                 CBitmap bmMask;\r
219                 bmMask.Attach(ii.hbmMask);\r
220                 if (ii.hbmColor) DeleteObject(ii.hbmColor);\r
221 \r
222                 BITMAP  bm;\r
223                 bmMask.GetBitmap(&bm);\r
224 \r
225                 if (!m_Images.Create(bm.bmWidth, bm.bmHeight, ILC_COLOR32|ILC_MASK, 0, 1))\r
226                         return;\r
227 \r
228                 if (m_Images.Add(hIcon) == -1)\r
229                         m_Images.DeleteImageList();\r
230         }\r
231 }\r
232 \r
233 \r
234 CRect CPropPageFrameDefault::CalcMsgArea()\r
235 {\r
236         CRect   rect;\r
237         GetClientRect(rect);\r
238         if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())\r
239         {\r
240                 HTHEME  hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");\r
241                 if (hTheme)\r
242                 {\r
243                         CRect   rectContent;\r
244                         CDC             *pDc = GetDC();\r
245                         g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);\r
246                         ReleaseDC(pDc);\r
247                         g_ThemeLib.CloseThemeData(hTheme);\r
248                         \r
249                         if (GetShowCaption())\r
250                                 rectContent.top = rect.top+GetCaptionHeight()+1;\r
251                         rect = rectContent;\r
252                 }\r
253         }\r
254         else if (GetShowCaption())\r
255                 rect.top+= GetCaptionHeight()+1;\r
256         \r
257         return rect;\r
258 }\r
259 \r
260 \r
261 CRect CPropPageFrameDefault::CalcCaptionArea()\r
262 {\r
263         CRect   rect;\r
264         GetClientRect(rect);\r
265         if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())\r
266         {\r
267                 HTHEME  hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");\r
268                 if (hTheme)\r
269                 {\r
270                         CRect   rectContent;\r
271                         CDC             *pDc = GetDC();\r
272                         g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);\r
273                         ReleaseDC(pDc);\r
274                         g_ThemeLib.CloseThemeData(hTheme);\r
275                         \r
276                         if (GetShowCaption())\r
277                                 rectContent.bottom = rect.top+GetCaptionHeight();\r
278                         else\r
279                                 rectContent.bottom = rectContent.top;\r
280 \r
281                         rect = rectContent;\r
282                 }\r
283         }\r
284         else\r
285         {\r
286                 if (GetShowCaption())\r
287                         rect.bottom = rect.top+GetCaptionHeight();\r
288                 else\r
289                         rect.bottom = rect.top;\r
290         }\r
291 \r
292         return rect;\r
293 }\r
294 \r
295 void CPropPageFrameDefault::DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon)\r
296 {\r
297         COLORREF        clrLeft = GetSysColor(COLOR_INACTIVECAPTION);\r
298         COLORREF        clrRight = pDc->GetPixel(rect.right-1, rect.top);\r
299         FillGradientRectH(pDc, rect, clrLeft, clrRight);\r
300 \r
301         // draw icon\r
302         if (hIcon && m_Images.GetSafeHandle() && m_Images.GetImageCount() == 1)\r
303         {\r
304                 IMAGEINFO       ii;\r
305                 m_Images.GetImageInfo(0, &ii);\r
306                 CPoint          pt(3, rect.CenterPoint().y - (ii.rcImage.bottom-ii.rcImage.top)/2);\r
307                 m_Images.Draw(pDc, 0, pt, ILD_TRANSPARENT);\r
308                 rect.left+= (ii.rcImage.right-ii.rcImage.left) + 3;\r
309         }\r
310 \r
311         // draw text\r
312         rect.left+= 2;\r
313 \r
314         COLORREF        clrPrev = pDc->SetTextColor(GetSysColor(COLOR_CAPTIONTEXT));\r
315         int                             nBkStyle = pDc->SetBkMode(TRANSPARENT);\r
316         CFont                   *pFont = (CFont*)pDc->SelectStockObject(SYSTEM_FONT);\r
317 \r
318         //pDc->DrawText(lpszCaption, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);\r
319 \r
320         TextOutTryFL(pDc->GetSafeHdc(), rect.left, rect.top, lpszCaption, _tcslen(lpszCaption));\r
321 \r
322         pDc->SetTextColor(clrPrev);\r
323         pDc->SetBkMode(nBkStyle);\r
324         pDc->SelectObject(pFont);\r
325 }\r
326 \r
327 \r
328 /////////////////////////////////////////////////////////////////////\r
329 // Implementation helpers\r
330 \r
331 void CPropPageFrameDefault::FillGradientRectH(CDC *pDc, const RECT &rect, COLORREF clrLeft, COLORREF clrRight)\r
332 {\r
333         // pre calculation\r
334         int     nSteps = rect.right-rect.left;\r
335         int     nRRange = GetRValue(clrRight)-GetRValue(clrLeft);\r
336         int     nGRange = GetGValue(clrRight)-GetGValue(clrLeft);\r
337         int     nBRange = GetBValue(clrRight)-GetBValue(clrLeft);\r
338 \r
339         double  dRStep = (double)nRRange/(double)nSteps;\r
340         double  dGStep = (double)nGRange/(double)nSteps;\r
341         double  dBStep = (double)nBRange/(double)nSteps;\r
342 \r
343         double  dR = (double)GetRValue(clrLeft);\r
344         double  dG = (double)GetGValue(clrLeft);\r
345         double  dB = (double)GetBValue(clrLeft);\r
346 \r
347         CPen    *pPrevPen = NULL;\r
348         for (int x = rect.left; x <= rect.right; ++x)\r
349         {\r
350                 CPen    Pen(PS_SOLID, 1, RGB((BYTE)dR, (BYTE)dG, (BYTE)dB));\r
351                 pPrevPen = pDc->SelectObject(&Pen);\r
352                 pDc->MoveTo(x, rect.top);\r
353                 pDc->LineTo(x, rect.bottom);\r
354                 pDc->SelectObject(pPrevPen);\r
355                 \r
356                 dR+= dRStep;\r
357                 dG+= dGStep;\r
358                 dB+= dBStep;\r
359         }\r
360 }\r
361 \r
362 \r
363 /////////////////////////////////////////////////////////////////////\r
364 // message handlers\r
365 \r
366 void CPropPageFrameDefault::OnPaint() \r
367 {\r
368         CPaintDC dc(this);\r
369         Draw(&dc);      \r
370 }\r
371 \r
372 \r
373 BOOL CPropPageFrameDefault::OnEraseBkgnd(CDC* pDC) \r
374 {\r
375         if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())\r
376         {\r
377                 HTHEME  hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"TREEVIEW");\r
378                 if (hTheme)\r
379                 {\r
380                         CRect   rect;\r
381                         GetClientRect(rect);\r
382                         g_ThemeLib.DrawThemeBackground(hTheme, pDC->m_hDC, 0, 0, rect, NULL);\r
383 \r
384                         g_ThemeLib.CloseThemeData(hTheme);\r
385                 }\r
386                 return TRUE;\r
387         }\r
388         else\r
389         {\r
390                 return CWnd::OnEraseBkgnd(pDC);\r
391         }\r
392 }\r
393 \r
394 \r
395 \r
396 } //namespace TreePropSheet\r