Usando Delphi para escrever extensões de shell do Windows
Amigos familiarizados com os princípios dos sistemas operacionais saberão que um sistema operacional completo fornecerá um shell para facilitar os usuários comuns.
Use várias funções fornecidas pelo sistema operacional. O shell do Windows (aqui se refere ao sistema operacional Windows 95, Windows NT4.0 ou superior) não fornece apenas
Ele não apenas fornece uma interface gráfica GUI conveniente e bonita, mas também fornece funções poderosas de extensão de shell. Você pode ver essas extensões de shell em muitos softwares. Por exemplo em seu
Se o Winzip estiver instalado no sistema, ao clicar com o botão direito em uma pasta ou arquivo no Windows Explorer, o arquivo Winzip aparecerá no menu pop-up.
cardápio abreviado. Ou a pasta do site FTP que aparece no Windows Explorer no Bullet FTP.
O Windows oferece suporte a sete tipos de extensões de shell (chamadas de manipuladores) e suas funções correspondentes são descritas resumidamente a seguir:
(1) Manipuladores de menu de contexto: adicionam menus sensíveis ao contexto a tipos específicos de objetos de arquivo;
(2) Os manipuladores de arrastar e soltar são usados para suportar a transmissão de dados OLE quando os usuários executam operações de arrastar e soltar em certos tipos de objetos de arquivo;
(3) Os manipuladores de ícones são usados para fornecer um ícone exclusivo para um determinado objeto de arquivo e também podem especificar um ícone para um determinado tipo de objeto de arquivo;
(4) Manipuladores de folhas de propriedades adicionam páginas de propriedades a objetos de arquivo (ou seja, clique com o botão direito no objeto de arquivo ou objeto de pasta e selecione Propriedades no menu pop-up
caixa de diálogo exibida após o item), as páginas de propriedades podem ser compartilhadas por objetos de arquivo do mesmo tipo ou uma página de propriedades exclusiva pode ser atribuída a um objeto de arquivo;
(5) Os manipuladores de gancho de cópia serão chamados pelo sistema quando o objeto pasta ou objeto impressora for copiado, movido, excluído ou renomeado através do Windows
Adicione manipuladores de copy-hook para permitir ou proibir determinadas operações;
(6) Os manipuladores de destino de queda serão chamados pelo sistema quando um objeto for arrastado e solto em outro objeto;
(7) Os manipuladores de objetos de dados serão chamados pelo sistema quando os arquivos forem arrastados, soltos, copiados ou colados.
Todas as extensões de shell do Windows são baseadas no modelo de componente COM (Component Object Model), e o shell acessa objetos por meio de interfaces.
As extensões Shell são projetadas como programas de servidor em processo de 32 bits e fornecem serviços ao sistema operacional na forma de bibliotecas de vínculo dinâmico. Portanto, se você quiser usar o Windows
Se a interface do usuário for expandida, é muito necessário ter algum conhecimento de escrita de objetos COM. Devido a limitações de espaço, o COM não será apresentado aqui.
De acordo com a biblioteca MSDN da Microsoft ou documentos de ajuda relacionados, uma interface pode ser considerada uma classe especial, que contém um conjunto de funções e procedimentos que podem ser usados para operar um objeto.
Depois de escrever suas extensões de shell, você deverá registrá-las para que tenham efeito. Todas as extensões de shell devem estar no registro do Windows na chave HKEY_CLASSES_ROOTCLSID
Cadastre-se abaixo. Sob esta chave, você pode encontrar muitas chaves com nomes como {0000002F-0000-0000-C000-000000000046}. Essas chaves são identificadores de classe globalmente exclusivos.
Guia. Cada extensão de shell deve ter um identificador de classe globalmente exclusivo, que é como o Windows encontra o manipulador de extensão de shell.
A localização da biblioteca de link dinâmico de extensão shell no sistema é registrada na subchave InProcServer32 no identificador de classe. As extensões shell associadas a um tipo de arquivo são registradas em
Sob a chave primária shellex do tipo correspondente. Se o sistema operacional Windows for Windows NT, a extensão do shell também deverá estar no registro.
Registre-se na chave primária HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionShellExtensionsApproved.
Depois de compilar o programa DLL de extensão shell, você pode usar regsvr32.exe fornecido pelo próprio Windows para registrar o programa do servidor DLL. Se estiver usando Delphi, você também pode
Para registrar, selecione Registrar servidor ActiveX no menu Executar.
Vamos primeiro apresentar um aplicativo de extensão de shell mais comumente usado: o menu sensível ao contexto, que aparece quando você clica com o botão direito em um arquivo ou pasta no Windows.
Este menu é chamado de menu sensível ao contexto. Para adicionar itens de menu dinamicamente a um menu sensível ao contexto, você pode escrever um manipulador de menu de contexto. Por exemplo, todo mundo
Softwares familiares como WinZip e UltraEdit adicionam itens de menu dinamicamente ao menu escrevendo um manipulador de menu de contexto. Se instalado no sistema
WinZip, quando você clicar com o botão direito em um arquivo (pasta) chamado Windows, seu menu sensível ao contexto terá um item de menu chamado Adicionar ao Windows.zip.
O manipulador de menu de contexto a ser implementado neste artigo é semelhante ao menu de contexto fornecido pelo WinZip. Ele adicionará um
Item de menu de operação de arquivo, quando clicado, o programa de interface abrirá uma janela de operação de arquivo para realizar cópia, movimentação e outras operações de arquivo.
A escrita do manipulador de menu de contexto deve implementar três interfaces: IShellExtInit, IContextMenu e TComObjectFactory. Implementação IShellExtInit
Inicialização da interface, o objeto de interface IContextMenu implementa o menu sensível ao contexto e a interface IComObjectFactory implementa a criação do objeto.
A implementação específica do programa é apresentada abaixo. Primeiro, clique no item Arquivo|Novo do menu do Delphi, selecione DLL na janela Novo Item para criar um arquivo de projeto DLL.
Em seguida, clique no item Arquivo|Novo do menu, selecione Unidade na janela Novo Item para criar um arquivo de Unidade, clique no item Arquivo|Novo do menu e selecione Unidade na janela Novo Item.
Selecione Formulário para criar uma nova janela. Salve o arquivo do projeto como Contextmenu.dpr, Unit1 como Contextmenuhandle.pas e salve o formulário como
OpWindow.pas.
A lista de programas de Contextmenu.dpr é a seguinte:
menu de contexto da biblioteca;
usa
ComServ,
contextmenuhandle em 'contextmenuhandle.pas',
opwindow em 'opwindow.pas' {Form2};
exportações
DllGetClassObject,
DllCanUnloadAgora,
DllRegisterServer,
DllUnregisterServer;
{$R *.TLB}
{$R *.RES}
começar
fim.
A lista de programas do Contextmenuhandle é a seguinte:
unidade ContextMenuHandle;
interface
usa Windows, ActiveX, ComObj, ShlObj, Classes;
tipo
TContextMenu = classe(TComObject,IShellExtInit,IContextMenu)
privado
FFileName: array[0..MAX_PATH] de Char;
protegido
function IShellExtInit.Initialize = SEIInitialize; // Evite aviso do compilador
função SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult;
função QueryContextMenu (Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
uFlags: UINT): HResult;
função InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
função GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HResult;
fim;
const
Class_ContextMenu: TGUID = '{19741013-C829-11D1-8233-0020AF3E97A0}';
{O identificador global exclusivo (GUID) é um valor de 16 bytes (128 bytes) que identifica exclusivamente uma interface}
var
Lista de Arquivos:TStringList;
implementação
usa ComServ, SysUtils, ShellApi, Registry,UnitForm;
função TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult;
var
StgMedium: TStgMedium;
FormatEtc: TFormatEtc;
NúmeroArquivo,i:Inteiro;
começar
file://Se lpdobj for igual a Nil, esta chamada falhará
if (lpdobj = nil) então comece
Resultado:=E_INVALIDARG;
Saída;
fim;
file:// primeiro inicializa e limpa FileList para adicionar arquivos
ListaArquivo:=TStringList.Create;
Lista de arquivos.Clear;
file://Inicializar arquivo no formato da área de transferência
com FormatEtc comece
cfFormat := CF_HDROP;
ptd := nulo;
dwaspect := DVASPECT_CONTENT;
lindex := -1;
digitado := TYMED_HGLOBAL;
fim;
Resultado:= lpdobj.GetData(FormatEtc, StgMedium);
se falhou (resultado), então saia;
file://Primeira consulta o número de arquivos selecionados pelo usuário
FileNumber := DragQueryFile(StgMedium.hGlobal,$FFFFFFFF,nil,0);
file:// lê em um loop e salva todos os arquivos selecionados pelo usuário em FileList
para i:=0 para FileNumber-1 comece
DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName));
FileList.Add(FFileName);
Resultado := NOERROR;
fim;
ReleaseStgMedium(StgMedium);
fim;
função TContextMenu.QueryContextMenu (Menu: HMENU; indexMenu, idCmdFirst,
idCmdLast, uFlags: UINT): HResult;
começar
Resultado:= 0;
se ((uFlags e $0000000F) = CMF_NORMAL) ou
((uFlags e CMF_EXPLORE) <> 0) então comece
//Adiciona um item de menu ao menu de contexto, o título do item de menu é Exibir arquivo bitmap
InsertMenu(Menu, indexMenu, MF_STRING ou MF_BYPOSITION, idCmdFirst,
PChar('operação de arquivo'));
// Retorna o número de itens de menu adicionados
Resultado:= 1;
fim;
fim;
função TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
var
frmOP:TForm1;
começar
// Primeiro certifique-se de que o processo seja chamado pelo sistema e não por um programa
if (HiWord(Integer(lpici.lpVerb)) <> 0) então
começar
Resultado:= E_FAIL;
Saída;
fim;
// Determina a validade dos parâmetros passados
if (LoWord(lpici.lpVerb) <> 0) então comece
Resultado:=E_INVALIDARG;
Saída;
fim;
file://Criar uma janela de operação de arquivo
frmOP:=TForm1.Create(nil);
file://adiciona uma lista de todos os arquivos à lista na janela de operação de arquivo
frmOP.ListBox1.Items := Lista de Arquivos;
Resultado := NOERROR;
fim;
função TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HRESULT;
começar
se (idCmd = 0) então comece
se (uType = GCS_HELPTEXT) então
{Retorna as informações de ajuda deste item de menu. Essas informações de ajuda serão exibidas quando o usuário mover o mouse.
Aparece na barra de status ao passar para este item de menu. }
StrCopy(pszName, PChar('Clicar neste item de menu executará operações de arquivo'));
Resultado := NOERROR;
fim
outro
Resultado:=E_INVALIDARG;
fim;
tipo
TContextMenuFactory = classe(TComObjectFactory)
público
procedimento UpdateRegistry (Registro: substituição booleana);
fim;
procedimento TContextMenuFactory.UpdateRegistry(Registro: Boolean);
var
ClassID: string;
começar
se registrar, então comece
herdado UpdateRegistry (Registro);
ClassID := GUIDToString(Class_ContextMenu);
file://Ao registrar um arquivo de biblioteca de extensão, adicione a biblioteca ao registro
CreateRegKey('*shellex', ', ');
CreateRegKey('*shellexContextMenuHandlers', ', ');
CreateRegKey('*shellexContextMenuHandlersFileOpreation', ', ClassID);
arquivo://se o sistema operacional for Windows NT
se (Win32Platform = VER_PLATFORM_WIN32_NT) então
com TRegistry.Create faça
tentar
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('Extensões SOFTWAREMicrosoftWindowsCurrentVersionShell', Verdadeiro);
OpenKey('Aprovado', Verdadeiro);
WriteString(ClassID, 'Extensão Shell do Menu de Contexto');
finalmente
Livre;
fim;
fim
senão começar
DeleteRegKey('*shellexContextMenuHandlersFileOpreation');
herdado UpdateRegistry (Registro);
fim;
fim;
inicialização
TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
', 'Extensão do Shell do Menu de Contexto', ciMultiInstance,tmApartment);
fim.
Adicione um controle TListBox e dois controles TButton à janela OpWindow A lista de programas de OpWindows.pas é a seguinte:
janela de operação da unidade;
interface
usa
Windows, Mensagens, SysUtils, Classes, Gráficos, Controles, Formulários, Diálogos,
ExtCtrls, StdCtrls,shlobj,shellapi,ActiveX;
tipo
TForm1 = classe(TForm)
ListBox1: TListBox;
Botão1: Botão T;
Botão2: Botão T;
procedimento FormCreate(Remetente: TObject);
procedimento FormClose(Sender: TObject; var Action: TCloseAction);
procedimento Button1Click(Remetente: TObject);
procedimento Button2Click(Remetente: TObject);
privado
{Declarações privadas}
público
Lista de Arquivos:TStringList;
{Declarações públicas}
fim;
var
Formulário1: TForm1;
implementação
{$R *.DFM}
procedimento TForm1.FormCreate(Remetente: TObject);
começar
ListaArquivo:=TStringList.Create;
Button1.Caption :='Copiar arquivo';
Button2.Caption :='Mover arquivos';
Auto.Mostrar;
fim;
procedimento TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
começar
Lista de arquivos.Free;
fim;
procedimento TForm1.Button1Click(Remetente: TObject);
var
caminho:string;
fsTemp:SHFILEOPSTRUCT;
eu: inteiro;
começar
sPath:=InputBox('Operação de arquivo','Caminho de cópia de entrada','c:windows');
se sPath<>'então comece
fsTemp.Wnd := Self.Handle;
arquivo: // definir tipo de operação de arquivo
fsTemp.wFunc :=FO_COPY;
file:// permite desfazer operações
fsTemp.fFlags :=FOF_ALLOWUNDO;
para i:=0 para ListBox1.Items.Count-1 comece
file://caminho completo do arquivo fonte
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
arquivo://caminho para copiar
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='Copiar arquivo';
se SHFileOperation(fsTemp)<>0 então
ShowMessage('Falha na cópia do arquivo');
fim;
fim;
fim;
procedimento TForm1.Button2Click(Remetente: TObject);
var
caminho:string;
fsTemp:SHFILEOPSTRUCT;
eu: inteiro;
começar
sPath:=InputBox('Operação de arquivo','Caminho de movimento de entrada','c:windows');
se sPath<>'então comece
fsTemp.Wnd := Self.Handle;
fsTemp.wFunc :=FO_MOVE;
fsTemp.fFlags :=FOF_ALLOWUNDO;
para i:=0 para ListBox1.Items.Count-1 comece
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='Mover arquivos';
se SHFileOperation(fsTemp)<>0 então
ShowMessage('Falha na cópia do arquivo');
fim;
fim;
fim;
fim.
Clique no item Project | Build ContextMenu no menu e o Delphi criará o arquivo Contextmenu.dll. Este é o programa de menu sensível ao contexto.
Use Regsvr32.exe para registrar o programa, clique com o botão direito em qualquer um ou vários arquivos no Windows Explorer e ele aparecerá no menu de contexto.
Há um item de menu adicional para operações de arquivo. Clique neste item e os nomes de todos os arquivos selecionados serão listados na lista na janela pop-up.
O botão Mover arquivo executa operações de arquivo.