Condividi tramite


Implementazione dell'oggetto COM pagina delle proprietà

Un'estensione della finestra delle proprietà è un oggetto COM implementato come server in-proc. L'estensione della finestra delle proprietà deve implementare le interfacce IShellExtInit e IShellPropSheetExt. Viene creata un'istanza di un'estensione della finestra delle proprietà quando l'utente visualizza la finestra delle proprietà per un oggetto di una classe per cui l'estensione della finestra delle proprietà è stata registrata nell'identificatore di visualizzazione della classe .

Implementazione di IShellExtInit

Dopo aver creato un'istanza dell'oggetto COM dell'estensione della finestra delle proprietà, viene chiamato il metodo IShellExtInit::Initialize . IShellExtInit::Initialize fornisce l'estensione della finestra delle proprietà con un oggetto IDataObject che contiene dati relativi all'oggetto directory applicato dalla finestra delle proprietà.

L'oggetto IDataObject contiene dati nel formato CFSTR_DSOBJECTNAMES. Il formato dati CFSTR_DSOBJECTNAMES è un oggetto HGLOBAL che contiene una struttura DSOBJECTNAMES . La struttura DSOBJECTNAMES contiene i dati dell'oggetto directory applicati dall'estensione della finestra delle proprietà.

IDataObject contiene anche i dati nel formato CFSTR_DS_DISPLAY_SPEC_OPTIONS. Il formato dei dati CFSTR_DS_DISPLAY_SPEC_OPTIONS è un oggetto HGLOBAL che contiene una struttura DSDISPLAYSPECOPTIONS . DSDISPLAYSPECOPTIONS contiene i dati di configurazione per l'uso da parte dell'estensione.

Se un valore diverso da S_OK viene restituito da IShellExtInit::Initialize, la finestra delle proprietà non viene visualizzata.

I parametri pidlFolder e hkeyProgID del metodo IShellExtInit::Initialize non vengono usati.

Il puntatore IDataObject può essere salvato dall'estensione incrementando il conteggio dei riferimenti di IDataObject. Questa interfaccia deve essere rilasciata quando non è più necessario.

Implementazione di IShellPropSheetExt

Dopo la restituzione di IShellExtInit::Initialize, viene chiamato il metodo IShellPropSheetExt::AddPages. L'estensione della finestra delle proprietà deve aggiungere la pagina o le pagine durante questo metodo. Una pagina delle proprietà viene creata compilando una struttura PROPSH edizione Enterprise TPAGE e quindi passando questa struttura alla funzione CreatePropertySheetPage. La pagina delle proprietà viene quindi aggiunta alla finestra delle proprietà chiamando la funzione di callback passata a IShellPropSheetExt::AddPages nel parametro lpfnAddPage .

Se un valore diverso da S_OK viene restituito da IShellPropSheetExt::AddPages, la finestra delle proprietà non viene visualizzata.

Se l'estensione della finestra delle proprietà non è necessaria per aggiungere pagine alla finestra delle proprietà, non deve chiamare la funzione di callback passata a IShellPropSheetExt::AddPages nel parametro lpfnAddPage.

Il metodo IShellPropSheetExt::ReplacePage non viene utilizzato.

Passaggio dell'oggetto extension alla pagina delle proprietà

L'oggetto estensione della finestra delle proprietà è indipendente dalla pagina delle proprietà. In molti casi, è consigliabile essere in grado di usare l'oggetto di estensione, o un altro oggetto, dalla pagina delle proprietà. A tale scopo, impostare il membro lParam della struttura PROPSH edizione Enterprise TPAGE sul puntatore all'oggetto. La pagina delle proprietà può quindi recuperare questo valore quando elabora il messaggio di WM_INITDIALOG. Per una pagina delle proprietà, il parametro lParam del messaggio WM_INITDIALOG è un puntatore alla struttura PROPSH edizione Enterprise TPAGE. Recuperare il puntatore all'oggetto eseguendo il cast del parametro lParam del messaggio di WM_INITDIALOG a un puntatore PROPSH edizione Enterprise TPAGE e quindi recuperando il membro lParam della struttura PROPSH edizione Enterprise TPAGE.

Nell'esempio di codice C++ seguente viene illustrato come passare un oggetto a una pagina delle proprietà.

case WM_INITDIALOG:
    {
        LPPROPSHEETPAGE pPage = (LPPROPSHEETPAGE)lParam;

        if(NULL != pPage)
        {
            CPropSheetExt *pPropSheetExt;
            pPropSheetExt = (CPropSheetExt*)pPage->lParam;

            if(pPropSheetExt)
            {
                return pPropSheetExt>OnInitDialog(wParam, lParam);
            }
        }
    }
    break;

Tenere presente che, dopo aver chiamato IShellPropSheetExt::AddPages , la finestra delle proprietà rilascia l'oggetto estensione della finestra delle proprietà e non lo userà mai più. Ciò significa che l'oggetto estensione verrà eliminato prima che venga visualizzata la pagina delle proprietà. Quando la pagina tenta di accedere al puntatore all'oggetto, la memoria sarà stata liberata e il puntatore non sarà valido. Per risolvere il problema, incrementare il conteggio dei riferimenti per l'oggetto estensione quando viene aggiunta la pagina e rilasciare l'oggetto quando la finestra di dialogo della pagina delle proprietà viene eliminata definitivamente. Verrà creato un altro problema perché la finestra di dialogo della pagina delle proprietà non viene creata fino alla prima visualizzazione della pagina. Se l'utente non seleziona mai la pagina di estensione, la pagina non viene mai creata e eliminata definitivamente. In questo modo l'oggetto di estensione non viene mai rilasciato, quindi si verifica una perdita di memoria. Per evitare questo problema, implementare una funzione di callback della pagina delle proprietà. A tale scopo, aggiungere il flag PSP_Uedizione Standard CALLBACK al membro dwFlags della struttura PROPSH edizione Enterprise TPAGE e impostare il membro pfnCallback della struttura PROPSH edizione Enterprise TPAGE sull'indirizzo della funzione PropSheetPageProc implementata. Quando la funzione PropSheetPageProc riceve la notifica di PSPCB_RELEAedizione Standard, il parametro ppsp di PropSheetPageProc contiene un puntatore alla struttura PROPSH edizione Enterprise TPAGE. Il membro lParam della struttura PROPSH edizione Enterprise TPAGE contiene il puntatore di estensione che può essere utilizzato per rilasciare l'oggetto.

Nell'esempio di codice C++ seguente viene illustrato come rilasciare un oggetto estensione.

UINT CALLBACK CPropSheetExt::PageCallbackProc(  HWND hWnd,
                                                UINT uMsg,
                                                LPPROPSHEETPAGE ppsp)
{
    switch(uMsg)
    {
    case PSPCB_CREATE:
        // Must return TRUE to enable the page to be created.
        return TRUE;

    case PSPCB_RELEASE:
        {
            /*
            Release the object. This is called even if the page dialog box was 
            never actually created.
            */
            CPropSheetExt *pPropSheetExt = (CPropSheetExt*)ppsp->lParam;

            if(pPropSheetExt)
            {
                pPropSheetExt->Release();
            }
        }
        break;
    }

    return FALSE;
}

Utilizzo dell'oggetto Notification

Poiché le pagine di estensione della finestra delle proprietà vengono visualizzate all'interno di una finestra delle proprietà creata da un componente sconosciuto all'estensione, è necessario utilizzare un "manager" per gestire il trasferimento dei dati tra le pagine di estensione e la finestra delle proprietà. Questo "manager" è denominato oggetto di notifica. L'oggetto notifica opera come moderatore tra le singole pagine e la finestra delle proprietà.

Quando l'oggetto estensione della finestra delle proprietà viene inizializzato, l'estensione deve creare un oggetto di notifica chiamando ADsPropCreateNotifyObj, passando l'oggetto IDataObject ottenuto da IShellExtInit::Initialize e il nome dell'oggetto directory. Non è necessario incrementare il conteggio dei riferimenti dell'interfaccia IDataObject , perché l'oggetto notifica creato dalla funzione ADsPropCreateNotifyObj eseguirà questa operazione. L'handle dell'oggetto di notifica fornito da ADsPropCreateNotifyObj deve essere salvato per un uso successivo. ADsPropCreateNotifyObj può essere chiamato durante IShellExtInit::Initialize o IShellPropSheetExt::AddPages. Quando l'estensione della finestra delle proprietà viene arrestata, deve inviare un messaggio di WM_ADSPROP_NOTIFY_EXIT all'oggetto notifica. In questo modo l'oggetto di notifica viene eliminato definitivamente. Questa operazione viene eseguita al meglio quando la funzione PropSheetPageProc riceve la notifica di PSPCB_RELEAedizione Standard.

L'estensione della finestra delle proprietà può ottenere dati oltre a quello fornito dal formato degli Appunti CFSTR_DSOBJECTNAMES chiamando ADsPropGetInitInfo. Uno dei vantaggi dell'uso di ADsPropGetInitInfo consiste nel fatto che fornisce un oggetto IDirectoryObject usato per lavorare a livello di codice con l'oggetto directory.

Nota

A differenza della maggior parte dei metodi e delle funzioni COM, ADsPropGetInitInfo non incrementa il conteggio dei riferimenti per l'oggetto IDirectoryObject. L'oggetto IDirectoryObject non deve essere rilasciato a meno che il conteggio dei riferimenti non venga incrementato manualmente per primo.

 

Quando la pagina delle proprietà viene creata per la prima volta, l'estensione deve registrare la pagina con l'oggetto notifica chiamando ADsPropSetHwnd con l'handle di finestra della pagina.

ADsPropCheckIfWritable è una funzione di utilità che l'estensione della finestra delle proprietà può usare per determinare se è possibile scrivere una proprietà.

Varie

L'handle della pagina delle proprietà viene passato alla routine della finestra di dialogo della pagina. La finestra delle proprietà è l'elemento padre diretto della pagina delle proprietà, pertanto l'handle della finestra delle proprietà può essere ottenuto chiamando la funzione GetParent con l'handle della pagina delle proprietà.

Quando il contenuto della pagina di estensione viene modificato, l'estensione deve utilizzare la macro PropSheet_Changed per notificare alla finestra delle proprietà le modifiche. La finestra delle proprietà abiliterà quindi il pulsante Applica.

Finestre delle proprietà a selezione multipla

Con i sistemi operativi Windows Server 2003 e versioni successive, gli snap-in MMC amministrativi di Active Directory supportano le estensioni della finestra delle proprietà per più oggetti directory. Queste finestre delle proprietà vengono visualizzate quando le proprietà vengono visualizzate per più di un elemento alla volta. La differenza principale tra un'estensione della finestra delle proprietà a selezione singola e un'estensione della finestra delle proprietà a selezione multipla è che la struttura DSOBJECTNAMES fornita dal formato degli Appunti CFSTR_DSOBJECTNAMES in IShellExtInit::Initialize conterrà più di una struttura DSOBJECT.

Quando viene creato l'oggetto notifica, un'estensione della finestra delle proprietà a selezione multipla deve passare un nome univoco fornito dallo snap-in anziché un nome creato dall'estensione. Per ottenere il nome univoco, richiedere il formato degli Appunti CFSTR_DS_MULTIedizione Standard LECTPROPPAGE dall'oggetto IDataObject ottenuto da IShellExtInit::Initialize. Questi dati sono un HGLOBAL che contiene una stringa Unicode con terminazione Null che corrisponde al nome univoco. Questo nome univoco viene quindi passato alla funzione ADsPropCreateNotifyObj per creare l'oggetto notifica. La funzione di esempio CreateADsNotificationObject in Codice di esempio per l'implementazione dell'oggetto COM della finestra delle proprietà illustra come eseguire questa operazione correttamente, oltre a essere compatibile con le versioni precedenti dello snap-in che non supportano le finestre delle proprietà a selezione multipla.

Per le finestre delle proprietà a selezione multipla, il sistema viene associato solo al primo oggetto nella matrice DSOBJECT. Per questo motivo, ADsPropGetInitInfo fornisce solo gli attributi IDirectoryObject e scrivibili per il primo oggetto nella matrice. Gli altri oggetti nella matrice non sono associati a .

Un'estensione della finestra delle proprietà a selezione multipla viene registrata nell'attributo adminMultiselectPropertyPages .

Novità con Windows Server 2003

Le funzionalità seguenti sono nuove con Windows Server 2003.

Se la pagina delle proprietà rileva un errore, È possibile chiamare ADsPropSendErrorMessage con i dati di errore appropriati. ADsPropSendErrorMessage archivierà tutti i messaggi di errore in una coda. Questi messaggi verranno visualizzati alla successiva chiamata di ADsPropShowErrorDialog. Quando ADsPropShowErrorDialog viene restituito, i messaggi in coda vengono eliminati.

Windows Server 2003 introduce la funzione ADsPropSetHwndWithTitle. Questa funzione è simile a ADsPropSetHwnd, ma include il titolo della pagina. In questo modo viene attivata la finestra di dialogo di errore visualizzata da ADsPropShowErrorDialog per fornire dati più utili all'utente. Se l'estensione della finestra delle proprietà usa la funzione ADsPropShowErrorDialog , l'estensione deve usare ADsPropSetHwndWithTitle anziché ADsPropSetHwnd.

Codice di esempio per l'implementazione dell'oggetto COM della finestra delle proprietà