Tutorial : Association d'un fichier dans Windows - par [SFX]-ZeuS


But :

  Ce tutorial va vous montrer comment lier un fichier par son extension à votre application et comment gérer l'ouverture de plusieurs fichiers dans la même application.
Il peut aussi servir d'exemple comme application en OneInstance, c'est-à-dire qui est autorisée à être lancée qu’une seule fois.

Situation :

  Nous allons travailler avec un exemple simple. Il s'agira d'une application qui va charger des fichiers texte d'extension ".PHD".
Pour cela, nous allons faire des TabSheet (du PageControl, onglet Win32) en dynamique avec un Memo qui chargera le fichier texte.

Création de l'application :

  Créer une nouvelle application. Puis disposer sur la Form un PageControl.
Mettez la propriété Align de votre PageControl à alClient.
Nous allons maintenant créer une procédure de création du TabSheet et chargement du fichier texte.

 

Ajoutez la procedure CreerNvlFiche(filename : string); sous le mot clef « public » de la class TForm1 :


public
   procedure CreerNvlFiche(filename : string);

procedure TForm1.CreerNvlFiche(filename : string);
 var
    Fiche : TTabSheet;
    Memo : TMemo;

begin
   Fiche:= TTabSheet.Create(Self);  // Création du TabSheet
   Fiche.PageControl := PageControl1; //Assignation du TabSheet au PageControl
   Fiche.Caption := ExtractFileName(filename); //Donne au nom du TabSheet le nom du fichier chargé

   Memo := TMemo.Create(Self); //Création du mémo
   Memo.Parent := Fiche //Assignation du mémo au TabSheet
   Memo.Align := alClient; //Met le mémo en Client
   Memo.Lines.LoadFromFile(filename); //Charge le fichier dans le mémo
end;


Association de l'extension .PHD  à notre application:

  Bien maintenant nous allons associer l'extension .PHD à notre application, avant quelques explications. Ouvrez la base de registre (Démarrer -> Executer puis Regedit.exe).  Développez la clé HKEY_CLASSES_ROOT (HKCU).
Cette clé contient toutes les extensions des fichiers répertoriées et associées à Windows.
A noter qu'il y a deux clés qui peuvent être intéressantes :

  • * : cette clé permet de rajouter dans le menu contextuel de la souris, l'ouverture de tous les fichiers avec votre application. Très pratique si vous voulez faire un éditeur Hexadécimal ou autre.
  • Unknow : Cette clé permet de rajouter dans le menu contextuel de la souris, l'ouverture de tous les fichiers inconnu par Windows.


Nous allons écrire notre procédure d'enregistrement de l'extension. Elle s'ecrit en deux étapes :

  • Création de la clé ".PHD"
  • Affecter "Phidels extension" à la Valeur (par défaut)

En fait nous allons faire une redirection sur une autre clé appeller "Phidels extension" ce qui va nous permettre d'associer plusieurs extension de fichier sans trop se casser la tête. Méthode à suivre :

  • Création de la clé "Phidels extension"
  • Créer une sous-clé "Shell"
  • Créer une sous-clé "Open"
  • Créer une sous-clé "Command"
  • Affecter "L'adresse de votre appli "%1" " à la Valeur (par défaut)

%1 correspond au nom complet du fichier (chemin absolu) que vous voulez ouvrir. Attention, les espaces peuvent être dans le nom de fichier, il faut donc mettre des guillemets pour bien dire à Windows que "C:\Documents and Settings\ZeuS\Bureau\Tuto Association\fichier.phd" est un ensemble (c'est important pour la suite). Cela donne donc "%1".

Voilà ce que vous devrier avoir:


Maintenant passons au code de cette fonction:


Dans les Uses de votre Form déclarer l'Unit "Registry".

procedure TForm1.Button1Click(Sender: TObject);
var
  reg:Tregistry;

begin
  reg:=TRegistry.Create; // ouverture de la base de registre
  reg.RootKey:=HKEY_CLASSES_ROOT; // On va dans la clé HKCU
  reg.OpenKey('.PHD',True); // Création de la clé .PHD seulement si elle n'existe pas
  reg.WriteString(' ','Phidels Extensions'); // On redirige l'extension sur notre clé
                                             //(le nom de la valeur est un chaine vide)
  reg.CloseKey // On ferme la clé

  reg.OpenKey('Phidels Extensions\Shell\Open\Command',True); // Création des trois
                                                            //clés si elles n'existent pas
  reg.WriteString(' ',' " '+ParamStr(0)+' " "%1" '); //On met le "chemin de notre appli" 
                                                     //+espace+ " %1", paramStr(0) premet de
                                                     //récuperer le chemin de l'application

  reg.CloseKey; // fermeture de la clé
  reg.free// on libere la base de registre
end;


J'ai écrit cette procédure dans un bouton mais elle devra être exécuté par votre application à son premier démarrage où encore lors de son installation.
Comme je le disais juste ci-dessus si vous voulez ouvrir en plus les fichiers .TXT vous n'aurez plus cas mettre en valeur par défaut "Phidels extensions".

Ouverture d'un fichier .PHD dans notre application:

 Après avoir enregistré votre extension dans la base de registre,  votre application devra maintenant savoir qu'il faut ouvrir un fichier lorsqu'elle est appelée avec un paramètre.

Pour cela nous allons utilisé la fonction
ParamStr(num : integer) :
    Nous l'avons utilisé juste avant avec
ParamStr(0) qui retourne lui le chemin de l'application + le nom de l'application.
   
ParamStr(1) lui va retourner le 1er paramètre
   
ParamStr(2) va retourner le 2nd paramètre etc. ...

En fait nous pouvons savoir le nombre de paramètre grâce à la fonction ParamCount qui renvoi le nombre de paramètre. Notez qu’il existe une fonction CmdLine renvoyant toute la liste des paramètres (y compris le 0) de l’application.

Attention: Les paramètres sont déterminés par les espaces et les guillemets si jamais vous oubliez de mette les guillemets autour du %1 vous aurez autant de paramètres que vous aurez d'espaces dans le chemin du fichier, comme dit plus haut.

Par exemple :
- C:\Nouveau Dossier\Tutoriel.PHD sans les guillemets  ParamStr(1)='C:\Nouveau' et ParamStr(2)='Dossier\Tutoriel.PHD'
- C:\Nouveau Dossier\Tutoriel.PHD avec les guillemets  ParamStr(1)='C:\Nouveau Dossier\Tutoriel.PHD'

   
Cela ce passe dans la procédure Create de votre Form principale :



procedure TForm1.FormCreate(Sender: TObject);
begin
   if ParamStr(1) <> '' then         //On vérifie que le premier paramètre n'est pas nul
       CreerNvlFiche(ParamStr(1));  //On charge une nouvelle fiche avec le fichier envoyé par le paramètre
end
;


Bon voila une bonne partie de faite. Maintenant le problème devient un peu plus dur lorsqu'on veut que plusieurs fichiers soient ouverts dans la même application. Car pour l'instant à chaque ouverture d'un fichier PHD, on se retrouve avec une application pour chaque fichier. Donc le but sera d'ouvrir des fichiers dans la même fenêtre, et ensuite on va un peu compliquer le tout en permettant l'ouverture de plusieurs applications en même temps.

Nous allons réaliser ceci en empêchant la nouvelle application de se lancer lorsqu'une application est déjà lancée sauf quand les paramètres d'exécution sont vides.

Mais il faut aussi penser à transmettre les nouveaux paramètres à l’application déjà lancée, cela sera réalisé grâce aux messages Windows.

Pour réaliser cela, ouvrez le code du projet (.DPR):


program Project1;

uses
  Forms,
 
Windows,
 
SysUtils,
 
Messages,
  Unit1 in 'Unit1.pas' {Form1};

const
  WM_PARAMETRE = WM_USER + 1 //Définition de notre numéro de message

{$R *.res}

var
  Texte : Atom;
  H : THandle;

begin
   //CreateMutex permet de vérifier si une application est déjà lancée
   CreateMutex(nil, False, PChar(ExtractFileName(Application.ExeName)));

   //Déjà lancé et paramètre non nul ?
   if (GetLastError = ERROR_ALREADY_EXISTS) and (ParamStr(1) <> '') then
   begin
     
//Stockage d'un PChar dans un Atom (si vous voulez plus d'explication
      //sur les Atom regardez dans la
MSDN)
      Texte := GlobalAddAtom(PChar(ParamStr(1)));
 
     
// On recherche le nom de la fenêtre lancé ici Form1
     
h := FindWindow(nil, 'Form1');

     
// On envoie a la fenêtre le message avec le paramètre     
      SendMessage(h, WM_PARAMETRE, 0, Texte);  
   end
   else
   begin  // exécution normale de l'application
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
   end;
end.


Bien voilà, maintenant on envoit un message contenant les nouveaux paramètres à l'application qui est déjà lancée, maintenant il faut les réceptionner.
On retourne donc dans notre Form:

Après les Uses on re-déclare notre message
  
const WM_PARAMETRE = WM_USER + 1;
 
Ensuite dans les déclarations public on rajoute une nouvelle procédure
  
procedure ReceptionParametre(var msg : TMessage); message WM_PARAMETRE;   

Bien maintenant on va réceptionner nos nouveaux paramètres:


procedure TForm1.ReceptionParametre(var Msg : TMessage);
var
  NumAtom : atom;
  Texte : PChar;

begin
   NumAtom := Msg.LParam; //on récupère l'adresse de l'Atom
   GetMem(Texte, 256); //on alloue 255 caractères (MAX_PATH) + le caractère 0
   GlobalGetAtomName(NumAtom, texte, 256); //on remplit le tableau de caractères
   GlobalDeleteAtom(NumAtom); // Surtout n'oubliez pas de libérer l'atom
   CreerNvlFiche(Texte); //on crée notre nouvelle fiche avec les nouveaux paramètres
   FreeMem(Texte); // on libère la mémoire allouée au tableau de char
end;


Et voila c'est fini !!! 
Vous pouvez télécharger ce tutorial avec l'exemple ici.

[SFX]-ZeuS
zeusfx@free.fr
 
À l'occasion visitez notre site www.sfxteam.org si vous êtes sur la région lyonnaise nous organisons fréquemment des LANs.

Corrigé, complété et adapté pour Phidels le 24/06/05 par [big_fury]SiZiOUS.