⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirsel.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
字号:
/*
 * dirsel.c - Copyright (C) 1999,2000 Jay A. Key
 *
 * Directory select dialog.  Not yet implemented.
 *
 **********************************************************************
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#include <windows.h>
#include <commctrl.h>
#include "globals.h"
#include "resources.h"


typedef struct {
  BOOL bAutoCreate;
  char szIn[MAX_PATH+1];
  char szOut[MAX_PATH+1];
  HIMAGELIST hImageList;
} DIRSEL, FAR *LPDIRSEL;


BOOL CALLBACK DirSelProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
HWND CreateTreeControl( HWND hParent, LPDIRSEL lpd );
void FillTree( HWND hTree );
void AddDriveToTree( HWND hWnd, HTREEITEM hParent, char *drive, UINT dtype );
BOOL ChildExists( HWND hWnd, HTREEITEM hParent, char *fname );
void HandleTreeMessage( HWND, LPARAM );
char *GetItemPath( HWND hWnd, HTREEITEM hItem, char *path, int maxPathLen );
void ValidateSelDir( HWND hWnd );
BOOL DirExists( char * );
BOOL InvalidDir( char *szDir );
void DisplayDirInTree( char *lpszDir, HTREEITEM hParent, HWND hTreeWnd );


#define DRIVE_DIRECTORY  999


/*
 * Pops up a dialog with a tree-control that allows the selection/creation
 * of a directory.  If bAutoCreate is TRUE, the directory will automatically
 * be created when the user presses OK (user can override this behaviour)
 */
BOOL SelectDirectory( HWND hParent, LPTSTR lpszDir, int len, BOOL bAutoCreate )
{
  BOOL retVal = FALSE;
  LPDIRSEL lpDirSel;

  lpDirSel = (LPDIRSEL)GlobalAlloc( GPTR, sizeof(DIRSEL) );

  if ( !lpDirSel )
    return FALSE;

  lstrcpy( lpDirSel->szIn, lpszDir );
  lstrcpy( lpDirSel->szOut, lpszDir );
  lpDirSel->bAutoCreate = bAutoCreate;

  DialogBoxParam( ghInstance, "DirSelectDialog", hParent, (DLGPROC)DirSelProc, (LPARAM)lpDirSel );

  if ( lstrcmp( lpDirSel->szIn, lpDirSel->szOut ) )
    {
      retVal = TRUE;
      lstrcpyn( lpszDir, lpDirSel->szOut, len );

      CreateDirectory( lpszDir, NULL );
    }

  GlobalFree( (HGLOBAL)lpDirSel );

  return retVal;
}


BOOL CALLBACK DirSelProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  WORD wCtrlId;
  LPDIRSEL lpd;
  NMHDR *lpn;

  lpd = (LPDIRSEL)GetWindowLong( hWnd, GWL_USERDATA );

  switch( uMsg )
    {
    case WM_INITDIALOG:
      SetWindowLong( hWnd, GWL_USERDATA, (LONG)lParam );
      lpd = (LPDIRSEL)lParam;
      SetDlgItemText( hWnd, IDE_DIRSEL, lpd->szIn );
      CheckDlgButton( hWnd, IDCKB_AUTOCREATE, lpd->bAutoCreate?BST_CHECKED:BST_UNCHECKED );
      DisplayDirInTree( lpd->szIn, NULL, CreateTreeControl( hWnd, lpd ) );
      break;


    case WM_COMMAND:
      wCtrlId = LOWORD(wParam);
      switch( wCtrlId )
	{
	case IDCANCEL:
	case IDBN_DIRSELCANCEL:
	  EndDialog( hWnd, 0 );
	  break;

	case IDE_DIRSEL:
	  if ( HIWORD(wParam) == EN_UPDATE || HIWORD(wParam) == EN_CHANGE )
	    ValidateSelDir( hWnd );
	  break;

	case IDBN_DIRSELOK:
	  GetDlgItemText( hWnd, IDE_DIRSEL, lpd->szOut, MAX_PATH+1 );
	  EndDialog( hWnd, 0 );
	  break;

	case IDCKB_AUTOCREATE:
	  ValidateSelDir( hWnd );
	  break;
	}
      break;

    case WM_NOTIFY:
      lpn = (NMHDR *)lParam;
      if ( lpn->idFrom == ID_DIRSELTREE )
	HandleTreeMessage( lpn->hwndFrom, lParam );
      break;

    default:
      return FALSE;
    }

  // message processed
  return TRUE;
}


HWND CreateTreeControl( HWND hParent, LPDIRSEL lpd )
{
  HWND hRet;
  RECT r;

  r.left = 10;
  r.top = 24;
  r.right = 170;
  r.bottom = 160;
  MapDialogRect( hParent, &r );

  hRet = CreateWindowEx( WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
			 WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES |
			 TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS,
			 r.left, r.top, r.right - r.left, r.bottom - r.top,
			 hParent, (HMENU)ID_DIRSELTREE, ghInstance, NULL );

  if ( !hRet )
    return hRet;

  lpd->hImageList = ImageList_LoadImage( ghInstance,
					 MAKEINTRESOURCE(idImageList ),
					 16,
					 0,
					 CLR_DEFAULT,
					 IMAGE_BITMAP,
					 LR_DEFAULTCOLOR );
  TreeView_SetImageList( hRet, lpd->hImageList, TVSIL_NORMAL );

  FillTree( hRet );

  return hRet;
}



void FillTree( HWND hTree )
{
  char drive[4];
  char ch;

  for( ch = 'C'; ch <= 'Z'; ch++ )
    {
      UINT retVal;
      lstrcpy( drive, "C:\\" );
      drive[0] = ch;
      retVal = GetDriveType( drive );
      if ( ( retVal == DRIVE_FIXED ) || ( retVal == DRIVE_REMOTE ) )
	{
	  drive[2] = '\0';
	  AddDriveToTree( hTree, NULL, drive, retVal );
	}
    }
}


void AddDriveToTree( HWND hWnd, HTREEITEM hParent, char *drive, UINT dtype )
{
  TV_INSERTSTRUCT tvi;
  HTREEITEM hDriveRoot;
  HTREEITEM hItem;
  WIN32_FIND_DATA wd;
  HANDLE hFF;
  char findBuf[MAX_PATH+1];
  BOOL bFileFound;

  // add the root entry first
  if ( !hParent )
    {
      ZeroMemory( &tvi, sizeof(tvi) );
      tvi.hInsertAfter    = TVI_SORT;
      tvi.item.mask       = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
      tvi.item.stateMask  = TVIS_EXPANDED | TVIS_FOCUSED | TVIS_SELECTED;
      tvi.item.pszText    = drive;
      if ( dtype == DRIVE_FIXED )
	{
	  tvi.item.iImage     = 0;
	  tvi.item.iSelectedImage = 0;
	}
      else if ( dtype == DRIVE_REMOTE )
	{
	  tvi.item.iImage     = 1;
	  tvi.item.iSelectedImage = 1;
	}
      hDriveRoot = (HTREEITEM)TreeView_InsertItem( hWnd, &tvi );
    }
  else
    hDriveRoot = hParent;

  // add first-level subdirectories
  wsprintf( findBuf, "%s%s*.*", drive, drive[lstrlen(drive)-1]!='\\'?"\\":"" );
  hFF = FindFirstFile( findBuf, &wd );
  bFileFound = ( hFF != INVALID_HANDLE_VALUE );
  while( bFileFound )
    {
      if ( (wd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
	   lstrcmp( wd.cFileName, "." ) && lstrcmp( wd.cFileName, ".." ) )
	{
	  if ( !ChildExists( hWnd, hDriveRoot, wd.cFileName ) )
	    {
	      ZeroMemory( &tvi, sizeof(tvi) );
	      tvi.hInsertAfter      = TVI_SORT;
	      tvi.hParent           = hDriveRoot;
	      tvi.item.mask         = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
	      tvi.item.stateMask    = TVIS_EXPANDED | TVIS_FOCUSED | TVIS_SELECTED;
	      tvi.item.pszText      = wd.cFileName;
	      tvi.item.cchTextMax   = lstrlen( wd.cFileName ) + 1;
	      tvi.item.iImage       = 3;
	      tvi.item.iSelectedImage = 4;
	      hItem = (HTREEITEM)TreeView_InsertItem( hWnd, &tvi );
	    }
	}
      bFileFound = FindNextFile( hFF, &wd );
      if ( !bFileFound )
	FindClose( hFF );
    }
  // select the root item?
  hItem = (HTREEITEM)TreeView_GetChild( hWnd, hDriveRoot );
}


BOOL ChildExists( HWND hWnd, HTREEITEM hParent, char *fname )
{
  HTREEITEM hItem;
  TV_ITEM tv;
  char pszBuf[MAX_PATH+1];

  hItem = (HTREEITEM)TreeView_GetChild( hWnd, hParent );
  while( hItem )
    {
      ZeroMemory( &tv, sizeof(tv) );
      tv.mask       = TVIF_TEXT;
      tv.pszText    = pszBuf;
      tv.cchTextMax = MAX_PATH+1;
      tv.hItem      = hItem;
      if ( TreeView_GetItem( hWnd, &tv ) )
	{
	  if ( !lstrcmpi( pszBuf, fname ) )
	    return TRUE;
	}
      hItem = (HTREEITEM)TreeView_GetNextSibling( hWnd, hItem );
    }

  return FALSE;
}


void HandleTreeMessage( HWND hWnd, LPARAM lParam )
{
  LPNM_TREEVIEW lpn = (LPNM_TREEVIEW)lParam;
  char path[MAX_PATH+1];
  HTREEITEM hChild;

  switch( lpn->hdr.code )
    {
    case TVN_ITEMEXPANDING:
      // add or remove grandchildren, use lpn->action to determine
      // if it is going to expand (TVE_EXPAND) or collapse (TVE_COLLAPSE)
      if ( lpn->action & TVE_EXPAND )
	{
	  // check for new children
	  hChild = (HTREEITEM)TreeView_GetChild( hWnd, lpn->itemNew.hItem );
	  while( hChild )
	    {
	      GetItemPath( hWnd, hChild, path, MAX_PATH+1 );
	      AddDriveToTree( hWnd, hChild, path, DRIVE_DIRECTORY );
	      hChild = (HTREEITEM)TreeView_GetNextSibling( hWnd, hChild );
	    }
	}
      else  // ( lpn->action & TVE_COLLAPSE )
	{
	  hChild = (HTREEITEM)TreeView_GetChild( hWnd, lpn->itemNew.hItem );
	  while( hChild )
	    {
	      HTREEITEM hGrandchild;
	      hGrandchild = (HTREEITEM)TreeView_GetChild( hWnd, hChild );
	      while( hGrandchild )
		{
		  TreeView_DeleteItem( hWnd, hGrandchild );
		  hGrandchild = (HTREEITEM)TreeView_GetChild( hWnd, hChild );
		}
	      hChild = (HTREEITEM)TreeView_GetNextSibling( hWnd, hChild );
	    }
	}
      break;

    case TVN_SELCHANGED:
      GetItemPath( hWnd, lpn->itemNew.hItem, path, MAX_PATH+1 );
      SetDlgItemText( GetParent( hWnd ), IDE_DIRSEL, path );
      break;

    default:
      break;
    }
}


char *GetItemPath( HWND hWnd, HTREEITEM hItem, char *path, int maxPathLen )
{
  TV_ITEM tvi;
  HTREEITEM hParent;
  char pszTemp[MAX_PATH+1];

  path[0] = '\0';

  hParent = (HTREEITEM)TreeView_GetParent( hWnd, hItem );
  if ( hParent )
    GetItemPath( hWnd, hParent, path, maxPathLen );

  pszTemp[0] = '\0';
  tvi.mask       = TVIF_TEXT;
  tvi.pszText    = pszTemp;
  tvi.cchTextMax = MAX_PATH+1;
  tvi.hItem      = hItem;
  if ( TreeView_GetItem( hWnd, &tvi ) )
    {
      strcat( path, tvi.pszText );
      strcat( path, "\\" );
    }

  return path;
}


void ValidateSelDir( HWND hWnd )
{
  char buf[MAX_PATH+1];

  buf[0] = '\0';
  GetDlgItemText( hWnd, IDE_DIRSEL, buf, MAX_PATH+1 );

  if ( !buf[0] || InvalidDir( buf ) )
    {
      EnableWindow( GetDlgItem( hWnd, IDBN_DIRSELOK ), FALSE );
      return;
    }

  if ( IsDlgButtonChecked( hWnd, IDCKB_AUTOCREATE ) ||
       DirExists( buf ) )
    {
      EnableWindow( GetDlgItem( hWnd, IDBN_DIRSELOK ), TRUE );
      return;
    }

  EnableWindow( GetDlgItem( hWnd, IDBN_DIRSELOK ), FALSE );
}


/*
 * Returns TRUE if the directory szDir is not syntactically correct
 */
BOOL InvalidDir( char *szDir )
{
  return FALSE;
}


void DisplayDirInTree( char *lpszDir, HTREEITEM hParent, HWND hTreeWnd )
{
  int i;
  char *buf;
  HTREEITEM hChild;
  TV_ITEM tvi;
  char *itemBuf;
  static char foobuf[256];
  
  wsprintf( foobuf, "DisplayDirInTree( \"%s\", %04X, %04X )", lpszDir, hParent, hTreeWnd );
  OutputDebugString( foobuf );

  if ( *lpszDir == '\0' )
    {
      // display the parent item and return
      TreeView_SelectItem( hTreeWnd, hParent );
      TreeView_Expand( hTreeWnd, hParent, TVE_EXPAND );
      return;
    }

  buf = (char *)GlobalAlloc( GPTR, lstrlen( lpszDir ) + 1 );
  itemBuf = (char *)GlobalAlloc( GPTR, MAX_PATH+1 );

  lstrcpy( buf, lpszDir );
  for( i = 0; buf[i]; i++ )
    {
      if ( buf[i] == '\\' )
	buf[i] = 0;
    }

  if ( !hParent )
    {
      OutputDebugString( "Getting the parent..." );
      hChild = TreeView_GetRoot( hTreeWnd );
      TreeView_SelectItem( hTreeWnd, hChild );
    }
  else
    {
      hChild = TreeView_GetChild( hTreeWnd, hParent );
      TreeView_SelectItem( hTreeWnd, hChild );
    }

  if ( !hChild )
    OutputDebugString( "No child found..." );

  while( hChild )
    {
      tvi.mask     = TVIF_TEXT;
      tvi.pszText  = itemBuf;
      tvi.cchTextMax = MAX_PATH+1;
      tvi.hItem    = hChild;
      if ( TreeView_GetItem( hTreeWnd, &tvi ) )
	{
	  OutputDebugString( itemBuf );
	  if ( !lstrcmpi( buf, itemBuf ) )
	    {
	      DisplayDirInTree( lpszDir + lstrlen(buf) + 1, hChild, hTreeWnd );
	      hChild = NULL;
	    }
	}
      else
	OutputDebugString( "TreeView_GetItem failed!" );
      if ( hChild )
	hChild = TreeView_GetNextSibling( hTreeWnd, hChild );
    }

  GlobalFree( (HGLOBAL)buf );
  GlobalFree( (HGLOBAL)itemBuf );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -