Added advanced taskbar grouping and highlighting in Win7
[TortoiseGit.git] / src / Utils / MiscUI / StandAloneDlg.h
blob3275be82de4b755243d2ac9a8006be15eff9a702
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2013 - 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
21 #include "ResizableDialog.h"
22 #include "TaskbarUUID.h"
24 #pragma comment(lib, "htmlhelp.lib")
26 /**
27 * \ingroup TortoiseProc
29 * A template which can be used as the base-class of dialogs which form the main dialog
30 * of a 'dialog-style application'
31 * Just provides the boiler-plate code for dealing with application icons
33 * \remark Replace all references to CDialog or CResizableDialog in your dialog class with
34 * either CResizableStandAloneDialog, CStandAloneDialog or CStateStandAloneDialog, as appropriate
36 template <typename BaseType> class CStandAloneDialogTmpl : public BaseType
38 protected:
39 CStandAloneDialogTmpl(UINT nIDTemplate, CWnd* pParentWnd = NULL) : BaseType(nIDTemplate, pParentWnd)
41 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
43 virtual BOOL OnInitDialog()
45 BaseType::OnInitDialog();
47 // Set the icon for this dialog. The framework does this automatically
48 // when the application's main window is not a dialog
49 SetIcon(m_hIcon, TRUE); // Set big icon
50 SetIcon(m_hIcon, FALSE); // Set small icon
52 return FALSE;
55 virtual BOOL PreTranslateMessage(MSG* pMsg)
57 if (pMsg->message == WM_KEYDOWN)
59 int nVirtKey = (int) pMsg->wParam;
61 if (nVirtKey == 'A' && (GetKeyState(VK_CONTROL) & 0x8000 ) )
63 TCHAR buffer[129];
64 ::GetClassName(pMsg->hwnd, buffer,128);
66 if(_tcsnicmp(buffer,_T("EDIT"),128) == 0)
68 ::PostMessage(pMsg->hwnd,EM_SETSEL,0,-1);
69 return TRUE;
73 return BaseType::PreTranslateMessage(pMsg);
75 afx_msg void OnPaint()
77 if (IsIconic())
79 CPaintDC dc(this); // device context for painting
81 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
83 // Center icon in client rectangle
84 int cxIcon = GetSystemMetrics(SM_CXICON);
85 int cyIcon = GetSystemMetrics(SM_CYICON);
86 CRect rect;
87 GetClientRect(&rect);
88 int x = (rect.Width() - cxIcon + 1) / 2;
89 int y = (rect.Height() - cyIcon + 1) / 2;
91 // Draw the icon
92 dc.DrawIcon(x, y, m_hIcon);
94 else
96 BaseType::OnPaint();
99 /**
100 * Wrapper around the CWnd::EnableWindow() method, but
101 * makes sure that a control that has the focus is not disabled
102 * before the focus is passed on to the next control.
104 BOOL DialogEnableWindow(UINT nID, BOOL bEnable)
106 CWnd * pwndDlgItem = GetDlgItem(nID);
107 if (pwndDlgItem == NULL)
108 return FALSE;
109 if (bEnable)
110 return pwndDlgItem->EnableWindow(bEnable);
111 if (GetFocus() == pwndDlgItem)
113 SendMessage(WM_NEXTDLGCTL, 0, FALSE);
115 return pwndDlgItem->EnableWindow(bEnable);
119 * Adjusts the size of a checkbox or radio button control.
120 * Since we always make the size of those bigger than 'necessary'
121 * for making sure that translated strings can fit in those too,
122 * this method can reduce the size of those controls again to only
123 * fit the text.
125 RECT AdjustControlSize(UINT nID)
127 CWnd * pwndDlgItem = GetDlgItem(nID);
128 // adjust the size of the control to fit its content
129 CString sControlText;
130 pwndDlgItem->GetWindowText(sControlText);
131 // next step: find the rectangle the control text needs to
132 // be displayed
134 CDC * pDC = pwndDlgItem->GetWindowDC();
135 RECT controlrect;
136 RECT controlrectorig;
137 pwndDlgItem->GetWindowRect(&controlrect);
138 ::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT)&controlrect, 2);
139 controlrectorig = controlrect;
140 if (pDC)
142 CFont * font = pwndDlgItem->GetFont();
143 CFont * pOldFont = pDC->SelectObject(font);
144 if (pDC->DrawText(sControlText, -1, &controlrect, DT_WORDBREAK | DT_EDITCONTROL | DT_EXPANDTABS | DT_LEFT | DT_CALCRECT))
146 // now we have the rectangle the control really needs
147 if ((controlrectorig.right - controlrectorig.left) > (controlrect.right - controlrect.left))
149 // we're dealing with radio buttons and check boxes,
150 // which means we have to add a little space for the checkbox
151 // the value of 3 pixels added here is necessary in case certain visual styles have
152 // been disabled. Without this, the width is calculated too short.
153 const int checkWidth = GetSystemMetrics(SM_CXMENUCHECK) + 2*GetSystemMetrics(SM_CXEDGE) + 3;
154 controlrectorig.right = controlrectorig.left + (controlrect.right - controlrect.left) + checkWidth;
155 pwndDlgItem->MoveWindow(&controlrectorig);
158 pDC->SelectObject(pOldFont);
159 ReleaseDC(pDC);
161 return controlrectorig;
165 * Adjusts the size of a static control.
166 * \param nID control ID
167 * \param rc the position of the control where this control shall
168 * be positioned next to on its right side.
169 * \param spacing number of pixels to add to rc.right
171 RECT AdjustStaticSize(UINT nID, RECT rc, long spacing)
173 CWnd * pwndDlgItem = GetDlgItem(nID);
174 // adjust the size of the control to fit its content
175 CString sControlText;
176 pwndDlgItem->GetWindowText(sControlText);
177 // next step: find the rectangle the control text needs to
178 // be displayed
180 CDC * pDC = pwndDlgItem->GetWindowDC();
181 RECT controlrect;
182 RECT controlrectorig;
183 pwndDlgItem->GetWindowRect(&controlrect);
184 ::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT)&controlrect, 2);
185 controlrect.right += 200; // in case the control needs to be bigger than it currently is (e.g., due to translations)
186 controlrectorig = controlrect;
188 long height = controlrectorig.bottom-controlrectorig.top;
189 long width = controlrectorig.right-controlrectorig.left;
190 controlrectorig.left = rc.right + spacing;
191 controlrectorig.right = controlrectorig.left + width;
192 controlrectorig.bottom = rc.bottom;
193 controlrectorig.top = controlrectorig.bottom - height;
195 if (pDC)
197 CFont * font = pwndDlgItem->GetFont();
198 CFont * pOldFont = pDC->SelectObject(font);
199 if (pDC->DrawText(sControlText, -1, &controlrect, DT_WORDBREAK | DT_EDITCONTROL | DT_EXPANDTABS | DT_LEFT | DT_CALCRECT))
201 // now we have the rectangle the control really needs
202 controlrectorig.right = controlrectorig.left + (controlrect.right - controlrect.left);
203 pwndDlgItem->MoveWindow(&controlrectorig);
205 pDC->SelectObject(pOldFont);
206 ReleaseDC(pDC);
208 return controlrectorig;
212 * Display a balloon with close button, anchored at a given edit control on this dialog.
214 void ShowEditBalloon(UINT nIdControl, UINT nIdText, UINT nIdTitle, int nIcon = TTI_WARNING)
216 CString text(MAKEINTRESOURCE(nIdText));
217 CString title(MAKEINTRESOURCE(nIdTitle));
218 ShowEditBalloon(nIdControl, text, title, nIcon);
220 void ShowEditBalloon(UINT nIdControl, const CString& text, const CString& title, int nIcon = TTI_WARNING)
222 EDITBALLOONTIP bt;
223 bt.cbStruct = sizeof(bt);
224 bt.pszText = text;
225 bt.pszTitle = title;
226 bt.ttiIcon = nIcon;
227 SendDlgItemMessage(nIdControl, EM_SHOWBALLOONTIP, 0, (LPARAM)&bt);
231 * Refreshes the cursor by forcing a WM_SETCURSOR message.
233 void RefreshCursor()
235 POINT pt;
236 GetCursorPos(&pt);
237 SetCursorPos(pt.x, pt.y);
240 protected:
241 DECLARE_MESSAGE_MAP()
243 private:
244 HCURSOR OnQueryDragIcon()
246 return static_cast<HCURSOR>(m_hIcon);
249 virtual void HtmlHelp(DWORD_PTR dwData, UINT nCmd = 0x000F)
251 CWinApp* pApp = AfxGetApp();
252 ASSERT_VALID(pApp);
253 ASSERT(pApp->m_pszHelpFilePath != NULL);
254 // to call HtmlHelp the m_fUseHtmlHelp must be set in
255 // the application's constructor
256 ASSERT(pApp->m_eHelpType == afxHTMLHelp);
258 CWaitCursor wait;
260 PrepareForHelp();
261 // run the HTML Help engine
262 if (!::HtmlHelp(m_hWnd, pApp->m_pszHelpFilePath, nCmd, dwData))
264 AfxMessageBox(AFX_IDP_FAILED_TO_LAUNCH_HELP);
268 afx_msg LRESULT OnTaskbarButtonCreated(WPARAM /*wParam*/, LPARAM /*lParam*/)
270 SetUUIDOverlayIcon(m_hWnd);
271 return 0;
274 HICON m_hIcon;
277 class CStateDialog : public CDialog, public CResizableWndState
279 public:
280 CStateDialog()
281 : m_bEnableSaveRestore(false)
282 , m_bRectOnly(false)
284 CStateDialog(UINT /*nIDTemplate*/, CWnd* /*pParentWnd = NULL*/)
285 : m_bEnableSaveRestore(false)
286 , m_bRectOnly(false)
288 CStateDialog(LPCTSTR /*lpszTemplateName*/, CWnd* /*pParentWnd = NULL*/)
289 : m_bEnableSaveRestore(false)
290 , m_bRectOnly(false)
292 virtual ~CStateDialog() {};
294 private:
295 // flags
296 bool m_bEnableSaveRestore;
297 bool m_bRectOnly;
299 // internal status
300 CString m_sSection; // section name (identifies a parent window)
302 protected:
303 // section to use in app's profile
304 void EnableSaveRestore(LPCTSTR pszSection, bool bRectOnly = FALSE)
306 m_sSection = pszSection;
308 m_bEnableSaveRestore = true;
309 m_bRectOnly = bRectOnly;
311 // restore immediately
312 LoadWindowRect(pszSection, bRectOnly);
315 virtual CWnd* GetResizableWnd() const
317 // make the layout know its parent window
318 return CWnd::FromHandle(m_hWnd);
321 afx_msg void OnDestroy()
323 if (m_bEnableSaveRestore)
324 SaveWindowRect(m_sSection, m_bRectOnly);
325 CDialog::OnDestroy();
328 DECLARE_MESSAGE_MAP()
332 class CResizableStandAloneDialog : public CStandAloneDialogTmpl<CResizableDialog>
334 public:
335 CResizableStandAloneDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
337 private:
338 DECLARE_DYNAMIC(CResizableStandAloneDialog)
340 protected:
341 afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
342 afx_msg void OnMoving(UINT fwSide, LPRECT pRect);
343 afx_msg void OnNcMButtonUp(UINT nHitTest, CPoint point);
344 afx_msg void OnNcRButtonUp(UINT nHitTest, CPoint point);
346 DECLARE_MESSAGE_MAP()
348 private:
349 bool m_bVertical;
350 bool m_bHorizontal;
351 CRect m_rcOrgWindowRect;
354 class CStandAloneDialog : public CStandAloneDialogTmpl<CDialog>
356 public:
357 CStandAloneDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
358 protected:
359 DECLARE_MESSAGE_MAP()
360 private:
361 DECLARE_DYNAMIC(CStandAloneDialog)
364 class CStateStandAloneDialog : public CStandAloneDialogTmpl<CStateDialog>
366 public:
367 CStateStandAloneDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
368 protected:
369 DECLARE_MESSAGE_MAP()
370 private:
371 DECLARE_DYNAMIC(CStateStandAloneDialog)