Utiliser Delphi pour écrire des extensions de shell Windows
Les amis qui connaissent les principes des systèmes d'exploitation sauront qu'un système d'exploitation complet fournira un shell pour faciliter les utilisateurs ordinaires.
Utilisez diverses fonctions fournies par le système d'exploitation. Le shell de Windows (fait ici référence au système d'exploitation Windows 95, Windows NT4.0 ou supérieur) fournit non seulement
Il fournit non seulement une interface graphique GUI pratique et esthétique, mais fournit également de puissantes fonctions d'extension de shell. Vous pouvez voir ces extensions de shell dans de nombreux logiciels. Par exemple dans votre
Si Winzip est installé sur le système, lorsque vous cliquez avec le bouton droit sur un dossier ou un fichier dans l'Explorateur Windows, le fichier Winzip apparaîtra dans le menu contextuel.
menu abrégé. Ou le dossier du site FTP qui apparaît dans l'Explorateur Windows dans Bullet FTP.
Windows prend en charge sept types d'extensions shell (appelées gestionnaires) et leurs fonctions correspondantes sont brièvement décrites comme suit :
(1) Gestionnaires de menus contextuels : ajoutez des menus contextuels à des types spécifiques d'objets de fichier ;
(2) Les gestionnaires de glisser-déposer sont utilisés pour prendre en charge la transmission de données OLE lorsque les utilisateurs effectuent des opérations de glisser-déposer sur certains types d'objets fichier ;
(3) Les gestionnaires d'icônes sont utilisés pour fournir une icône unique à un certain objet fichier et peuvent également spécifier une icône pour un certain type d'objet fichier ;
(4) Les gestionnaires de feuilles de propriétés ajoutent des pages de propriétés aux objets fichier (c'est-à-dire, cliquez avec le bouton droit sur l'objet fichier ou l'objet dossier et sélectionnez Propriétés dans le menu contextuel.
boîte de dialogue qui apparaît après l'élément), les pages de propriétés peuvent être partagées par des objets fichier du même type, ou une page de propriétés unique peut être attribuée à un objet fichier ;
(5) Les gestionnaires de crochet de copie seront appelés par le système lorsque l'objet dossier ou l'objet imprimante est copié, déplacé, supprimé ou renommé via Windows.
Ajoutez des gestionnaires de copy-hook pour autoriser ou interdire certaines opérations ;
(6) Les gestionnaires de cibles de dépôt seront appelés par le système lorsqu'un objet est glissé et déposé sur un autre objet ;
(7) Les gestionnaires d'objets de données seront appelés par le système lorsque les fichiers sont glissés, déposés, copiés ou collés.
Toutes les extensions shell de Windows sont basées sur le modèle de composant COM (Component Object Model) et le shell accède aux objets via des interfaces.
Les extensions Shell sont conçues comme des programmes serveur en cours de processus 32 bits et fournissent des services au système d'exploitation sous la forme de bibliothèques de liens dynamiques. Par conséquent, si vous souhaitez utiliser Windows
Si l'interface utilisateur est étendue, il est indispensable d'avoir des connaissances en écriture d'objets COM. En raison de contraintes d'espace, COM ne sera pas présenté ici. Les lecteurs peuvent s'y référer.
Selon la bibliothèque MSDN de Microsoft ou les documents d'aide associés, une interface peut être considérée comme une classe spéciale contenant un ensemble de fonctions et de procédures pouvant être utilisées pour faire fonctionner un objet.
Après avoir écrit vos extensions shell, vous devez les enregistrer pour prendre effet. Toutes les extensions shell doivent être dans le registre Windows sous la clé HKEY_CLASSES_ROOTCLSID
Inscrivez-vous ci-dessous. Sous cette clé, vous pouvez trouver de nombreuses clés portant des noms tels que {0000002F-0000-0000-C000-000000000046}. Ces clés sont des identifiants de classe globalement uniques.
Guide. Chaque extension de shell doit avoir un identifiant de classe unique au monde, c'est ainsi que Windows trouve le gestionnaire d'extension de shell.
L'emplacement de la bibliothèque de liens dynamiques d'extension shell dans le système est enregistré sous la sous-clé InProcServer32 sous l'identifiant de classe. Les extensions Shell associées à un type de fichier sont enregistrées dans
Sous la clé primaire shellex du type correspondant. Si le système d'exploitation Windows est Windows NT, l'extension shell doit également figurer dans le registre.
Enregistrez-vous sous la clé primaire HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionShellExtensionsApproved.
Après avoir compilé le programme DLL d'extension shell, vous pouvez utiliser regsvr32.exe fourni par Windows lui-même pour enregistrer le programme serveur DLL. Si vous utilisez Delphi, vous pouvez également
Pour vous inscrire, sélectionnez Enregistrer le serveur ActiveX dans le menu Exécuter.
Introduisons d'abord une application d'extension shell plus couramment utilisée : le menu contextuel, qui apparaît lorsque vous cliquez avec le bouton droit sur un fichier ou un dossier sous Windows.
Ce menu est appelé menu contextuel. Pour ajouter dynamiquement des éléments de menu à un menu contextuel, vous pouvez écrire un gestionnaire de menu contextuel. Par exemple, tout le monde
Des logiciels familiers tels que WinZip et UltraEdit ajoutent dynamiquement des éléments de menu au menu en écrivant un gestionnaire de menu contextuel. Si installé dans le système
WinZip, puis lorsque vous cliquez avec le bouton droit sur un fichier (dossier) nommé Windows, son menu contextuel comportera un élément de menu nommé Ajouter à Windows.zip.
Le gestionnaire de menu contextuel à implémenter dans cet article est similaire au menu contextuel fourni par WinZip. Cela ajoutera un
Élément de menu d'opération de fichier, lorsque vous cliquez dessus, le programme d'interface fera apparaître une fenêtre d'opération de fichier pour effectuer la copie, le déplacement et d'autres opérations de fichier.
Le gestionnaire de menu contextuel d'écriture doit implémenter trois interfaces : IShellExtInit, IContextMenu et TComObjectFactory. Implémentation d'IShellExtInit
Initialisation de l'interface, l'objet d'interface IContextMenu implémente le menu contextuel et l'interface IComObjectFactory implémente la création de l'objet.
La mise en œuvre spécifique du programme est présentée ci-dessous. Tout d'abord, cliquez sur l'élément Fichier | Nouvel élément du menu Delphi, sélectionnez DLL dans la fenêtre Nouvel élément pour créer un fichier de projet DLL.
Cliquez ensuite sur l'élément Fichier|Nouvel du menu, sélectionnez Unité dans la fenêtre Nouvel élément pour créer un fichier d'unité, cliquez sur l'élément Fichier|Nouvel du menu et sélectionnez Unité dans la fenêtre Nouvel élément.
Sélectionnez Formulaire pour créer une nouvelle fenêtre. Enregistrez le fichier de projet sous Contextmenu.dpr, Unit1 sous Contextmenuhandle.pas et enregistrez le formulaire sous
OpWindow.pas.
La liste des programmes de Contextmenu.dpr est la suivante :
menu contextuel de la bibliothèque ;
utilise
ComServ,
poignée de menu contextuel dans 'contextmenuhandle.pas',
opwindow dans 'opwindow.pas' {Form2} ;
exportations
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer ;
{$R *.TLB}
{$R *.RES}
commencer
fin.
La liste des programmes de Contextmenuhandle est la suivante :
unité ContextMenuHandle ;
interface
utilise Windows, ActiveX, ComObj, ShlObj, Classes ;
taper
TContextMenu = classe (TComObject, IShellExtInit, IContextMenu)
privé
FFileName : tableau[0..MAX_PATH] de Char ;
protégé
function IShellExtInit.Initialize = SEIInitialize; // Éviter l'avertissement du compilateur
fonction SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID : HKEY) : HResult ;
fonction QueryContextMenu(Menu : HMENU ; indexMenu, idCmdFirst, idCmdLast,
uFlags : UINT ): HResult ;
fonction InvokeCommand (var lpici : TCMInvokeCommandInfo) : HResult stdcall ;
fonction GetCommandString(idCmd, uType : UINT ; pwReserved : PUINT ;
pszName : LPSTR ; cchMax : UINT : HResult ;
fin;
const
Class_ContextMenu : TGUID = '{19741013-C829-11D1-8233-0020AF3E97A0}' ;
{L'identifiant global unique (GUID) est une valeur de 16 octets (128 octets) qui identifie de manière unique une interface}
var
Liste de fichiers : TStringList ;
mise en œuvre
utilise ComServ, SysUtils, ShellApi, Registry, UnitForm ;
function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID : HKEY ): HRésult ;
var
StgMedium : TStgMedium ;
FormatEtc : TFormatEtc ;
Numéro de fichier,i : entier ;
commencer
file://Si lpdobj est égal à Nil, cet appel échoue
si (lpdobj = nul) alors commencez
Résultat := E_INVALIDARG;
Sortie;
fin;
file:// initialise et efface d'abord FileList pour ajouter des fichiers
FileList:=TStringList.Create;
FileList.Clear;
file://Initialiser le fichier au format presse-papiers
avec FormatEtc commencez
cfFormat := CF_HDROP;
ptd := nul ;
dwaspect := DVASPECT_CONTENT;
lindex := -1;
tymed := TYMED_HGLOBAL;
fin;
Résultat := lpdobj.GetData(FormatEtc, StgMedium);
en cas d'échec (résultat), alors quittez ;
file://Requête d'abord le nombre de fichiers sélectionnés par l'utilisateur
FileNumber := DragQueryFile(StgMedium.hGlobal,$FFFFFFFF,nil,0);
file:// lit en boucle et enregistre tous les fichiers sélectionnés par l'utilisateur dans FileList
pour i:=0 à FileNumber-1, commencez
DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName));
FileList.Add(FFileName);
Résultat := NOERREUR ;
fin;
ReleaseStgMedium(StgMedium);
fin;
fonction TContextMenu.QueryContextMenu(Menu : HMENU ; indexMenu, idCmdFirst,
idCmdLast, uFlags : UINT) : HResult ;
commencer
Résultat := 0;
si ((uFlags et $0000000F) = CMF_NORMAL) ou
((uFlags et CMF_EXPLORE) <> 0) puis commencez
//Ajoute un élément de menu au menu contextuel, le titre de l'élément de menu est Afficher le fichier bitmap
InsertMenu(Menu, indexMenu, MF_STRING ou MF_BYPOSITION, idCmdFirst,
PChar('opération sur fichier'));
// Renvoie le nombre d'éléments de menu ajoutés
Résultat := 1;
fin;
fin;
fonction TContextMenu.InvokeCommand (var lpici : TCMInvokeCommandInfo) : HResult ;
var
frmOP:TForm1;
commencer
// Assurez-vous d'abord que le processus est appelé par le système plutôt que par un programme
si (HiWord(Integer(lpici.lpVerb)) <> 0) alors
commencer
Résultat := E_FAIL;
Sortie;
fin;
// Détermine la validité des paramètres passés
if (LoWord(lpici.lpVerb) <> 0) alors commencez
Résultat := E_INVALIDARG;
Sortie;
fin;
file://Créer une fenêtre d'opération de fichier
frmOP:=TForm1.Create(nil);
file://ajoute une liste de tous les fichiers à la liste dans la fenêtre d'opération de fichier
frmOP.ListBox1.Items := FileList;
Résultat := NOERREUR ;
fin;
function TContextMenu.GetCommandString(idCmd, uType : UINT; pwReserved : PUINT;
pszName : LPSTR ; cchMax : UINT : HRESULT ;
commencer
si (idCmd = 0) alors commencez
si (uType = GCS_HELPTEXT) alors
{Renvoie les informations d'aide de cet élément de menu. Ces informations d'aide seront affichées lorsque l'utilisateur déplace la souris.
Apparaît sur la barre d'état lors du passage à cet élément de menu. }
StrCopy(pszName, PChar('Cliquer sur cet élément de menu effectuera des opérations sur les fichiers'));
Résultat := NOERREUR ;
fin
autre
Résultat := E_INVALIDARG;
fin;
taper
TContextMenuFactory = classe (TComObjectFactory)
publique
procédure UpdateRegistry (Registre : remplacement booléen );
fin;
procédure TContextMenuFactory.UpdateRegistry(Register: Boolean);
var
ID de classe : chaîne ;
commencer
si vous vous inscrivez, alors commencez
hérité UpdateRegistry(Register);
ClassID := GUIDToString(Class_ContextMenu);
file://Lors de l'enregistrement d'un fichier de bibliothèque d'extension, ajoutez la bibliothèque au registre
CreateRegKey('*shellex', ', ');
CreateRegKey('*shellexContextMenuHandlers', ', ');
CreateRegKey('*shellexContextMenuHandlersFileOpreation', ', ClassID);
fichier://si le système d'exploitation est Windows NT
si (Win32Platform = VER_PLATFORM_WIN32_NT) alors
avec TRegistry.Create do
essayer
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('LOGICIELMicrosoftWindowsCurrentVersionShell Extensions', True);
OpenKey('Approuvé', True);
WriteString (ClassID, 'Extension du shell du menu contextuel');
enfin
Gratuit;
fin;
fin
sinon commencer
DeleteRegKey('*shellexContextMenuHandlersFileOpreation');
hérité UpdateRegistry(Register);
fin;
fin;
initialisation
TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
', 'Extension du shell du menu contextuel', ciMultiInstance,tmApartment);
fin.
Ajoutez un contrôle TListBox et deux contrôles TButton à la fenêtre OpWindow. La liste des programmes d'OpWindows.pas est la suivante :
fenêtre d'exploitation de l'unité ;
interface
utilise
Windows, messages, SysUtils, classes, graphiques, contrôles, formulaires, boîtes de dialogue,
ExtCtrls, StdCtrls, shlobj, shellapi, ActiveX ;
taper
TForm1 = classe(TForm)
ListBox1 : TListBox ;
Bouton1 : TButton ;
Bouton2 : TButton ;
procédure FormCreate(Expéditeur : TObject);
procédure FormClose (Expéditeur : TObject ; var Action : TCloseAction);
procédure Button1Click (Expéditeur : TObject);
procédure Button2Click (Expéditeur : TObject);
privé
{Déclarations privées}
publique
Liste de fichiers : TStringList ;
{Déclarations publiques}
fin;
var
Formulaire1 : TForm1 ;
mise en œuvre
{$R *.DFM}
procédure TForm1.FormCreate(Expéditeur : TObject);
commencer
FileList:=TStringList.Create;
Button1.Caption :='Copier le fichier';
Button2.Caption :='Déplacer les fichiers';
Auto-exposition ;
fin;
procédure TForm1.FormClose(Expéditeur : TObject ; var Action : TCloseAction) ;
commencer
FileList.Free;
fin;
procédure TForm1.Button1Click(Expéditeur : TObject);
var
sChemin : chaîne ;
fsTemp:SHFILEOPSTRUCT;
je:entier;
commencer
sPath:=InputBox('Opération sur fichier','Chemin de copie d'entrée','c:windows');
si sPath<>'alors commencez
fsTemp.Wnd := Self.Handle;
fichier://définir le type d'opération de fichier
fsTemp.wFunc :=FO_COPY;
file:// permet d'annuler les opérations
fsTemp.fFlags :=FOF_ALLOWUNDO;
pour i:=0 à ListBox1.Items.Count-1 commencez
fichier://chemin complet du fichier source
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
fichier://chemin vers lequel copier
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='Copier le fichier';
si SHFileOperation(fsTemp)<>0 alors
ShowMessage('Échec de la copie du fichier');
fin;
fin;
fin;
procédure TForm1.Button2Click(Expéditeur : TObject);
var
sChemin : chaîne ;
fsTemp:SHFILEOPSTRUCT;
je:entier;
commencer
sPath:=InputBox('Opération sur fichier','Chemin de mouvement d'entrée','c:windows');
si sPath<>'alors commencez
fsTemp.Wnd := Self.Handle;
fsTemp.wFunc :=FO_MOVE;
fsTemp.fFlags :=FOF_ALLOWUNDO;
pour i:=0 à ListBox1.Items.Count-1 commencez
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='Déplacer les fichiers';
si SHFileOperation(fsTemp)<>0 alors
ShowMessage('Échec de la copie du fichier');
fin;
fin;
fin;
fin.
Cliquez sur l'élément Projet | Créer ContextMenu dans le menu et Delphi créera le fichier Contextmenu.dll. Il s'agit du programme de menu contextuel.
Utilisez Regsvr32.exe pour enregistrer le programme, puis cliquez avec le bouton droit sur un ou plusieurs fichiers dans l'Explorateur Windows et il apparaîtra dans le menu contextuel.
Il existe un élément de menu supplémentaire pour les opérations sur les fichiers. Cliquez sur cet élément et les noms de fichiers de tous les fichiers que vous avez sélectionnés seront répertoriés dans la liste de la fenêtre contextuelle. Vous pouvez choisir le bouton Copier le fichier ou.
Le bouton Déplacer le fichier effectue des opérations sur les fichiers.