dirsel.c
上传用户:xmgzy123
上传日期:2007-01-07
资源大小:373k
文件大小:12k
源码类别:

SCSI/ASPI

开发平台:

WINDOWS

  1. /*
  2.  * dirsel.c - Copyright (C) 1999,2000 Jay A. Key
  3.  *
  4.  * Directory select dialog.  Not yet implemented.
  5.  *
  6.  **********************************************************************
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21.  *
  22.  */
  23. #include <windows.h>
  24. #include <commctrl.h>
  25. #include "globals.h"
  26. #include "resources.h"
  27. typedef struct {
  28.   BOOL bAutoCreate;
  29.   char szIn[MAX_PATH+1];
  30.   char szOut[MAX_PATH+1];
  31.   HIMAGELIST hImageList;
  32. } DIRSEL, FAR *LPDIRSEL;
  33. BOOL CALLBACK DirSelProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  34. HWND CreateTreeControl( HWND hParent, LPDIRSEL lpd );
  35. void FillTree( HWND hTree );
  36. void AddDriveToTree( HWND hWnd, HTREEITEM hParent, char *drive, UINT dtype );
  37. BOOL ChildExists( HWND hWnd, HTREEITEM hParent, char *fname );
  38. void HandleTreeMessage( HWND, LPARAM );
  39. char *GetItemPath( HWND hWnd, HTREEITEM hItem, char *path, int maxPathLen );
  40. void ValidateSelDir( HWND hWnd );
  41. BOOL DirExists( char * );
  42. BOOL InvalidDir( char *szDir );
  43. void DisplayDirInTree( char *lpszDir, HTREEITEM hParent, HWND hTreeWnd );
  44. #define DRIVE_DIRECTORY  999
  45. /*
  46.  * Pops up a dialog with a tree-control that allows the selection/creation
  47.  * of a directory.  If bAutoCreate is TRUE, the directory will automatically
  48.  * be created when the user presses OK (user can override this behaviour)
  49.  */
  50. BOOL SelectDirectory( HWND hParent, LPTSTR lpszDir, int len, BOOL bAutoCreate )
  51. {
  52.   BOOL retVal = FALSE;
  53.   LPDIRSEL lpDirSel;
  54.   lpDirSel = (LPDIRSEL)GlobalAlloc( GPTR, sizeof(DIRSEL) );
  55.   if ( !lpDirSel )
  56.     return FALSE;
  57.   lstrcpy( lpDirSel->szIn, lpszDir );
  58.   lstrcpy( lpDirSel->szOut, lpszDir );
  59.   lpDirSel->bAutoCreate = bAutoCreate;
  60.   DialogBoxParam( ghInstance, "DirSelectDialog", hParent, (DLGPROC)DirSelProc, (LPARAM)lpDirSel );
  61.   if ( lstrcmp( lpDirSel->szIn, lpDirSel->szOut ) )
  62.     {
  63.       retVal = TRUE;
  64.       lstrcpyn( lpszDir, lpDirSel->szOut, len );
  65.       CreateDirectory( lpszDir, NULL );
  66.     }
  67.   GlobalFree( (HGLOBAL)lpDirSel );
  68.   return retVal;
  69. }
  70. BOOL CALLBACK DirSelProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  71. {
  72.   WORD wCtrlId;
  73.   LPDIRSEL lpd;
  74.   NMHDR *lpn;
  75.   lpd = (LPDIRSEL)GetWindowLong( hWnd, GWL_USERDATA );
  76.   switch( uMsg )
  77.     {
  78.     case WM_INITDIALOG:
  79.       SetWindowLong( hWnd, GWL_USERDATA, (LONG)lParam );
  80.       lpd = (LPDIRSEL)lParam;
  81.       SetDlgItemText( hWnd, IDE_DIRSEL, lpd->szIn );
  82.       CheckDlgButton( hWnd, IDCKB_AUTOCREATE, lpd->bAutoCreate?BST_CHECKED:BST_UNCHECKED );
  83.       DisplayDirInTree( lpd->szIn, NULL, CreateTreeControl( hWnd, lpd ) );
  84.       break;
  85.     case WM_COMMAND:
  86.       wCtrlId = LOWORD(wParam);
  87.       switch( wCtrlId )
  88. {
  89. case IDCANCEL:
  90. case IDBN_DIRSELCANCEL:
  91.   EndDialog( hWnd, 0 );
  92.   break;
  93. case IDE_DIRSEL:
  94.   if ( HIWORD(wParam) == EN_UPDATE || HIWORD(wParam) == EN_CHANGE )
  95.     ValidateSelDir( hWnd );
  96.   break;
  97. case IDBN_DIRSELOK:
  98.   GetDlgItemText( hWnd, IDE_DIRSEL, lpd->szOut, MAX_PATH+1 );
  99.   EndDialog( hWnd, 0 );
  100.   break;
  101. case IDCKB_AUTOCREATE:
  102.   ValidateSelDir( hWnd );
  103.   break;
  104. }
  105.       break;
  106.     case WM_NOTIFY:
  107.       lpn = (NMHDR *)lParam;
  108.       if ( lpn->idFrom == ID_DIRSELTREE )
  109. HandleTreeMessage( lpn->hwndFrom, lParam );
  110.       break;
  111.     default:
  112.       return FALSE;
  113.     }
  114.   // message processed
  115.   return TRUE;
  116. }
  117. HWND CreateTreeControl( HWND hParent, LPDIRSEL lpd )
  118. {
  119.   HWND hRet;
  120.   RECT r;
  121.   r.left = 10;
  122.   r.top = 24;
  123.   r.right = 170;
  124.   r.bottom = 160;
  125.   MapDialogRect( hParent, &r );
  126.   hRet = CreateWindowEx( WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
  127.  WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES |
  128.  TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS,
  129.  r.left, r.top, r.right - r.left, r.bottom - r.top,
  130.  hParent, (HMENU)ID_DIRSELTREE, ghInstance, NULL );
  131.   if ( !hRet )
  132.     return hRet;
  133.   lpd->hImageList = ImageList_LoadImage( ghInstance,
  134.  MAKEINTRESOURCE(idImageList ),
  135.  16,
  136.  0,
  137.  CLR_DEFAULT,
  138.  IMAGE_BITMAP,
  139.  LR_DEFAULTCOLOR );
  140.   TreeView_SetImageList( hRet, lpd->hImageList, TVSIL_NORMAL );
  141.   FillTree( hRet );
  142.   return hRet;
  143. }
  144. void FillTree( HWND hTree )
  145. {
  146.   char drive[4];
  147.   char ch;
  148.   for( ch = 'C'; ch <= 'Z'; ch++ )
  149.     {
  150.       UINT retVal;
  151.       lstrcpy( drive, "C:\" );
  152.       drive[0] = ch;
  153.       retVal = GetDriveType( drive );
  154.       if ( ( retVal == DRIVE_FIXED ) || ( retVal == DRIVE_REMOTE ) )
  155. {
  156.   drive[2] = '';
  157.   AddDriveToTree( hTree, NULL, drive, retVal );
  158. }
  159.     }
  160. }
  161. void AddDriveToTree( HWND hWnd, HTREEITEM hParent, char *drive, UINT dtype )
  162. {
  163.   TV_INSERTSTRUCT tvi;
  164.   HTREEITEM hDriveRoot;
  165.   HTREEITEM hItem;
  166.   WIN32_FIND_DATA wd;
  167.   HANDLE hFF;
  168.   char findBuf[MAX_PATH+1];
  169.   BOOL bFileFound;
  170.   // add the root entry first
  171.   if ( !hParent )
  172.     {
  173.       ZeroMemory( &tvi, sizeof(tvi) );
  174.       tvi.hInsertAfter    = TVI_SORT;
  175.       tvi.item.mask       = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  176.       tvi.item.stateMask  = TVIS_EXPANDED | TVIS_FOCUSED | TVIS_SELECTED;
  177.       tvi.item.pszText    = drive;
  178.       if ( dtype == DRIVE_FIXED )
  179. {
  180.   tvi.item.iImage     = 0;
  181.   tvi.item.iSelectedImage = 0;
  182. }
  183.       else if ( dtype == DRIVE_REMOTE )
  184. {
  185.   tvi.item.iImage     = 1;
  186.   tvi.item.iSelectedImage = 1;
  187. }
  188.       hDriveRoot = (HTREEITEM)TreeView_InsertItem( hWnd, &tvi );
  189.     }
  190.   else
  191.     hDriveRoot = hParent;
  192.   // add first-level subdirectories
  193.   wsprintf( findBuf, "%s%s*.*", drive, drive[lstrlen(drive)-1]!='\'?"\":"" );
  194.   hFF = FindFirstFile( findBuf, &wd );
  195.   bFileFound = ( hFF != INVALID_HANDLE_VALUE );
  196.   while( bFileFound )
  197.     {
  198.       if ( (wd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  199.    lstrcmp( wd.cFileName, "." ) && lstrcmp( wd.cFileName, ".." ) )
  200. {
  201.   if ( !ChildExists( hWnd, hDriveRoot, wd.cFileName ) )
  202.     {
  203.       ZeroMemory( &tvi, sizeof(tvi) );
  204.       tvi.hInsertAfter      = TVI_SORT;
  205.       tvi.hParent           = hDriveRoot;
  206.       tvi.item.mask         = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  207.       tvi.item.stateMask    = TVIS_EXPANDED | TVIS_FOCUSED | TVIS_SELECTED;
  208.       tvi.item.pszText      = wd.cFileName;
  209.       tvi.item.cchTextMax   = lstrlen( wd.cFileName ) + 1;
  210.       tvi.item.iImage       = 3;
  211.       tvi.item.iSelectedImage = 4;
  212.       hItem = (HTREEITEM)TreeView_InsertItem( hWnd, &tvi );
  213.     }
  214. }
  215.       bFileFound = FindNextFile( hFF, &wd );
  216.       if ( !bFileFound )
  217. FindClose( hFF );
  218.     }
  219.   // select the root item?
  220.   hItem = (HTREEITEM)TreeView_GetChild( hWnd, hDriveRoot );
  221. }
  222. BOOL ChildExists( HWND hWnd, HTREEITEM hParent, char *fname )
  223. {
  224.   HTREEITEM hItem;
  225.   TV_ITEM tv;
  226.   char pszBuf[MAX_PATH+1];
  227.   hItem = (HTREEITEM)TreeView_GetChild( hWnd, hParent );
  228.   while( hItem )
  229.     {
  230.       ZeroMemory( &tv, sizeof(tv) );
  231.       tv.mask       = TVIF_TEXT;
  232.       tv.pszText    = pszBuf;
  233.       tv.cchTextMax = MAX_PATH+1;
  234.       tv.hItem      = hItem;
  235.       if ( TreeView_GetItem( hWnd, &tv ) )
  236. {
  237.   if ( !lstrcmpi( pszBuf, fname ) )
  238.     return TRUE;
  239. }
  240.       hItem = (HTREEITEM)TreeView_GetNextSibling( hWnd, hItem );
  241.     }
  242.   return FALSE;
  243. }
  244. void HandleTreeMessage( HWND hWnd, LPARAM lParam )
  245. {
  246.   LPNM_TREEVIEW lpn = (LPNM_TREEVIEW)lParam;
  247.   char path[MAX_PATH+1];
  248.   HTREEITEM hChild;
  249.   switch( lpn->hdr.code )
  250.     {
  251.     case TVN_ITEMEXPANDING:
  252.       // add or remove grandchildren, use lpn->action to determine
  253.       // if it is going to expand (TVE_EXPAND) or collapse (TVE_COLLAPSE)
  254.       if ( lpn->action & TVE_EXPAND )
  255. {
  256.   // check for new children
  257.   hChild = (HTREEITEM)TreeView_GetChild( hWnd, lpn->itemNew.hItem );
  258.   while( hChild )
  259.     {
  260.       GetItemPath( hWnd, hChild, path, MAX_PATH+1 );
  261.       AddDriveToTree( hWnd, hChild, path, DRIVE_DIRECTORY );
  262.       hChild = (HTREEITEM)TreeView_GetNextSibling( hWnd, hChild );
  263.     }
  264. }
  265.       else  // ( lpn->action & TVE_COLLAPSE )
  266. {
  267.   hChild = (HTREEITEM)TreeView_GetChild( hWnd, lpn->itemNew.hItem );
  268.   while( hChild )
  269.     {
  270.       HTREEITEM hGrandchild;
  271.       hGrandchild = (HTREEITEM)TreeView_GetChild( hWnd, hChild );
  272.       while( hGrandchild )
  273. {
  274.   TreeView_DeleteItem( hWnd, hGrandchild );
  275.   hGrandchild = (HTREEITEM)TreeView_GetChild( hWnd, hChild );
  276. }
  277.       hChild = (HTREEITEM)TreeView_GetNextSibling( hWnd, hChild );
  278.     }
  279. }
  280.       break;
  281.     case TVN_SELCHANGED:
  282.       GetItemPath( hWnd, lpn->itemNew.hItem, path, MAX_PATH+1 );
  283.       SetDlgItemText( GetParent( hWnd ), IDE_DIRSEL, path );
  284.       break;
  285.     default:
  286.       break;
  287.     }
  288. }
  289. char *GetItemPath( HWND hWnd, HTREEITEM hItem, char *path, int maxPathLen )
  290. {
  291.   TV_ITEM tvi;
  292.   HTREEITEM hParent;
  293.   char pszTemp[MAX_PATH+1];
  294.   path[0] = '';
  295.   hParent = (HTREEITEM)TreeView_GetParent( hWnd, hItem );
  296.   if ( hParent )
  297.     GetItemPath( hWnd, hParent, path, maxPathLen );
  298.   pszTemp[0] = '';
  299.   tvi.mask       = TVIF_TEXT;
  300.   tvi.pszText    = pszTemp;
  301.   tvi.cchTextMax = MAX_PATH+1;
  302.   tvi.hItem      = hItem;
  303.   if ( TreeView_GetItem( hWnd, &tvi ) )
  304.     {
  305.       strcat( path, tvi.pszText );
  306.       strcat( path, "\" );
  307.     }
  308.   return path;
  309. }
  310. void ValidateSelDir( HWND hWnd )
  311. {
  312.   char buf[MAX_PATH+1];
  313.   buf[0] = '';
  314.   GetDlgItemText( hWnd, IDE_DIRSEL, buf, MAX_PATH+1 );
  315.   if ( !buf[0] || InvalidDir( buf ) )
  316.     {
  317.       EnableWindow( GetDlgItem( hWnd, IDBN_DIRSELOK ), FALSE );
  318.       return;
  319.     }
  320.   if ( IsDlgButtonChecked( hWnd, IDCKB_AUTOCREATE ) ||
  321.        DirExists( buf ) )
  322.     {
  323.       EnableWindow( GetDlgItem( hWnd, IDBN_DIRSELOK ), TRUE );
  324.       return;
  325.     }
  326.   EnableWindow( GetDlgItem( hWnd, IDBN_DIRSELOK ), FALSE );
  327. }
  328. /*
  329.  * Returns TRUE if the directory szDir is not syntactically correct
  330.  */
  331. BOOL InvalidDir( char *szDir )
  332. {
  333.   return FALSE;
  334. }
  335. void DisplayDirInTree( char *lpszDir, HTREEITEM hParent, HWND hTreeWnd )
  336. {
  337.   int i;
  338.   char *buf;
  339.   HTREEITEM hChild;
  340.   TV_ITEM tvi;
  341.   char *itemBuf;
  342.   static char foobuf[256];
  343.   
  344.   wsprintf( foobuf, "DisplayDirInTree( "%s", %04X, %04X )", lpszDir, hParent, hTreeWnd );
  345.   OutputDebugString( foobuf );
  346.   if ( *lpszDir == '' )
  347.     {
  348.       // display the parent item and return
  349.       TreeView_SelectItem( hTreeWnd, hParent );
  350.       TreeView_Expand( hTreeWnd, hParent, TVE_EXPAND );
  351.       return;
  352.     }
  353.   buf = (char *)GlobalAlloc( GPTR, lstrlen( lpszDir ) + 1 );
  354.   itemBuf = (char *)GlobalAlloc( GPTR, MAX_PATH+1 );
  355.   lstrcpy( buf, lpszDir );
  356.   for( i = 0; buf[i]; i++ )
  357.     {
  358.       if ( buf[i] == '\' )
  359. buf[i] = 0;
  360.     }
  361.   if ( !hParent )
  362.     {
  363.       OutputDebugString( "Getting the parent..." );
  364.       hChild = TreeView_GetRoot( hTreeWnd );
  365.       TreeView_SelectItem( hTreeWnd, hChild );
  366.     }
  367.   else
  368.     {
  369.       hChild = TreeView_GetChild( hTreeWnd, hParent );
  370.       TreeView_SelectItem( hTreeWnd, hChild );
  371.     }
  372.   if ( !hChild )
  373.     OutputDebugString( "No child found..." );
  374.   while( hChild )
  375.     {
  376.       tvi.mask     = TVIF_TEXT;
  377.       tvi.pszText  = itemBuf;
  378.       tvi.cchTextMax = MAX_PATH+1;
  379.       tvi.hItem    = hChild;
  380.       if ( TreeView_GetItem( hTreeWnd, &tvi ) )
  381. {
  382.   OutputDebugString( itemBuf );
  383.   if ( !lstrcmpi( buf, itemBuf ) )
  384.     {
  385.       DisplayDirInTree( lpszDir + lstrlen(buf) + 1, hChild, hTreeWnd );
  386.       hChild = NULL;
  387.     }
  388. }
  389.       else
  390. OutputDebugString( "TreeView_GetItem failed!" );
  391.       if ( hChild )
  392. hChild = TreeView_GetNextSibling( hTreeWnd, hChild );
  393.     }
  394.   GlobalFree( (HGLOBAL)buf );
  395.   GlobalFree( (HGLOBAL)itemBuf );
  396. }