Come creare procedure guidate

Una procedura guidata è un tipo di finestra delle proprietà che offre un modo semplice e potente per guidare gli utenti tramite una procedura.

Le procedure guidate sono una delle chiavi per semplificare l'esperienza utente. Consentono di eseguire un'operazione complessa, ad esempio la configurazione di un'applicazione, e di suddividerla in una serie di semplici passaggi. A ogni punto del processo, è possibile fornire una spiegazione degli elementi necessari e visualizzare i controlli che consentono all'utente di effettuare selezioni e immettere testo.

Una procedura guidata è effettivamente un tipo di finestra delle proprietà. Una finestra delle proprietà è essenzialmente un contenitore per una raccolta di pagine, in cui ogni pagina è una finestra di dialogo separata. Mentre le normali finestre delle proprietà consentono all'utente di accedere a qualsiasi pagina in qualsiasi momento, le procedure guidate presentano pagine in sequenza. Anziché le schede, i pulsanti vengono usati per spostarsi avanti e indietro. L'ordine in cui le pagine vengono visualizzate è controllato dall'applicazione e può essere modificato in base all'input dell'utente.

Esistono due stili principali della procedura guidata: il vecchio stile Wizard97 e lo stile Aero introdotto in Windows Vista. Per le illustrazioni, vedere Informazioni sulle finestre delle proprietà. Un terzo stile, usando solo il flag PSH_WIZARD o PSH_WIZARD_LITE, presenta una semplice sequenza di finestre delle proprietà senza intestazioni o filigrane.

Nota

Una "filigrana" nel contesto delle procedure guidate è una bitmap visualizzata nel margine sinistro di alcune pagine.

 

La discussione nella maggior parte di questo documento presuppone che si stia implementando una procedura guidata per un sistema con la versione 5.80 o successiva dei controlli comuni. Se si tenta di usare lo stile Wizard97 con le versioni precedenti dei controlli comuni, l'applicazione potrebbe essere compilata ma non verrà visualizzata correttamente. Per una discussione su come creare una procedura guidata compatibile con Wizard97 nei sistemi precedenti, vedere Procedure guidate compatibili con le versioni precedenti più avanti in questo argomento.

Informazioni importanti

Tecnologie

Prerequisiti

  • C/C++
  • Programmazione dell'interfaccia utente di Windows

Istruzioni

Implementazione della procedura guidata

L'implementazione di una procedura guidata è simile all'implementazione di una normale finestra delle proprietà. Al livello più semplice, è importante impostare uno dei flag o combinazioni di flag seguenti nella struttura PROPSH edizione Enterprise THEADER che definisce la finestra delle proprietà.

Flag Style
PSH_WIZARD Procedura guidata semplice senza intestazioni o bitmap.
PSH_WIZARD_LITE Simile a PSH_WIZARD, con alcune piccole differenze nell'aspetto; Ad esempio, il divisore sopra i pulsanti è impostato sulla larghezza intera della finestra.
PSH_WIZARD97 Procedura guidata Wizard97 con intestazioni (facoltative), bitmap di intestazione e filigrane.
PSH_WIZARD | PSH_AEROWIZARD Un Aero Wizard. Le procedure guidate aero non usano filigrane o bitmap di intestazione. Richiedono il modello apartment a thread singolo (STA).

 

La procedura di base per l'implementazione di una procedura guidata è la seguente:

  1. Creare un modello di finestra di dialogo per ogni pagina.
  2. Definire le pagine creando una struttura PROPSH edizione Enterprise TPAGE per ogni pagina. Questa struttura definisce la pagina e contiene puntatori al modello di finestra di dialogo ed eventuali bitmap o altre risorse.
  3. Passare la struttura PROPSH edizione Enterprise TPAGE creata nel passaggio precedente alla funzione CreatePropertySheetPage per creare l'handle HPROPSH edizione Enterprise TPAGE della pagina.
  4. Definire la procedura guidata creando una struttura PROPSH edizione Enterprise THEADER.
  5. Passare la struttura PROPSH edizione Enterprise THEADER alla funzione PropertySheet per visualizzare la procedura guidata.
  6. Implementare le procedure della finestra di dialogo per ogni pagina per gestire i messaggi di notifica dai controlli della pagina e i pulsanti della procedura guidata e per elaborare altri messaggi di Windows.

Creare i modelli della finestra di dialogo

Esistono due tipi di base di pagina della procedura guidata: esterni e interni. Le pagine esterne sono le pagine introduttive (benvenuto) e di completamento. Tutti gli altri sono pagine interne.

Modelli di finestra di dialogo Pagina esterna

Il layout di base delle pagine di introduzione e completamento è identico. La figura seguente mostra una pagina introduttiva di esempio Wizard97 con una filigrana segnaposto.

screen shot showing a wizard page with a graphic on the left, title and body text on the right, and back, next and cancel buttons at the bottom

Per le pagine esterne wizard97, il modello di finestra di dialogo è 317x193 unità di dialogo. Riempie tutte le procedure guidate, ad eccezione del didascalia e della banda nella parte inferiore che contiene i pulsanti Indietro, Avanti e Annulla. Il lato sinistro del modello, riservato per una bitmap "watermark", non deve contenere controlli. La filigrana viene specificata nella struttura PROPSH della procedura guidata edizione Enterprise THEADER e viene aggiunta automaticamente alla pagina. Quando si progetta il modello di risorsa, è necessario consentire lo spazio necessario.

Quando si crea la bitmap della filigrana, tenere presente che la finestra di dialogo può aumentare le dimensioni se, ad esempio, l'utente sceglie un tipo di carattere di sistema di grandi dimensioni. Anche lingue diverse tendono ad avere metriche dei tipi di carattere diverse. Quando la pagina cresce, l'area riservata per la filigrana diventa proporzionalmente più grande. Tuttavia, non è possibile modificare la bitmap della filigrana, né è la bitmap estesa per riempire l'area più grande. Al contrario, la bitmap viene lasciata nella dimensione originale nella parte superiore sinistra dell'area riservata. La parte dell'area riservata più grande che non è coperta dalla filigrana viene riempita automaticamente con il colore del pixel superiore sinistro della bitmap.

Se è necessario disporre di bitmap di filigrana di dimensioni diverse per metriche dei tipi di carattere diverse, sono disponibili due possibili soluzioni:

  • Ottenere le metriche dei tipi di carattere prima di creare la procedura guidata e specificare una bitmap limite di dimensioni appropriate.
  • Non specificare una bitmap filigrana quando si crea la procedura guidata. Wizard97 lascerà vuota l'area filigrana. Disegnare quindi una bitmap di dimensioni appropriate nell'area riservata per la filigrana.

È possibile posizionare i controlli nell'area a destra della filigrana come si farebbe per una normale finestra di dialogo. Il colore di sfondo di questa area è determinato dal sistema e non richiede alcuna azione da parte dell'utente. In genere vengono inseriti due controlli statici in questa area. Quello superiore contiene il titolo e usa un carattere grassetto grande (12 punti Verdana Bold per Wizard97). L'altro, che è per il testo esplicativo, usa il tipo di carattere della finestra di dialogo standard.

La differenza principale tra le pagine introduttive e di completamento è costituito dai pulsanti della procedura guidata e dal testo nei controlli statici. Le pagine introduttive in genere hanno un pulsante Avanti e Indietro , con solo il pulsante Avanti abilitato. Le pagine di completamento hanno il pulsante Indietro abilitato e il pulsante Avanti viene sostituito da un pulsante Fine .

Nota

In Aero Wizards il pulsante Indietro viene sostituito da un pulsante freccia nella barra didascalia.

 

È possibile modificare il testo nel pulsante Fine inviando alla procedura guidata un messaggio PSM_edizione Standard TFINISHTEXT. Per impostazione predefinita, il pulsante Fine non include un tasto di scelta rapida. Per definire un tasto di scelta rapida, includere una e commerciale nella stringa di testo passata a PSM_edizione Standard TFINISHTEXT. Ad esempio, "&Finish" definisce 'F' come tasto di scelta rapida.

Modelli di finestra di dialogo Pagina interna

Le pagine interne hanno un aspetto leggermente diverso rispetto alle pagine esterne. La figura seguente mostra una pagina interna wizard97 di esempio, con una bitmap di intestazione segnaposto.

screen shot of a wizard page with title and subtitle text and a graphic at the top, text in the middle, and buttons on the bottom

L'area dell'intestazione nella parte superiore della pagina viene gestita dalla finestra delle proprietà, pertanto non è inclusa nel modello. Il contenuto dell'intestazione viene specificato nella struttura PROPSH edizione Enterprise TPAGE della pagina e nella struttura PROPSH edizione Enterprise THEADER della procedura guidata. Poiché la pagina interna deve adattarsi tra l'intestazione e i pulsanti, il modello della finestra di dialogo Wizard97 è 317x143 unità di dialogo, leggermente più piccolo del modello per le pagine esterne.

La figura seguente mostra una procedura guidata Aero creata dallo stesso modello.

screen shot that differs from the previous one by having a title area at the top, and only next and cancel buttons at the bottom

Definire le pagine della procedura guidata

Dopo aver creato i modelli di finestra di dialogo e le risorse correlate, ad esempio bitmap e tabelle di stringhe, è possibile creare le pagine della finestra delle proprietà. La procedura è simile a quella per le finestre delle proprietà standard. Compilare prima di tutto i membri appropriati di una struttura PROPSH edizione Enterprise TPAGE. Alcuni membri sono specifici delle procedure guidate. Chiamare quindi la funzione CreatePropertySheetPage per creare l'handle HPROPSH edizione Enterprise TPAGE della pagina.

I flag correlati alla procedura guidata seguenti possono essere impostati nel membro dwFlags della struttura PROPSH edizione Enterprise TPAGE.

Flag Descrizione
PSP_HIDEHEADER Impostare questo flag per le pagine esterne in Wizard97. L'intestazione non viene visualizzata e è possibile visualizzare una filigrana.
PSP_Uedizione Standard HEADERTITLE Impostare questo flag per le pagine interne per inserire un titolo nell'area di intestazione in Wizard97 o nella parte superiore dell'area client in un Aero Wizard.
PSP_Uedizione Standard HEADERSUBTITLE Impostare questo flag per le pagine interne per inserire un sottotitolo nell'area di intestazione in Wizard97.

 

Se è stato impostato PSP_Uedizione Standard HEADERTITLE o PSP_Uedizione Standard HEADERSUBTITLE, assegnare rispettivamente il titolo e il testo del sottotitolo ai membri pszHeaderTitle e pszHeaderSubtitle. Quando si assegnano stringhe di testo ai membri delle strutture PROPSH edizione Enterprise TPAGE e PROPSH edizione Enterprise THEADER, è possibile assegnare un puntatore di stringa o utilizzare la macro MAKEINTRESOURCE per assegnare un valore da una risorsa stringa. La risorsa stringa viene caricata dal modulo specificato nel membro hInstance della struttura PROPSH edizione Enterprise THEADER della procedura guidata.

Quando si chiama CreatePropertySheetPage per creare una pagina, assegnare il risultato a un elemento di una matrice di handle HPROPSH edizione Enterprise TPAGE. Questa matrice viene utilizzata durante la creazione della finestra delle proprietà. L'indice di matrice dell'handle di una pagina determina l'ordine predefinito in cui viene visualizzato. Dopo aver creato l'handle HPROPSH edizione Enterprise TPAGE di una pagina, è possibile riutilizzare la stessa struttura PROPSH edizione Enterprise TPAGE per creare la pagina successiva assegnando nuovi valori ai membri pertinenti.

Un modo alternativo per creare pagine consiste nell'usare strutture PROPSH edizione Enterprise TPAGE separate per ogni pagina e creare una matrice di strutture. Questa matrice viene usata anziché una matrice di handle HPROPSH edizione Enterprise TPAGE durante la creazione della finestra delle proprietà. L'uso di strutture PROPSH edizione Enterprise TPAGE separate elimina la necessità di chiamare CreatePropertySheetPage, ma usa più memoria. In caso contrario, non esiste alcuna differenza significativa tra i due approcci.

Nell'esempio seguente viene definita una pagina interna wizard97 assegnando valori a una struttura PROPSH edizione Enterprise TPAGE. In questo esempio, il titolo, il sottotitolo e il modello di finestra di dialogo della pagina sono tutti identificati dai relativi ID risorsa. Viene quindi chiamata la funzione CreatePropertySheetPage per creare l'handle HPROPSH edizione Enterprise TPAGE della pagina. Poiché sarà la seconda pagina da visualizzare, l'handle viene assegnato alla matrice di handle, ahpsp, con un indice pari a 1.

// g_hInstance is the global HINSTANCE of the application.
// IntPage1DlgProc is the dialog procedure for this page.
// ahpsp is an array of HPROPSHEETPAGE handles.

PROPSHEETPAGE psp = { sizeof(psp) };

psp.hInstance         = g_hInstance;
psp.dwFlags           = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
psp.lParam            = (LPARAM) &wizdata;
psp.pszHeaderTitle    = MAKEINTRESOURCE(IDS_TITLE1);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUBTITLE1);
psp.pszTemplate       = MAKEINTRESOURCE(IDD_INTERIOR1);
psp.pfnDlgProc        = IntPage1DlgProc;

ahpsp[1] = CreatePropertySheetPage(&psp);

Dati pagina personalizzati

Quando si crea una pagina, è possibile assegnare dati personalizzati usando il membro lParam della struttura PROPSH edizione Enterprise TPAGE, assegnando in genere un puntatore a una struttura definita dall'utente.

Quando la pagina viene selezionata per la prima volta, la relativa routine della finestra di dialogo riceve un messaggio di WM_INITDIALOG . Il valore lParam del messaggio punta a una copia della struttura PROPSH edizione Enterprise TPAGE della pagina, da cui è possibile recuperare i dati personalizzati. È quindi possibile archiviare questi dati per l'uso nei messaggi successivi usando SetWindowLongPtr con GWL_Uedizione Standard RDATA come parametro di indice. Più pagine possono avere un puntatore agli stessi dati e qualsiasi modifica ai dati apportati da una pagina è disponibile per le altre pagine nelle relative procedure di dialogo.

Definire la finestra delle proprietà della procedura guidata

Come per le finestre delle proprietà normali, è possibile definire la finestra delle proprietà della procedura guidata compilando i membri di una struttura PROPSH edizione Enterprise THEADER. Questa struttura consente di specificare le pagine che costituiscono la procedura guidata e l'ordine predefinito in cui vengono visualizzate, insieme a diversi parametri correlati. Avviare quindi la procedura guidata chiamando la funzione PropertySheet.

Nello stile Wizard97 il membro pszCaption della struttura PROPSH edizione Enterprise THEADER viene ignorato. La procedura guidata visualizza invece il didascalia specificato nel modello della finestra di dialogo della pagina corrente. Se il modello non dispone di un didascalia, viene visualizzato il didascalia della pagina precedente. Pertanto, per visualizzare la stessa didascalia in tutte le pagine, specificare il didascalia nel modello per la pagina introduttiva.

Nello stile Aero Wizard la finestra di dialogo didascalia viene ricavata da pszCaption.

Se è stata creata una matrice di handle HPROPSH edizione Enterprise TPAGE per le pagine, assegnare la matrice al membro phpage. Se invece è stata creata una matrice di strutture PROPSH edizione Enterprise TPAGE, assegnare la matrice al membro ppsp e impostare il flag PSH_PROPSHedizione Enterprise TPAGE nel membro dwFlags.

Nell'esempio seguente i valori sono assegnati a psh, una struttura PROPSH edizione Enterprise THEADER e chiama la funzione PropertySheet per avviare la procedura guidata. La procedura guidata in stile Wizard97 include elementi grafici filigrana e intestazione, specificati dai relativi ID risorsa. La matrice ahpsp contiene tutti gli handle HPROPSH edizione Enterprise TPAGE e definisce l'ordine predefinito in cui vengono visualizzati.

// g_hInstance is the global HINSTANCE of the application.
// ahpsp is an array of HPROPSHEETPAGE handles.

PROPSHEETHEADER psh = { sizeof(psh) };

psh.hInstance      = g_hInstance;
psh.hwndParent     = NULL;
psh.phpage         = ahpsp;
psh.dwFlags        = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
psh.pszbmHeader    = MAKEINTRESOURCE(IDB_BANNER);
psh.nStartPage     = 0;
psh.nPages         = 4;

PropertySheet(&psh);

Procedura della finestra di dialogo

Ogni pagina della procedura guidata richiede una procedura di finestra di dialogo per elaborare i messaggi di Windows, in particolare le notifiche dei relativi controlli e la procedura guidata. I tre messaggi che quasi tutte le procedure guidate devono essere in grado di gestire sono WM_INITDIALOG, WM_DESTROY e WM_NOTIFY.

Il messaggio WM_NOTIFY viene ricevuto prima della visualizzazione della pagina e quando si fa clic su uno dei pulsanti della procedura guidata. Il parametro lParam del messaggio è un puntatore a una struttura di intestazione NMHDR. L'ID della notifica è contenuto nel membro del codice della struttura. Di seguito sono riportate le quattro notifiche che la maggior parte delle procedure guidate deve gestire.

Codice Descrizione
PSN_edizione Standard TACTIVE Inviato prima della visualizzazione della pagina.
PSN_WIZBACK Inviato quando si fa clic sul pulsante Indietro .
PSN_WIZNEXT Inviato quando si fa clic sul pulsante Avanti .
PSN_WIZFINISH Inviato quando si fa clic sul pulsante Fine .

 

Gestire WM_INITDIALOG e WM_DESTROY

Quando una pagina sta per essere visualizzata per la prima volta, la relativa routine della finestra di dialogo riceve un messaggio di WM_INITDIALOG . La gestione di questo messaggio consente alla procedura guidata di eseguire qualsiasi attività di inizializzazione necessaria, ad esempio l'archiviazione di dati personalizzati o l'impostazione dei tipi di carattere.

Quando la finestra delle proprietà viene eliminata definitivamente, viene visualizzato un messaggio di WM_DESTROY . La procedura guidata viene eliminata automaticamente dal sistema, ma la gestione di questo messaggio consente di eseguire eventuali operazioni di pulizia necessarie.

Gestire PSN_edizione Standard TACTIVE

Il codice di notifica PSN_edizione Standard TACTIVE viene inviato ogni volta che una pagina sta per essere resa visibile. La prima volta che viene visitata una pagina, PSN_edizione Standard TACTIVE segue il messaggio di WM_INITDIALOG. Se la pagina viene successivamente rivisitata, riceve solo una notifica PSN_edizione Standard TACTIVE. Questa notifica viene in genere gestita per inizializzare i dati per la pagina e abilitare i pulsanti appropriati.

Per impostazione predefinita, la procedura guidata visualizza i pulsanti Indietro, Avanti e Annulla , con tutti i pulsanti abilitati. Per disabilitare un pulsante o visualizzare Fine invece di Avanti, è necessario inviare un messaggio PSM_edizione Standard TWIZBUTTONS. Dopo l'invio di questo messaggio, lo stato dei pulsanti viene mantenuto fino a quando non viene modificato da un altro messaggio PSM_edizione Standard TWIZBUTTONS, anche se è selezionata una nuova pagina. In genere, tutti i gestori PSN_edizione Standard TACTIVE inviano questo messaggio per assicurarsi che ogni pagina abbia lo stato corretto del pulsante.

È possibile modificare lo stato del pulsante con questo messaggio in qualsiasi momento. Ad esempio, potrebbe essere necessario disabilitare inizialmente il pulsante Avanti . Dopo che un utente ha immesso tutte le informazioni necessarie, è possibile inviare un altro messaggio PSM_edizione Standard TWIZBUTTONS per abilitare il pulsante Avanti e consentire all'utente di passare alla pagina successiva.

Il frammento di codice seguente usa la macro PropSheet_SetWizButtons per abilitare i pulsanti Indietro e Avanti in una pagina interna prima che venga visualizzato.

case WM_NOTIFY :
    {
        LPNMHDR pnmh = (LPNMHDR)lParam;
        
        switch(pnmh->code)
        {
        
        ...
        
        case PSN_SETACTIVE :
        
            ...
            
            // This is an interior page.
            PropSheet_SetWizButtons(hwnd, PSWIZB_NEXT | PSWIZB_BACK);
            
            ...
        }
    ...
    
    }

Gestire PSN_WIZNEXT, PSNWIZBACK e PSN_WIZFINISH

Quando si fa clic su un pulsante Avanti o Indietro , si riceve un PSN_WIZNEXT o PSN_WIZBACK codice di notifica. Per impostazione predefinita, la procedura guidata passa automaticamente alla pagina successiva o precedente nell'ordine definito al momento della creazione della finestra delle proprietà. Un motivo comune per gestire queste notifiche è impedire all'utente di cambiare pagina o di ignorare l'ordine di pagina predefinito.

Per impedire all'utente di cambiare pagina, gestire la notifica del pulsante, chiamare la funzione SetWindowLong con il valore DWL_MSGRESULT impostato su -1 e restituire TRUE. Ad esempio:

case PSN_WIZNEXT :

        ...
        
        // Do not go to the next page yet.
        SetWindowLong(hwnd, DWL_MSGRESULT, -1);
        
        return TRUE;
        
        ...

Per eseguire l'override dell'ordine standard e passare a una determinata pagina, chiamare SetWindowLong con il valore DWL_MSGRESULT impostato sull'ID risorsa della finestra di dialogo della pagina e restituire TRUE. Ad esempio:

case PSN_WIZNEXT :

        ...
        
        // Go straight to the completion page.
        SetWindowLong(hwnd, DWL_MSGRESULT, IDD_FINISH);
        
        return TRUE;
        
        ...

Quando si fa clic sul pulsante Fine o Annulla, si riceve rispettivamente un codice di notifica PSN_WIZFINISH o PSN_REedizione Standard T. Quando si fa clic su uno di questi pulsanti, la procedura guidata viene eliminata automaticamente dal sistema. Tuttavia, è possibile gestire queste notifiche se è necessario eseguire attività di pulizia prima che la procedura guidata venga eliminata definitivamente. Per evitare che la procedura guidata venga eliminata definitivamente quando si riceve una notifica di PSN_WIZFINISH, chiamare SetWindowLong con il valore DWL_MSGRESULT impostato su TRUE e restituire TRUE. Ad esempio:

case PSN_WIZFINISH :

        ...
        
        // Not finished yet.
        SetWindowLong(hwnd, DWL_MSGRESULT, TRUE);
        
        return TRUE;
        
        ...

Procedure guidate compatibili con le versioni precedenti

La sezione precedente presuppone che si stia implementando una procedura guidata per un sistema con la versione 5 o successiva dei controlli comuni.

Se si scrive una procedura guidata per i sistemi con versioni precedenti dei controlli comuni, molte delle funzionalità descritte nella sezione precedente non saranno disponibili. Diversi membri delle strutture PROPSH edizione Enterprise THEADER e PROPSH edizione Enterprise TPAGE utilizzate dallo stile Wizard97 sono supportati solo dai controlli comuni versione 5 e successive. Tuttavia, è comunque possibile implementare una procedura guidata compatibile con le versioni precedenti con un aspetto simile a quello dello stile Wizard97. A tale scopo, è necessario implementare in modo esplicito quanto segue:

  • Aggiungere l'elemento grafico filigrana al modello di finestra di dialogo per le pagine introduttive e di completamento.
  • Rendere tutti i modelli le stesse dimensioni. Non esiste un'area di intestazione definita dal sistema separata per le pagine interne.
  • Creare l'area di intestazione della pagina interna in modo esplicito nei modelli.
  • Non usare un elemento grafico di intestazione perché può essere in conflitto con il titolo o il sottotitolo se la procedura guidata cambia dimensione.

Per altre informazioni sulle procedure guidate compatibili con le versioni precedenti, vedere Procedura guidata compatibile con le versioni precedenti 97.

Osservazioni:

Per una descrizione completa dei problemi di progettazione per Wizard97, vedere La specifica wizard97, altrove in Windows SDK.For a complete discussion of design issues for Wizard97, see the Wizard97 Specification, elsewhere in the Windows SDK. Questo documento include linee guida per elementi quali le dimensioni per le finestre di dialogo, le dimensioni bitmap e i colori e la posizione dei controlli.

Utilizzo delle finestre delle proprietà

Demo dei controlli comuni di Windows (CppWindowsCommonControls)