Accueil > > > EXPLORATEUR DE FICHIERS WINDOWS EN C
EXPLORATEUR DE FICHIERS WINDOWS EN C
Information sur la source
Description
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
- // 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
-
- }
// 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
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
explorateur windows [ par m.beber ]
Salut à tous,Je vous écrits car j'ai un petit problème pour programmerune application de type "explorateur windows".Je travaille sous borland C++ Buil
Parcourir une arborescence en C [ par HCJarod ]
Salut, je voudrai savoir comment en utilisant les fonction findfirst() et findnext() du C trouver tous les fichiers d'extension .exe. Je mexplique : l
sources explorateur windows [ par linkinlife66 ]
LINKINLIFE66 je cherche un explorateur windows pour mon projet
Drag Drop [ par said01 ]
Bonjour,Au momoent d'un drag&Drop depuis l'explorateur windows vers ma treeview, je souhaite détéctcter le présence de la sour
Arborescence ( Comme l'explorer dans windows) [ par t0ine ]
Bonjour , je dois faire un travail avec une base de donnée acces et je dois recharger mes données sur ma forme sous la forme d'un expl
plugin pour l'explorateur windows [ par clempar55 ]
Salut tout le monde!Je voudrais savoir s'il est possible de creer une sorte de plugin pour l'explorateur windows pour modifier la facon dont celui-ci
MFC => Parcourir l'arborescence [ par jul39dole ]
Bonjour,Je souhaiterai obtenir la liste des fichiers contenus dans un répertoire et ses sous-répertoires. Seulement, ne pouvant utiliser les
parcourir [ par sarafaiz ]
Bonjour,je cherche une fonction en java sous windows qui permet de parcourir tous les disques,les dossiers et les sous dossiers du système pour choisi
Ouvrir explorateur windows + focus sur fichier [ par shuttleur ]
Bonjour à tous,Depuis un programme C++ utilisant win32, je cherche à lancer l'explorateur windows dans un répertoire donné.J'utilise actuellement syst
TOOLTIPS SUR FICHIERS IMAGES DANS L EXPLORATEUR WINDOWS [ par freddow ]
bonjour a tous et a toutes... je pense que tout est dit dans le titre....je voudrais savoir, comment faire avec des composants du style sdk xnview pou
|
Derniers Blogs
QUELQUES TRUCS INTéRESSANTS (05/09/2010)QUELQUES TRUCS INTéRESSANTS (05/09/2010) par coq
Cette fois-ci : .NET Debug / Performance Sécurité SQL Server .NET Determining if a type is defined in the .NET Framework (blog de Scott Dorman) Ha tiens, je n'avais jamais vraiment pensé à utiliser le jeton de clé publique...
Cliquez pour lire la suite de l'article par coq ENUMERABLECOLLECTIONENUMERABLECOLLECTION par Matthieu MEZIL
Prenons le scénario suivant. On utilise MVVM. On a les deux classes suivantes dans le model : public class Child { } public class Parent { private ObservableCollection < Child > _children; public ObservableCollection < Child > Children { get {...
Cliquez pour lire la suite de l'article par Matthieu MEZIL [HS] CHROME 6 + MOI = COUP DE GUEULE ![HS] CHROME 6 + MOI = COUP DE GUEULE ! par JeremyJeanson
Attention, le poste qui suit n'est pas la complainte d'une personne : Qui n'aime pas Chrome. D'un anti Google. D'un développeur qui a un poil énorme dans la main. Ceux qui me fréquentent savent que je change de navigateur favori tous les 2 ou 3 mois afin ...
Cliquez pour lire la suite de l'article par JeremyJeanson [WP7] UTILISER UN WRAPPANEL DANS UNE APPLICATION WINDOWS PHONE 7[WP7] UTILISER UN WRAPPANEL DANS UNE APPLICATION WINDOWS PHONE 7 par Audrey
Lors de la réalisation de ma 2ème application Windows Phone 7, j'ai souhaité utiliser un WrapPanel pour afficher plusieurs photos. Mais le contrôle WrapPanel ne fait pas parti de la liste des contrôles inclus dans le SDK de la version Beta des outils pour...
Cliquez pour lire la suite de l'article par Audrey
Forum
LISTE ET TABLEAULISTE ET TABLEAU par dida87
Cliquez pour lire la suite par dida87
Logiciels
WebLogAndPass (1.0.0)WEBLOGANDPASS (1.0.0)WebLogAndPass est un logiciel permettant de mémoriser vos sites préférés et pour chacun d'entre-e... Cliquez pour télécharger WebLogAndPass uTorrent (2.0.4)UTORRENT (2.0.4)C'est un client BitTorrent très puissant et très performant. Comme son nom l'indique, uTorrent (m... Cliquez pour télécharger uTorrent Bureau de Gestion - ERP Devis Facturation (2.02)BUREAU DE GESTION - ERP DEVIS FACTURATION (2.02)- Version gratuite du 10/06/2010
Le Bureau de Gestion est un logiciel dédié à la gestion de l'en... Cliquez pour télécharger Bureau de Gestion - ERP Devis Facturation 4Videosoft Transfert iPod Mac (3.2.08)4VIDEOSOFT TRANSFERT IPOD MAC (3.2.08)4Videosoft Transfert iPod-Mac caractérise principalement à transférer les fichiers iPod vers Mac.... Cliquez pour télécharger 4Videosoft Transfert iPod Mac 4Videosoft HD Convertisseur (3.3.08)4VIDEOSOFT HD CONVERTISSEUR (3.3.08)Etant le meilleur HD Vidéo Convertisseur, 4Videosoft HD Convertisseur, vous pouvez regarder la vi... Cliquez pour télécharger 4Videosoft HD Convertisseur
|