1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37 #define _CRT_SECURE_NO_DEPRECATE
46 extern HINSTANCE hInst
;
48 #define ITEM_BITMAPWIDTH 16
49 #define ITEM_BITMAPHEIGHT 16
50 #define ITEM_LEFTMARGIN 4
53 static HWND hWndDirPicker
;
54 static HICON hIconDrives
[5];
55 static HICON hIconFolders
[3];
56 static LPSTR lpszStringToReturn
;
57 static char szUNCRoot
[256] = "";
59 UINT
DriveType(UINT iType
);
61 static void fillComboBox(HWND hWnd
)
63 HWND hWndCB
= GetDlgItem(hWnd
, ID_COMBO_DIR
);
64 HWND hWndTempLB
= GetDlgItem(hWnd
, ID_LISTTEMP_DIR
);
67 ComboBox_ResetContent(hWndCB
);
68 ListBox_ResetContent(hWndTempLB
);
69 ListBox_Dir(hWndTempLB
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPSTR
)"*");
71 int iDriveCount
= ListBox_GetCount(hWndTempLB
);
72 int iCurDrive
=_getdrive() - 1;
77 for (int i
= 0; i
< iDriveCount
; i
++)
79 ListBox_GetText(hWndTempLB
, i
, szDrive
);
81 int iDrive
= szDrive
[2] - 'a';
83 sprintf(szRoot
, "%c:\\", szDrive
[2]);
85 int iType
= DriveType(iDrive
);
90 //Start the item string with the drive letter, colon, and two spaces
91 sprintf(szItem
, "%c%s", szDrive
[2], ": ");
93 if((iType
== DRIVE_FIXED
) || (iType
== DRIVE_RAMDISK
))
98 GetVolumeInformation(szRoot
, // address of root directory of the file system
99 szVolumeID
, // address of name of the volume
100 sizeof(szVolumeID
), // length of lpVolumeNameBuffer
101 NULL
, // address of volume serial number
102 &dwMaxLength
, // address of system's maximum filename length
103 &dwSysFlags
, // address of file system flags
104 NULL
, // address of name of file system
105 NULL
); // length of lpFileSystemNameBuffer
107 CharLower(szVolumeID
);
108 lstrcat(szItem
, szVolumeID
);
111 //For network drives, go grab the \\server\share for it.
112 if(DRIVE_REMOTE
== iType
)
116 DWORD dwSizeOfszNet
= sizeof(szNet
);
118 sprintf(szDrive
, "%c:", szDrive
[2]);
120 WNetGetConnection(szDrive
, szNet
, &dwSizeOfszNet
);
122 lstrcat(szItem
, szNet
);
125 int index
= ComboBox_AddString(hWndCB
, szItem
);
126 ComboBox_SetItemData(hWndCB
, index
, MAKELONG(iDrive
, iType
));
127 if(iDrive
== iCurDrive
)
128 ComboBox_SetCurSel(hWndCB
, index
);
129 if(szUNCRoot
[0] != '\0')
130 ComboBox_SetCurSel(hWndCB
, -1);
134 static void fillTempLBWithDirs(HWND hWndTempLB
, LPSTR lpszDir
)
137 WIN32_FIND_DATA ffdataStruct
;
139 char szPath
[_MAX_PATH
];
140 char szFileName
[_MAX_PATH
];
141 lstrcpy(szPath
, lpszDir
);
142 if(szPath
[lstrlen(szPath
) - 1] == '\\')
143 szPath
[lstrlen(szPath
) - 1] = '\0';
144 lstrcpy(szFileName
, szPath
);
145 lstrcat(szFileName
, "\\*");
146 HANDLE handle
= FindFirstFile(szFileName
, &ffdataStruct
);
147 if(handle
== INVALID_HANDLE_VALUE
)
154 lstrcpy(szFileName
, szPath
);
155 lstrcat(szFileName
, "\\");
156 lstrcat(szFileName
, ffdataStruct
.cFileName
);
157 if(ffdataStruct
. dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
159 char szStringToAdd
[_MAX_PATH
+ 2];
160 lstrcpy(szStringToAdd
, "[");
161 lstrcat(szStringToAdd
, ffdataStruct
.cFileName
);
162 lstrcat(szStringToAdd
, "]");
163 CharLower(szStringToAdd
);
164 ListBox_AddString(hWndTempLB
, szStringToAdd
);
166 bDone
= !FindNextFile(handle
, &ffdataStruct
);
171 static void fillListBox(HWND hWnd
, LPSTR lpszDir
)
173 HWND hWndLB
= GetDlgItem(hWnd
, ID_LIST_DIR
);
174 HWND hWndTempLB
= GetDlgItem(hWnd
, ID_LISTTEMP_DIR
);
175 HWND hWndEdit
= GetDlgItem(hWnd
, ID_EDIT_DIR
);
176 if((hWndLB
== NULL
) || (lpszDir
== NULL
))
179 int iLastChar
= lstrlen(lpszDir
);
180 if(lpszDir
[iLastChar
- 1] == '\\')
181 lpszDir
[iLastChar
- 1] = '\0';
183 SetWindowRedraw(hWndLB
, FALSE
);
184 ListBox_ResetContent(hWndLB
);
185 ListBox_ResetContent(hWndTempLB
);
188 lpszLast
= CharLower(lpszDir
);
190 SetWindowText(hWndLB
, lpszDir
);
192 char szDir
[_MAX_DIR
];
193 char szFullDir
[_MAX_DIR
];
194 sprintf(szFullDir
, "%s", lpszDir
);
195 sprintf(szDir
, "%s\\*.*", lpszDir
);
203 if((lpszDir
[0] == '\\') && (lpszDir
[1] == '\\') && bFirst
)
204 lpsz
= strchr(lpszLast
+ lstrlen(szUNCRoot
), '\\');
206 lpsz
= strchr(lpszLast
, '\\');
216 //If we're looking at a drive only, then append a backslash
217 if (lpszLast
== lpszDir
&& bFirst
)
218 lstrcat(lpszLast
, "\\");
220 //Add the drive string--includes the last one where lpsz == NULL
221 index
= ListBox_AddString(hWndLB
, lpszLast
);
223 UINT i
= (NULL
!= lpsz
) ? ID_ICON_FOLDEROPEN
: ID_ICON_OPENSELECT
;
224 ListBox_SetItemData(hWndLB
, index
, MAKELONG(index
, i
));
229 //Restore last character.
231 lpsz
+= (bFirst
) ? 0 : 1;
236 int indent
= index
+ 1;
238 //Get available directories
239 fillTempLBWithDirs(hWndTempLB
, lpszDir
);
241 int itemCount
= ListBox_GetCount(hWndTempLB
);
244 for (i
= 0; i
< itemCount
; i
++) {
245 index
= ListBox_GetText(hWndTempLB
, i
, lpszDir
);
246 //Skip directories beginning with . (skipping . and ..)
247 if(lpszDir
[1] == '.')
249 //Remove the ending ']'
250 iLastChar
= lstrlen(lpszDir
);
251 lpszDir
[iLastChar
- 1] = '\0';
252 //Add the string to the real directory list.
253 index
= ListBox_AddString(hWndLB
, lpszDir
+ 1);
254 ListBox_SetItemData(hWndLB
, index
, MAKELONG(indent
, ID_ICON_FOLDERCLOSED
));
256 //Force a listbox repaint.
257 SetWindowRedraw(hWndLB
, TRUE
);
258 InvalidateRect(hWndLB
, NULL
, TRUE
);
260 if(szFullDir
[lstrlen(szFullDir
) - 1] == ':')
261 lstrcat(szFullDir
, "\\");
262 Edit_SetText(hWndEdit
, szFullDir
);
264 GetScrollRange(hWndLB
, SB_VERT
, (LPINT
)&i
, (LPINT
)&index
);
266 if(!(i
== 0 && index
== 0))
267 ListBox_SetTopIndex(hWndLB
, max((int)(index
- 2), 0));
269 ListBox_SetCurSel(hWndLB
, indent
- 1);
272 static void onDrawItem(LPDRAWITEMSTRUCT lpdis
, BOOL bDrive
)
274 if((int)lpdis
->itemID
< 0)
277 char szItem
[_MAX_DIR
];
282 dwItemData
= ComboBox_GetItemData(lpdis
->hwndItem
, lpdis
->itemID
);
283 ComboBox_GetLBText(lpdis
->hwndItem
, lpdis
->itemID
, szItem
);
287 dwItemData
= ListBox_GetItemData(lpdis
->hwndItem
, lpdis
->itemID
);
288 ListBox_GetText(lpdis
->hwndItem
, lpdis
->itemID
, szItem
);
291 if(lpdis
->itemAction
& (ODA_DRAWENTIRE
| ODA_SELECT
))
295 if(lpdis
->itemState
& ODS_SELECTED
)
297 colorText
= SetTextColor(lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
298 colorBack
= SetBkColor(lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHT
));
304 int iType
=(int)HIWORD(dwItemData
);
307 case DRIVE_REMOVABLE
:
308 hIcon
= hIconDrives
[0];
311 hIcon
= hIconDrives
[1];
314 hIcon
= hIconDrives
[2];
317 hIcon
= hIconDrives
[3];
320 hIcon
= hIconDrives
[4];
327 int iconID
= (int)HIWORD(lpdis
->itemData
);
330 case ID_ICON_FOLDERCLOSED
:
331 hIcon
= hIconFolders
[0];
333 case ID_ICON_FOLDEROPEN
:
334 hIcon
= hIconFolders
[1];
336 case ID_ICON_OPENSELECT
:
337 hIcon
= hIconFolders
[2];
340 indent
= 4 * (1 + LOWORD(lpdis
->itemData
));
343 ExtTextOut(lpdis
->hDC
,
344 lpdis
->rcItem
.left
+ ITEM_LEFTMARGIN
+ ITEM_BITMAPWIDTH
+ ITEM_GAP
+ indent
,
346 ETO_OPAQUE
| ETO_CLIPPED
,
352 BOOL res
= DrawIcon(lpdis
->hDC
,
353 lpdis
->rcItem
.left
+ ITEM_LEFTMARGIN
+ indent
,
357 if(lpdis
->itemState
& ODS_SELECTED
)
359 SetTextColor(lpdis
->hDC
, colorText
);
360 SetBkColor(lpdis
->hDC
, colorBack
);
363 if((lpdis
->itemAction
& ODA_FOCUS
) || (lpdis
->itemState
& ODS_FOCUS
))
364 DrawFocusRect(lpdis
->hDC
, &lpdis
->rcItem
);
367 static void fillUNCRootArray(LPSTR lpsz
)
369 char szCurDir
[_MAX_PATH
];
370 _getcwd(szCurDir
, sizeof(szCurDir
));
371 lstrcpy(szUNCRoot
, lpsz
);
372 if(szUNCRoot
[lstrlen(szUNCRoot
) - 1] == '\\')
373 szUNCRoot
[lstrlen(szUNCRoot
) - 1] = '\0';
376 LPSTR lptemp
= strrchr(szUNCRoot
, '\\');
380 if(_chdir(szUNCRoot
) == -1)
389 static void onInitDialog(HWND hWnd
, LPSTR lpsz
)
391 hWndDirPicker
= hWnd
;
392 lpszStringToReturn
= lpsz
;
394 hIconDrives
[0] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_DRIVEFLOPPY
));
395 hIconDrives
[1] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_DRIVEHARD
));
396 hIconDrives
[2] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_DRIVENETWORK
));
397 hIconDrives
[3] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_DRIVECDROM
));
398 hIconDrives
[4] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_DRIVERAM
));
400 hIconFolders
[0] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_FOLDERCLOSED
));
401 hIconFolders
[1] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_FOLDEROPEN
));
402 hIconFolders
[2] = LoadIcon(hInst
, MAKEINTRESOURCE(ID_ICON_OPENSELECT
));
405 _getcwd(lpsz
, _MAX_PATH
);
406 else if(lpsz
[lstrlen(lpsz
) - 1] == ':')
409 int ret
= _chdir(lpsz
);
412 char szText
[_MAX_PATH
+ 80];
413 sprintf(szText
, "The specified directory %s\ncannot be found", lpsz
);
414 MessageBox(GetParent(hWnd
), szText
, "Choose Directory", MB_ICONEXCLAMATION
|MB_OK
);
415 _getcwd(lpsz
, _MAX_PATH
);
417 if((lpsz
[0] == '\\') && (lpsz
[1] == '\\'))
418 fillUNCRootArray(lpsz
);
419 fillListBox(hWnd
, lpsz
);
423 static void shutDialog(HWND hWnd
)
428 static void onCommand(HWND hWnd
, int id
, HWND hWndCtl
, UINT codeNotify
)
430 char szCurDir
[_MAX_PATH
];
434 if(codeNotify
== LBN_DBLCLK
)
436 int index
= ListBox_GetCurSel(hWndCtl
);
437 DWORD dwItemData
= ListBox_GetItemData(hWndCtl
, index
);
439 if(HIWORD(dwItemData
) == ID_ICON_OPENSELECT
)
442 char szString
[_MAX_PATH
];
443 Edit_GetText(GetDlgItem(hWndDirPicker
, ID_EDIT_DIR
), szString
, sizeof(szString
));
444 lstrcpy(lpszStringToReturn
, szString
);
445 EndDialog(hWnd
, IDOK
);
449 ListBox_GetText(hWndCtl
, index
, szCurDir
);
451 char szDir
[_MAX_DIR
];
453 if((HIWORD(dwItemData
) == ID_ICON_FOLDEROPEN
) && (index
!= 0))
455 GetWindowText(hWndCtl
, szDir
, sizeof(szDir
));
456 lpsz
=_fstrstr(szDir
, szCurDir
);
457 *(lpsz
+ lstrlen(szCurDir
)) = '\0';
458 lstrcpy(szCurDir
, szDir
);
460 if (_chdir(szCurDir
) == 0)
462 _getcwd(szCurDir
, _MAX_PATH
);
463 fillListBox(hWndDirPicker
, szCurDir
);
468 if(codeNotify
== CBN_SELCHANGE
)
471 int index
= ComboBox_GetCurSel(hWndCtl
);
474 ComboBox_GetLBText(hWndCtl
, index
, szDrive
);
476 int iCurDrive
= _getdrive();
478 HCURSOR hCursorOld
= SetCursor(LoadCursor(NULL
, IDC_WAIT
));
479 SetCapture(hWndDirPicker
);
480 if((0 == _chdrive((int)(szDrive
[0] - 'a' + 1))) && (NULL
!= _getcwd(szCurDir
, _MAX_PATH
)))
482 fillListBox(hWndDirPicker
, szCurDir
);
483 ListBox_SetTopIndex(GetDlgItem(hWndDirPicker
, ID_LIST_DIR
), 0);
484 SetCursor(hCursorOld
);
488 SetCursor(hCursorOld
);
492 sprintf(szText
, "Cannot read drive %c:", szDrive
[0]);
493 if(IDRETRY
== MessageBox(hWndDirPicker
, szText
, "Choose Directory", MB_ICONEXCLAMATION
|MB_RETRYCANCEL
))
496 //Changing drives failed so restore drive and selection
499 sprintf(szDrive
, "%c:", (char)(iCurDrive
+ 'a' - 1));
500 index
= ComboBox_SelectString(hWndCtl
, -1, szDrive
);
505 char szString
[_MAX_PATH
];
506 Edit_GetText(GetDlgItem(hWndDirPicker
, ID_EDIT_DIR
), szString
, sizeof(szString
));
507 lstrcpy(lpszStringToReturn
, szString
);
508 EndDialog(hWnd
, IDOK
);
512 lpszStringToReturn
[0] = '\0';
513 EndDialog(hWnd
, IDCANCEL
);
520 static BOOL CALLBACK
DirPickDlgProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
524 onInitDialog(hWnd
, (LPSTR
)lParam
);
527 HANDLE_WM_COMMAND(hWnd
, wParam
, lParam
, onCommand
);
531 static int cyItem
= -1; //Height of a listbox item
532 LPMEASUREITEMSTRUCT lpmis
= (LPMEASUREITEMSTRUCT
)lParam
;
535 HFONT hFont
= (HFONT
)SendMessage(hWnd
, WM_GETFONT
, 0, 0L);
537 hFont
= GetStockFont(SYSTEM_FONT
);
538 HDC hDC
= GetDC(hWnd
);
539 HFONT hFontOld
= SelectFont(hDC
, hFont
);
541 GetTextMetrics(hDC
, &tm
);
542 cyItem
= max(ITEM_BITMAPHEIGHT
, tm
.tmHeight
);
543 SelectFont(hDC
, hFontOld
);
544 ReleaseDC(hWnd
, hDC
);
547 lpmis
->itemHeight
= cyItem
;
551 onDrawItem((LPDRAWITEMSTRUCT
)lParam
, ((UINT
)wParam
== ID_COMBO_DIR
));
552 return TRUE
; // to prevent default action in listbox (drawing focus)
563 * Augments the Windows API GetDriveType with a call to the CD-ROM
564 * extensions to determine if a drive is a floppy, hard disk, CD-ROM,
565 * RAM-drive, or networked drive.
568 * iDrive UINT containing the zero-based drive index
571 * UINT One of the following values describing the drive:
572 * DRIVE_FLOPPY, DRIVE_HARD, DRIVE_CDROM, DRIVE_RAMDISK,
575 * Copyright (c)1992 Kraig Brockschmidt, All Right Reserved
576 * Compuserve: 70750,2344
577 * Internet : kraigb@microsoft.com
580 UINT
DriveType(UINT iDrive
)
582 //Validate possible drive indices
583 if((0 > iDrive
) || (25 < iDrive
))
586 static char path
[] = "d:\\";
587 path
[0] = 'a' + iDrive
;
588 int iType
= GetDriveType(path
);
591 * Under Windows NT, GetDriveType returns complete information
592 * not provided under Windows 3.x which we now get through other
599 BOOL
PickupDirectory(HWND hWndOwner
, LPSTR lpszString
)
601 if(hWndOwner
== NULL
)
602 hWndOwner
= GetDesktopWindow();
603 int ret
= DialogBoxParam(hInst
, MAKEINTRESOURCE(ID_DIALOG_CHOOSEDIR
), hWndOwner
, DirPickDlgProc
, (LPARAM
)lpszString
);
604 return (ret
== IDOK
);