OSDN Git Service

Show Ignore Sub Menu
[tortoisegit/TortoiseGitJp.git] / Utils / MiscUI / StandAloneDlg.h
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #pragma once\r
20 \r
21 #include "ResizableDialog.h"\r
22 #include "Balloon.h"\r
23 \r
24 #pragma comment(lib, "htmlhelp.lib")\r
25 \r
26 /**\r
27  * \ingroup TortoiseProc\r
28  *\r
29  * A template which can be used as the base-class of dialogs which form the main dialog\r
30  * of a 'dialog-style application'\r
31  * Just provides the boiler-plate code for dealing with application icons\r
32  * \r
33  * \remark Replace all references to CDialog or CResizableDialog in your dialog class with \r
34  * either CResizableStandAloneDialog, CStandAloneDialog or CStateStandAloneDialog, as appropriate\r
35  */\r
36 template <typename BaseType> class CStandAloneDialogTmpl : public BaseType\r
37 {\r
38 protected:\r
39         CStandAloneDialogTmpl(UINT nIDTemplate, CWnd* pParentWnd = NULL) : BaseType(nIDTemplate, pParentWnd)\r
40         {\r
41                 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);\r
42         }\r
43         virtual BOOL OnInitDialog()\r
44         {\r
45                 BaseType::OnInitDialog();\r
46 \r
47                 // Set the icon for this dialog.  The framework does this automatically\r
48                 //  when the application's main window is not a dialog\r
49                 SetIcon(m_hIcon, TRUE);                 // Set big icon\r
50                 SetIcon(m_hIcon, FALSE);                // Set small icon\r
51 \r
52                 return FALSE;\r
53         }\r
54 \r
55         afx_msg void OnPaint()\r
56         {\r
57                 if (IsIconic())\r
58                 {\r
59                         CPaintDC dc(this); // device context for painting\r
60 \r
61                         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);\r
62 \r
63                         // Center icon in client rectangle\r
64                         int cxIcon = GetSystemMetrics(SM_CXICON);\r
65                         int cyIcon = GetSystemMetrics(SM_CYICON);\r
66                         CRect rect;\r
67                         GetClientRect(&rect);\r
68                         int x = (rect.Width() - cxIcon + 1) / 2;\r
69                         int y = (rect.Height() - cyIcon + 1) / 2;\r
70 \r
71                         // Draw the icon\r
72                         dc.DrawIcon(x, y, m_hIcon);\r
73                 }\r
74                 else\r
75                 {\r
76                         BaseType::OnPaint();\r
77                 }\r
78         }\r
79         /**\r
80          * Wrapper around the CWnd::EnableWindow() method, but\r
81          * makes sure that a control that has the focus is not disabled\r
82          * before the focus is passed on to the next control.\r
83          */\r
84         BOOL DialogEnableWindow(UINT nID, BOOL bEnable)\r
85         {\r
86                 CWnd * pwndDlgItem = GetDlgItem(nID);\r
87                 if (pwndDlgItem == NULL)\r
88                         return FALSE;\r
89                 if (bEnable)\r
90                         return pwndDlgItem->EnableWindow(bEnable);\r
91                 if (GetFocus() == pwndDlgItem)\r
92                 {\r
93                         SendMessage(WM_NEXTDLGCTL, 0, FALSE);\r
94                 }\r
95                 return pwndDlgItem->EnableWindow(bEnable);\r
96         }\r
97 \r
98         /**\r
99          * Adjusts the size of a checkbox or radio button control.\r
100          * Since we always make the size of those bigger than 'necessary'\r
101          * for making sure that translated strings can fit in those too,\r
102          * this method can reduce the size of those controls again to only\r
103          * fit the text.\r
104          */\r
105         void AdjustControlSize(UINT nID)\r
106         {\r
107                 CWnd * pwndDlgItem = GetDlgItem(nID);\r
108                 // adjust the size of the control to fit its content\r
109                 CString sControlText;\r
110                 pwndDlgItem->GetWindowText(sControlText);\r
111                 // next step: find the rectangle the control text needs to\r
112                 // be displayed\r
113 \r
114                 CDC * pDC = pwndDlgItem->GetWindowDC();\r
115                 RECT controlrect;\r
116                 RECT controlrectorig;\r
117                 pwndDlgItem->GetWindowRect(&controlrect);\r
118                 ::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT)&controlrect, 2);\r
119                 controlrectorig = controlrect;\r
120                 if (pDC)\r
121                 {\r
122                         CFont * font = pwndDlgItem->GetFont();\r
123                         CFont * pOldFont = pDC->SelectObject(font);\r
124                         if (pDC->DrawText(sControlText, -1, &controlrect, DT_WORDBREAK | DT_EDITCONTROL | DT_EXPANDTABS | DT_LEFT | DT_CALCRECT))\r
125                         {\r
126                                 // now we have the rectangle the control really needs\r
127                                 if ((controlrectorig.right - controlrectorig.left) > (controlrect.right - controlrect.left))\r
128                                 {\r
129                                         // we're dealing with radio buttons and check boxes,\r
130                                         // which means we have to add a little space for the checkbox\r
131                                         controlrectorig.right = controlrectorig.left + (controlrect.right - controlrect.left) + 20;\r
132                                         pwndDlgItem->MoveWindow(&controlrectorig);\r
133                                 }\r
134                         }\r
135                         pDC->SelectObject(pOldFont);\r
136                         ReleaseDC(pDC);\r
137                 }\r
138         }\r
139 \r
140         /**\r
141          * Display a balloon with close button, anchored at a given control on this dialog.\r
142          */\r
143         void ShowBalloon(UINT nIdControl, UINT nIdText, LPCTSTR szIcon = IDI_EXCLAMATION)\r
144         {\r
145                 CBalloon::ShowBalloon(this, CBalloon::GetCtrlCentre(this, nIdControl), nIdText, TRUE, szIcon);\r
146         }\r
147 \r
148         /**\r
149          * Refreshes the cursor by forcing a WM_SETCURSOR message.\r
150          */\r
151         void RefreshCursor()\r
152         {\r
153                 POINT pt;\r
154                 GetCursorPos(&pt);\r
155                 SetCursorPos(pt.x, pt.y);\r
156         }\r
157 private:\r
158         HCURSOR OnQueryDragIcon()\r
159         {\r
160                 return static_cast<HCURSOR>(m_hIcon);\r
161         }\r
162 \r
163         virtual void HtmlHelp(DWORD_PTR dwData, UINT nCmd = 0x000F)\r
164         {\r
165                 CWinApp* pApp = AfxGetApp();\r
166                 ASSERT_VALID(pApp);\r
167                 ASSERT(pApp->m_pszHelpFilePath != NULL);\r
168                 // to call HtmlHelp the m_fUseHtmlHelp must be set in\r
169                 // the application's constructor\r
170                 ASSERT(pApp->m_eHelpType == afxHTMLHelp);\r
171 \r
172                 CWaitCursor wait;\r
173 \r
174                 PrepareForHelp();\r
175                 // run the HTML Help engine\r
176                 if (!::HtmlHelp(m_hWnd, pApp->m_pszHelpFilePath, nCmd, dwData))\r
177                 {\r
178                         AfxMessageBox(AFX_IDP_FAILED_TO_LAUNCH_HELP);\r
179                 }\r
180         }\r
181 \r
182 \r
183         HICON m_hIcon;\r
184 };\r
185 \r
186 class CStateDialog : public CDialog, public CResizableWndState\r
187 {\r
188 public:\r
189         CStateDialog() {m_bEnableSaveRestore = false;}\r
190         CStateDialog(UINT /*nIDTemplate*/, CWnd* /*pParentWnd = NULL*/) {m_bEnableSaveRestore = false;}\r
191         CStateDialog(LPCTSTR /*lpszTemplateName*/, CWnd* /*pParentWnd = NULL*/) {m_bEnableSaveRestore = false;}\r
192         virtual ~CStateDialog();\r
193 \r
194 private:\r
195         // flags\r
196         bool m_bEnableSaveRestore;\r
197         bool m_bRectOnly;\r
198 \r
199         // internal status\r
200         CString m_sSection;                     // section name (identifies a parent window)\r
201 \r
202 protected:\r
203         // section to use in app's profile\r
204         void EnableSaveRestore(LPCTSTR pszSection, bool bRectOnly = FALSE)\r
205         {\r
206                 m_sSection = pszSection;\r
207 \r
208                 m_bEnableSaveRestore = true;\r
209                 m_bRectOnly = bRectOnly;\r
210 \r
211                 // restore immediately\r
212                 LoadWindowRect(pszSection, bRectOnly);\r
213         };\r
214 \r
215         virtual CWnd* GetResizableWnd() const\r
216         {\r
217                 // make the layout know its parent window\r
218                 return CWnd::FromHandle(m_hWnd);\r
219         };\r
220 \r
221         afx_msg void OnDestroy()\r
222         {\r
223                 if (m_bEnableSaveRestore)\r
224                         SaveWindowRect(m_sSection, m_bRectOnly);\r
225                 CDialog::OnDestroy();\r
226         };\r
227 \r
228         DECLARE_MESSAGE_MAP()\r
229 \r
230 };\r
231 \r
232 class CResizableStandAloneDialog : public CStandAloneDialogTmpl<CResizableDialog>\r
233 {\r
234 public:\r
235         CResizableStandAloneDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);\r
236 \r
237 private:\r
238         DECLARE_DYNAMIC(CResizableStandAloneDialog)\r
239 \r
240 protected:\r
241         afx_msg void    OnSizing(UINT fwSide, LPRECT pRect);\r
242         afx_msg void    OnMoving(UINT fwSide, LPRECT pRect);\r
243         afx_msg void    OnNcMButtonUp(UINT nHitTest, CPoint point);\r
244         afx_msg void    OnNcRButtonUp(UINT nHitTest, CPoint point);\r
245 \r
246         DECLARE_MESSAGE_MAP()\r
247 \r
248 private:\r
249         bool            m_bVertical;\r
250         bool            m_bHorizontal;\r
251         CRect           m_rcOrgWindowRect;\r
252 };\r
253 \r
254 typedef CStandAloneDialogTmpl<CDialog> CStandAloneDialog;\r
255 typedef CStandAloneDialogTmpl<CStateDialog> CStateStandAloneDialog;\r