Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence

Utilisation des FilesMapping sous C++ Builder

10/07/2003

Par DjmSoftware
 

niveau : facile

durée : 30 minutes

ce tutorial démontre l'utilisation des File Mapping avec un exemple d'application


Sources du Programme disponible ici.


Définition
1. Avantages
1.1. API Utilisée
1.2. Programme d'exemple
1.3. Limitation
1.4. Cahier des Charges
2. Définition du GUI
2.1. définition de la forme principale
2.2. ImageList
2.3. ActionsList
2.3. Menu Principal
2.4. Tools Buttons
3. Classe TMMF
3.1. But de cette classe
3.2. Déclaration de la classe
3.3. Implémentation de la classe
3.4. Constructeur avec FileName
3.5. Destructeur
3.6. Méthode GetFile
3.7. Méthode GetMapping
3.8. Méthode GetPtrAdresse
3.9. Méthode Execute
3.10. Méthode GetSizeofFile
3.11. Explicatif
4. Classe Tform
4.1. Constructeur
4.2. Méthode OpenFileExecute
4.3. Méthode CloseApp
4.4. Méthode ExecuteExecute
4.5. Méthode CleanPtr
4.6. Méthode CancelActionExecute
4.7. Méthode FormDestroy
4.8. Méthode ParseCmdLine
5. Instalation dans C++ Builder
6. Utilisation dans C++ Builder


Définition


Files Mapping est une des plus puissantes fonctionnalité API Win32 permettant de partager dans la mémoire attribuée
à chaque Processus (2 Gb) des zones de mémoires physiques ou de fichiers stockés sur disque.
Il est alors possible de travailler de manière avec le contenu d'un fichier ou contenu mémoire

Les Fichiers sur disques peuvent être des tous de types même le système Page Files
Les Fichires peuvent être chargés entièrement ou découpés en bloc
La seule limitation est que l'on ne peut pas utiliser des fichiers se trouvant sur une autre Computer


1. Avantages


Partage mémoire entre plusieurs Processus de manière à communiquer entre eux
Accès très rapide aux fichiers sur le disque
Mise a jour de DLL, etc


1.1. API Utilisée


  • 1. CreateFile
  • 2. CreateFileMapping
  • 3. MapiewOfFile
  • 4. MapViewOfFileEx
  • 5. OpenMappedFile
  • 6. UmpapViewOfFile
  • 7. FlushViewOfFile

Explication des Api

CreateFile
Permet de créer ou d'ouvrir les objets suivants

  • 1. files
  • 2. pipes
  • 3. mailslots
  • 4. communications resources
  • 5. disk devices (Windows NT only)
  • 6. consoles
  • 7. directories (open only)

CreateFileMapping
Crée un un object de mémoire partagée Nommé ou anonyme
MapiewOfFile
Mappe dans la zone mémoire du process l'object précédemment obtenu par l'appel à Create FileMapping
MapViewOfFileEx
Identique à MapiewOfFile mais avec la possibilité supplémentaire d'indiquer ou l'object
FileMapping doit être placé dans la mémoire du process appelant
OpenFileMapping
Ouvre un object FileMapping
Cette fonction est généralement utilisée pour connaître le Handle d'un object FileMapping
UmpapViewOfFile
Retire de l'espace mémoire du process l'object FileMapping
FlushViewOfFile
Permet de remplir des fichier Mappés sur dique avec la valeur 0 en précisant
l'adresse de départ ainsi que le nombre d'éléments à supprimer


1.2. Programme d'exemple


Dans le but de démontrer une utilisation possible des Mapping Files
Je vous propose une application

J'ai remarqué que depuis la version 3 du compilateur Borland C++ Builder
La table d'exportation de l'exécutable généré est toujours emplie avec des symboles
plus ou moins barbares du genre suivant

  • @@Testbitmap@Finalize
  • @@Testbitmap@Initialize
  • @Classes@TComponent@UpdateRegistry$qqr4boolx17System@AnsiStringxt2
  • @Forms@TForm@$bctr$qqrp18Classes@TComponent
  • @Forms@TForm@$bdtr$qqrv

ce qui ne donne pas une représentation très professionnelle de l'exécutable fourni
les exécutable générés par Delphi ne souffrent pas de ce défaut

l'application proposée à l'utilité de supprimer la table d'exportation des exécutables
générés par C++ Builder


1.3. Limitation


Ce programme est écrit en C++ à l'aide de C++ Builder 6
Dans ce programme est utilisé certaines fonctionnalités VCL qui rendent la parti GUI non portable sur une autre compilateur, l'adaptation du code est par contre possible


1.4. Cahier des Charges


  • Etablir un Tools avec un GUI
  • Permettre la possibilité d'installer et de désinstaller ce programme dans la Shell
  • Permettre le fonctionnement via une ligne de commande
  • Permettre la Commande Via la Shell (Touche droite de la souris sur un fichier Exe)
  • · Création d'une classe de travail pour les Files Mapping


2. Définition du GUI



2.1. définition de la forme principale


Pour Commencer nous allons définir la forme Principale
Déposer les Composants suivants sur une Form

1 TAction List ActionList1
1 TImageList ImageList1
1 TMainMenu MainMenu1
1 TOpenDialog OpenDialog1
1 TTool Bar Align = alTop
1 TPanel Align = alClient
1 TStatusBar ""
Déposer les Composants sur le Panel

1 Tedit Edit1
1 Tbutton Button1
1 Tlabel Label1
Clicker avec la touche droite de la souris sur la tool Bar et créer 4 Boutons

TToolsButtons ToolsButtons1
TToolsButtons ToolsButtons2
TToolsButtons ToolsButtons3
TToolsButtonsl ToolsButtons4

2.2. ImageList


Nous allons créer Charger les Images dans le composant ImageList1
choisir 5 Images dans les fichiers communs de Borland

Image1 Open File
Image2 Execute
Image3 Cancel
Image4 Close
Image5 Help


2.3. ActionsList


Ouvrir le composant ActionList1

Nom Caption Image OnExecute
OpenFile Open * OpenFileExecute
Execute Execute * ExecuteExecute
CancelAction Cancel * CancelActionExecute
About A propos de * AboutExecute
*= Index de l'image choisie


2.3. Menu Principal


Création d'un menu selon Image Suivante

donnez aux Items Actions les valeurs suivantes

Item Action
Open OpenFile
Execute Execute
Close CloseApp
A Propos de About

2.4. Tools Buttons


Donnez aux aux Actions de Buttons les Valeurs Suivantes

Item Action
ToolButton1 OpenFile
ToolButton2 Execute
CancelAction CancelAction
ToolButton6 CloseApp
Le design de l'application est maintenant terminé


3. Classe TMMF


Pour travailler en C++ avec les API WIN32 il est préférable de déclarer une nouvelle classe


3.1. But de cette classe


  • Encapsuler les Api relatives aux Files Mapping
  • Fournir via l'appel a une méthode public un pointeur sur une zone mappée
  • Dans le cas d'une erreur fournir un message d'erreur win32


3.2. Déclaration de la classe


#ifndef MMFH
#define MMFH
#include <vcl.h>
//---------------------------------------------------------------------------
class TMMF {
   
        private :
        HANDLE FFileMap;
        HANDLE FFileHandle;
        void * FMappingPtr;
        DWORD FFileSize;
        DWORD FFileSizeHigh;
        AnsiString FFileName;
        AnsiString FErrorMsg;
        void __fastcall GetFile();
        void __fastcall GetMapping();
        void __fastcall GetPtrAdresse();
        void __fastcall GetSizeofFile();
       
    protected :
   
        public :
        __fastcall TMMF();
        __fastcall TMMF(AnsiString FileName);
        __fastcall ~TMMF();
        bool __fastcall Execute();
        __property HANDLE FileHandle = { read = FFileHandle };
        __property HANDLE MappingHandle = { read = FFileMap };
        __property void * PtrMapping = { read = FMappingPtr };
        __property AnsiString ErrorMessage = { read = FErrorMsg };
        __property DWORD FileSize = { read = FFileSize };
       
   
} //---------------------------------------------------------------------------

définitions des champs

Champs description
HANDLE FFileMap Contient le Handle du fichier Ouvert
HANDLE FFileHandle Contient le Nom du Fichier
void* FMappingPtr Contient le pointeur sur la zone mappée
DWORD FFileSize Contient la taille du fichier mappé
DWORD FFileSizeHigh Contient la taille haute du fichier mappé
AnsiString FFileName Contient le nom du fichier à mappé
AnsiString FErrorMsg Contient le message d'erreur
définitions des méthodes

Méthode partie description
__fastcall TMMF() public Constructeur par défault
__fastcall TMMF(AnsiString FileName) public Constructeur avec nom du fichier
__fastcall ~TMMF(); public destructeur
bool __fastcall Execute() public appel des différentes fonctions
void __fastcall GetFile() private initialise FfileHandle
void __fastcall GetPtrAdresse() private initialise FMappingPtr
void __fastcall GetSizeofFile() private initialise FfileSize et FfileSizeHigh

3.3. Implémentation de la classe


Constructeur

#include "MMF.h"
//---------------------------------------------------------------------------
__fastcall TMMF::TMMF()
    :FFileMap(NULL),
    FFileHandle(NULL),
    FMappingPtr(NULL),
    FFileSize(0),
    FFileSizeHigh(0),
    FFileName(""),
    FErrorMsg("")
   
{
   
}


3.4. Constructeur avec FileName


//---------------------------------------------------------------------------
__fastcall TMMF::TMMF(AnsiString FileName)
    :FFileMap(NULL),
    FFileHandle(NULL),
    FMappingPtr(NULL),
    FFileSize(0),
    FFileSizeHigh(0),
    FFileName(""),
    FErrorMsg("")
   
{
    FFileName=FileName;
   
} //---------------------------------------------------------------------------


3.5. Destructeur


__fastcall TMMF::~TMMF()
{
    if (FMappingPtr)
    {
        UnmapViewOfFile(FMappingPtr);
        FMappingPtr=NULL;
        }
    if (FFileMap)
    {
        CloseHandle(FFileMap);
        FFileMap=NULL;
        }
    if (FFileHandle)
    {
        CloseHandle(FFileHandle);
        FFileHandle=NULL;
        }
   
} //---------------------------------------------------------------------------


3.6. Méthode GetFile


void __fastcall TMMF::GetFile()
{
    FFileHandle=CreateFile(FFileName.c_str(), // pointer to name of the file
   
        GENERIC_READ|GENERIC_WRITE, // access (read-write) mode
        FILE_SHARE_READ|FILE_SHARE_WRITE,// share mode
        NULL, // pointer to security attributes
        OPEN_EXISTING, // how to create
        FILE_ATTRIBUTE_NORMAL, // file attributes
        NULL); //TODO: Add your source code here
       
    if (FFileHandle==NULL |(long )FFileHandle==-1)
    RaiseLastOSError();
   
} //---------------------------------------------------------------------------


3.7. Méthode GetMapping


void __fastcall TMMF::GetMapping()
{
    FFileMap=CreateFileMapping(FFileHandle, // handle to file to map
   
        NULL, // optional security attributes
        PAGE_READWRITE, // protection for mapping object
        0, // high-order 32 bits of object size
        0, // low-order 32 bits of object size
        NULL); //
       
    if (!FFileMap)
    RaiseLastOSError();
   
} //---------------------------------------------------------------------------


3.8. Méthode GetPtrAdresse


void __fastcall TMMF::GetPtrAdresse()
{
    FMappingPtr=MapViewOfFile(FFileMap,
   
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        0);
       
    if (!FMappingPtr)
    RaiseLastOSError();
   
}


3.9. Méthode Execute


bool __fastcall TMMF::Execute()
{
    try
    {
        GetFile();
        GetMapping();
        GetPtrAdresse();
        }
    catch (EOSError &E)
    {
        FErrorMsg=E.Message;
        return false;
        }
    GetSizeofFile();
    return true;
   
}


3.10. Méthode GetSizeofFile


void __fastcall TMMF::GetSizeofFile()
{
    FFileSize=GetFileSize(FFileHandle,&FFileSizeHigh);
}


3.11. Explicatif


Généralement les APIwin32 retourne un code indiquant si l'opération désirée s'est terminée par un succès
Une valeur de 0 ou true indique une opération terminée avec succès
Dans le cas contraire un appel GetLastError() nous retourne le code d'erreur

La VCL intègre une classe EOSError permettant de retourner dans la variable membre Message
le code ainsi que le message d'erreur

Il suffit donc de tester la sortie de l'api et en cas d'insuccès de générer une exception
De type EOSError par un appel à RaiseLastOSError()

La classe d'exception EOSError est intégrée dans C++ builder 6 dans les versions précédentes
On peut utiliser la classe d'exception EWin32Error et pour le déclenchement
d'une exception de ce type l'appel à RaiseLastWin32Error()

Description des méthodes
Le constructeur

__fastcall TMMF::TMMF(AnsiString FileName)
    :FFileMap(NULL),
    FFileHandle(NULL),
    FMappingPtr(NULL),
    FFileSize(0),
    FFileSizeHigh(0),
    FFileName(""),
    FErrorMsg("")
   
{
    FFileName=FileName;
   
} }

initialise les membres de la classe puis copie dans FFileName le paramètre du constructeur

le Destructeur

__fastcall TMMF::~TMMF()
{
    if (FMappingPtr)
    {
        UnmapViewOfFile(FMappingPtr);
        FMappingPtr=NULL;
        }
    if (FFileMap)
    {
        CloseHandle(FFileMap);
        FFileMap=NULL;
        }
    if (FFileHandle)
    {
        CloseHandle(FFileHandle);
        FFileHandle=NULL;
        }
   
} //---------------------------------------------------------------------------

teste l'état des différents pointeurs , libére la zone mappée ainsi que les handles de fichiers

méthode GetFile()

void __fastcall TMMF::GetFile()
{
    FFileHandle=CreateFile(FFileName.c_str(), // pointer to name of the file
   
        GENERIC_READ|GENERIC_WRITE, // access (read-write) mode
        FILE_SHARE_READ|FILE_SHARE_WRITE,// share mode
        NULL, // pointer to security attributes
        OPEN_EXISTING, // how to create
        FILE_ATTRIBUTE_NORMAL, // file attributes
        NULL); //TODO: Add your source code here
       
    if (FFileHandle==NULL |(long )FFileHandle==-1)
    RaiseLastOSError();
   
} //---------------------------------------------------------------------------

cette méthode utilise l'API WIN32 CreateFile pour obtenir un Handle de fichier
le champ FFileHandle contient le Handle du fichier
si la valeur de retour est différente d'un Handle Valide on génère une exception

méthode GetMapping

void __fastcall TMMF::GetMapping()
{
    FFileMap=CreateFileMapping(FFileHandle, // handle to file to map
   
        NULL, // optional security attributes
        PAGE_READWRITE, // protection for mapping object
        0, // high-order 32 bits of object size
        0, // low-order 32 bits of object size
        NULL); //
       
    if (!FFileMap)
    RaiseLastOSError();
   
} //---------------------------------------------------------------------------

cette méthode utilise l'API WIN32 CreateFileMapping pour créer une zone commune en mémoire
et retourner dans le le champ FFileMap un Handle sur cette zone
si la valeur de retour est NULL on génère une exception

méthode GetPtrAdresse

void __fastcall TMMF::GetPtrAdresse()
{
    FMappingPtr=MapViewOfFile(FFileMap,
   
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        0);
       
    if (!FMappingPtr)
    RaiseLastOSError();
   
}

cette méthode utilise l'API WIN32 MapViewofFile qui retourne dans FMappingPtr
un pointeur sur la zone mappée en mémoire avec FFileMap en paramètre
si la valeur de retour est NULL on génère une exception

méthode GetSizeofFile

void __fastcall TMMF::GetSizeofFile()
{
    FFileSize=GetFileSize(FFileHandle,&FFileSizeHigh);
    }

cette méthode initialise les 2 champs membres FFileSize et FFileSizeHigh avec la longueur
du fichier obtenu par l'appel à GetFileSize

méthode Execute

bool __fastcall TMMF::Execute()
{
    try
    {
        GetFile();
        GetMapping();
        GetPtrAdresse();
        }
    catch (EOSError &E)
    {
        FErrorMsg=E.Message;
        return false;
        }
    GetSizeofFile();
    return true;
   
}

la méthode Execute est le cœur de cette classe , elle appelle successivement dans une partie protégée
du programme (try catch) GetFile,GetMapping,GetPtrAdresse
en cas d'erreur dans une de ces méthodes la variable FerrorMessage

est initialisée avec le message d'erreur retournée par le système d'exploitation


4. Classe Tform


Déclaration de la classe

//---------------------------------------------------------------------------
#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include lt;Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <ActnList.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <ImgList.hpp>
#include <Menus.hpp>
#include <ToolWin.hpp>
#define ExeKeyName "exefile\\shell"
#define CommandKeyName "ExportCleaner\\Command"
#define PrgKeyName "ExportCleaner"
#define Command "ExportCleaner.exe %1"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
    __published: // Composants gérés par l'EDI
    TPanel *Panel1;
    TToolBar *ToolBar1;
    TOpenDialog *OpenDialog1;
    TMainMenu *MainMenu1;
    TImageList *ImageList1;
    TActionList *ActionList1;
    TAction *OpenFile;
    TAction *Execute;
    TAction *CloseApp;
    TEdit *Edit1;
    TButton *Button1;
    TLabel *Label1;
    TMenuItem *Open1;
    TMenuItem *Execute1;
    TMenuItem *Open2;
    TMenuItem *Close1;
    TMenuItem *N3;
    TAction *CancelAction;
    TStatusBar *StatusBar1;
    TToolButton *ToolButton1;
    TToolButton *ToolButton2;
    TToolButton *ToolButton5;
    TToolButton *ToolButton6;
    TMenuItem *Aide;
    TAction *About;
    TMenuItem *AProposde1;
    void __fastcall OpenFileExecute(TObject *Sender);
    void __fastcall CloseAppExecute(TObject *Sender);
    void __fastcall ExecuteExecute(TObject *Sender);
    void __fastcall CancelActionExecute(TObject *Sender);
    void __fastcall FormDestroy(TObject *Sender);
    void __fastcall AboutExecute(TObject *Sender);
    private :
    AnsiString FileName; // Déclarations de l'utilisateur
    void * DirectoryEntry;
    void __fastcall CleanPtr();
    void __fastcall ParseCmdLine();
    public : // Déclarations de l'utilisateur
    __fastcall TForm1(TComponent* Owner);
   
} ;
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

nous allons déclarer dans la partie private de la classe TForm1
les champs Suivants

AnsiString FileName; // Déclarations de l'utilisateur
void* DirectoryEntry;

les Méthodes suivantes

void__fastcall CleanPtr();
void__fastcall ParseCmdLine();
description des champs

FileName est utilisé pour stocker le nom de l'exécutable à traiter
DirectoryEntry est un pointeur sur la directoy entry de l'exécutable


4.1. Constructeur


__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
   
{
    pMap=NULL;
    CleanPtr();
    StatusBar1->SimpleText="Please Select exe File";
    if (ParamCount()>=1)
   
    ParseCmdLine(); // appel avec une ligne de commande
    }

on appelle un méthode pour s'assurer que les pointeurs sont dans un état défini,
et que les hanlde de fichiers sont tous libéré
l'appel à la méthode ParseCmdLine permet de controler si une ligne de commande est présente


4.2. Méthode OpenFileExecute


void __fastcall TForm1::OpenFileExecute(TObject *Sender)
{
    if (OpenDialog1->Execute())
    {
        FileName=OpenDialog1->FileName;
        Edit1->Text= FileName;
        StatusBar1->SimpleText="Please Press Execute";
        }
    Execute->Enabled = (FileName!="");
    }

cette méthode appelée depuis le menu ou un Tools Button affiche une DialogBox Standard
qui permet la saisie de l'exécutable à traiter


4.3. Méthode CloseApp


void __fastcall TForm1::CloseAppExecute(TObject *Sender)
{
    Close();
    }

Appelle la fermeture du programme


4.4. Méthode ExecuteExecute


void __fastcall TForm1::ExecuteExecute(TObject *Sender)
{
    ULONG DSize;
    IMAGE_NT_HEADERS * myImage;
    DWORD HeaderSum,CheckSum ;
    TMMF * myMMF = new TMMF(FileName);
    Execute->Enabled=false;
    OpenFile->Enabled=false;
    if (myMMF->Execute())
    {
        try
        {
            DirectoryEntry=ImageDirectoryEntryToData(myMMF->PtrMapping,
            false,
            IMAGE_DIRECTORY_ENTRY_EXPORT,
            &DSize );
            if (!DirectoryEntry)
            RaiseLastOSError();
            FlushViewOfFile(DirectoryEntry,DSize);
            myImage= CheckSumMappedFile(myMMF->PtrMapping,
            myMMF->FileSize,
            &HeaderSum,
            &CheckSum);
            myImage->OptionalHeader.DataDirectory[0].VirtualAddress=0L;
            myImage->OptionalHeader.DataDirectory[0].Size=0L;
            }
        catch (EOSError &E)
        {
            StatusBar1->SimpleText="Exe File Contains no Export Directories";
            MessageDlg(StatusBar1->SimpleText,mtInformation,TMsgDlgButtons()<< mbOK, 0);
            delete myMMF;
            CleanPtr();
            OpenFile->Enabled=true;
            return ;
            }
        StatusBar1->SimpleText="Saved Successfuly ..." ;
        MessageDlg(StatusBar1->SimpleText,mtInformation, TMsgDlgButtons()<< mbOK, 0);
        }
    else
    {
        MessageDlg(myMMF->ErrorMessage, mtError, TMsgDlgButtons() << mbOK, 0);
        StatusBar1->SimpleText="Error occurs ....";
        }
    delete myMMF;
    CleanPtr();
    OpenFile->Enabled=true;
    }

cette méthode est le cœur du programme



    IMAGE_NT_HEADERS * myImage; DWORD HeaderSum,CheckSum ; ULONG DSize;
   

MyImage est un pointeur sur la structure IMAGE_NT_HEADERS qui contient la Strucuture du fichier dans le monde Windows PE32 HeaderSum,CheckSum,Dsize sont des variables de Travail


    TMMF * myMMF = new TMMF(FileName); MyMMF contient une instance de la classe TMMF

L'appel à la méthode Execute va nous retourner un pointeur sur la zone mappée
Dans un bloc protégé on va tenter d'obtenir dans DirectoryEntry un pointeur sur la table d'exportation
de l'executable par un appel a l'API WIN32 ImageDirectoryEntryToData
En cas de retour avec une valeur NULL une execption est déclenchée

Cette exeption est interceptée dans le Bloc Catch qui affiche une boîte de dialogue
Affiche une message dans la ligne de Status, détruit le myMMF,et sort de la méthode

si tout c'est bien passé Il nous reste maintenant à supprimer cette table d'exportation à l'aide
FlushViewOfFile(DirectoryEntry,DSize);

Nous devons maintenant ajuster l'entête PE de notre exécutable à une valeur correcte

myImage= CheckSumMappedFile(

    pMap,
    FielSize,
    &HeaderSum,
    &CheckSum);
    myImage->OptionalHeader.DataDirectory[0].VirtualAddress=0L;
    myImage->OptionalHeader.DataDirectory[0].Size=0L;
   

l'Api CheckSumMappedFile nous renvoie un pointeur sur IMAGE_NT_HEADERS, ainsi que la taille du Header et son check Summ on positionne à la taille à 0


    myImage->OptionalHeader.DataDirectory[0].VirtualAddress=0L;
    myImage->OptionalHeader.DataDirectory[0].Size=0L;
   

On affiche le résultat des operations dans la StatusBar ,ainsi que dans une boite de dialogue , détruit le myMMF,et sort de la méthode


4.5. Méthode CleanPtr


void __fastcall TForm1::CleanPtr()
{
    DirectoryEntry=NULL;
    FileName=NULL;
    Edit1->Text="";
    }

la méthode CleanPtr réinitialise les variables,ainsi que le champ Edit1->Text


4.6. Méthode CancelActionExecute


void __fastcall TForm1::CancelActionExecute(TObject *Sender)
{
    OpenFile->Enabled=true;
    Execute->Enabled=false;
    CleanPtr();
    StatusBar1->SimpleText="Please Select exe File";
    }

Cancel annule les ordres en cours , appelle cleanPtr, et remet le système dans son état de départ


4.7. Méthode FormDestroy


void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    CleanPtr();
    }

Form Destroy Appelé par Close() libére la mémoire


4.8. Méthode ParseCmdLine


void __fastcall TForm1::ParseCmdLine() {
    AnsiString Tmp;
    int ParamNr=ParamCount();
    if (ParamNr ==1) // Command Line Exists
    {
        AnsiString cmd=ParamStr(1).UpperCase();
        if ((cmd =="/INSTALL") ||(cmd =="/UNINSTALL"))
        {
            TRegistry* mReg= new TRegistry();
            try
            {
                mReg->RootKey=HKEY_CLASSES_ROOT;
                mReg->OpenKey(ExeKeyName,false); // open Shell Key in registry
                if (cmd =="/INSTALL")
                }{
                    if (!mReg->KeyExists(PrgKeyName))
                    {
                        mReg->OpenKey(CommandKeyName,true); // Command Install
                        mReg->WriteString("",Command);
                        MessageDlg("Export Cleaner installed Succesfuly", mtInformation, TMsgDlgButtons() << mbOK, 0);
                        }
                    }
                } if (cmd =="/UNINSTALL")
                {
                    if (mReg->KeyExists(PrgKeyName))
                    mReg->DeleteKey(PrgKeyName); // delete Registry Key
                    MessageDlg("Export Cleaner desinstalled Succesfuly", mtInformation, TMsgDlgButtons() << mbOK, 0);
                    }
                }
            catch (...)
            {
                mReg->CloseKey();
                }
            delete mReg;
            Application->Terminate(); // Exit Application
            }
        else
        {
            for (int i=0;i<ParamNr;i++)
            {
                Tmp+=ParamStr(i+1);
                Tmp+=" ";
                }
            Tmp.Delete(Tmp.Length(),1); //delete Last Space
            FileName=Tmp;
            if ((!FileExists(Tmp)) &&(ExtractFileExt(Tmp)!=".exe")
            ) MessageBox(Application->Handle,
            "File Not Exist or Not a valid Exe File",
            "Export Cleaner",
            MB_OK|MB_ICONINFORMATION);
            else ExecuteExecute(NULL); // Call suppress
            Application->Terminate(); // Exit Application
            }
        }
    }

cette méthode teste la présence d'une ligne de commande
si la ligne de commande est égale à INSTALL le programme installe dans la registry
un shell pour les fichiers de type exe
ce qui permettra avec un click bouton droit de la souris la possibilité de lancer le
programme exportCLeaner.exe
une boite de dialogue vous indique le résultat de l'opération
La ligne de commande avec un une valeur egale à /UNINSTALL supprimera de la registry la shell
pour les fichiers de type exe

si une ligne de commande est présente et n'est pas égale aux commdes d'installation cela signifie
que le paramètre est le nom du fichier exe à traiter
on test s'il s'agit bien d'un fichier executable et si la réponse est positive on lance l'application


5. Instalation dans C++ Builder


  • dans le menu Outils sélectionner Configurer les outils
  • sélectionner ajouter
  • Dans le champ Titre insérer ExportCLeaner
  • sélectionner le bouton Parcourir et sélectionner le fichier ExportCleaner.exe
  • sélectionner le bouton Macro dans la listBox choisisser $TDW
  • sélectionner le bouton Insérer
  • sélectionner le bouton OK

ExportCleaner est désormais installé et apparait dans la liste d'outils


6. Utilisation dans C++ Builder


  • Compiler un nouveau projet
  • sélectionner dans le menu Outil l'item ExportCleaaner
  • a la fin de l'excution du programme une boite de dialogue vous indique le résultat de l'opération


Voir également mes autres articles :
Utilisation des Files Mapping sous C++Builder C++ Builder
La technique des PatchFiles C++ Builder
Maîtrisez les files d'impression sous windows C++ Builder
Travailler avec les Interfaces en C++Builder Partie 1 C++ Builder
Composant de gestion des ports d'imprimantes C++ Builder
Programme de Test Version ActiveX du composant TDLIoport Delphi
Sans oublier :
la FAQ C++ Builder par Geronimo
la FAQ C
la FAQ C++

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Responsables bénévoles de la rubrique Accueil : Nicolas Vallée (gorgonite) et Guillaume Rossolini (Yogui) - Contacter par EMail :
Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.