BETA La rivista ipertestuale tecnica
BETA
BETA La rivista ipertestuale tecnicaBarra BETA
Barra Sito Beta.it

BETA 2299.5 - Programmazione: Costruiamo un'estensione della shell per Windows95  -  Indici | Guida

Clicca qui!

Costruiamo un'estensione della shell per Windows95

Parte 2

di Stefano Casini
Articolista, BETA

Le classi della nostra DLL

    Vediamo adesso quali classi (oggetti, se preferite) vengono implementate dalla nostra DLL.
Sono due: la prima deriva (F_I_ClassFactory) da IClassFactory, la seconda (F_I_ ShellExt) deriva da IContextMenu e IShellExtInit. Di IContextMenu e IShellExtInit abbiamo già parlato nel precedente articolo [2]; accenniamo qualcosa riguardo IClassFactory.
Questa interfaccia gestisce la creazione di nuovi oggetti, per quegli oggetti che sono associati a dei CLSID mappati nel registro, ed espone due metodi:

STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppv);
LPUNKNOWN pUnkOuter
è un parametro passato in ingresso che indica se il componente deve essere creato come parte di un aggregato. Nel nostro caso l’oggetto non è parte di un aggregato e quindi questo parametro ha valore NULL;
REFIID riid
è l’IID dell’interfaccia richiesta da chi ci sta chiedendo di creare il componente. Quando il parametro pUnkOuter è NULL, spesso riid rappresenta, come nel nostro caso, l’IID dell’interfaccia di inizializzazione della shell extension (IID_IShellExtInit);
LPVOID * ppv
rappresenta il puntatore all’interfaccia di comunicazione che, se supportata dal nostro componente, restituiremo al chiamante.
Nel caso di successo la funzione ritorna S_OK, altrimenti ritorna un valore di errore.
STDMETHODIMP LockServer(BOOL fLock);
BOOL fLock
è un flag che incrementa, se TRUE, o decrementa, se FALSE, il contatore del bloccaggio sul server.
Questo metodo viene chiamato per tenere il componente aperto in memoria e creare più rapidamente le istanze dei suoi oggetti; nel nostro caso non c’è bisogno di implementarla.
Come si vede dal listato, le classi della nostra shell extension implementano solo i membri delle interfacce della shell da cui sono derivate, e come membri di dati hanno solo il contatore interno e, per la F_I_ShellExt, una stringa (m_szFileSelezionato) che conterrà il nome del file selezionato da Explorer sul quale applicheremo i nuovi item di menu contestuale.

Pronti, partenza, via!

   Ecco, in sintesi, cosa succede, miracolosamente, alla nostra shell extension, dopo aver inserito nel registro il suo CLSID ed averlo aggiunto agli handlers del menu contestuale dei file con estensione .BMP.
Apriamo Explorer, selezioniamo un file BMP, e clicchiamo col tasto destro; Explorer entra nel registro, cerca la chiave

HKEY_CLASSES_ROOT\.BMP
e legge il valore Predefinito associato: se il programma che gestisce i file BMP è MSPAINT.EXE questo valore è Paint.Picture; allora Explorer va a cercare la chiave
HKEY_CLASSES_ROOT\Paint.Picture\shellex\ContextMenuHandlers
e trova, al suo interno, la sottochiave File Information Shell Extension, il cui  valore Predefinito è {98248760-F1AE-11d2-A4E2-004095D0529B}; quindi cerca la chiave
HKEY_CLASSES_ROOT\CLSID\{98248760-F1AE-11d2-A4E2-004095D0529B}
e scopre che il server ad essa associato ha il pathname della nostra FILEINFO.DLL.
A questo punto viene chiamata la DllMain e quindi la funzione DllGetClassObject, chiedendo di creare il componente che ha quel CLSID e l’interfaccia IID_IClassFactory; ottenuto il puntatore all’interfaccia IID_IClassFactory  dalla nostra DLL, Explorer ne chiama il metodo CreateInstance, chiedendo l’interfaccia IID_IShellExtInit; per dargliela, il metodo CreateInstance dovrà creare un’istanza della classe F_I_ ShellExt.
Ottenuta l’interfaccia IID_IShellExtInit, Explorer ne chiama il metodo Initialize, e nel far questo passa in ingresso all’interfaccia il puntatore ad un’interfaccia IDataObject, nel quale è contenuto l’elenco dei file che sono correntemente selezionati nella finestra di Explorer; la nostra DLL, dopo aver renderizzato quanto contenuto in IDataObject, controlla che ci sia un solo file selezionato e, in caso affermativo, ne memorizza il pathname nel membro m_szFileSelezionato.
Ora il gioco è quasi fatto: Explorer chiede l’interfaccia IID_IContextMenu di F_I_ ShellExt, e ne chiama i 3 metodi:
QueryContextMenu, all’interno del quale abbiamo posto il codice che aggiunge gli item di menu Altezza, Larghezza, Colori, Informazioni; nel nostro caso, abbiamo messo all’interno il codice che apre il file .BMP e ne legge l’header per calcolarne Altezza, Larghezza, Colori, ma questo pezzo di codice poteva benissimo essere messo in una funzione a se stante;
InvokeCommand, che serve per eventuali azioni da prendere se si clicca su uno dei menu contestuali aggiunti; nel nostro caso, cliccando sul menu Informazioni viene mostrata una finestra di dialogo;
GetCommandString, che serve per mostrare sulla status bar di Explorer una stringa di testo associata agli item del menu contestuale che abbiamo aggiunto.
Quando clicchiamo fuori dal menu contestuale, oppure su uno dei suoi item attivi, che ne provocano la chiusura, Explorer rilascia le interfacce che non gli servono più ed il reference count della DLL decresce; quando g_cRefThisDll arriva a zero e viene chiamata la funzione DllCanUnloadNow, la DLL viene scaricata dalla memoria.
Come avete visto, la complessità è notevole, e, soprattutto, poco documentata ufficialmente, ed il fatto che funzioni ha quasi del miracoloso.
Nella figura che segue, potete vedere evidenziato a lato in giallo il risultato ottenuto quando seleziono la bitmap ASBES.BMP presente sul mio desktop.

visualizzazione di esempio
Figura 1 - Un esempio dell'output di FileInfo

Collegamento d'articolo
Parte 1 | Parte 2 | Parte 3

Parte 3


Copyright © 1999 Stefano Casini, tutti i diritti sono riservati. Questo Articolo di BETA, insieme alla Rivista, è distribuito secondo i termini e le condizioni della Licenza Pubblica Beta, come specificato nel file LPB.

BETAe-mail info@beta.it
Barra Sito Beta.it
Frontespizio Abbonamenti a BETA Redazione Liste/Forum Informazioni Mirror ufficiali Beta Home Page Beta Home Page english Beta News BETA Rivista Articoli BETA Beta Edit, pubblicazioni Beta Logo, premi Beta Lpb, Licenza Pubblica e Articoli Lpb Beta Navigatore Beta Online Beta Library Beta Info Gruppo Beta BETA La rivista ipertestuale tecnica Collegamento al sito Web