Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

934 lines
25 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. DirBrows.H
  5. Abstract:
  6. Directory browser dialog box functions
  7. Author:
  8. Bob Watson (a-robw)
  9. Revision History:
  10. 17 Feb 94 Written
  11. --*/
  12. //
  13. // Windows Include Files
  14. //
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <malloc.h>
  18. #include <tchar.h> // unicode macros
  19. //
  20. // app include files
  21. //
  22. #include "otnboot.h"
  23. #include "otnbtdlg.h"
  24. //
  25. // static data
  26. //
  27. static PDB_DATA pDbData = NULL;
  28. static TCHAR szSaveCurrentDir[MAX_PATH];
  29. static TCHAR szReturnPath[MAX_PATH+1];
  30. static
  31. BOOL
  32. UpdateReturnPath (
  33. LPCTSTR szNewDir
  34. )
  35. /*++
  36. Routine Description:
  37. appends the "new dir" from the argument and updates the current
  38. fully qualified path in the return buffer (this is to accomodate
  39. relative directory entries (e.g. "..")).
  40. Arguments:
  41. directory to add to current path
  42. Return Value:
  43. TRUE if path updated
  44. FALSE if an error occured
  45. --*/
  46. {
  47. LPTSTR szLocalPath;
  48. DWORD dwLength;
  49. szLocalPath = GlobalAlloc (GPTR, MAX_PATH_BYTES);
  50. if (szLocalPath != NULL) {
  51. lstrcpy (szLocalPath, szReturnPath);
  52. if (szLocalPath[lstrlen(szLocalPath)-1] != cBackslash) {
  53. lstrcat (szLocalPath, cszBackslash);
  54. }
  55. lstrcat (szLocalPath, szNewDir);
  56. GetFullPathName (
  57. szLocalPath,
  58. MAX_PATH,
  59. szReturnPath,
  60. NULL);
  61. FREE_IF_ALLOC (szLocalPath);
  62. // remove trailing backslash if not the root dir
  63. dwLength = lstrlen(szReturnPath);
  64. if (dwLength > 3) {
  65. if (szReturnPath[dwLength-1] == cBackslash) {
  66. szReturnPath[dwLength-1] = 0;
  67. }
  68. }
  69. return TRUE;
  70. } else {
  71. return FALSE;
  72. }
  73. }
  74. static
  75. LPCTSTR
  76. GetDefaultDisplayDir (
  77. IN LPCTSTR szPath
  78. )
  79. /*++
  80. Routine Description:
  81. returns a valid and existing path based on the path passed in the
  82. argument list using the following logic:
  83. if szPath is valid as is, then return it
  84. else
  85. search up the path to the root until a valid dir is
  86. found in the path and return that
  87. if the path is completely bogus, then use the current
  88. default direcotry
  89. Arguments:
  90. IN LPCTSTR szPath
  91. initial path to try
  92. Return Value:
  93. pointer to read only string containg a path from the logic described
  94. above.
  95. --*/
  96. {
  97. static TCHAR szLocalPath[MAX_PATH];
  98. BOOL bFound;
  99. LONG lBsCount;
  100. LPTSTR szLastBs;
  101. LPTSTR szThisChar;
  102. LPTSTR szRootBs = NULL;
  103. if (IsPathADir(szPath)) {
  104. // this one is valid so return it
  105. lstrcpy(szLocalPath, szPath);
  106. } else if ((pDbData->Flags & PDB_FLAGS_NOCHECKDIR) == PDB_FLAGS_NOCHECKDIR) {
  107. // they don't care about a valid path so just give it back
  108. lstrcpy(szLocalPath, szPath);
  109. } else {
  110. // is this a valid DRIVE?
  111. if (MediaPresent(szPath, TRUE)) {
  112. // well the drive is valid, so start backing up the path
  113. // until a valid dir is found
  114. lstrcpy (szLocalPath, szPath); // get a local copy of the path
  115. bFound = FALSE;
  116. while (!bFound) {
  117. if (IsUncPath(szPath)) {
  118. // goto "root" backslash and save pointer
  119. lBsCount = 0;
  120. szThisChar = &szLocalPath[0];
  121. while (*szThisChar != 0) {
  122. if (*szThisChar == cBackslash) lBsCount++;
  123. if (lBsCount == 4) {
  124. szRootBs = szThisChar;
  125. break;
  126. }
  127. }
  128. if (lBsCount != 4) {
  129. // bogus path
  130. GetCurrentDirectory (MAX_PATH, szLocalPath);
  131. bFound = TRUE;
  132. } // else all should be OK so far
  133. } else {
  134. szRootBs = &szLocalPath[2]; // dos "root" backslash
  135. if (*szRootBs != cBackslash) {
  136. // then this is a bogus path so return the current
  137. GetCurrentDirectory (MAX_PATH, szLocalPath);
  138. bFound = TRUE;
  139. }
  140. }
  141. if (!bFound) {
  142. szLastBs = szThisChar = &szLocalPath[0];
  143. while (*szThisChar != 0) {
  144. if (*szThisChar == cBackslash) szLastBs = szThisChar;
  145. szThisChar++;
  146. }
  147. // szThisChar should point to the last backslash found in
  148. // the string. If this isn't the "root" backslash, then
  149. // replace it with a NULL, otherwise just use the root path
  150. if ((szThisChar != szLocalPath) && // not the beginning char
  151. (szThisChar != szRootBs)) { // not the root dir
  152. *szLastBs = 0; // terminate at the BS and see if
  153. // this is a valid dir.
  154. if (IsPathADir(szLocalPath)) {
  155. // this works so use it
  156. bFound = TRUE;
  157. }
  158. } else {
  159. // hit the root so terminate AFTER the BS and
  160. // return what's in the buffer
  161. *++szLastBs = 0;
  162. bFound = TRUE;
  163. }
  164. }
  165. }
  166. } else {
  167. // this isnt' a valid drive so load current directory
  168. GetCurrentDirectory (MAX_PATH, szLocalPath);
  169. }
  170. }
  171. return (LPCTSTR)&szLocalPath[0];
  172. }
  173. static
  174. BOOL
  175. ListDirsInEditPath (
  176. IN HWND hwndDlg,
  177. IN LPCTSTR szPath
  178. )
  179. /*++
  180. Routine Description:
  181. Loads directory list box in dialog box using dirs found in path
  182. Arguments:
  183. IN HWND hwndDlg,
  184. handle to dialog box window
  185. IN LPCTSTR szPath
  186. path to list dirs in.
  187. Return Value:
  188. TRUE if list box updated
  189. FALSE if error
  190. --*/
  191. {
  192. LPTSTR szLocalPath;
  193. szLocalPath = GlobalAlloc (GPTR, (lstrlen(szPath) + 1) * sizeof(TCHAR) );
  194. if (szLocalPath != NULL) {
  195. lstrcpy (szLocalPath, szPath);
  196. if (IsPathADir (szLocalPath)) {
  197. // make a local copy of the path since this call will modify the value
  198. if (DlgDirList (
  199. hwndDlg,
  200. szLocalPath,
  201. NCDU_DIR_LIST,
  202. NCDU_DIR_PATH,
  203. DDL_DIRECTORY | DDL_EXCLUSIVE)) {
  204. // select dir in new list
  205. SendDlgItemMessage (hwndDlg, NCDU_DIR_LIST,
  206. LB_SETCURSEL, (WPARAM)0, 0);
  207. SendDlgItemMessage (hwndDlg, NCDU_DIR_LIST,
  208. LB_SETCARETINDEX, (WPARAM)0, MAKELPARAM(TRUE,0));
  209. }
  210. } else {
  211. SendDlgItemMessage (hwndDlg, NCDU_DIR_LIST,
  212. LB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
  213. SetDlgItemText (hwndDlg, NCDU_DIR_PATH, szLocalPath);
  214. }
  215. FREE_IF_ALLOC (szLocalPath);
  216. return TRUE;
  217. } else {
  218. return FALSE;
  219. }
  220. }
  221. static
  222. LPCTSTR
  223. GetVolumeName (
  224. IN LPCTSTR szPath
  225. )
  226. /*++
  227. Routine Description:
  228. looks up the volume name (or net path for redirected dirs) and return's
  229. it to the caller. The caller is assumed to check for the existence
  230. of the path to prevent any OS errors.
  231. Arguments:
  232. IN LPCTSTR szPath
  233. path containing drive to look up
  234. Return Value:
  235. volume name string if name or path found, otherwise an
  236. empty string if an error.
  237. --*/
  238. {
  239. static TCHAR szVolumeName[MAX_PATH];
  240. TCHAR szRootDir[4];
  241. DWORD dwBufLen;
  242. szVolumeName[0] = 0; // initialize string
  243. if (!IsUncPath(szPath)) {
  244. szRootDir[0] = szPath[0]; // create DriveName and root path
  245. szRootDir[1] = cColon;
  246. szRootDir[2] = cBackslash;
  247. szRootDir[3] = 0;
  248. dwBufLen = MAX_PATH * sizeof(TCHAR);
  249. if (OnRemoteDrive (szRootDir)) {
  250. // look up server and share of redirected drive
  251. LookupRemotePath (
  252. szRootDir,
  253. szVolumeName,
  254. &dwBufLen);
  255. // remove trailing backslash
  256. if (szVolumeName[lstrlen(szVolumeName)-1] == cBackslash) {
  257. szVolumeName[lstrlen(szVolumeName)-1] = 0;
  258. }
  259. } else {
  260. // look up volume name
  261. GetVolumeInformation (
  262. szRootDir,
  263. szVolumeName,
  264. dwBufLen / sizeof(TCHAR),
  265. NULL,
  266. NULL,
  267. NULL,
  268. NULL,
  269. 0);
  270. }
  271. } else {
  272. lstrcpy (szVolumeName, szPath);
  273. }
  274. return (LPCTSTR)&szVolumeName[0];
  275. }
  276. static
  277. DWORD
  278. LoadVolumeNames (
  279. DWORD dwArg
  280. )
  281. /*++
  282. Routine Description:
  283. scans the combo box entries of the drive list and adds the
  284. corresponding volume names to the drives in the list.
  285. This routine is meant to be called by the CreateThread function.
  286. Arguments:
  287. Handle to dialog box window (passed in as a DWORD to conform to the
  288. CreateThread calling format)
  289. Return Value:
  290. ERROR_SUCCESS if successful
  291. WIN32 Error if not
  292. --*/
  293. {
  294. HWND hwndDlg;
  295. HWND hwndDriveList;
  296. LONG lItems;
  297. LONG lThisItem;
  298. LONG lCurrentSel;
  299. DWORD dwReturn;
  300. LPTSTR szListBoxText;
  301. TCHAR szRootDir[4];
  302. szListBoxText = GlobalAlloc (GPTR, MAX_PATH_BYTES);
  303. if (szListBoxText == NULL) {
  304. dwReturn = ERROR_OUTOFMEMORY;
  305. } else {
  306. hwndDlg = (HWND)ULongToPtr(dwArg);
  307. hwndDriveList = GetDlgItem (hwndDlg, NCDU_DRIVE_LIST);
  308. lItems = (LONG)SendMessage (hwndDriveList, CB_GETCOUNT, 0, 0);
  309. szRootDir[1] = cColon;
  310. szRootDir[2] = cBackslash;
  311. szRootDir[3] = 0;
  312. for (lThisItem = 0; lThisItem < lItems; lThisItem++) {
  313. lCurrentSel = (LONG)SendMessage (hwndDriveList, CB_GETCURSEL, 0, 0);
  314. *szListBoxText = 0;
  315. SendMessage (hwndDriveList, CB_GETLBTEXT,
  316. (WPARAM)lThisItem, (LPARAM)szListBoxText);
  317. szRootDir[0] = szListBoxText[0];
  318. if (MediaPresent(szRootDir, TRUE)) {
  319. lstrcpy (&szListBoxText[2], csz2Spaces);
  320. lstrcat (szListBoxText, GetVolumeName(szRootDir));
  321. SendMessage (hwndDriveList, CB_DELETESTRING, (WPARAM)lThisItem, 0);
  322. SendMessage (hwndDriveList, CB_INSERTSTRING,
  323. (WPARAM)lThisItem, (LPARAM)szListBoxText);
  324. if (lCurrentSel == lThisItem) {
  325. szRootDir[2] = 0;
  326. SendMessage (hwndDriveList, CB_SELECTSTRING, (WPARAM)-1,
  327. (LPARAM)szRootDir);
  328. szRootDir[2] = cBackslash;
  329. }
  330. }
  331. }
  332. dwReturn = ERROR_SUCCESS;
  333. }
  334. FREE_IF_ALLOC (szListBoxText);
  335. return dwReturn;
  336. }
  337. static
  338. BOOL
  339. LoadDriveList (
  340. IN HWND hwndDlg,
  341. IN LPCTSTR szPath
  342. )
  343. /*++
  344. Routine Description:
  345. initializes the drive list combo box with the drive letters of the
  346. valid drives then calls the LoadVolumeNames function as a
  347. separate thread to add the volume names.
  348. Arguments:
  349. IN HWND hwndDlg
  350. window handle of dialog box
  351. IN LPCTSTR szPath
  352. path to initialize as default
  353. Return Value:
  354. TRUE if successful
  355. FALSE if not
  356. --*/
  357. {
  358. HWND hwndDriveList;
  359. LPTSTR szDriveName;
  360. TCHAR szRootDir[4];
  361. LONG nCurrentDrive;
  362. DWORD idThread;
  363. szDriveName = GlobalAlloc (GPTR, MAX_PATH_BYTES);
  364. if (szDriveName != NULL) {
  365. hwndDriveList = GetDlgItem (hwndDlg, NCDU_DRIVE_LIST);
  366. SendMessage (hwndDriveList, CB_RESETCONTENT, 0, 0);
  367. szRootDir[0] = 0;
  368. szRootDir[1] = cColon;
  369. szRootDir[2] = cBackslash;
  370. szRootDir[3] = 0;
  371. for (szRootDir[0] = ca; szRootDir[0] <= cz; szRootDir[0] += 1) {
  372. // load floppy disks always
  373. if ((szRootDir[0] == ca) || (szRootDir[0] == cb)) {
  374. szRootDir[2] = 0; // make it just a drive
  375. SendMessage (hwndDriveList, CB_ADDSTRING, 0, (LPARAM)szRootDir);
  376. szRootDir[2] = cBackslash;
  377. } else {
  378. if (MediaPresent(szRootDir, TRUE)) {
  379. szRootDir[2] = 0; // make it just a drive
  380. SendMessage (hwndDriveList, CB_ADDSTRING, 0, (LPARAM)szRootDir);
  381. szRootDir[2] = cBackslash;
  382. }
  383. }
  384. }
  385. if (!IsUncPath(szPath)) {
  386. szRootDir[0] = szPath[0];
  387. szRootDir[1] = szPath[1];
  388. szRootDir[2] = 0;
  389. } else {
  390. GetCurrentDirectory (MAX_PATH, szDriveName);
  391. szRootDir[0] = szDriveName[0];
  392. szRootDir[1] = szDriveName[1];
  393. szRootDir[2] = 0;
  394. }
  395. _tcslwr (szRootDir);
  396. nCurrentDrive = (int)SendMessage (hwndDriveList, CB_SELECTSTRING,
  397. (WPARAM)-1, (LPARAM)szRootDir);
  398. if (nCurrentDrive == CB_ERR) {
  399. szRootDir[0] = cc;
  400. nCurrentDrive = (int)SendMessage (hwndDriveList, CB_SELECTSTRING,
  401. (WPARAM)-1, (LPARAM)szRootDir);
  402. if (nCurrentDrive == CB_ERR) {
  403. SendMessage (hwndDriveList, CB_SETCURSEL, (WPARAM)2, 0);
  404. }
  405. }
  406. }
  407. // start thread to fill in volume names
  408. CreateThread ((LPSECURITY_ATTRIBUTES)NULL, 0,
  409. (LPTHREAD_START_ROUTINE)LoadVolumeNames,
  410. (LPVOID)hwndDlg, 0, &idThread);
  411. FREE_IF_ALLOC (szDriveName);
  412. return TRUE;
  413. }
  414. static
  415. BOOL
  416. DirBrowseDlg_WM_INITDIALOG (
  417. IN HWND hwndDlg,
  418. IN WPARAM wParam,
  419. IN LPARAM lParam
  420. )
  421. /*++
  422. Routine Description:
  423. Process the WM_INITDIALOG windows message. Initializea the
  424. values in the dialog box controls to reflect the current
  425. values of browser struct passed in.
  426. Arguments:
  427. IN HWND hwndDlg
  428. handle to dialog box window
  429. IN WPARAM wParam
  430. Not Used
  431. IN LPARAM lParam
  432. address of a DIR_BROWSER_STRUCT used to pass args back & forth
  433. Return Value:
  434. FALSE
  435. --*/
  436. {
  437. TCHAR szTitle[MAX_PATH];
  438. if (lParam != 0) {
  439. pDbData = (PDB_DATA)lParam;
  440. if (pDbData->dwTitle != 0) {
  441. if (LoadString (
  442. (HINSTANCE)GetWindowLongPtr(hwndDlg, GWLP_HINSTANCE),
  443. pDbData->dwTitle,
  444. szTitle,
  445. MAX_PATH) > 0) {
  446. SetWindowText (hwndDlg, szTitle);
  447. }
  448. }
  449. // save the current directory
  450. GetCurrentDirectory (MAX_PATH, szSaveCurrentDir);
  451. if (*pDbData->szPath != 0) {
  452. lstrcpy (szReturnPath, GetDefaultDisplayDir (pDbData->szPath));
  453. } else {
  454. lstrcpy (szReturnPath, szSaveCurrentDir);
  455. }
  456. LoadDriveList (hwndDlg, szReturnPath);
  457. ListDirsInEditPath (hwndDlg, szReturnPath);
  458. SetFocus (GetDlgItem (hwndDlg, NCDU_DIR_LIST));
  459. } else {
  460. EndDialog (hwndDlg, IDCANCEL); // error
  461. }
  462. return FALSE;
  463. }
  464. static
  465. BOOL
  466. DirBrowseDlg_IDOK (
  467. IN HWND hwndDlg
  468. )
  469. /*++
  470. Routine Description:
  471. Processes the IDOK button click. Validates the entries and looks up
  472. the distribution path to try and translate it to a UNC path.
  473. Then ends the dialog and calls the next dialog box.
  474. Arguments:
  475. IN HWND hwndDlg
  476. handle to the dialog box window
  477. Return Value:
  478. FALSE
  479. --*/
  480. {
  481. lstrcpy(pDbData->szPath, szReturnPath);
  482. EndDialog (hwndDlg, IDOK);
  483. return TRUE;
  484. }
  485. static
  486. BOOL
  487. DirBrowseDlg_IDCANCEL (
  488. IN HWND hwndDlg
  489. )
  490. /*++
  491. Routine Description:
  492. ends the dialog box (and ultimately the app)
  493. Arguments:
  494. IN HWND hwndDlg
  495. Return Value:
  496. FALSE
  497. --*/
  498. {
  499. EndDialog (hwndDlg, IDCANCEL);
  500. return TRUE;
  501. }
  502. static
  503. BOOL
  504. DirBrowseDlg_WM_COMMAND (
  505. IN HWND hwndDlg,
  506. IN WPARAM wParam,
  507. IN LPARAM lParam
  508. )
  509. /*++
  510. Routine Description:
  511. Processes the WM_COMMAND windows message and dispatches to
  512. the routine that corresponds to the control issuing the
  513. message.
  514. Arguments:
  515. IN HWND hwndDlg
  516. Handle to dialog box window
  517. IN WPARAM wParam
  518. LOWORD has ID of control initiating the message
  519. IN LPARAM lParam
  520. Not Used
  521. Return Value:
  522. TRUE if message not processed by this routine, otherwise the
  523. value of the dispatched routine .
  524. --*/
  525. {
  526. LPTSTR szTempPath;
  527. BOOL bCheckDrive;
  528. BOOL bNewDriveOk;
  529. UINT nMessageBoxButton;
  530. switch (LOWORD(wParam)) {
  531. case IDCANCEL: return DirBrowseDlg_IDCANCEL (hwndDlg);
  532. case IDOK: return DirBrowseDlg_IDOK (hwndDlg);
  533. case NCDU_DIR_LIST:
  534. // test notification message
  535. switch (HIWORD(wParam)) {
  536. case LBN_DBLCLK:
  537. if (SendDlgItemMessage(hwndDlg, NCDU_DIR_LIST,
  538. LB_GETCOUNT, 0, 0) > 0) {
  539. szTempPath = GlobalAlloc (GPTR, MAX_PATH_BYTES);
  540. if (szTempPath != NULL) {
  541. // there's items in the list box and the
  542. // selection changed so update dlg contents
  543. DlgDirSelectEx (
  544. hwndDlg,
  545. szTempPath,
  546. MAX_PATH,
  547. NCDU_DIR_LIST);
  548. UpdateReturnPath (szTempPath);
  549. ListDirsInEditPath (
  550. hwndDlg,
  551. szReturnPath);
  552. FREE_IF_ALLOC (szTempPath);
  553. return TRUE;
  554. } else {
  555. // unable to allocate memory
  556. return FALSE;
  557. }
  558. } else {
  559. // no list box items
  560. return FALSE;
  561. }
  562. default:
  563. return FALSE;
  564. }
  565. case NCDU_DRIVE_LIST:
  566. switch (HIWORD(wParam)) {
  567. case CBN_SELCHANGE:
  568. case CBN_DBLCLK:
  569. szTempPath = GlobalAlloc (GPTR, MAX_PATH_BYTES);
  570. if (szTempPath != NULL) {
  571. SendDlgItemMessage (hwndDlg, NCDU_DRIVE_LIST,
  572. WM_GETTEXT, (WPARAM)MAX_PATH,
  573. (LPARAM)szTempPath);
  574. szTempPath[2] = cBackslash;
  575. szTempPath[3] = 0;
  576. if ((pDbData->Flags & PDB_FLAGS_NOCHECKDIR) == PDB_FLAGS_NOCHECKDIR) {
  577. bCheckDrive = FALSE;
  578. bNewDriveOk = TRUE;
  579. } else {
  580. bCheckDrive = TRUE;
  581. bNewDriveOk = FALSE;
  582. }
  583. while (bCheckDrive) {
  584. if (!MediaPresent(szTempPath, TRUE)) {
  585. nMessageBoxButton = DisplayMessageBox (
  586. hwndDlg,
  587. NCDU_DRIVE_NOT_AVAILABLE,
  588. 0,
  589. MB_ICONEXCLAMATION | MB_RETRYCANCEL | MB_TASKMODAL);
  590. if (nMessageBoxButton == IDCANCEL) {
  591. bCheckDrive = FALSE;
  592. bNewDriveOk = FALSE;
  593. }
  594. } else {
  595. bCheckDrive = FALSE;
  596. bNewDriveOk = TRUE;
  597. }
  598. }
  599. if (bNewDriveOk) {
  600. // update dir list for new drive
  601. lstrcpy (szReturnPath, szTempPath);
  602. ListDirsInEditPath (
  603. hwndDlg,
  604. szReturnPath);
  605. } else {
  606. // reset drive list selection
  607. szTempPath[0] = szReturnPath[0];
  608. szTempPath[1] = cColon;
  609. szTempPath[2] = 0;
  610. SendDlgItemMessage (hwndDlg, NCDU_DRIVE_LIST,
  611. CB_SELECTSTRING, (WPARAM)-1, (LPARAM)szTempPath);
  612. }
  613. FREE_IF_ALLOC (szTempPath);
  614. return TRUE;
  615. } else {
  616. return FALSE;
  617. }
  618. default:
  619. return FALSE;
  620. }
  621. case NCDU_BROWSE_NETWORK:
  622. WNetConnectionDialog (hwndDlg, RESOURCETYPE_DISK);
  623. // update dir list
  624. LoadDriveList (hwndDlg, szReturnPath);
  625. ListDirsInEditPath (hwndDlg, szReturnPath);
  626. return TRUE;
  627. default:
  628. return FALSE;
  629. }
  630. }
  631. static
  632. BOOL
  633. DirBrowseDlg_WM_VKEYTOITEM (
  634. IN HWND hwndDlg,
  635. IN WPARAM wParam,
  636. IN LPARAM lParam
  637. )
  638. /*++
  639. Routine Description:
  640. Processes the WM_COMMAND windows message and dispatches to
  641. the routine that corresponds to the control issuing the
  642. message.
  643. Arguments:
  644. IN HWND hwndDlg
  645. Handle to dialog box window
  646. IN WPARAM wParam
  647. LOWORD has Virtual Key code of key pressed
  648. HIWORD has current caret position
  649. IN LPARAM lParam
  650. Handle of list box issuing message
  651. Return Value:
  652. -2 if no further action required by DefWindowProc
  653. -1 if default action for key should be taken by DefWindowProc
  654. >=0 if default action should be take on the n'th item in the list
  655. --*/
  656. {
  657. HWND hwndListBox;
  658. WORD wCaretPos = 0;
  659. int nLbItemCount = 0;
  660. BOOL bSetCaretPos = FALSE;
  661. int nReturn;
  662. LPTSTR szTempPath;
  663. hwndListBox = GetDlgItem(hwndDlg, NCDU_DIR_LIST);
  664. if ((HWND)lParam == hwndListBox) {
  665. // this is from the dir list box
  666. wCaretPos = HIWORD(wParam);
  667. switch (LOWORD(wParam)) {
  668. // take action on specific key code.
  669. case VK_UP:
  670. case VK_LEFT:
  671. // go up one item if not at top
  672. if (wCaretPos > 0){
  673. wCaretPos -= 1; // decrement one
  674. }
  675. bSetCaretPos = TRUE;
  676. nReturn = -2;
  677. break;
  678. case VK_RIGHT:
  679. case VK_DOWN:
  680. // go down one if not at bottom
  681. nLbItemCount = (int)SendDlgItemMessage (
  682. hwndDlg, NCDU_DIR_LIST, LB_GETCOUNT, 0, 0);
  683. // adjust to be Max Index
  684. nLbItemCount -= 1;
  685. if ((int)wCaretPos < nLbItemCount) {
  686. wCaretPos += 1;
  687. }
  688. bSetCaretPos = TRUE;
  689. nReturn = -2;
  690. break;
  691. case VK_SPACE:
  692. if (SendDlgItemMessage(hwndDlg, NCDU_DIR_LIST,
  693. LB_GETCOUNT, 0, 0) > 0) {
  694. szTempPath = GlobalAlloc (GPTR, MAX_PATH_BYTES);
  695. if (szTempPath != NULL) {
  696. // select this item
  697. DlgDirSelectEx (
  698. hwndDlg,
  699. szTempPath,
  700. MAX_PATH,
  701. NCDU_DIR_LIST);
  702. UpdateReturnPath (szTempPath);
  703. ListDirsInEditPath (hwndDlg, szReturnPath);
  704. bSetCaretPos = FALSE;
  705. FREE_IF_ALLOC (szTempPath);
  706. }
  707. } else {
  708. // no items in list box so ignore.
  709. }
  710. nReturn = -2;
  711. break;
  712. default:
  713. bSetCaretPos = FALSE;
  714. nReturn = -1;
  715. break;
  716. }
  717. if (bSetCaretPos) {
  718. SendDlgItemMessage (hwndDlg, NCDU_DIR_LIST,
  719. LB_SETCURSEL, (WPARAM)wCaretPos, 0);
  720. SendDlgItemMessage (hwndDlg, NCDU_DIR_LIST,
  721. LB_SETCARETINDEX, (WPARAM)wCaretPos, MAKELPARAM(TRUE,0));
  722. }
  723. return (BOOL)nReturn;
  724. } else {
  725. return (BOOL)-1;
  726. }
  727. }
  728. INT_PTR CALLBACK
  729. DirBrowseDlgProc (
  730. IN HWND hwndDlg,
  731. IN UINT message,
  732. IN WPARAM wParam,
  733. IN LPARAM lParam
  734. )
  735. /*++
  736. Routine Description:
  737. Main Dialog Box Window Procedure for the Initial configuration screen
  738. Processes the following windows messages by dispatching the
  739. appropriate routine.
  740. WM_INITDIALOG: dialog box initialization
  741. WM_COMMAND: user input
  742. All other windows messages are processed by the default dialog box
  743. procedure.
  744. Arguments:
  745. Standard WNDPROC arguments
  746. Return Value:
  747. FALSE if the message is not processed by this routine, otherwise the
  748. value returned by the dispatched routine.
  749. --*/
  750. {
  751. switch (message) {
  752. case WM_INITDIALOG: return (DirBrowseDlg_WM_INITDIALOG (hwndDlg, wParam, lParam));
  753. case WM_COMMAND: return (DirBrowseDlg_WM_COMMAND (hwndDlg, wParam, lParam));
  754. case WM_VKEYTOITEM: return (DirBrowseDlg_WM_VKEYTOITEM (hwndDlg, wParam, lParam));
  755. case WM_DESTROY:
  756. SetCurrentDirectory (szSaveCurrentDir);
  757. return TRUE;
  758. default: return FALSE;
  759. }
  760. }