Interaction Windows Explorer/mon Appli

Résolu
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 11 juil. 2005 à 16:33
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 13 juil. 2005 à 18:50
Salut tout le monde,
je voudrais après avoir seleccionné des fichiers/répertoires ds Windows Explorer, ouvrir le popMenu de Windows Explorer et y montrer une option genre 'Traiter dans mon appli' qui ouvrirait mon prog. Ce dernier me montrant dans un memo par exemple, les fichiers seleccionnés.
A+

25 réponses

jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
13 juil. 2005 à 10:41
Bonjour tout le monde, je suis parti de l'exemple de Borland et du Net
pour arriver à cela,,je n'ai pas affiché le fichier dans un Mémo mais à
l'aide d'un ShowMessage tout simple:



Il faut tout d'abord créer une Bibliothèque ActiveX, puis ajouter un
objet COM, cela va générer un squelette de code à compléter:





Fichier dpr:



library MyContextMenu;



uses

ComServ,

TestMenu in 'TestMenu.pas',

MyContextMenu_TLB in 'MyContextMenu_TLB.pas';



exports

DllGetClassObject,

DllCanUnloadNow,

DllRegisterServer,

DllUnregisterServer;



{$R *.TLB}



{$R *.RES}



begin

end.



Unit TestMenu.pas :



unit TestMenu;



interface



uses

Windows, ActiveX, Classes, ComObj, ShlObj;



type

TMyContextMenu = class(TComObject, IShellExtInit, IContextMenu)

private

FFileName: array[0..MAX_PATH] of Char;

protected

{Déclarez les méthodes IShellExtInit ici}

// On redirige la procédure Initialize car elle
existe déjà dans TComObject, mais n'est pas compatible avc IShellExtInit

function IShellExtInit.Initialize = SEIInitialize;

function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;

hKeyProgID: HKEY): HResult; stdcall;



{Déclarez les méthodes IContextMenu ici}

//Lorsqu'on demande l'affichage du menu

function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,

uFlags: UINT): HResult; stdcall;

//Lorsqu'on invoque une commande, clic sur un item du menu

function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;

//Utilisée pour l'aide

function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;

pszName: LPSTR; cchMax: UINT): HResult; stdcall;

end;



const

Class_TMyContextMenu: TGUID = '{C763DB5D-B6A8-4A21-9B7E-41EF5CBABD56}';



implementation



uses ComServ,ShellAPI,SysUtils,Dialogs, Registry;



function TMyContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult;

var

StgMedium: TStgMedium;

FormatEtc: TFormatEtc;

begin

// Exit si aucun objet n'est sélectionné

if (lpdobj = nil) then begin

Result := E_INVALIDARG;

Exit;

end;



with FormatEtc do begin

cfFormat := CF_HDROP;

ptd := nil;

dwAspect := DVASPECT_CONTENT;

lindex := -1;

tymed := TYMED_HGLOBAL;

end;



//on récupère les Data du IdataObject et dans on les stocke dans un container au format CF_HDROP

Result := lpdobj.GetData(FormatEtc, StgMedium);

if Failed(Result) then

Exit;

//On trouve le fichier sélectionné

if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1) then begin

DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));

Result := NOERROR;

end

else begin

FFileName[0] := #0;

Result := E_FAIL;

end;

ReleaseStgMedium(StgMedium);

end;







function TMyContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,

idCmdLast, uFlags: UINT): HResult;

begin

Result := 0;



if ((uFlags and $0000000F) = CMF_NORMAL) or

((uFlags and CMF_EXPLORE) <> 0) then begin

// Ajoute un item au menu

InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst,

'TEST MENU');



// Retourne le nombre d'items ajoutés

Result := 1;

end;

end;





function TMyContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;



begin

Result := E_FAIL;



//Si le mot de poids fort > 0, cela veut dire que l'action est souvent déclenchée par une autre application

if (HiWord(Integer(lpici.lpVerb)) <> 0) then

begin

Exit;

end;



if (LoWord(lpici.lpVerb) <> 0) then begin

Result := E_INVALIDARG;

Exit;

end;

//Affichage du fichier sélectionné, on peut l'ajouter dans un Mémo bien sûr

ShowMessage(FFileName);

Result := NOERROR;

end;



function TMyContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;

pszName: LPSTR; cchMax: UINT): HRESULT;

begin

if (idCmd = 0) then begin

if (uType = GCS_HELPTEXT) then

// Retourne la chaine d'aide pour l'item du menu

StrCopy(pszName, 'Help String');

Result := NOERROR;

end

else

Result := E_INVALIDARG;

end;



//On crée une classe enfant de TComObjectFactory.

//Cela permet de surcharger la méthode virtuelle UpdateRegistry qui permettra

//en plus du recensement de l'objet COM d'activer le ContextMenu pour tous les fichiers(*)

// et les répertoires (Directory).

type

TContextMenuFactory = class(TComObjectFactory)

public

procedure UpdateRegistry(Register: Boolean); override;

end;





procedure TContextMenuFactory.UpdateRegistry(Register: Boolean);

var

ClassID: string;

begin

if Register then begin

inherited UpdateRegistry(Register);



ClassID := GUIDToString(Class_TMyContextMenu);

CreateRegKey('*\shellex', '', '');

CreateRegKey('*\shellex\ContextMenuHandlers', '', '');

CreateRegKey('*\shellex\ContextMenuHandlers\TEST CONTEXT MENU', '', ClassID);

CreateRegKey('Directory\shellex', '', '');

CreateRegKey('Directory\shellex\ContextMenuHandlers', '', '');

CreateRegKey('Directory\shellex\ContextMenuHandlers\TEST CONTEXT MENU', '', ClassID);



if (Win32Platform = VER_PLATFORM_WIN32_NT) then

with TRegistry.Create do

try

RootKey := HKEY_LOCAL_MACHINE;


OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions',
True);

OpenKey('Approved', True);

WriteString(ClassID, 'TEST CONTEXT MENU');

finally

Free;

end;

end

else begin

DeleteRegKey('*\shellex\ContextMenuHandlers\TEST CONTEXT MENU');

DeleteRegKey('*\shellex\ContextMenuHandlers');

DeleteRegKey('*\shellex');

DeleteRegKey('Directory\shellex\ContextMenuHandlers\TEST CONTEXT MENU');

DeleteRegKey('Directory\shellex\ContextMenuHandlers');

DeleteRegKey('Directory\shellex');



inherited UpdateRegistry(Register);

end;

end;





initialization

TContextMenuFactory.Create(ComServer, TMyContextMenu, Class_TMyContextMenu,

'TMyContextMenu', 'TEST CONTEXT MENU', ciMultiInstance, tmApartment);

end.



J'ai commenté mais n'hésitez pas à poser des questions ou à exprimer des remarque sur des améliorations éventuelles.
















j!nH
3
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
13 juil. 2005 à 17:15
Faux :). En fait ma source le permet facilement. Si tu regardes dans la méthode SEInitialize,

if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1) then begin
DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));

Tu vois qu'il teste si un fichier uniquement a été sélectionné, il suffit de changer ce test et de boucler ensuite sur tous les fichiers sélectionnés :) en remplaçant $FFFFFFFF par l'indice du fichier.

j!nH
3
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
11 juil. 2005 à 17:24
Salut,
Si tu as Windows XP, tu peux mettre ce raccourci dans le menu Envoyer Vers en ajoutant un raccourci qui pointe vers ton application dans le dossier C:\Documents and Settings\Nom du Compte\SendTo\.
Sinon je pense que il faut modifier la base de registre pour le mettre directement dans le popup-menu.



<HR>

Le plus dur dans un programme c'est de savoir pourquoi il marche !
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
11 juil. 2005 à 17:33
Salut Cedricbi,
c' est bien sur la base de registre qu' il faut travailler mais tu me donnes pas la soluce.
D' ailleurs, celui qui s' est le plus approché de ce sujet fut VBFrance (je crois) sur une source postée sur ce site en utilisant les DDE Commands.
J' ai moi même posté une source sur les DDE Commands inspirée de la source de VBFrance mais en simplifiant le tout pour que se soit utilisable dans n' importe quel prog. Cela montre comment enregistrer son extension pour qu' elle soit reconnue sous Win et que les fichiers de l' extension désirée s' ouvre avec notre prog. Facile me direz vous? Et si on clique sur un autre fichier de même extension? Il faut récupérer la commande DDE dans l' instance de notre prog. déjà ouvert et ouvrir une nouvelle fenêtre pour le 2nd fichier.
Comme tu peux le voir, je suis loin de ne pas connaitre le sujet!
Ce qu'il me faudrait maintenant c' est un exemple montrant de comment fait WinZip/WinRar par exemple ... A+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
roud59 Messages postés 99 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 26 juillet 2007 2
11 juil. 2005 à 18:22
Bonjour Mauricio

Tu peux aller voir ShellExt dans les demos de Delphi (...\Demos\ActiveX\ShellExt). Je ne suis pas sûr que ça repondra à 100% à ton problème mais qui sait ...

Roud59
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
11 juil. 2005 à 18:44
Merci pour l' intention mais j' ai déjà essayé de "pomper" quelques sur ces exemples mais rien ...
a+
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
12 juil. 2005 à 01:01
J'avais fait ceci, mais pour un seul fichier. En esperant que ca t'aide.



procedure TMainForm.RegisterExt(Ext, IDTypeFichier, NomTypeFichier : string);

begin

with TRegistry.Create do

try

RootKey := HKEY_CLASSES_ROOT; // Pour tout le monde

// RootKey := HKEY_LOCAL_MACHINE; // Pour l'utilisateur en cours



// Affectation à l'extension Ext le type IDTypeFichier

OpenKey('\.'+Ext, True);

WriteString('', IDTypeFichier);

CloseKey;



// Spécification du nom du type de fichier

OpenKey('\'+IDTypeFichier, True);

WriteString('', NomTypeFichier);

CloseKey;



// Spécification de l'icône assossiée aux fichiers de ce type

OpenKey('\'+IDTypeFichier+'\DefaultIcon', True);

WriteString('', Application.ExeName+',0');

CloseKey;



// Spécification de la liste des commandes

OpenKey('\'+IDTypeFichier+'\shell', True);

WriteString('open','');

CloseKey;



// Spécification du nom de la commande open

OpenKey('\'+IDTypeFichier+'\shell\open', True);

WriteString('', '&Editer ce fichier');

CloseKey;



// Spécification de la commande open

OpenKey('\'+IDTypeFichier+'\shell\open\command', True);

WriteString('', '"'+Application.ExeName+'" "%1"');

CloseKey;

finally

Free;

end;

end;



(Fonction largement inspiré sur celle de Developpez.com)



Je pense que tu peux recuperer tout les noms de fichiers en regardant les valeurs de ParamStr(1),ParamStr(2),ParamStr(...)
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
12 juil. 2005 à 10:19
Merci cptPingu, mais comme je le dis plus haut, le problème n' est pas de cette nature ...
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
12 juil. 2005 à 15:34
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
12 juil. 2005 à 15:38
Et les gars, vous le faites exprès? C' est peut être la chaleur après tout, j' explique encore une fois:

je voudrais après avoir seleccionné , ouvrir le popMenu de Windows Explorer et y montrer une option genre 'Traiter dans mon appli' qui ouvrirait mon prog. Ce dernier me montrant dans un memoles fichiers seleccionnés</gras>.
A+
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
12 juil. 2005 à 15:47
Keep Cool gars, la chaleur c'est pas trop le cas ds mon coin aujourd'hui :).



Alors bon j'espère ne pas me planter cette fois ci, et que cela va te détendre un peu :



http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/copyhookhandlers.asp




j!nH
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
12 juil. 2005 à 15:59
Merci pour l' effort jinh68 !
C' est bien trop compliqué mais il me semble que ce n' est pas ça non plus même si ça y est tout près (d' après ce que j' ai compris, on peut créer un prog. pour aprouver/anuler l' elimination des fichiers etc ...) ...
Et biensur mon dernier commentaire z' était pour rire !!!

N' empêche que c' est pas evident, j' ai même regardé le Registry pour voir comment faisait WinZip/WinRar.
On est pas couché
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
12 juil. 2005 à 16:11
Lol je suis trop con j'ai mis le mauvais lien, le bon lien est :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/shell_ext.asp

En fait c'est pas si compliqué une fois qu' on a compris le principe, le tout est de savoir utiliser les interfaces.

Tu peux trouver des exemples sur le net avc le mot clé <!--StartFragment -->
Context Menu Handlers



Bon courage, et si tu arrives au bout, on pourra faire un tuto sur ce sujet peu documenté !

j!nH
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
12 juil. 2005 à 16:17
Désolé mais j' avais déju vu cette page depuis un link de la page que tu m' as donné précédemment ...
C' est vrai que c' est un sujet presque tabou vu que l' on trouve pas un seul exemple sur ce sujet ...

Pour info, ça fait quelques mois déjà que je cherche. J' ai au moins appris à créer une association de fichier à un programme fait par moi.
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
12 juil. 2005 à 16:20
Bon ça y'est tu m'as filé une idée sur mon prochain sujet d'études , je te tiens au courant dès que j'ai quelque chose de solide.

j!nH
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
12 juil. 2005 à 16:26
Ok, je te conseille de regarder (je pense que ça va t' aider) dans le registry à l' extension * (étoile), tu verras un registre laissé par Winzip.

Si tu pouvais faire une source qui montrerait les fichiers seleccionnés dans WinExplorer dans un Memo, après chacun pourra en profiter pour sa propre finalité.
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
13 juil. 2005 à 11:16
En tout cas, bravo si ça marche...
Je vais essayer cet après midi. Tu vas poster une source ou pas?
0
jinh68 Messages postés 215 Date d'inscription mardi 29 juillet 2003 Statut Membre Dernière intervention 1 septembre 2006
13 juil. 2005 à 11:22
Je n'en ai posté encore aucune ici, mais pourquoi pas partir sur un compo directement :).

j!nH
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
13 juil. 2005 à 12:06
Oui, se serait mieux, bonne prog'!
0
cs_Kenavo Messages postés 702 Date d'inscription vendredi 21 mars 2003 Statut Membre Dernière intervention 1 octobre 2009 5
13 juil. 2005 à 12:07
Salut Mauricio,



Si la notion de CONTEXT MENU HANDLER peut sembler arride, la technique
de base, si elle te suffit, est beaucoup plus simple ! Surtout si tu
sais déja associer une extension à une application.



http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/context.asp




Ca ne permet pas tout, mais je pense que ça doit répondre (en partie) à ton problème.


Pour fonctionner correctement avec une sélection de plusieurs
fichiers, il faut que ton programme réponde correctement aux commandes
du shell :

- 1 seule instance du programme

- Récupération par l'instance existante des paramètres passé lors des nouvelles tentatives d'exécution



Pour ça, il y a le composant RunOne d'Etienne Mansot qui peut te rendre service (http://www.phidels.com/php/index.php3?page=../php/mescompo/runone.htm&id=419)


Ken@vo


<hr size="2" width="100%">Code, Code, Codec !

[%3C/body ]
0
Rejoignez-nous