1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - 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.
21 #include "ResizableDialog.h"
23 #pragma comment(lib, "htmlhelp.lib")
26 * \ingroup TortoiseProc
28 * A template which can be used as the base-class of dialogs which form the main dialog
29 * of a 'dialog-style application'
30 * Just provides the boiler-plate code for dealing with application icons
32 * \remark Replace all references to CDialog or CResizableDialog in your dialog class with
33 * either CResizableStandAloneDialog, CStandAloneDialog or CStateStandAloneDialog, as appropriate
35 template <typename BaseType
> class CStandAloneDialogTmpl
: public BaseType
38 CStandAloneDialogTmpl(UINT nIDTemplate
, CWnd
* pParentWnd
= NULL
) : BaseType(nIDTemplate
, pParentWnd
)
40 m_hIcon
= AfxGetApp()->LoadIcon(IDR_MAINFRAME
);
42 virtual BOOL
OnInitDialog()
44 BaseType::OnInitDialog();
46 // Set the icon for this dialog. The framework does this automatically
47 // when the application's main window is not a dialog
48 SetIcon(m_hIcon
, TRUE
); // Set big icon
49 SetIcon(m_hIcon
, FALSE
); // Set small icon
54 virtual BOOL
PreTranslateMessage(MSG
* pMsg
)
56 if (pMsg
->message
== WM_KEYDOWN
)
58 int nVirtKey
= (int) pMsg
->wParam
;
60 if (nVirtKey
== 'A' && (GetKeyState(VK_CONTROL
) & 0x8000 ) )
63 ::GetClassName(pMsg
->hwnd
, buffer
,128);
65 if(_tcsnicmp(buffer
,_T("EDIT"),128) == 0)
67 ::PostMessage(pMsg
->hwnd
,EM_SETSEL
,0,-1);
72 return BaseType::PreTranslateMessage(pMsg
);
74 afx_msg
void OnPaint()
78 CPaintDC
dc(this); // device context for painting
80 SendMessage(WM_ICONERASEBKGND
, reinterpret_cast<WPARAM
>(dc
.GetSafeHdc()), 0);
82 // Center icon in client rectangle
83 int cxIcon
= GetSystemMetrics(SM_CXICON
);
84 int cyIcon
= GetSystemMetrics(SM_CYICON
);
87 int x
= (rect
.Width() - cxIcon
+ 1) / 2;
88 int y
= (rect
.Height() - cyIcon
+ 1) / 2;
91 dc
.DrawIcon(x
, y
, m_hIcon
);
99 * Wrapper around the CWnd::EnableWindow() method, but
100 * makes sure that a control that has the focus is not disabled
101 * before the focus is passed on to the next control.
103 BOOL
DialogEnableWindow(UINT nID
, BOOL bEnable
)
105 CWnd
* pwndDlgItem
= GetDlgItem(nID
);
106 if (pwndDlgItem
== NULL
)
109 return pwndDlgItem
->EnableWindow(bEnable
);
110 if (GetFocus() == pwndDlgItem
)
112 SendMessage(WM_NEXTDLGCTL
, 0, FALSE
);
114 return pwndDlgItem
->EnableWindow(bEnable
);
118 * Adjusts the size of a checkbox or radio button control.
119 * Since we always make the size of those bigger than 'necessary'
120 * for making sure that translated strings can fit in those too,
121 * this method can reduce the size of those controls again to only
124 void AdjustControlSize(UINT nID
)
126 CWnd
* pwndDlgItem
= GetDlgItem(nID
);
127 // adjust the size of the control to fit its content
128 CString sControlText
;
129 pwndDlgItem
->GetWindowText(sControlText
);
130 // next step: find the rectangle the control text needs to
133 CDC
* pDC
= pwndDlgItem
->GetWindowDC();
135 RECT controlrectorig
;
136 pwndDlgItem
->GetWindowRect(&controlrect
);
137 ::MapWindowPoints(NULL
, GetSafeHwnd(), (LPPOINT
)&controlrect
, 2);
138 controlrectorig
= controlrect
;
141 CFont
* font
= pwndDlgItem
->GetFont();
142 CFont
* pOldFont
= pDC
->SelectObject(font
);
143 if (pDC
->DrawText(sControlText
, -1, &controlrect
, DT_WORDBREAK
| DT_EDITCONTROL
| DT_EXPANDTABS
| DT_LEFT
| DT_CALCRECT
))
145 // now we have the rectangle the control really needs
146 if ((controlrectorig
.right
- controlrectorig
.left
) > (controlrect
.right
- controlrect
.left
))
148 // we're dealing with radio buttons and check boxes,
149 // which means we have to add a little space for the checkbox
150 controlrectorig
.right
= controlrectorig
.left
+ (controlrect
.right
- controlrect
.left
) + 20;
151 pwndDlgItem
->MoveWindow(&controlrectorig
);
154 pDC
->SelectObject(pOldFont
);
160 * Display a balloon with close button, anchored at a given edit control on this dialog.
162 void ShowEditBalloon(UINT nIdControl
, UINT nIdText
, UINT nIdTitle
, int nIcon
= TTI_WARNING
)
164 CString
text(MAKEINTRESOURCE(nIdText
));
165 CString
title(MAKEINTRESOURCE(nIdTitle
));
166 ShowEditBalloon(nIdControl
, text
, title
, nIcon
);
168 void ShowEditBalloon(UINT nIdControl
, const CString
& text
, const CString
& title
, int nIcon
= TTI_WARNING
)
171 bt
.cbStruct
= sizeof(bt
);
175 SendDlgItemMessage(nIdControl
, EM_SHOWBALLOONTIP
, 0, (LPARAM
)&bt
);
179 * Refreshes the cursor by forcing a WM_SETCURSOR message.
185 SetCursorPos(pt
.x
, pt
.y
);
188 HCURSOR
OnQueryDragIcon()
190 return static_cast<HCURSOR
>(m_hIcon
);
193 virtual void HtmlHelp(DWORD_PTR dwData
, UINT nCmd
= 0x000F)
195 CWinApp
* pApp
= AfxGetApp();
197 ASSERT(pApp
->m_pszHelpFilePath
!= NULL
);
198 // to call HtmlHelp the m_fUseHtmlHelp must be set in
199 // the application's constructor
200 ASSERT(pApp
->m_eHelpType
== afxHTMLHelp
);
205 // run the HTML Help engine
206 if (!::HtmlHelp(m_hWnd
, pApp
->m_pszHelpFilePath
, nCmd
, dwData
))
208 AfxMessageBox(AFX_IDP_FAILED_TO_LAUNCH_HELP
);
216 class CStateDialog
: public CDialog
, public CResizableWndState
220 : m_bEnableSaveRestore(false)
223 CStateDialog(UINT
/*nIDTemplate*/, CWnd
* /*pParentWnd = NULL*/)
224 : m_bEnableSaveRestore(false)
227 CStateDialog(LPCTSTR
/*lpszTemplateName*/, CWnd
* /*pParentWnd = NULL*/)
228 : m_bEnableSaveRestore(false)
231 virtual ~CStateDialog();
235 bool m_bEnableSaveRestore
;
239 CString m_sSection
; // section name (identifies a parent window)
242 // section to use in app's profile
243 void EnableSaveRestore(LPCTSTR pszSection
, bool bRectOnly
= FALSE
)
245 m_sSection
= pszSection
;
247 m_bEnableSaveRestore
= true;
248 m_bRectOnly
= bRectOnly
;
250 // restore immediately
251 LoadWindowRect(pszSection
, bRectOnly
);
254 virtual CWnd
* GetResizableWnd() const
256 // make the layout know its parent window
257 return CWnd::FromHandle(m_hWnd
);
260 afx_msg
void OnDestroy()
262 if (m_bEnableSaveRestore
)
263 SaveWindowRect(m_sSection
, m_bRectOnly
);
264 CDialog::OnDestroy();
267 DECLARE_MESSAGE_MAP()
271 class CResizableStandAloneDialog
: public CStandAloneDialogTmpl
<CResizableDialog
>
274 CResizableStandAloneDialog(UINT nIDTemplate
, CWnd
* pParentWnd
= NULL
);
277 DECLARE_DYNAMIC(CResizableStandAloneDialog
)
280 afx_msg
void OnSizing(UINT fwSide
, LPRECT pRect
);
281 afx_msg
void OnMoving(UINT fwSide
, LPRECT pRect
);
282 afx_msg
void OnNcMButtonUp(UINT nHitTest
, CPoint point
);
283 afx_msg
void OnNcRButtonUp(UINT nHitTest
, CPoint point
);
285 DECLARE_MESSAGE_MAP()
290 CRect m_rcOrgWindowRect
;
293 typedef CStandAloneDialogTmpl
<CDialog
> CStandAloneDialog
;
294 typedef CStandAloneDialogTmpl
<CStateDialog
> CStateStandAloneDialog
;