Condividi tramite


Come personalizzare le barre degli strumenti

La maggior parte delle applicazioni basate su Windows usa i controlli della barra degli strumenti per fornire agli utenti un accesso pratico alla funzionalità del programma. Tuttavia, le barre degli strumenti statiche presentano alcune carenze, ad esempio troppo poco spazio per visualizzare in modo efficace tutti gli strumenti disponibili. La soluzione a questo problema consiste nel rendere personalizzabili le barre degli strumenti dell'applicazione. Quindi, gli utenti possono scegliere di visualizzare solo gli strumenti di cui hanno bisogno e possono organizzarli in modo adatto al proprio stile di lavoro personale.

Nota

Le barre degli strumenti nelle finestre di dialogo non possono essere personalizzate.

 

Per abilitare la personalizzazione, includere il flag di stile dei controlli comuni CCS_ADJUSTABLE quando si crea il controllo barra degli strumenti. Esistono due approcci di base alla personalizzazione:

  • Finestra di dialogo di personalizzazione. Questa finestra di dialogo fornita dal sistema è l'approccio più semplice. Offre agli utenti un'interfaccia utente grafica che consente di aggiungere, eliminare o spostare icone.
  • Strumenti per trascinamento e rilascio. L'implementazione della funzionalità di trascina e rilascia consente agli utenti di spostare gli strumenti in un'altra posizione sulla barra degli strumenti o di eliminarli trascinandoli fuori da essa. Offre agli utenti un modo rapido e semplice per organizzare la barra degli strumenti, ma non consente loro di aggiungere strumenti.

È possibile implementare un approccio o entrambi, a seconda delle esigenze dell'applicazione. Nessuno di questi due approcci alla personalizzazione fornisce un meccanismo predefinito, ad esempio un pulsante Annulla o Annulla, per restituire la barra degli strumenti allo stato precedente. È necessario usare in modo esplicito l'API di controllo della barra degli strumenti per archiviare lo stato di precustomizzazione della barra degli strumenti. Se necessario, è possibile utilizzare queste informazioni archiviate in un secondo momento per ripristinare lo stato originale della barra degli strumenti.

Cosa è necessario sapere

Tecnologie

Prerequisiti

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

Disposizioni

Finestra di dialogo Personalizzazione

La finestra di dialogo di personalizzazione viene fornita dal controllo barra degli strumenti per offrire agli utenti un modo semplice per aggiungere, spostare o eliminare strumenti. Gli utenti possono avviarlo facendo doppio clic sulla barra degli strumenti. Le applicazioni possono avviare la finestra di dialogo di personalizzazione a livello di codice inviando un messaggio TB_CUSTOMIZE al controllo della barra degli strumenti.

La figura seguente mostra un esempio della finestra di dialogo di personalizzazione della barra degli strumenti.

schermata di una finestra con una barra degli strumenti a tre elementi e una finestra di dialogo con elenchi dei pulsanti disponibili e correnti della barra degli strumenti

Gli strumenti nella casella di riepilogo a destra sono quelli attualmente presenti sulla barra degli strumenti. Inizialmente, questo elenco conterrà gli strumenti specificati quando si crea la barra degli strumenti. La casella di riepilogo a sinistra contiene gli strumenti disponibili per l'aggiunta alla barra degli strumenti. L'applicazione è responsabile del popolamento dell'elenco ,ad eccezione del separatore, visualizzato automaticamente.

Il controllo della barra degli strumenti notifica all'applicazione che sta avviando una finestra di dialogo di personalizzazione inviando alla finestra padre un codice di notifica TBN_BEGINADJUST seguito da un codice di notifica TBN_INITCUSTOMIZE. Nella maggior parte dei casi, l'applicazione non deve rispondere a questi codici di notifica. Tuttavia, se non si desidera che la finestra di dialogo Personalizza barra degli strumenti visualizzi il pulsante Guida, gestire TBN_INITCUSTOMIZE restituendo TBNRF_HIDEHELP.

Il controllo barra degli strumenti raccoglie quindi le informazioni necessarie per inizializzare la finestra di dialogo inviando tre serie di codici di notifica, nell'ordine seguente:

  • Codice di notifica TBN_QUERYINSERT per ogni pulsante sulla barra degli strumenti per determinare dove inserire i pulsanti. Restituisce false per impedire l'inserimento di un pulsante a sinistra del pulsante specificato nel messaggio di notifica. Se si restituisce false a tutti i codici di notifica TBN_QUERYINSERT, la finestra di dialogo non verrà visualizzata.
  • Codice di notifica TBN_QUERYDELETE per ogni strumento attualmente presente sulla barra degli strumenti. Restituisce TRUE se è possibile eliminare uno strumento oppure FALSO in caso contrario.
  • Serie di codici di notifica TBN_GETBUTTONINFO per popolare l'elenco dei pulsanti disponibili. Per aggiungere un pulsante all'elenco, compilare la struttura NMTOOLBAR passata con il codice di notifica e restituire TRUE. Quando non sono disponibili altri strumenti da aggiungere, restituire FALSE. Si noti che è possibile restituire informazioni per i pulsanti già presenti sulla barra degli strumenti; questi pulsanti non verranno aggiunti all'elenco.

La finestra di dialogo viene quindi visualizzata e l'utente può iniziare a personalizzare la barra degli strumenti.

Quando la finestra di dialogo è aperta, l'applicazione può ricevere un'ampia gamma di codici di notifica, a seconda delle azioni dell'utente:

  • TBN_QUERYINSERT. L'utente ha modificato la posizione di uno strumento sulla barra degli strumenti o ha aggiunto uno strumento. Restituisce "false" per impedire l'inserimento dello strumento in tale posizione.
  • TBN_DELETINGBUTTON. L'utente sta per rimuovere uno strumento dalla barra degli strumenti.
  • TBN_CUSTHELP. L'utente ha fatto clic sul pulsante Aiuto.
  • TBN_TOOLBARCHANGE. L'utente ha aggiunto, spostato o eliminato uno strumento.
  • TBN_RESET. L'utente ha fatto clic sul pulsante Reimposta.

Dopo l'eliminazione definitiva della finestra di dialogo, l'applicazione riceverà un codice di notifica TBN_ENDADJUST.

Nell'esempio di codice seguente viene illustrato un modo per implementare la personalizzazione della barra degli strumenti.

// The buttons are stored in an array of TBBUTTON structures. 
//
// Constants such as STD_FILENEW are identifiers for the 
// built-in bitmaps that have already been assigned as the toolbar's 
// image list.
//
// Constants such as IDM_NEW are application-defined command identifiers.

TBBUTTON allButtons[] = 
    {
        { MAKELONG(STD_FILENEW,  ImageListID), IDM_NEW,   TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"New" },
        { MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN,  TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Open"},
        { MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE,  TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Save"},
        { MAKELONG(STD_CUT,      ImageListID), IDM_CUT,   TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Cut" },
        { MAKELONG(STD_COPY,     ImageListID), IDM_COPY,  TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Copy"},
        { MAKELONG(STD_PASTE,    ImageListID), IDM_PASTE, TBSTATE_ENABLED, 0, {0}, 0, (INT_PTR)L"Paste"}
    };

// The following appears in the window's message handler.

case WM_NOTIFY: 
    {
        switch (((LPNMHDR)lParam)->code) 
        {
        
        case TBN_GETBUTTONINFO:  
            {
                LPTBNOTIFY lpTbNotify = (LPTBNOTIFY)lParam;

                // Pass the next button from the array. There is no need to filter out buttons
                // that are already used—they will be ignored.
                
                int buttonCount = sizeof(allButtons) / sizeof(TBBUTTON);
                
                if (lpTbNotify->iItem < buttonCount)
                {
                    lpTbNotify->tbButton = allButtons[lpTbNotify->iItem];
                    return TRUE;
                }
                
                else
                
                {
                    return FALSE;  // No more buttons.
                }
            }
            
            break;

            case TBN_QUERYINSERT:
            
            case TBN_QUERYDELETE:
                return TRUE; 
        }
    }

Trascinamento e rimozione di strumenti

Gli utenti possono anche riorganizzare i pulsanti su una barra degli strumenti premendo MAIUSC e trascinando il pulsante in un'altra posizione. Il processo di trascinamento della selezione viene gestito automaticamente dal controllo della barra degli strumenti. Visualizza un'immagine fantasma del pulsante mentre viene trascinato e riorganizza la barra degli strumenti dopo che è stato rilasciato. Gli utenti non possono aggiungere pulsanti in questo modo, ma possono eliminare un pulsante rilasciandolo dalla barra degli strumenti.

Anche se il controllo barra degli strumenti esegue normalmente questa operazione automaticamente, invia anche all'applicazione due codici di notifica: TBN_QUERYDELETE e TBN_QUERYINSERT. Per controllare il processo di trascinamento e rilascio, gestire i seguenti codici di notifica come indicato di seguito.

  • Il codice di notifica TBN_QUERYDELETE viene inviato non appena l'utente tenta di spostare il pulsante, prima che venga visualizzato il pulsante fantasma. Restituisci FALSE per impedire lo spostamento del pulsante. Se si restituisce TRUE, l'utente sarà in grado di spostare lo strumento o eliminarlo rimuovendolo dalla barra degli strumenti. Se uno strumento può essere spostato, può essere eliminato. Tuttavia, se l'utente elimina uno strumento, il controllo barra degli strumenti invierà all'applicazione un codice di notifica TBN_DELETINGBUTTON, a questo punto è possibile scegliere di reinserire il pulsante nella posizione originale, annullando così l'eliminazione.
  • Il codice di notifica TBN_QUERYINSERT viene inviato quando l'utente tenta di rilasciare il pulsante sulla barra degli strumenti. Per impedire che il pulsante spostato venga posizionato a sinistra del pulsante specificato nella notifica, restituire FALSE. Questo codice di notifica non viene inviato se l'utente elimina lo strumento dalla barra degli strumenti.

Se l'utente tenta di trascinare un pulsante senza premere il tasto MAIUSC, il controllo della barra degli strumenti non gestirà l'operazione di trascina e rilascia. Tuttavia, invierà all'applicazione un codice di notifica TBN_BEGINDRAG per indicare l'inizio di un'operazione di trascinamento e un codice di notifica TBN_ENDDRAG per indicare la fine. Se si desidera abilitare questa forma di trascinamento della selezione, l'applicazione deve gestire questi codici di notifica, fornire l'interfaccia utente necessaria e modificare la barra degli strumenti in modo da riflettere eventuali modifiche.

Salvataggio e ripristino delle barre degli strumenti

Nel processo di personalizzazione di una barra degli strumenti, l'applicazione potrebbe dover salvare le informazioni in modo da poter ripristinare lo stato originale della barra degli strumenti. Per avviare il salvataggio o il ripristino di uno stato della barra degli strumenti, inviare un messaggio al controllo della barra degli strumenti con TB_SAVERESTORE e il wParam impostato su TRUE. Il valore wParam di questo messaggio specifica se si richiede un'operazione di salvataggio o ripristino. Dopo l'invio del messaggio, esistono due modi per gestire l'operazione di salvataggio/ripristino:

  • Con i controlli comuni versione 4.72 e versioni precedenti, è necessario implementare un gestore TBN_GETBUTTONINFO. Il controllo barra degli strumenti invia questo codice di notifica per richiedere informazioni su ogni pulsante durante il ripristino.
  • La versione 5.80 include un'opzione di salvataggio/ripristino. All'inizio del processo e, man mano che ogni pulsante viene salvato o ripristinato, l'applicazione riceverà un codice di notifica TBN_SAVE o TBN_RESTORE. Per usare questa opzione, è necessario implementare i gestori di notifica per fornire le informazioni di bitmap e stato necessarie per salvare o ripristinare correttamente lo stato della barra degli strumenti.

Gli stati della barra degli strumenti vengono salvati in un flusso di dati costituito da blocchi di dati definiti dalla shell alternati con blocchi di dati definiti dall'applicazione. Un blocco di dati di ogni tipo viene archiviato per ogni pulsante, insieme a un blocco facoltativo di dati globali che le applicazioni possono posizionare all'inizio del flusso. Durante il processo di salvataggio, il gestore TBN_SAVE aggiunge i blocchi definiti dall'applicazione al flusso di dati. Durante il processo di ripristino, il gestore TBN_RESTORE legge ogni blocco e fornisce alla shell le informazioni necessarie per ricostruire la barra degli strumenti.

Come gestire una notifica di TBN_SAVE

Il primo TBN_SAVE codice di notifica viene inviato all'inizio del processo di salvataggio. Prima di salvare i pulsanti, i membri della struttura NMTBSAVE vengono impostati come illustrato nella tabella seguente.

Membro Impostazione
elemento –1
cbData Quantità di memoria necessaria per i dati definiti dalla shell.
cButtons Numero di pulsanti.
pData Quantità calcolata di memoria necessaria per i dati definiti dall'applicazione. In genere, si includono alcuni dati globali, oltre ai dati per ogni pulsante. Aggiungi tale valore a cbData e allocare memoria sufficiente per pData per contenerli tutti.
Corrente Primo byte inutilizzato nel flusso di dati. Se non sono necessarie informazioni sulla barra degli strumenti globali, impostare pCurrent = pData in modo che punti all'inizio del flusso di dati. Se sono necessarie informazioni globali sulla barra degli strumenti, archiviarla in pData, quindi impostare pCurrent all'inizio della parte inutilizzata del flusso di dati prima di restituire.

 

Se si desidera aggiungere alcune informazioni sulla barra degli strumenti globali, inserirle all'inizio del flusso di dati. Avanzare pCurrent alla fine dei dati globali in modo che punti all'inizio della parte inutilizzata del flusso di dati e ritorna.

Dopo il tuo ritorno, la Shell inizia a salvare le informazioni sul pulsante. Aggiunge i dati definiti dalla shell per il primo pulsante in pCurrent e quindi sposta pCurrent all'inizio della parte inutilizzata.

Dopo aver salvato ogni pulsante, viene inviato un codice di notifica TBN_SAVE e NMTBSAVE viene restituito con questi membri impostati come indicato di seguito.

Membro Impostazione
iItem Indice in base zero del numero del pulsante.
pCorrente Puntatore al primo byte inutilizzato nel flusso di dati. Se si desidera memorizzare informazioni aggiuntive sul pulsante, conservarle nella posizione indicata da pCurrent e aggiornare pCurrent in modo che punti alla prima parte inutilizzata del flusso di dati successiva.
TBBUTTON Una struttura di TBBUTTON che descrive il pulsante che viene salvato.

 

Quando si riceve il codice di notifica, è necessario estrarre le informazioni specifiche del pulsante necessarie da TBBUTTON. Ricorda che quando aggiungi un pulsante, puoi utilizzare il membro dwData di TBBUTTON per contenere dati specifici dell'applicazione. Carica i tuoi dati nel flusso di dati a pCurrent. Sposta pCurrent alla fine dei tuoi dati per puntare nuovamente all'inizio della parte inutilizzata del flusso e ritorna.

Shell passa quindi al pulsante successivo, aggiunge le informazioni a pData, sposta pCurrent, carica TBBUTTONe invia un altro codice di notifica TBN_SAVE. Questo processo continua fino a quando non vengono salvati tutti i pulsanti.

Ripristino delle barre degli strumenti salvate

Il processo di ripristino inverte fondamentalmente il processo di salvataggio. All'inizio, l'applicazione riceverà un codice di notifica TBN_RESTORE con il membro iItem della struttura di NMTBRESTORE impostato su -1. Il membro cbData è impostato alla dimensione di pData, e cButtons è impostato sul numero di pulsanti.

Il gestore delle notifiche deve estrarre le informazioni globali inserite all'inizio di pData durante il salvataggio e passare pCurrent all'inizio del primo blocco di dati definiti dalla shell. Impostare cBytesPerRecord sulle dimensioni dei blocchi di dati usati per salvare i dati del pulsante. Impostare cButtons sul numero di pulsanti e restituire.

Il successivo NMTBRESTORE è relativo al primo pulsante. Il membro pCurrent punta all'inizio del primo blocco di dati dei pulsanti e iItem è impostato sull'indice del pulsante. Estrai i dati e avanza pCurrent. Carica i dati in TBBUTTON, e restituisci. Per omettere un pulsante dalla barra degli strumenti ripristinata, impostare il membro idCommand di TBBUTTON su zero. Shell ripeterà il processo per i pulsanti rimanenti. Oltre ai messaggiNMTBSAVEe NMTBRESTORE, è anche possibile usare messaggi come TBN_RESET per salvare e ripristinare una barra degli strumenti.

Nell'esempio di codice seguente viene salvata una barra degli strumenti prima che venga personalizzata e ripristinata se l'applicazione riceve un messaggio di TBN_RESET.

int               i;
LPNMHDR           lpnmhdr;
static int        nResetCount;
static LPTBBUTTON lpSaveButtons;
LPARAM            lParam;

switch( lpnmhdr->code)
{
    case TBN_BEGINADJUST: // Begin customizing the toolbar.
    {
        LPTBNOTIFY  lpTB = (LPTBNOTIFY)lparam;
       
        // Allocate memory for the button information.
        
        nResetCount   = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
        lpSaveButtons = (LPTBBUTTON)GlobalAlloc(GPTR, sizeof(TBBUTTON) * nResetCount);
      
        // In case the user presses reset, save the current configuration 
        // so the original toolbar can be restored.
        
        for(i = 0; i < nResetCount; i++)
        {
            SendMessage(lpTB->hdr.hwndFrom, 
                        TB_GETBUTTON, i, 
                        (LPARAM)(lpSaveButtons + i));
        }
    }
    
    return TRUE;
   
    case TBN_RESET:
    {
        LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
        
        int nCount, i;
    
        // Remove all of the existing buttons, starting with the last one.
        
        nCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
        
        for(i = nCount - 1; i >= 0; i--)
        {
            SendMessage(lpTB->hdr.hwndFrom, TB_DELETEBUTTON, i, 0);
        }
      
        SendMessage(lpTB->hdr.hwndFrom,      // Restore the saved buttons.
                    TB_ADDBUTTONS, 
                    (WPARAM)nResetCount, 
                    (LPARAM)lpSaveButtons);
    }
    
    return TRUE;
   
    case TBN_ENDADJUST:                // Free up the memory you allocated.
        GlobalFree((HGLOBAL)lpSaveButtons);
        
        return TRUE;
}

Uso dei controlli della barra degli strumenti

Valori dell'indice delle immagini standard del pulsante della barra degli strumenti

demo dei controlli comuni di Windows (CppWindowsCommonControls)