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;
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);
}
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);
}
} //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
else{
pn->suiv = *sommet ; // relier au top de la pile
}
}
/**************************************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
if (i%20 == 0 )
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
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.