Mercurial > projects > dwt-win
comparison dwt/widgets/DirectoryDialog.d @ 181:52c185ec49e8
Directory Dialog ported
author | Zhiguang Liang <davelzg@gmail.com> |
---|---|
date | Mon, 10 Mar 2008 11:31:43 +0800 |
parents | 43c42c637c9c |
children | 811e926196d6 |
comparison
equal
deleted
inserted
replaced
178:e186b01aa62e | 181:52c185ec49e8 |
---|---|
10 * Port to the D programming language: | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | 11 * Frank Benoit <benoit@tionex.de> |
12 *******************************************************************************/ | 12 *******************************************************************************/ |
13 module dwt.widgets.DirectoryDialog; | 13 module dwt.widgets.DirectoryDialog; |
14 | 14 |
15 import dwt.widgets.Display; | |
15 import dwt.widgets.Dialog; | 16 import dwt.widgets.Dialog; |
16 import dwt.widgets.Shell; | 17 import dwt.widgets.Shell; |
17 | 18 |
18 class DirectoryDialog : Dialog { | |
19 public this (Shell parent, int style) { | |
20 super (parent, style); | |
21 } | |
22 } | |
23 | |
24 /++ | |
25 import dwt.DWT; | 19 import dwt.DWT; |
26 import dwt.DWTException; | 20 import dwt.DWTException; |
27 import dwt.internal.Callback; | |
28 import dwt.internal.win32.BROWSEINFO; | |
29 import dwt.internal.win32.OS; | 21 import dwt.internal.win32.OS; |
30 import dwt.internal.win32.TCHAR; | 22 import dwt.internal.C; |
23 | |
24 import dwt.dwthelper.utils; | |
25 static import tango.text.Text; | |
31 | 26 |
32 /** | 27 /** |
33 * Instances of this class allow the user to navigate | 28 * Instances of this class allow the user to navigate |
34 * the file system and select a directory. | 29 * the file system and select a directory. |
35 * <dl> | 30 * <dl> |
42 * IMPORTANT: This class is intended to be subclassed <em>only</em> | 37 * IMPORTANT: This class is intended to be subclassed <em>only</em> |
43 * within the DWT implementation. | 38 * within the DWT implementation. |
44 * </p> | 39 * </p> |
45 */ | 40 */ |
46 | 41 |
47 public class DirectoryDialog extends Dialog { | 42 public class DirectoryDialog : Dialog { |
48 String message = "", filterPath = ""; //$NON-NLS-1$//$NON-NLS-2$ | 43 static char[] message = ""; |
49 String directoryPath; | 44 static char[] filterPath = ""; //$NON-NLS-1$//$NON-NLS-2$ |
45 static char[] directoryPath; | |
50 | 46 |
51 /** | 47 /** |
52 * Constructs a new instance of this class given only its parent. | 48 * Constructs a new instance of this class given only its parent. |
53 * | 49 * |
54 * @param parent a shell which will be the parent of the new instance | 50 * @param parent a shell which will be the parent of the new instance |
59 * @exception DWTException <ul> | 55 * @exception DWTException <ul> |
60 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | 56 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
61 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | 57 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
62 * </ul> | 58 * </ul> |
63 */ | 59 */ |
64 public DirectoryDialog (Shell parent) { | 60 public this (Shell parent) { |
65 this (parent, DWT.PRIMARY_MODAL); | 61 this (parent, DWT.PRIMARY_MODAL); |
66 } | 62 } |
67 | 63 |
68 /** | 64 /** |
69 * Constructs a new instance of this class given its parent | 65 * Constructs a new instance of this class given its parent |
87 * @exception DWTException <ul> | 83 * @exception DWTException <ul> |
88 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | 84 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
89 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | 85 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
90 * </ul> | 86 * </ul> |
91 */ | 87 */ |
92 public DirectoryDialog (Shell parent, int style) { | 88 public this (Shell parent, int style) { |
93 super (parent, style); | 89 super (parent, style); |
94 checkSubclass (); | 90 checkSubclass (); |
95 } | 91 } |
96 | 92 |
97 int BrowseCallbackProc (int hwnd, int uMsg, int lParam, int lpData) { | 93 extern(Windows)static int BrowseCallbackProc (HWND hwnd, uint uMsg, int lParam, int lpData) { |
94 DirectoryDialog pThis = cast(DirectoryDialog)cast(void*)lpData; | |
98 switch (uMsg) { | 95 switch (uMsg) { |
99 case OS.BFFM_INITIALIZED: | 96 case OS.BFFM_INITIALIZED: |
100 if (filterPath !is null && filterPath.length () !is 0) { | 97 if (pThis.filterPath !is null && pThis.filterPath.length !is 0) { |
101 /* Use the character encoding for the default locale */ | 98 /* Use the character encoding for the default locale */ |
102 TCHAR buffer = new TCHAR (0, filterPath.replace ('/', '\\'), true); | 99 TCHAR[] buffer = StrToTCHARs (0, pThis.filterPath.replace ('/', '\\'), true); |
103 OS.SendMessage (hwnd, OS.BFFM_SETSELECTION, 1, buffer); | 100 OS.SendMessage (hwnd, OS.BFFM_SETSELECTION, 1, buffer.ptr); |
104 } | 101 } |
105 if (title !is null && title.length () !is 0) { | 102 if (pThis.title !is null && pThis.title.length !is 0) { |
106 /* Use the character encoding for the default locale */ | 103 /* Use the character encoding for the default locale */ |
107 TCHAR buffer = new TCHAR (0, title, true); | 104 TCHAR[] buffer = StrToTCHARs (0, pThis.title, true); |
108 OS.SetWindowText (hwnd, buffer); | 105 OS.SetWindowText (hwnd, buffer.ptr); |
109 } | 106 } |
110 break; | 107 break; |
111 case OS.BFFM_VALIDATEFAILEDA: | 108 case OS.BFFM_VALIDATEFAILEDA: |
112 case OS.BFFM_VALIDATEFAILEDW: | 109 case OS.BFFM_VALIDATEFAILEDW: |
113 /* Use the character encoding for the default locale */ | 110 /* Use the character encoding for the default locale */ |
114 int length = OS.IsUnicode ? OS.wcslen (lParam) : OS.strlen (lParam); | 111 // int length = OS.IsUnicode ? OS.wcslen (lParam) : OS.strlen (lParam); |
115 TCHAR buffer = new TCHAR (0, length); | 112 // TCHAR buffer = new TCHAR (0, length); |
116 int byteCount = buffer.length () * TCHAR.sizeof; | 113 // int byteCount = buffer.length * TCHAR.sizeof; |
117 OS.MoveMemory (buffer, lParam, byteCount); | 114 // OS.MoveMemory (buffer, lParam, byteCount); |
118 directoryPath = buffer.toString (0, length); | 115 // directoryPath = buffer.toString (0, length); |
116 pThis.directoryPath = TCHARzToStr( cast(TCHAR*)lParam ); | |
119 break; | 117 break; |
120 default: | 118 default: |
121 } | 119 } |
122 return 0; | 120 return 0; |
123 } | 121 } |
128 * | 126 * |
129 * @return the filter path | 127 * @return the filter path |
130 * | 128 * |
131 * @see #setFilterPath | 129 * @see #setFilterPath |
132 */ | 130 */ |
133 public String getFilterPath () { | 131 public char[] getFilterPath () { |
134 return filterPath; | 132 return filterPath; |
135 } | 133 } |
136 | 134 |
137 /** | 135 /** |
138 * Returns the dialog's message, which is a description of | 136 * Returns the dialog's message, which is a description of |
139 * the purpose for which it was opened. This message will be | 137 * the purpose for which it was opened. This message will be |
140 * visible on the dialog while it is open. | 138 * visible on the dialog while it is open. |
141 * | 139 * |
142 * @return the message | 140 * @return the message |
143 */ | 141 */ |
144 public String getMessage () { | 142 public char[] getMessage () { |
145 return message; | 143 return message; |
146 } | 144 } |
147 | 145 |
148 /** | 146 /** |
149 * Makes the dialog visible and brings it to the front | 147 * Makes the dialog visible and brings it to the front |
155 * @exception DWTException <ul> | 153 * @exception DWTException <ul> |
156 * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li> | 154 * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li> |
157 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li> | 155 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li> |
158 * </ul> | 156 * </ul> |
159 */ | 157 */ |
160 public String open () { | 158 public char[] open () { |
161 if (OS.IsWinCE) DWT.error (DWT.ERROR_NOT_IMPLEMENTED); | 159 if (OS.IsWinCE) DWT.error (DWT.ERROR_NOT_IMPLEMENTED); |
162 | 160 |
163 int hHeap = OS.GetProcessHeap (); | 161 auto hHeap = OS.GetProcessHeap (); |
164 | 162 |
165 /* Get the owner HWND for the dialog */ | 163 /* Get the owner HWND for the dialog */ |
166 int hwndOwner = 0; | 164 HWND hwndOwner; |
167 if (parent !is null) hwndOwner = parent.handle; | 165 if (parent !is null) hwndOwner = parent.handle; |
168 | 166 |
169 /* Copy the message to OS memory */ | 167 /* Copy the message to OS memory */ |
170 int lpszTitle = 0; | 168 TCHAR* lpszTitle; |
171 if (message.length () !is 0) { | 169 if (message.length !is 0) { |
172 String string = message; | 170 char[] string = message; |
173 if (string.indexOf ('&') !is -1) { | 171 if (string.indexOf ('&') !is -1) { |
174 int length = string.length (); | 172 int length = string.length; |
175 char [] buffer = new char [length * 2]; | 173 char [] buffer = new char [length * 2]; |
176 int index = 0; | 174 int index = 0; |
177 for (int i=0; i<length; i++) { | 175 for (int i=0; i<length; i++) { |
178 char ch = string.charAt (i); | 176 char ch = string.charAt (i); |
179 if (ch is '&') buffer [index++] = '&'; | 177 if (ch is '&') buffer [index++] = '&'; |
180 buffer [index++] = ch; | 178 buffer [index++] = ch; |
181 } | 179 } |
182 string = new String (buffer, 0, index); | 180 // string = new String (buffer, 0, index); |
183 } | 181 } |
184 /* Use the character encoding for the default locale */ | 182 /* Use the character encoding for the default locale */ |
185 TCHAR buffer = new TCHAR (0, string, true); | 183 TCHAR[] buffer = StrToTCHARs (0, string, true); |
186 int byteCount = buffer.length () * TCHAR.sizeof; | 184 int byteCount = buffer.length * TCHAR.sizeof; |
187 lpszTitle = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount); | 185 lpszTitle = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount); |
188 OS.MoveMemory (lpszTitle, buffer, byteCount); | 186 OS.MoveMemory (lpszTitle, buffer.ptr, byteCount); |
189 } | 187 } |
190 | 188 |
191 /* Create the BrowseCallbackProc */ | 189 /* Create the BrowseCallbackProc */ |
192 Callback callback = new Callback (this, "BrowseCallbackProc", 4); //$NON-NLS-1$ | 190 /+ Callback callback = new Callback (this, "BrowseCallbackProc", 4); //$NON-NLS-1$ |
193 int lpfn = callback.getAddress (); | 191 int lpfn = callback.getAddress ();+/ |
194 if (lpfn is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); | 192 BFFCALLBACK lpfn = &BrowseCallbackProc; |
193 if (lpfn is null) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); | |
195 | 194 |
196 /* Make the parent shell be temporary modal */ | 195 /* Make the parent shell be temporary modal */ |
197 Shell oldModal = null; | 196 Shell oldModal = null; |
198 Display display = parent.getDisplay (); | 197 Display display = parent.getDisplay (); |
199 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { | 198 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { |
200 oldModal = display.getModalDialogShell (); | 199 oldModal = display.getModalDialogShell (); |
201 display.setModalDialogShell (parent); | 200 display.setModalDialogShell (parent); |
202 } | 201 } |
203 | 202 |
204 directoryPath = null; | 203 directoryPath = null; |
205 BROWSEINFO lpbi = new BROWSEINFO (); | 204 BROWSEINFO lpbi; |
206 lpbi.hwndOwner = hwndOwner; | 205 lpbi.hwndOwner = hwndOwner; |
207 lpbi.lpszTitle = lpszTitle; | 206 lpbi.lpszTitle = lpszTitle; |
208 lpbi.ulFlags = OS.BIF_NEWDIALOGSTYLE | OS.BIF_RETURNONLYFSDIRS | OS.BIF_EDITBOX | OS.BIF_VALIDATE; | 207 lpbi.ulFlags = OS.BIF_NEWDIALOGSTYLE | OS.BIF_RETURNONLYFSDIRS | OS.BIF_EDITBOX | OS.BIF_VALIDATE; |
209 lpbi.lpfn = lpfn; | 208 lpbi.lpfn = lpfn; |
209 lpbi.lParam = cast(int)cast(void*)this; | |
210 /* | 210 /* |
211 * Bug in Windows. On some hardware configurations, SHBrowseForFolder() | 211 * Bug in Windows. On some hardware configurations, SHBrowseForFolder() |
212 * causes warning dialogs with the message "There is no disk in the drive | 212 * causes warning dialogs with the message "There is no disk in the drive |
213 * Please insert a disk into \Device\Harddisk0\DR0". This is possibly | 213 * Please insert a disk into \Device\Harddisk0\DR0". This is possibly |
214 * caused by SHBrowseForFolder() calling internally GetVolumeInformation(). | 214 * caused by SHBrowseForFolder() calling internally GetVolumeInformation(). |
237 * NOTE: This only happens in versions of the comctl32.dll | 237 * NOTE: This only happens in versions of the comctl32.dll |
238 * earlier than 6.0. | 238 * earlier than 6.0. |
239 */ | 239 */ |
240 bool oldRunMessages = display.runMessages; | 240 bool oldRunMessages = display.runMessages; |
241 if (OS.COMCTL32_MAJOR < 6) display.runMessages = false; | 241 if (OS.COMCTL32_MAJOR < 6) display.runMessages = false; |
242 int lpItemIdList = OS.SHBrowseForFolder (lpbi); | 242 ITEMIDLIST* lpItemIdList = OS.SHBrowseForFolder (&lpbi); |
243 if (OS.COMCTL32_MAJOR < 6) display.runMessages = oldRunMessages; | 243 if (OS.COMCTL32_MAJOR < 6) display.runMessages = oldRunMessages; |
244 OS.SetErrorMode (oldErrorMode); | 244 OS.SetErrorMode (oldErrorMode); |
245 | 245 |
246 /* Clear the temporary dialog modal parent */ | 246 /* Clear the temporary dialog modal parent */ |
247 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { | 247 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { |
248 display.setModalDialogShell (oldModal); | 248 display.setModalDialogShell (oldModal); |
249 } | 249 } |
250 | 250 |
251 bool success = lpItemIdList !is 0; | 251 bool success = lpItemIdList !is null; |
252 if (success) { | 252 if (success) { |
253 /* Use the character encoding for the default locale */ | 253 /* Use the character encoding for the default locale */ |
254 TCHAR buffer = new TCHAR (0, OS.MAX_PATH); | 254 TCHAR[OS.MAX_PATH] buffer; |
255 if (OS.SHGetPathFromIDList (lpItemIdList, buffer)) { | 255 if (OS.SHGetPathFromIDList (lpItemIdList, buffer.ptr)) { |
256 directoryPath = buffer.toString (0, buffer.strlen ()); | 256 directoryPath = TCHARzToStr (buffer.ptr); |
257 filterPath = directoryPath; | 257 filterPath = directoryPath; |
258 } | 258 } |
259 } | 259 } |
260 | 260 |
261 /* Free the BrowseCallbackProc */ | 261 /* Free the BrowseCallbackProc */ |
262 callback.dispose (); | 262 // callback.dispose (); |
263 | 263 |
264 /* Free the OS memory */ | 264 /* Free the OS memory */ |
265 if (lpszTitle !is 0) OS.HeapFree (hHeap, 0, lpszTitle); | 265 if (lpszTitle !is null) OS.HeapFree (hHeap, 0, lpszTitle); |
266 | 266 |
267 /* Free the pointer to the ITEMIDLIST */ | 267 /* Free the pointer to the ITEMIDLIST */ |
268 int [] ppMalloc = new int [1]; | 268 LPVOID ppMalloc; |
269 if (OS.SHGetMalloc (ppMalloc) is OS.S_OK) { | 269 if (OS.SHGetMalloc (&ppMalloc) is OS.S_OK) { |
270 /* void Free (struct IMalloc *this, void *pv); */ | 270 /* void Free (struct IMalloc *this, void *pv); */ |
271 OS.VtblCall (5, ppMalloc [0], lpItemIdList); | 271 OS.VtblCall (5, ppMalloc , cast(int)lpItemIdList); |
272 } | 272 } |
273 | 273 |
274 /* | 274 /* |
275 * This code is intentionally commented. On some | 275 * This code is intentionally commented. On some |
276 * platforms, the owner window is repainted right | 276 * platforms, the owner window is repainted right |
295 * as a path separator. | 295 * as a path separator. |
296 * </p> | 296 * </p> |
297 * | 297 * |
298 * @param string the filter path | 298 * @param string the filter path |
299 */ | 299 */ |
300 public void setFilterPath (String string) { | 300 public void setFilterPath (char[] string) { |
301 filterPath = string; | 301 filterPath = string; |
302 } | 302 } |
303 | 303 |
304 /** | 304 /** |
305 * Sets the dialog's message, which is a description of | 305 * Sets the dialog's message, which is a description of |
310 * | 310 * |
311 * @exception IllegalArgumentException <ul> | 311 * @exception IllegalArgumentException <ul> |
312 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | 312 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> |
313 * </ul> | 313 * </ul> |
314 */ | 314 */ |
315 public void setMessage (String string) { | 315 public void setMessage (char[] string) { |
316 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); | 316 if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
317 message = string; | 317 message = string; |
318 } | 318 } |
319 | 319 |
320 } | 320 } |
321 ++/ |