Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si è visto in precedenza che un oggetto può implementare più interfacce. L'oggetto Common Item Dialog è un esempio reale di questo tipo. Per supportare gli usi più comuni, l'oggetto implementa l'interfacciaIFileOpenDialog. Questa interfaccia definisce i metodi di base per visualizzare la finestra di dialogo e ottenere informazioni sul file selezionato. Per un uso più avanzato, tuttavia, l'oggetto implementa anche un'interfaccia denominata IFileDialogCustomize. Un programma può usare questa interfaccia per personalizzare l'aspetto e il comportamento della finestra di dialogo, aggiungendo nuovi controlli dell'interfaccia utente.
Tenere presente che ogni interfaccia COM deve ereditare, direttamente o indirettamente, dall'interfacciaIUnknown. Il diagramma seguente illustra l'ereditarietà dell'oggetto Common Item Dialog.
Come si può vedere dal diagramma, il predecessore diretto di IFileOpenDialog è l'interfaccia IFileDialog, che a sua volta eredita IModalWindow. Man mano che si passa alla catena di ereditarietà da IFileOpenDialog a IModalWindow, le interfacce definiscono funzionalità finestra sempre più generalizzate. Infine, l'interfaccia IModalWindow eredita IUnknown. L'oggetto Common Item Dialog implementa anche IFileDialogCustomize, che esiste in una catena di ereditarietà separata.
Supponiamo ora di avere un puntatore all'interfaccia IFileOpenDialog. Come si può ottenere un puntatore all'interfaccia IFileDialogCustomize?
La semplice conversione del puntatore IFileOpenDialog in un puntatore IFileDialogCustomize non funzionerà. Non esiste un modo affidabile per eseguire il "cross cast" in una gerarchia di ereditarietà, senza una forma di informazioni sul tipo di runtime (RTTI), che è una funzionalità altamente dipendente dal linguaggio.
L'approccio COM consiste nell'chiedere all'oggetto di fornire un puntatore IFileDialogCustomize, usando la prima interfaccia come condotto nell'oggetto. Per fare ciò, chiamare il metodo IUnknown::QueryInterface dal primo puntatore all'interfaccia. È possibile considerare QueryInterface come versione indipendente dal linguaggio della parola chiave dynamic_cast in C++.
Il metodo QueryInterface ha la firma seguente:
HRESULT QueryInterface(REFIID riid, void **ppvObject);
In base a quanto già noto su CoCreateInstance, si potrebbe essere in grado di indovinare il funzionamento QueryInterface.
- Il parametro riid è il GUID che identifica l'interfaccia richiesta. Il tipo di dati REFIID è un typedef per
const GUID&
. Si noti che l'identificatore di classe (CLSID) non è obbligatorio, perché l'oggetto è già stato creato. È necessario solo l'identificatore dell'interfaccia. - Il parametro ppvObject riceve un puntatore all'interfaccia. Il tipo di dati di questo parametro è void**, per lo stesso motivo per cui CoCreateInstance usa questo tipo di dati: QueryInterface può essere usato per eseguire query per qualsiasi interfaccia COM, pertanto il parametro non può essere fortemente tipizzato.
Ecco come chiamare QueryInterface per ottenere un puntatore IFileDialogCustomize:
hr = pFileOpen->QueryInterface(IID_IFileDialogCustomize,
reinterpret_cast<void**>(&pCustom));
if (SUCCEEDED(hr))
{
// Use the interface. (Not shown.)
// ...
pCustom->Release();
}
else
{
// Handle the error.
}
Come sempre, controllare il valore restituito HRESULT, nel caso in cui il metodo non riesca. Se il metodo ha esito positivo, è necessario chiamare Release al termine dell'uso del puntatore, come descritto in Gestione della durata di un oggetto.
Prossimo