Explorateur de fichiers windows en c

Contenu du snippet

application en langage C qui permet de parcourir les dossiers et les fichiers d'un système d'exploitation , créer des nouveaux dossiers , copier ou supprimer des fichiers...

L'application communique avec l'utilisateur via une interface graphique simple et claire faite avec graphics.h

Source / Exemple :


// Nom          : Parkour.cpp
// Description  : explorateur du system de fichiers windows  (supporte vista ! )
// Details      : l'utilisateur peut explorer l'arborescence du OS,copier,coller, creer de nouveaux repertoires ,et  des fichiers
//                ayant des fonctionnalités tels que le retour vers le repertoire parent,defilement des pages..
// L'auteur     : Daddaoua Marouan
// crée le      : 1 Mai 2009  23:30

#include <graphics.h>
#include <iostream.h>
#include <stdlib.h>
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <dirent.h>

struct Finfo{char nomfichier[26];double taille ; char DateCreation[256];char DateDernOuverture[256];char DateDernModif[256];int ddir ;struct  Finfo * suiv ;struct  Finfo * prec ;}Finfo;
typedef struct listeDD{char nomDD[3];struct listeDD * suiv;}listeDD ;
typedef struct pileCHEMprec{char chem[1000];struct pileCHEMprec * suiv;}pileCHEMprec;
ULONG_PTR ExcVal;   // poniteur vers long pour convertir HINSTANCE de ExcuteSHell

struct listeDD *  recuperLecteurs();
int AjoutNoud(WIN32_FIND_DATA fileinfo,struct Finfo ** dernier);
struct Finfo *  scannerRepertoire(char * chemin);
int dtctZoneSouri();
void guiDD(listeDD * debut);
int GUIrep(char * chemin,struct Finfo * debut,int NbrPages , int NumPage);
int isdir(char *pp);

/***************************************recuperer disque durs et lecteurs *****************************/
listeDD * recuperLecteurs(){

listeDD *p,*fin,* debut= (listeDD *)malloc(sizeof(listeDD ));
fin = debut;
unsigned long Mask = 1;                                 // LSB est A  (flag)  OOOO OOO1
unsigned long Drives = GetLogicalDrives ();             // parx si on a les drives C: et E: la var DRives aura 20 = 0b 0001 0100
char strDrive [3];

for (int i=0; i<26; i++) {                              // 26 letters in [A..Z] range

  if (Drives & Mask){                                   //      0001 0100     contenu de DRIVES apré trouvé C: et E:
    sprintf (strDrive, "%c:\\", 'A'+i);                 //    &
    p = (listeDD *)malloc(sizeof(listeDD ));            //      0000 0100     mask pour detecter un C: eventuel
    strcpy(p->nomDD,strDrive);                          //   --------------
    fin->suiv = p;                                      //  =   0000 0100     la resulta est 4  retranche 1 et voila vous avez le 3eme drives ki existe ( C:)
    fin = p;                                            //
    fin->suiv = NULL;
   }
  Mask <<= 1;                                           // decalage d un bit a gauche pour avoir un mask du lecteur suivant A-->B--C-->D.....
}

 return(debut->suiv);
}
 /***************************************ajouter un noeud info pour fichier/rep*****************************/
int AjoutNoud(WIN32_FIND_DATA fileinfo,struct Finfo ** dernier){                                                                            // struct a lire + pointeur du dernier noued pour la liaison

    SYSTEMTIME strtime;                                                                                                             // struct de temp brut
    struct Finfo * pfinf = (struct Finfo*)malloc(sizeof(Finfo));                                                                    // creation du noeud Finfo
    strncpy(pfinf->nomfichier,fileinfo.cFileName,26);                                                                               // copie du nom du fich/rep sous controle ( 26 max pour ne pas deborder du cadre )
    pfinf->taille = fileinfo.nFileSizeLow;                                                                                          // taille
    FileTimeToSystemTime(&(fileinfo.ftCreationTime),& strtime);                                                                     // conversion des dates creation
    sprintf(pfinf->DateCreation,"%02d:%02d %d/%d/%d",strtime.wHour,strtime.wMinute,strtime.wDay,strtime.wMonth,strtime.wYear);
    FileTimeToSystemTime(&(fileinfo.ftLastAccessTime),& strtime);                                                                   // conversion des dates derniere ouverture
    sprintf(pfinf->DateDernOuverture,"%02d:%02d %d/%d/%d",strtime.wHour,strtime.wMinute,strtime.wDay,strtime.wMonth,strtime.wYear);
    FileTimeToSystemTime(&(fileinfo.ftLastWriteTime),& strtime);                                                                    // conversion des dates derniere modif
    sprintf(pfinf->DateDernModif,"%02d:%02d %d/%d/%d",strtime.wHour,strtime.wMinute,strtime.wDay,strtime.wMonth,strtime.wYear);
    pfinf->ddir = 0;                                                                                                                // supposer ke  l element est un fichier
    if (  fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)                                                                     // un jeu d maskage pour detecter les rep's
            pfinf->ddir = 1;
    pfinf->prec =*dernier;                                                                                                           // le noeud actuel REtient @ de son PRECESSEUR
    (*dernier)->suiv =pfinf;                                                                                                         // lier le dernier noeud a celui ki vient d etre cree

  • dernier = pfinf; // rendre celui ki vient d etre cree le dernier
pfinf->suiv = NULL; } /***************************************scanner un repertoire*****************************/ struct Finfo * scannerRepertoire(char * chemin) { char cheminRecherch[MAX_PATH]; SYSTEMTIME strtime; // struct de temp brut HANDLE sh ; // pointzeur fichier WIN32_FIND_DATA ffd; // file information struct struct Finfo * debut = (struct Finfo*)malloc(sizeof(Finfo)); // noeud vide de debut struct Finfo * dernier = debut; // dernier et debut pointent sur le premier noeud vide lstrcpy(cheminRecherch, chemin); strcat(cheminRecherch,"*\0"); // la * est obligé , je c pa porkoi sh =FindFirstFile(cheminRecherch, &ffd); // preparation : lectrure du premier fichier/rep if(INVALID_HANDLE_VALUE == sh) return(NULL); // c pas un chemin valid j pense ! do { FileTimeToSystemTime(&(ffd.ftCreationTime),& strtime); // recuperer les infos du fichier lu pointé par sh AjoutNoud(ffd,&dernier); // copie les infos ki nou concern dan notre struct infofile } while (FindNextFile(sh, &ffd)); // tant k il ya des fichier/rep a lire return(debut->suiv->suiv->suiv); // pour ignorer le noeud 'debut ' (vide) et '.'( rep actuel) et '..' ( rep parent ) FindClose(sh); } /****************************retourn la zone des elements appuié ( gauche )*****************/ int dtctZoneSouri(int *x, int *y,int *maxx,int *maxy,int *minx,int *miny){ int i;
  • minx= 60;*maxx= 260;
while(1){
  • miny = 140;*maxy = 160; // initialiser les Y's pour la 1 ere ZONE element
getmouseclick( WM_LBUTTONUP, *x, *y ); // recuperer etat du botton GAUCHE de la souris for( i = 0 ; i < 20 ; i++){ if(*x <= *maxx && *x >= *minx && *y <= *maxy && *y >= *miny) // le (i + 1 ) eme element est appuié return(i+1); if(*x <= 760 && *x >= 740 && *y <= 578 && *y >= 563) // 740,563,760,578 cordonnés du rectangle des pages suivantes return(0); if(*x <= 640 && *x >= 620 && *y <= 578 && *y >= 563) // .. cordonnés du rectangle des pages precedentes return(-1); if(*x <= 760 && *x >= 720 && *y <= 80 && *y >= 40) // la fleche du REP fleche PArent est appuié return(-2); if(*x <= 700 && *x >= 660 && *y <= 80 && *y >= 40) // le bottons NEW est appuié return(-3);
  • miny+=20;*maxy+=20;
}
  • miny = 140;*maxy = 160;
getmouseclick( WM_RBUTTONUP, *x, *y ); // recuperer etat du botton GAUCHE de la souris for( i = 0 ; i < 20 ; i++){ if(*x <= *maxx && *x >= *minx && *y <= *maxy && *y >= *miny) // le (i + 1 ) eme element est appuié ( par le bottons droit ) return(i+1-40);
  • miny+=20;*maxy+=20;
} } //end while } /***************************************************interface pour choisir le disk dur ( logik ) a parcourir *****/ void guiDD(listeDD * debut){ int px=60,py=143; closegraph(CURRENT_WINDOW); initwindow(800,600); setcolor(DARKGRAY); rectangle(40,40,640,80); // cadre du chemin rectangle(40,100,760,560); // cadre des element setcolor(WHITE); outtextxy(60, 50, "Poste De Travail :"); while(debut != NULL){ outtextxy(px, py, debut->nomDD); // parex c: py+=20; // ligne suivante debut=debut->suiv; // noeud suivant } } /***************************************conversion taille en kilo Mo et Go puis en string****************************/ char * convTaille(long taille){ // taille en octets char tailleSTR[15]={'\0'}; if(taille > 1073741824) // plus ke 1 Go ...on doit deviser par 1 Go...meme methode pour Ko et Mo sprintf(tailleSTR,"%d.%d Go\0",taille/1073741824,taille%1073741824); else if(taille > 1048576) sprintf(tailleSTR,"%d.%2d Mo\0",taille/1048576,taille%1048576); else if(taille > 1024) sprintf(tailleSTR,"%d.%2d Ko\0",taille/1024,taille%1024); else // moins k un KILOoctet .. on le laisse trankil sprintf(tailleSTR,"%d octs\0",taille); return(tailleSTR); } /*************************************Interface REPERtoire**********************************/ int GUIrep(char * chemin,struct Finfo * debut,int NbrPages , int NumPage){ char pages[5],tailleSTR[10]; int px=60,py=143,i=0; struct Finfo * p =debut; closegraph(CURRENT_WINDOW); initwindow(800,600); sprintf(pages,"page %d/%d",NumPage,NbrPages); // config du string des pages setcolor(DARKGRAY); rectangle(40,40,640,80); // cadre du chemin rectangle(40,100,760,560); // cadre des element setcolor( BLUE); rectangle(740,563,760,578); // fleche SUIV outtextxy(745, 563,"->"); rectangle(620,563,640,578); // fleche PREC outtextxy(625, 563,"<-"); rectangle(720,40,760,80); // cadre du rep parent rectangle(660,40,700,80); // cadre new dossier setcolor( WHITE); line(40,120,760,120); // ligne des titres line(280,100,280,560); // les 4 barres separant les champs line(400,100,400,560); line(520,100,520,560); line(640,100,640,560); pieslice( 730, 44, 250, 290, 10 ); // fleche haut du rep parent line(730,54,730,70); line(730,70,750,70); outtextxy(50, 103,"Nom");outtextxy(290, 103,"Taille");outtextxy(410, 103,"Date Creation");outtextxy(530, 103,"Dern.Ouverture");outtextxy(645, 103,"Dern.Modification"); outtextxy(60, 50,chemin); outtextxy(660, 563,pages); outtextxy(665, 50,"new"); while ( p != NULL && i < 20 ){ // p pointe sur la premiere STRUCTURE contenant les infos du premier element dan un REP outtextxy(px, py, p->nomfichier); // parex bonjour.txt px+= 230;strcpy(tailleSTR ,convTaille(p->taille)); //+230 pour decaler vers la collone des tailles; appel de la conversion if(! p->ddir ) // c un fichier et on doit afficher sa taille outtextxy(px, py, tailleSTR); else // c une rep et on a pas sa taille , alor vaut mieu ecire "Repertoire" ke "0 byte" ! outtextxy(px, py, "Repertoire"); px+= 120;outtextxy(px, py, p->DateCreation); px+= 120;outtextxy(px, py, p->DateDernOuverture); px+= 120;outtextxy(px, py, p->DateDernModif); py+=20;px=60; // ligne suivante p=p->suiv; i++; } if (p != NULL) return(0); // le retour n est pa utlisé , pour le moment return (1); } /*****************************isdir******************************/ int isdir(char *pp){ // l idee est simple : essay d lire un element avec readdir(),si la fct est reussi : c un REP ! sinon c'est un FICHIER struct dirent *mydir; DIR * rep; // struct pour les infos des repertoires mais ell contient ke le nom est une var ki n a pa d interet ( au min pour moi ) int idir = -1; rep = opendir(pp); if (rep != NULL) if ((mydir = readdir(rep))) idir = 0; // c un rep closedir(rep); return idir; } /*************************empiler chemin*****************************/ void empilerChemin(pileCHEMprec ** sommet, char * chemin ){ //sommet de la pile des chemins precedents , et le chemin a emplier if ( (*sommet)->chem != NULL && strcmp(chemin,(*sommet)->chem)== 0) return; pileCHEMprec *p, * pn = (pileCHEMprec *)malloc(sizeof(pileCHEMprec)); strcpy(pn->chem,chemin); pn->suiv = NULL; if ( sommet == NULL ) // la pile est vide, donc pn sera le prem et le dern
  • sommet = pn;
else{ pn->suiv = *sommet ; // relier au top de la pile
  • sommet = pn;
} } /**************************************MESSAGE SYSTEM********************************/ void messageSys(ULONG_PTR i){ setcolor(RED); if ( i > 32 ) outtextxy(60, 563,"operation reussite"); // porkoi 32 ? ExcuteSHell() retourne une val > 32 si la fct est reussi else outtextxy(60, 563,"le system d'exploitation n'a pas pu ouvrir ce fichier"); setcolor(WHITE); delay(2000); } /**************************************detecter copier coller supprimer ************************/ int dtctOption(int refX,int refY,int *x,int *y){ // detect quelle botton est apuié ( copier ou coller ou supprimer) while(1){ getmouseclick( WM_LBUTTONUP, *x, *y ); if(*x <= (refX+100) && *x > refX && *y <= (refY + 60) && *y > refY+40) // supprimer return(2); if(*x <= (refX+100) && *x > refX && *y <= (refY + 20) && *y > refY) // copier return(1); if(*x <= (refX+100) && *x > refX && *y <= (refY + 40) && *y > (refY+20)) // coller return(0); } } /*********************************************config des numpage et nbrpages***************************************/ void configPages(int i,int * numpage,int * nbrpages){ if ( i > 20 ) { // ya plus k une page,on doit canfig les nbr des pages et le NUM de la page actuel
  • numpage = 1;
if (i%20 == 0 )
  • nbrpages = i / 20;
else
  • nbrpages =( i / 20) + 1 ;
} else{*numpage= *nbrpages = 1;} // ya une seule page } /***************************************THE MAIN MaCHINe****************************/ int main() { struct Finfo * p,* liste; listeDD * lstDD,*pDD; pileCHEMprec * sommetPileChem=NULL; char octet,chemin[500]={'\0'},chemFichier[500]={'\0'},chemNewDossier[500]={'\0'},CollChemin[500]={'\0'},CopChemin[500]={'\0'},nomFichAcoll[50]={'\0'},suppChemin[50]={'\0'}; int tmp,i,nbrpages,numpage,x1,y1; int minx = 60,maxx = 260,miny = 140,maxy = 160,x,y,FichAcoller=0,tmpslct; FILE *fcol,*fcop; // setcolor(WHITE); initwindow(800,600); // ouverture fenetre VIDE debut: lstDD = recuperLecteurs(); // lstDD contient les partitions logiks ainsi ke les lecteurs guiDD(lstDD); // passer la liste des partitions pour les afficher nicely ! tmp = dtctZoneSouri(&x,&y,&maxx,&maxy,&minx,&miny); // detecter le DD appuié for(pDD= lstDD,i= 0;i< tmp -1; pDD= pDD->suiv,i++); // pointer sur sa structure ( DD ) strcat(chemin,pDD->nomDD); // config du chemin pour lister son contenu ouvrCH: liste = scannerRepertoire(chemin); // lister le contenu for(p = liste,i=0;p != NULL ; i++,p=p->suiv); //compter le nbr des elements dan le chemin configPages(i,& numpage,&nbrpages); configPages(i,& numpage,&nbrpages); et1: GUIrep(chemin,liste,nbrpages, numpage); // dessiner la liste tmp = dtctZoneSouri(&x,&y,&maxx,&maxy,&minx,&miny); if( tmp <=0 ){ /// l un des bottons de foncionnalités est apuié ( dossier parent ..suiv.. prec...new ...) if(( !tmp ) && (numpage < nbrpages)) { // la fleche suiv eest cliké et ya d autre pages pour ce rep for(i = 0 ; i < 20 ; i++,liste = liste->suiv); // pinter sur le premier element de la pages suivant numpage++; goto et1; // redessiner } if(( tmp == -1 ) && (--numpage >= 1)) { // la fleche precedent eest cliké et ya d autre pages pour ce rep for(i = 0 ; i < 20 ; i++,liste = liste->prec); // pinter sur le premier element de la pages suivant goto et1; // redessiner } if(tmp == -2){ // le fleche du REP PARENT if(sommetPileChem != NULL){ // il ya une chemn sauvgardé strcpy(chemin,sommetPileChem->chem); sommetPileChem = sommetPileChem->suiv; // ignorer le top } else{ strcpy(chemin,"\0"); goto debut; } goto ouvrCH; } if(tmp == -3){ // le botton "new" est appuié strcpy(chemNewDossier,chemin); strcat(chemNewDossier,"\\Nouveau Dossier"); mkdir(chemNewDossier); goto ouvrCH; } if( tmp <= -20 && tmp > -40){ // l'un des elements est appuié avec le botton droite x1=x;y1=y; if(FichAcoller == 1 ){ // ya klk chose a coller setcolor(BLUE); rectangle(x,y,x+100,y+60); line(x,y+20,x+100,y+20); line(x,y+40,x+100,y+40); setcolor(LIGHTGRAY); outtextxy(x+3,y+23,"Coller"); outtextxy(x+3,y+43,"Supprimer"); } else{ // ya rien a coller setcolor(BLUE); rectangle(x,y,x+100,y+60); line(x,y+20,x+100,y+20); line(x,y+40,x+100,y+40); setcolor(LIGHTGRAY); outtextxy(x+3,y+3,"Copier"); outtextxy(x+3,y+43,"Supprimer"); } tmpslct = dtctOption(x1,y1,&x,&y); // 1 = copier , 0 = coller if( ((tmpslct==1) && !FichAcoller) || (! tmpslct && !FichAcoller)){ // on veut copier for(p=liste,i=1;i< (tmp+40);i++,p=p->suiv); // pointer le ficher concerné if( p->ddir) { setcolor(RED); outtextxy(20,583,"Vous pouvez copier seulement des FICHIERS"); delay(2000); setcolor(WHITE); goto ouvrCH; } // c un dossier : on peu pa copier un dossier ( au moin dan cett version ) strcpy(CollChemin,chemin); strcat(CollChemin,p->nomfichier); FichAcoller = 1; strcpy(nomFichAcoll,p->nomfichier); goto et1; } else if ( ! tmpslct && FichAcoller ) { // on veut coller et on a klk chose a coller dan le buffer // on doi chercher le fichier dan le buffer et l inserer dan le rep pointé for(p=liste,i=1;i< (tmp+40);i++,p=p->suiv); if(! p->ddir) goto ouvrCH; // c un fichier : on peu pa copier un fichier dan un fichier ! strcpy(CopChemin,chemin); strcat(CopChemin,p->nomfichier); strcat(CopChemin,"\\"); strcat(CopChemin,nomFichAcoll); fcol =fopen(CollChemin,"rb"); fcop =fopen(CopChemin,"wb"); while(!feof(fcol)){ fread(&octet,1,1,fcol); fwrite(&octet,1,1,fcop); } fclose(fcol);fclose(fcop); FichAcoller = 0; goto ouvrCH; } else if(tmpslct == 2 ){ // on veu supprimer l element for(p=liste,i=1;i< (tmp+40);i++,p=p->suiv); // pointer le ficher concerné if( p->ddir ) { // assurer k il est un fichier et pas un rep ou bien le vide ! setcolor(RED); outtextxy(20,583,"Vous pouvez supprimer que des FICHIERS"); delay(2000); setcolor(WHITE); goto ouvrCH; } strcpy(suppChemin,chemin); strcat(suppChemin,p->nomfichier); setcolor(RED); if( DeleteFile(suppChemin)) outtextxy(20,583,"Fichier supprimé"); else outtextxy(20,583,"Le fichier est protegé"); delay(2000); setcolor(WHITE); goto ouvrCH; } else{ // on veut coller et on a rien copié setcolor(RED); outtextxy(20,583,"Vous avez rien copié"); delay(2000); setcolor(WHITE); } goto ouvrCH; } goto ouvrCH; // mesure de securité dans le cas ou l'user clik les fleche sans raison ! } else { if( tmp <= 20 && tmp >0){ ///*un element est cliké*/ p=liste; for(i = 0; i < tmp-1 && p != NULL;i++,p = p->suiv); // pointe sur l element kliké if ( p == NULL) goto ouvrCH; empilerChemin(&sommetPileChem, chemin ); // : empiler strcat(chemin,p->nomfichier); // config le chemin pour lister if (isdir(chemin) == 0 ){ strcat(chemin,"\\"); // c est un dir goto ouvrCH; } else{ strcpy(chemFichier,"\""); // ajouter des "" pour ignorer les espaces internes strcat(chemFichier,chemin); strcat(chemFichier,"\""); ExcVal = (ULONG_PTR )ShellExecute(NULL,"open",chemFichier,NULL,NULL,SW_SHOW); // executer le fichier messageSys(ExcVal); strcpy(chemin,sommetPileChem->chem); // enlever le nom du fichier ki vient d etre ouvert goto ouvrCH; // ouvrir le dernier repertoire } } //ENd if } //end else }

Conclusion :


je suis encore débutant, donc si vous avez des réactions, critiques.. je serai trop reconnaissant

A voir également

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.