Bonjour,
Voici un listeur de fichiers réalisé dans le cadre d'un *petit* concours de programmation.
J'ai rajouté des petites fonctions basiques au listeur de fichier demandé. Mon programme liste séparément fichiers et dossiers. On peut naviguer sur tous les disques durs de l'ordinateur. Pour les fichiers, on peut l'ouvrir en lecture et voir quelques infos sur lui.
Pour certaines extensions, la vue du fichier ne fonctionne pas, ce qui est compréhensible. Pour y remédier, j'ai codé une sorte de filtre d'extensions.
Dans tous les cas, j'ai essayé d'utiliser des trucs courants en prog Win32 :
- Le sous classement de l'Edit où l'on peut rentrer le chemin du dossier à lister. Il s'agit de filtrer les messages et de voir si on appuie sur la touche <Entrée>. On fais suivre les autres si ce n'est pas le cas.
- Obtenir la liste des lecteurs d'un disque.
- Mapper un fichier en mémoire
- Réaction à un click sur une zone du Dialog. J'ai codé ça peut être un peu n'importe comment. Je voyais pas trop comment le faire sinon.
- L'obtention d'informations sur des fichiers. Ici j'ai affiché les dates (création/modification/dernier accès). On utilise une structure BY_HANDLE_FILE_INFORMATION et une SYSTEMTIME
Le projet VC++6 se trouve dans le zip
Voici le code du fichier principal : lister.cpp
Source / Exemple :
/************************************************************************************************
File Browser v1.03 by BiGBANG
-----------------------------
SecurityHack Programming Contest, August 2oo4
History :
---------
v1.03
- Filters for visualisation of files
- Two languages interface : French and English
v1.02
- File visualisation. Filter needed
v1.01
- Subclassing
- Numbers of Folders/Files
- File Informations
- Bitmap/AboutBox
v1.00
- File Browser only :)
#include <stdio.h> // sprintf(),...
#include <windows.h>
#include "resource.h"
HINSTANCE hinst;
WNDPROC oldProc; // orignal proc
HWND hcmb,hlistFiles,hlistFolders,hMainDlg;
char buf[MAX_PATH];
char CurrentFile[MAX_PATH];
char FileExt[8],buf2[8];
char c;
char *sz;
int i;
int xPos,yPos,nbFiles,nbFolders;
// Eextension Filter
char *ExtensionsOK="txt,bat,ini,c,cpp,asm,log,rc,res,dat,"; // a coma between them
// a terminal coma
/*
// French
char AppTitle[]="Listeur de fichiers v1.03 - BiGBANG - Security Hack Concours - 17/08/2004";
char AppDisks[]="Liste des lecteurs :";
char AppToList[]="Répertoire à lister :";
char AppNumFolders[]="Nombre de dossiers :";
char AppNumFiles[]="Nombre de fichiers :";
char AppName[]="Nom :";
char AppFileSize[]="Taille";
char AppFileCreation[]="Date de création";
char AppLastWrite[]="Date de denier écriture";
char AppLastAccess[]="Date de denier accès";
char AppDateFormat[]="Format de la date : jj/mm/aaaa";
char SeeFileTitle[]="Vue de fichiers";
char SeeFileCurrentFile[]="Fichier en cours";
char MsgError1[]="Le fichier n'existe pas";
char MsgError2[]="Impossible de mapper le fichier";
char MsgError3[]="Impossible de mapper le fichier. Fichier vide ?";
char MsgError4[]="Aucun lecteur trouvé. Le programme va se fermer.";
char MsgError5[]="Dossier inexistant";
char MsgError6[]="L'extension de ce fichier n'autorise pas sa visualisation.";
char AboutText[]="Listeur de fichiers pour le concours de programmation sur le forum de SecurityHack\n\nAuteur: Bigbang\nLangage: Win32Cpp\nDernière MAJ: 17 Août 2004\n\nGreetings to:\nCharlotte, Shad0w, P41f0x, Neitsa, Sigma, Nelio, Xiutecutli, le_rasta, Dark-Jedi,\nsn0oPy, Mattwood9, les challenges du BigContest, et tout ceux que j'ai oublié...";
char AboutTitle[]="A propos...";
/*
// English
char AppTitle[]="File Browser v1.03 - BiGBANG - Security Hack Contest - 17/08/2004";
char AppDisks[]="List of drives:";
char AppToList[]="Folder to list :";
char AppNumFolders[]="Number of folders :";
char AppNumFiles[]="Number of files :";
char AppName[]="Name :";
char AppFileSize[]="Size";
char AppFileCreation[]="Create on the";
char AppLastWrite[]="Last write on the";
char AppLastAccess[]="Last access on the";
char AppDateFormat[]="Date format : dd/mm/yyyy";
char SeeFileTitle[]="File Visualisation";
char SeeFileCurrentFile[]="Current File";
char MsgError1[]="File doesn't exist";
char MsgError2[]="File mapping failed";
char MsgError3[]="File mapping failed. Maybe the file is empty";
char MsgError4[]="0 drives found. Program will end";
char MsgError5[]="Folder doesn't exist";
char MsgError6[]="The extension of this file doesn't match for visualisation";
char AboutText[]="File browser for SecurityHack Programming contest\n\nAuthor: Bigbang\nLanguage: Win32Cpp\nLast update: 17 Août 2004\n\nGreetings to:\nCharlotte, Shad0w, P41f0x, Neitsa, Sigma, Nelio, Xiutecutli, le_rasta, Dark-Jedi,\nsn0oPy, Mattwood9, BigContest's challengers, and all I forgot...";
char AboutTitle[]="About...";
/*
- Find drive(s) and Fill Combo Box
-
- Return Value:
- number of drive(s)
- /
int __stdcall FillCmbDrives()
{
DWORD dwResult;
int nb=0;
char szDrive[]="A:\\";
/******** MSDN says : ***************
Thee GetLogicalDrives function retrieves a bitmask representing the currently
available disk drives.
DWORD GetLogicalDrives(void);
Parameters
This function has no parameters.
Return Values
If the function succeeds, the return value is a bitmask representing the currently
available disk drives. Bit position 0 (the least-significant bit) is drive A,
bit position 1 is drive B, bit position 2 is drive C, and so on.
---
DRIVE_FIXED The disk cannot be removed from the drive.
dwResult = GetLogicalDrives();
// if(dwResult==0) return 0;
while(dwResult!=0)
{
// only one BYTE
if((dwResult&1)&&(GetDriveType(szDrive)==DRIVE_FIXED)) SendMessage(hcmb,CB_ADDSTRING,0,(long)szDrive);
szDrive[0]++; // A, B, C, ...
nb++;
dwResult=dwResult>>1; // shr dwResult, 1
}
SendMessage(hcmb, CB_SETCURSEL, 0, 0); // selection on first item
return nb;
}
/*
- NB: Modified proc seen in MSDN samples
-
- Get dir, and list files/subdirs
- it uses FindFirstFile/FindNextFile method
*
- Return value : 0 Error
- 1 w00t!
- /
int __stdcall ListFiles(HWND hdlg)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
char DirSpec[MAX_PATH]; // directory specification
DWORD dwError;
char folder[MAX_PATH];
HWND hTmp;
char number[8];
memset(&folder,0,sizeof(folder));
memset(&FindFileData,0,sizeof(WIN32_FIND_DATA));
memset(&number,0,sizeof(number));
nbFiles=0;
nbFolders=0;
GetDlgItemText(hdlg,ID_TXT_DIR,folder,MAX_PATH); // get current folder
strncpy (DirSpec, folder, strlen(folder)+1);
if(*(folder+strlen(folder)-1)!='\\') strncat (DirSpec, "\\", 1);
strncat (DirSpec, "*", 1);
hFind = FindFirstFile(DirSpec, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) return 0;
else
{
// Clear List Boxes
SendMessage(hlistFiles, LB_RESETCONTENT, 0, 0);
SendMessage(hlistFolders, LB_RESETCONTENT, 0, 0);
// First file
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
hTmp=hlistFolders;
nbFolders++;
}
else
{
hTmp=hlistFiles;
nbFiles++;
}
SendMessage(hTmp,LB_ADDSTRING,0,(long)FindFileData.cFileName);
while (FindNextFile(hFind, &FindFileData) != 0)
{
// Next Files
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
hTmp=hlistFolders;
nbFolders++;
}
else
{
hTmp=hlistFiles;
nbFiles++;
}
SendMessage(hTmp,LB_ADDSTRING,0,(long)FindFileData.cFileName);
}
// Set Numbers Files/Folders numbers
itoa(nbFiles,number,10);
SetDlgItemText(hdlg,ID_ST_NBFILES,number);
itoa(nbFolders,number,10);
SetDlgItemText(hdlg,ID_ST_NBFOLDERS,number);
dwError = GetLastError();
if (dwError == ERROR_NO_MORE_FILES)
{
FindClose(hFind);
return 1;
}
else
{
return 0;
}
}
}
void __stdcall ChangeFolder(HWND hdlg)
{
char dir[MAX_PATH];
memset(&dir,0,sizeof(dir));
char *sz;
SendMessage(hlistFolders,LB_GETTEXT,SendMessage(hlistFolders,LB_GETCURSEL,0,0),(long)buf);
GetDlgItemText(hdlg,ID_TXT_DIR,dir,sizeof(dir));
if(*(dir+strlen(dir)-1)!='\\') strncat(dir, "\\", 1);
// different cases
if(!strcmp(buf,".")) *(dir+3)=0; // go to root
else if(!strcmp(buf,".."))
{
sz=dir+strlen(dir)-2;
while(*sz!='\\') sz--;
}
else strcat(dir,buf);
SetDlgItemText(hdlg,ID_TXT_DIR,dir);
// ask for listing THiS folder
SendMessage(hdlg,WM_COMMAND,ID_BT_LIST,0);
}
/*
void GetFileExtension(char *szFilename)
{
char *sz;
memset(&FileExt,0,sizeof(FileExt));
sz=szFilename+strlen(szFilename)-1;
while(*sz!='.') sz--;
sz++;
strcpy(FileExt,sz);
}
/*
BOOL CheckExtension(HWND hdlg)
{
/*
txt,pl,bat,ini,c,cpp,asm << ExtensionsOK
ini << bad. continue
ini << bad. continue
ini << bad. continue
ini << w00t. break -> Goto
memset(&CurrentFile,0,sizeof(CurrentFile));
SetDlgItemText(hdlg,ID_ST_STATUS,NULL);
SendMessage(hlistFiles,LB_GETTEXT,SendMessage(hlistFiles,LB_GETCURSEL,0,0),(long)CurrentFile);
GetFileExtension(CurrentFile); //MessageBox(hdlg,FileExt,"FileExt",0);
CharLower(FileExt);
i=0;c=0;sz=ExtensionsOK;
while((c=*sz)!=0)
{
if(c!=',') *(buf2+i)=*sz;
else
{
//MessageBox(hdlg,buf2,"buf2",0);
//MessageBox(hdlg,FileExt,"FileExt",0);
if(strcmp(buf2,FileExt)==0) goto _ExtOk;
i=-1;
memset(&buf2,0,sizeof(buf2));
}
i++;sz++;
}
return false;
_ExtOk:
return true;
}
BOOL CALLBACK SeeFileProc(HWND hdlg, UINT mssg, WPARAM wParam, LPARAM lParam)
{
switch(mssg)
{
case WM_INITDIALOG:
{
HANDLE hMapFile,hfile;
LPCTSTR pBuf;
// Set title
SetWindowText(hdlg,SeeFileTitle);
SetDlgItemText(hdlg,ID_ST_CURRENTFILE,SeeFileCurrentFile);
memset(&buf,0,sizeof(buf));
GetDlgItemText(hMainDlg,ID_TXT_DIR,CurrentFile,sizeof(CurrentFile));
strcat(buf,CurrentFile);
if(*(buf+strlen(buf)-1)!='\\') { *(buf+strlen(buf))='\\'; *(buf+strlen(buf)+1)='\\'; }
memset(&CurrentFile,0,sizeof(CurrentFile));
SendMessage(hlistFiles,LB_GETTEXT,SendMessage(hlistFiles,LB_GETCURSEL,0,0),(long)CurrentFile);
strcat(buf,CurrentFile);
SetDlgItemText(hdlg,ID_TXT_CURRENTFILE,buf);
// map the file
if((hfile = CreateFile(buf,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0))==INVALID_HANDLE_VALUE)
{
SetDlgItemText(hdlg,ID_ST_STATUS,MsgError1);
return 1;
}
hMapFile = CreateFileMapping(hfile,NULL,PAGE_READONLY,0,0,0);
if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
{
SetDlgItemText(hdlg,ID_ST_STATUS,MsgError2);
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,0);
if(pBuf == NULL)
{
SetDlgItemText(hdlg,ID_ST_STATUS,MsgError3);
return 1;
}
SetDlgItemText(hdlg,ID_TXT_SEEFILE,pBuf);
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
CloseHandle(hfile);
return 1;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case ID_BT_CLOSE:
{
EndDialog(hdlg, 0);
return 0;
}
}
return 0;
}
case WM_CLOSE:
{
EndDialog(hdlg, 0);
return 0;
}
}
return 0;
}
/*
- Sets texts in all Editboxes
- /
void SetStaticsText(HWND hdlg)
{
SetDlgItemText(hdlg,ID_ST_DISKS,AppDisks);
SetDlgItemText(hdlg,ID_ST_TOLIST,AppToList);
SetDlgItemText(hdlg,ID_ST_NUMFOLDERS,AppNumFolders);
SetDlgItemText(hdlg,ID_ST_NUMFILES,AppNumFiles);
SetDlgItemText(hdlg,ID_ST_NAME,AppName);
SetDlgItemText(hdlg,ID_ST_FILESIZE,AppFileSize);
SetDlgItemText(hdlg,ID_ST_FILECREATION,AppFileCreation);
SetDlgItemText(hdlg,ID_ST_LASTWRITE,AppLastWrite);
SetDlgItemText(hdlg,ID_ST_LASTACCESS,AppLastAccess);
SetDlgItemText(hdlg,ID_ST_DATEFORMAT,AppDateFormat);
}
/*
LRESULT CALLBACK TxtDirProc(HWND hwnd, UINT mssg, WPARAM wParam, LPARAM lParam)
{
if((mssg==WM_KEYDOWN)&&(wParam == VK_RETURN)) // if pressing VK_RETURN
{
// list folder
SendMessage(hMainDlg,WM_COMMAND,ID_BT_LIST,0);
return 0;
}
return CallWindowProc(oldProc, hwnd, mssg, wParam, lParam); // others messages
}
BOOL CALLBACK AppDlgProc(HWND hdlg, UINT mssg, WPARAM wParam, LPARAM lParam)
{
switch(mssg)
{
case WM_INITDIALOG:
{
hMainDlg=hdlg;
// icon
SetClassLong(hdlg, GCL_HICON, (long)LoadIcon(hinst, MAKEINTRESOURCE(IDI_ICON1)));
// Set Dialog Title
SetWindowText(hdlg,AppTitle);
SetStaticsText(hdlg);
// SubClassing edit ID_TXT_DIR
oldProc = (WNDPROC)SetWindowLong(GetDlgItem(hdlg,ID_TXT_DIR),GWL_WNDPROC,(long)TxtDirProc);
hcmb=GetDlgItem(hdlg,ID_CB_DRIVES);
hlistFiles=GetDlgItem(hdlg,ID_LIST_FILES);
hlistFolders=GetDlgItem(hdlg,ID_LIST_FOLDERS);
if(FillCmbDrives()==0) // if no drives found
{
SetDlgItemText(hdlg,ID_ST_STATUS,MsgError4);
EndDialog(hdlg, 0);
}
else
{
GetDlgItemText(hdlg,ID_CB_DRIVES,buf,sizeof(buf));
SetDlgItemText(hdlg,ID_TXT_DIR,buf);
}
// list root dir
SendMessage(hdlg,WM_COMMAND,ID_BT_LIST,0);
return 1;
}
/**** res.rc : **
CONTROL 107,ID_BITMAP,"Static",SS_BITMAP,412,7,153,36 < l
^ ^ ^
x y L
case WM_LBUTTONDOWN:
{
if(wParam==MK_LBUTTON)
{
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
/*
- (412+153)*1.5 = 848
- 412*1.5 = 619
- (7+36)*1.5 = 64 << uhuh
- 7*1.5 = 11
- /
if((xPos<=848)&&(xPos>=619)&&(yPos<=71)&&(yPos>=11))
MessageBox(hdlg,AboutText,AboutTitle,32);
}
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case ID_LIST_FOLDERS:
{
switch (HIWORD(wParam))
{
case LBN_DBLCLK:
{
ChangeFolder(hdlg);
break;
}
}
break;
}
case ID_LIST_FILES:
{
switch (HIWORD(wParam))
{
case LBN_SELCHANGE:
{
BY_HANDLE_FILE_INFORMATION FilesInfos;
SYSTEMTIME SystemTime;
HANDLE hfile;
DWORD FileSizeHigh,FileSizeLow,
__int64 size=0;
char buf2[48];
memset(&FilesInfos,0,sizeof(LPBY_HANDLE_FILE_INFORMATION));
memset(&buf,0,sizeof(buf));
memset(&CurrentFile,0,sizeof(CurrentFile));
memset(&buf2,0,sizeof(buf2));
SetDlgItemText(hdlg,ID_ST_STATUS,NULL);
SetDlgItemText(hdlg,ID_ST_FILENAME,NULL);
SetDlgItemText(hdlg,ID_ST_SIZE,NULL);
SetDlgItemText(hdlg,ID_ST_CREATION,NULL);
SetDlgItemText(hdlg,ID_ST_ACCES,NULL);
SetDlgItemText(hdlg,ID_ST_WRITTEN,NULL);
GetDlgItemText(hMainDlg,ID_TXT_DIR,CurrentFile,sizeof(CurrentFile));
strcat(buf,CurrentFile);
if(*(buf+strlen(buf)-1)!='\\') { *(buf+strlen(buf))='\\'; *(buf+strlen(buf)+1)='\\'; }
memset(&CurrentFile,0,sizeof(CurrentFile));
SendMessage(hlistFiles,LB_GETTEXT,SendMessage(hlistFiles,LB_GETCURSEL,0,0),(long)CurrentFile);
SetDlgItemText(hdlg,ID_ST_FILENAME,CurrentFile); // set ID_ST_FILENAME
strcat(buf,CurrentFile);
SetDlgItemText(hdlg,ID_TXT_CURRENTFILE,buf);
// Open file
if((hfile = CreateFile(buf,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0))==INVALID_HANDLE_VALUE)
{
SetDlgItemText(hdlg,ID_ST_STATUS,MsgError1);
return 0;
}
// get infos
GetFileInformationByHandle(hfile,&FilesInfos);
// Get File Size
FileSizeLow=GetFileSize(hfile,&FileSizeHigh);
size=FileSizeHigh;
size<<=8;
size+=FileSizeLow;
if(size<1000) sprintf(buf2,"%i octets",size); // in octets
else if((size/1024)<1000) sprintf(buf2,"%i ko",size/1024); // in ko
else sprintf(buf2,"%i Mo",(size/1024)/1024); // in Mo
SetDlgItemText(hMainDlg,ID_ST_SIZE,buf2);
/*
typedef struct _BY_HANDLE_FILE_INFORMATION
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD dwVolumeSerialNumber;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD nNumberOfLinks;
DWORD nFileIndexHigh;
DWORD nFileIndexLow;
} BY_HANDLE_FILE_INFORMATION,
- PBY_HANDLE_FILE_INFORMATION;
- /
// ftCreationTime
FileTimeToSystemTime(&(FilesInfos.ftCreationTime),&SystemTime);
sprintf(buf2,"%02i/%02i/%i",(int)SystemTime.wDay,(int)SystemTime.wMonth,(int)SystemTime.wYear);
SetDlgItemText(hMainDlg,ID_ST_CREATION,buf2);
// ftLastAccessTime
FileTimeToSystemTime(&(FilesInfos.ftLastAccessTime),&SystemTime);
sprintf(buf2,"%02i/%02i/%i",(int)SystemTime.wDay,(int)SystemTime.wMonth,(int)SystemTime.wYear);
SetDlgItemText(hMainDlg,ID_ST_ACCES,buf2);
// ftLastWriteTime
FileTimeToSystemTime(&(FilesInfos.ftLastWriteTime),&SystemTime);
sprintf(buf2,"%02i/%02i/%i",(int)SystemTime.wDay,(int)SystemTime.wMonth,(int)SystemTime.wYear);
SetDlgItemText(hMainDlg,ID_ST_WRITTEN,buf2);
// close file
CloseHandle(hfile);
break;
}
case LBN_DBLCLK:
{
if(CheckExtension(hdlg)) // if file as a *good* extension
DialogBox(hinst, MAKEINTRESOURCE(IDD_SEEFILE), NULL,SeeFileProc);
else
SetDlgItemText(hdlg,ID_ST_STATUS,MsgError6);
break;
}
}
break;
}
case ID_CB_DRIVES:
{
switch (HIWORD(wParam))
{
case CBN_SELCHANGE:
{
SendMessage(hcmb,CB_GETLBTEXT,SendMessage(hcmb,CB_GETCURSEL,0,0),(long)buf);
SetDlgItemText(hdlg,ID_TXT_DIR,buf);
SendMessage(hdlg,WM_COMMAND,ID_BT_LIST,0);
break;
}
}
break;
}
case ID_BT_LIST:
{
SetDlgItemText(hdlg,ID_ST_STATUS,NULL);
if(!ListFiles(hdlg)) SetDlgItemText(hdlg,ID_ST_STATUS,MsgError5);
return 0;
}
case ID_BT_EXIT:
{
EndDialog(hdlg, 0);
return 0;
}
}
return 0;
}
case WM_CLOSE:
{
EndDialog(hdlg, 0);
return 0;
}
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int)
{
hinst = hInstance;
DialogBox(hInstance, MAKEINTRESOURCE(IDD_APP), NULL, AppDlgProc);
return 0;
}
Conclusion :
Toutes remarques sont les bienvenues
Bonne journée
Bigbang
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.