OSDN Git Service

Change Dir Structure to be same as TortoiseSVN'
[tortoisegit/TortoiseGitJp.git] / src / Utils / MiscUI / BrowseFolder.cpp
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 #include "StdAfx.h"\r
20 #include <windowsx.h>\r
21 #include "BrowseFolder.h"\r
22 \r
23 BOOL CBrowseFolder::m_bCheck = FALSE;\r
24 BOOL CBrowseFolder::m_bCheck2 = FALSE;\r
25 WNDPROC CBrowseFolder::CBProc = NULL;\r
26 HWND CBrowseFolder::checkbox = NULL;\r
27 HWND CBrowseFolder::checkbox2 = NULL;\r
28 HWND CBrowseFolder::ListView = NULL;\r
29 TCHAR CBrowseFolder::m_CheckText[200];          \r
30 TCHAR CBrowseFolder::m_CheckText2[200];         \r
31 CString CBrowseFolder::m_sDefaultPath;\r
32 bool CBrowseFolder::m_DisableCheckbox2WhenCheckbox1IsChecked = false;\r
33 \r
34 \r
35 CBrowseFolder::CBrowseFolder(void)\r
36 :       m_style(0),\r
37         m_root(NULL)\r
38 {\r
39         memset(m_displayName, 0, sizeof(m_displayName));\r
40         memset(m_title, 0, sizeof(m_title));\r
41         memset(m_CheckText, 0, sizeof(m_CheckText));\r
42 }\r
43 \r
44 CBrowseFolder::~CBrowseFolder(void)\r
45 {\r
46 }\r
47 \r
48 //show the dialog\r
49 CBrowseFolder::retVal CBrowseFolder::Show(HWND parent, LPTSTR path, size_t pathlen, LPCTSTR szDefaultPath /* = NULL */)\r
50 {\r
51         CString temp;\r
52         temp = path;\r
53         CString sDefault;\r
54         if (szDefaultPath)\r
55                 sDefault = szDefaultPath;\r
56         CBrowseFolder::retVal ret = Show(parent, temp, sDefault);\r
57         _tcscpy_s(path, pathlen, temp);\r
58         return ret;\r
59 }\r
60 CBrowseFolder::retVal CBrowseFolder::Show(HWND parent, CString& path, const CString& sDefaultPath /* = CString() */)\r
61 {\r
62         retVal ret = OK;                //assume OK\r
63         m_sDefaultPath = sDefaultPath;\r
64         if (m_sDefaultPath.IsEmpty() && !path.IsEmpty())\r
65         {\r
66                 // if the result path already contains a path, use that as the default path\r
67                 m_sDefaultPath = path;\r
68         }\r
69         LPITEMIDLIST itemIDList;\r
70 \r
71         BROWSEINFO browseInfo;\r
72 \r
73         browseInfo.hwndOwner            = parent;\r
74         browseInfo.pidlRoot                     = m_root;\r
75         browseInfo.pszDisplayName       = m_displayName;\r
76         browseInfo.lpszTitle            = m_title;\r
77         browseInfo.ulFlags                      = m_style;\r
78         browseInfo.lpfn                         = NULL;\r
79         browseInfo.lParam                       = (LPARAM)this;\r
80         \r
81         if ((_tcslen(m_CheckText) > 0)||(!m_sDefaultPath.IsEmpty()))\r
82         {\r
83                 browseInfo.lpfn = BrowseCallBackProc;\r
84         }\r
85         \r
86         itemIDList = SHBrowseForFolder(&browseInfo);\r
87 \r
88         //is the dialog canceled?\r
89         if (!itemIDList)\r
90                 ret = CANCEL;\r
91 \r
92         if (ret != CANCEL) \r
93         {\r
94                 if (!SHGetPathFromIDList(itemIDList, path.GetBuffer(MAX_PATH)))         // MAX_PATH ok. Explorer can't handle paths longer than MAX_PATH.\r
95                         ret = NOPATH;\r
96 \r
97                 path.ReleaseBuffer();\r
98         \r
99                 LPMALLOC        shellMalloc;\r
100                 HRESULT         hr;\r
101 \r
102                 hr = SHGetMalloc(&shellMalloc);\r
103 \r
104                 if (SUCCEEDED(hr)) \r
105                 {\r
106                         //free memory\r
107                         shellMalloc->Free(itemIDList);\r
108                         //release interface\r
109                         shellMalloc->Release();\r
110                 }\r
111         }\r
112         return ret;\r
113 }\r
114 \r
115 void CBrowseFolder::SetInfo(LPCTSTR title)\r
116 {\r
117         ASSERT(title);\r
118         \r
119         if (title)\r
120                 _tcscpy_s(m_title, 200, title);\r
121 }\r
122 \r
123 void CBrowseFolder::SetCheckBoxText(LPCTSTR checktext)\r
124 {\r
125         ASSERT(checktext);\r
126 \r
127         if (checktext)\r
128                 _tcscpy_s(m_CheckText, 200, checktext);\r
129 }\r
130 \r
131 void CBrowseFolder::SetCheckBoxText2(LPCTSTR checktext)\r
132 {\r
133         ASSERT(checktext);\r
134 \r
135         if (checktext)\r
136                 _tcscpy_s(m_CheckText2, 200, checktext);\r
137 }\r
138 \r
139 void CBrowseFolder::SetFont(HWND hwnd,LPTSTR FontName,int FontSize)\r
140 {\r
141 \r
142         HFONT hf;\r
143         LOGFONT lf={0};\r
144         HDC hdc=GetDC(hwnd);\r
145 \r
146         GetObject(GetWindowFont(hwnd),sizeof(lf),&lf);\r
147         lf.lfWeight = FW_REGULAR;\r
148         lf.lfHeight = (LONG)FontSize;\r
149         lstrcpy( lf.lfFaceName, FontName );\r
150         hf=CreateFontIndirect(&lf);\r
151         SetBkMode(hdc,OPAQUE);\r
152         SendMessage(hwnd,WM_SETFONT,(WPARAM)hf,TRUE);\r
153         ReleaseDC(hwnd,hdc);\r
154 \r
155 }\r
156 \r
157 int CBrowseFolder::BrowseCallBackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM /*lpData*/)\r
158 {\r
159         RECT ListViewRect,Dialog;\r
160         //Initialization callback message\r
161         if (uMsg == BFFM_INITIALIZED)\r
162         {\r
163                 if (_tcslen(m_CheckText) > 0)\r
164                 {\r
165                         bool bSecondCheckbox = (_tcslen(m_CheckText2)!=0);\r
166                         //Rectangles for getting the positions\r
167                         checkbox = CreateWindowEx(      0,\r
168                                 _T("BUTTON"),\r
169                                 m_CheckText,\r
170                                 WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|BS_AUTOCHECKBOX,\r
171                                 0,100,100,50,\r
172                                 hwnd,\r
173                                 0,\r
174                                 NULL,\r
175                                 NULL);\r
176                         if (checkbox == NULL)\r
177                                 return 0;\r
178 \r
179                         if (bSecondCheckbox)\r
180                         {\r
181                                 //Rectangles for getting the positions\r
182                                 checkbox2 = CreateWindowEx(     0,\r
183                                         _T("BUTTON"),\r
184                                         m_CheckText2,\r
185                                         WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|BS_AUTOCHECKBOX,\r
186                                         0,100,100,50,\r
187                                         hwnd,\r
188                                         0,\r
189                                         NULL,\r
190                                         NULL);\r
191                                 if (checkbox2 == NULL)\r
192                                         return 0;\r
193                         }\r
194 \r
195                         ListView = FindWindowEx(hwnd,NULL,_T("SysTreeView32"),NULL);\r
196                         if (ListView == NULL)\r
197                                 ListView = FindWindowEx(hwnd,NULL,_T("SHBrowseForFolder ShellNameSpace Control"),NULL);\r
198 \r
199                         if (ListView == NULL)\r
200                                 return 0;\r
201 \r
202                         //Gets the dimensions of the windows\r
203                         GetWindowRect(hwnd,&Dialog);\r
204                         GetWindowRect(ListView,&ListViewRect);\r
205                         POINT pt;\r
206                         pt.x = ListViewRect.left;\r
207                         pt.y = ListViewRect.top;\r
208                         ScreenToClient(hwnd, &pt);\r
209                         ListViewRect.top = pt.y;\r
210                         ListViewRect.left = pt.x;\r
211                         pt.x = ListViewRect.right;\r
212                         pt.y = ListViewRect.bottom;\r
213                         ScreenToClient(hwnd, &pt);\r
214                         ListViewRect.bottom = pt.y;\r
215                         ListViewRect.right = pt.x;\r
216                         //Sets the list view controls dimensions\r
217                         SetWindowPos(ListView,0,ListViewRect.left,\r
218                                 bSecondCheckbox ? ListViewRect.top+40 : ListViewRect.top+20,\r
219                                 (ListViewRect.right-ListViewRect.left),\r
220                                 bSecondCheckbox ? (ListViewRect.bottom - ListViewRect.top)-40 : (ListViewRect.bottom - ListViewRect.top)-20,\r
221                                 SWP_NOZORDER);\r
222                         //Sets the window positions of checkbox and dialog controls\r
223                         SetWindowPos(checkbox,HWND_BOTTOM,ListViewRect.left,\r
224                                 ListViewRect.top,\r
225                                 (ListViewRect.right-ListViewRect.left),\r
226                                 14,\r
227                                 SWP_NOZORDER);\r
228                         if (bSecondCheckbox)\r
229                         {\r
230                                 SetWindowPos(checkbox2,HWND_BOTTOM,ListViewRect.left,\r
231                                         ListViewRect.top+20,\r
232                                         (ListViewRect.right-ListViewRect.left),\r
233                                         14,\r
234                                         SWP_NOZORDER);\r
235                         }\r
236                         HWND label = FindWindowEx(hwnd, NULL, _T("STATIC"), NULL);\r
237                         if (label)\r
238                         {\r
239                                 HFONT hFont = (HFONT)::SendMessage(label, WM_GETFONT, 0, 0);\r
240                                 LOGFONT lf = {0};\r
241                                 GetObject(hFont, sizeof(lf), &lf);\r
242                                 HFONT hf2 = CreateFontIndirect(&lf);\r
243                                 ::SendMessage(checkbox, WM_SETFONT, (WPARAM)hf2, TRUE);\r
244                                 if (bSecondCheckbox)\r
245                                         ::SendMessage(checkbox2, WM_SETFONT, (WPARAM)hf2, TRUE);\r
246                         }\r
247                         else\r
248                         {\r
249                                 //Sets the fonts of static controls\r
250                                 SetFont(checkbox,_T("MS Sans Serif"),12);\r
251                                 if (bSecondCheckbox)\r
252                                         SetFont(checkbox2,_T("MS Sans Serif"),12);\r
253                         }\r
254 \r
255                         // Subclass the checkbox control. \r
256                         CBProc = (WNDPROC) SetWindowLongPtr(checkbox,GWLP_WNDPROC, (LONG_PTR) CheckBoxSubclassProc); \r
257                         //Sets the checkbox to checked position\r
258                         SendMessage(checkbox,BM_SETCHECK,(WPARAM)m_bCheck,0);\r
259                         if (bSecondCheckbox)\r
260                         {\r
261                                 CBProc = (WNDPROC) SetWindowLongPtr(checkbox2,GWLP_WNDPROC, (LONG_PTR) CheckBoxSubclassProc2); \r
262                                 SendMessage(checkbox2,BM_SETCHECK,(WPARAM)m_bCheck,0);\r
263                         }\r
264                         // send a resize message to the resized list view control. Otherwise it won't show\r
265                         // up properly until the user resizes the window!\r
266                         SendMessage(ListView, WM_SIZE, SIZE_RESTORED, MAKELONG(ListViewRect.right-ListViewRect.left, bSecondCheckbox ? (ListViewRect.bottom - ListViewRect.top)-40 : (ListViewRect.bottom - ListViewRect.top)-20));\r
267                 }\r
268                 \r
269                 // now set the default directory\r
270                 SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)(LPCTSTR)m_sDefaultPath);\r
271         }\r
272         if (uMsg == BFFM_SELCHANGED)\r
273         {\r
274                 // Set the status window to the currently selected path.\r
275                 TCHAR szDir[MAX_PATH];\r
276                 if (SHGetPathFromIDList((LPITEMIDLIST)lParam, szDir))\r
277                 {\r
278                         SendMessage(hwnd,BFFM_SETSTATUSTEXT, 0, (LPARAM)szDir);\r
279                 }\r
280         }\r
281         \r
282         return 0;\r
283 }\r
284 \r
285 LRESULT CBrowseFolder::CheckBoxSubclassProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)\r
286 {\r
287         if (uMsg == WM_LBUTTONUP)\r
288         {\r
289                 m_bCheck = (SendMessage(hwnd,BM_GETCHECK,0,0)==BST_UNCHECKED);\r
290                 if (m_bCheck && m_DisableCheckbox2WhenCheckbox1IsChecked)\r
291                 {\r
292                         ::EnableWindow(checkbox2, !m_bCheck);\r
293                 }\r
294                 else\r
295                         ::EnableWindow(checkbox2, true);\r
296         }\r
297 \r
298         return CallWindowProc(CBProc, hwnd, uMsg, \r
299                 wParam, lParam); \r
300\r
301 \r
302 LRESULT CBrowseFolder::CheckBoxSubclassProc2(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)\r
303 {\r
304         if (uMsg == WM_LBUTTONUP)\r
305         {\r
306                 m_bCheck2 = (SendMessage(hwnd,BM_GETCHECK,0,0)==BST_UNCHECKED);\r
307         }\r
308 \r
309         return CallWindowProc(CBProc, hwnd, uMsg, \r
310                 wParam, lParam); \r
311\r