Compartir vía


Personalización de barras de herramientas

La mayoría de las aplicaciones basadas en Windows usan controles de barra de herramientas para proporcionar a los usuarios acceso cómodo a la funcionalidad del programa. Sin embargo, las barras de herramientas estáticas tienen algunas deficiencias, como demasiado poco espacio para mostrar eficazmente todas las herramientas disponibles. La solución a este problema es hacer que las barras de herramientas de la aplicación sean personalizables por el usuario. A continuación, los usuarios pueden optar por mostrar solo las herramientas que necesitan y pueden organizarlas de forma que se adapten a su estilo de trabajo personal.

Nota

Las barras de herramientas de los cuadros de diálogo no se pueden personalizar.

 

Para habilitar la personalización, incluya el CCS_ADJUSTABLE marca de estilo de controles comunes al crear el control de barra de herramientas. Hay dos enfoques básicos para la personalización:

  • Cuadro de diálogo de personalización. Este cuadro de diálogo proporcionado por el sistema es el enfoque más sencillo. Proporciona a los usuarios una interfaz gráfica de usuario que les permite agregar, eliminar o mover iconos.
  • Arrastrar y colocar herramientas. La implementación de la funcionalidad de arrastrar y colocar permite a los usuarios mover herramientas a otra ubicación de la barra de herramientas o eliminarlas arrastrándolas fuera de la barra de herramientas. Proporciona a los usuarios una manera rápida y sencilla de organizar su barra de herramientas, pero no les permite agregar herramientas.

Puede implementar un enfoque o ambos, en función de las necesidades de la aplicación. Ninguno de estos dos enfoques para la personalización proporciona un mecanismo integrado, como un botón Cancelar o Deshacer, para devolver la barra de herramientas a su estado anterior. Debe usar explícitamente la API de control de la barra de herramientas para almacenar el estado de precustomización de la barra de herramientas. Si es necesario, puede usar más adelante esta información almacenada para restaurar la barra de herramientas a su estado original.

Lo que necesita saber

Tecnologías

Requisitos previos

  • C/C++
  • Programación de la interfaz de usuario de Windows

Instrucciones

Personalización (cuadro de diálogo)

El control de la barra de herramientas proporciona el cuadro de diálogo de personalización para proporcionar a los usuarios una manera sencilla de agregar, mover o eliminar herramientas. Los usuarios pueden iniciarlo haciendo doble clic en la barra de herramientas. Las aplicaciones pueden iniciar el cuadro de diálogo de personalización mediante programación enviando al control de la barra de herramientas un mensaje de TB_CUSTOMIZE .

En la ilustración siguiente se muestra un ejemplo del cuadro de diálogo de personalización de la barra de herramientas.

captura de pantalla de una ventana con una barra de herramientas de tres elementos y un cuadro de diálogo con listas de los botones de barra de herramientas disponibles y actuales

Las herramientas del cuadro de lista de la derecha son las que se encuentran actualmente en la barra de herramientas. Inicialmente, esta lista contendrá las herramientas que especifique al crear la barra de herramientas. El cuadro de lista de la izquierda contiene las herramientas que están disponibles para agregar a la barra de herramientas. La aplicación es responsable de rellenar esa lista (que no sea con el separador, que aparece automáticamente).

El control de la barra de herramientas notifica a la aplicación que está iniciando un cuadro de diálogo de personalización enviando a su ventana primaria un código de notificación TBN_BEGINADJUST seguido de un código de notificación de TBN_INITCUSTOMIZE . En la mayoría de los casos, la aplicación no necesita responder a estos códigos de notificación. Sin embargo, si no desea que el cuadro de diálogo Personalizar barra de herramientas muestre un botón Ayuda, controle TBN_INITCUSTOMIZE devolviendo TBNRF_HIDEHELP.

A continuación, el control de barra de herramientas recopila la información que necesita para inicializar el cuadro de diálogo mediante el envío de tres series de códigos de notificación, en el orden siguiente:

  • Un TBN_QUERYINSERT código de notificación para cada botón de la barra de herramientas para determinar dónde se pueden insertar los botones. Devuelve FALSE para evitar que se inserte un botón a la izquierda del botón especificado en el mensaje de notificación. Si devuelve FALSE a todos los códigos de notificación de TBN_QUERYINSERT, no se mostrará el cuadro de diálogo.
  • Un código de notificación TBN_QUERYDELETE para cada herramienta que se encuentra actualmente en la barra de herramientas. Devuelve TRUE si se puede eliminar una herramienta o FALSE si no es así.
  • Serie de códigos de notificación de TBN_GETBUTTONINFO para rellenar la lista de botones disponibles. Para agregar un botón a la lista, rellene la estructura NMTOOLBAR que se pasa con el código de notificación y devuelve TRUE. Cuando no tenga más herramientas que agregar, devuelva FALSE. Tenga en cuenta que puede devolver información de los botones que ya están en la barra de herramientas; estos botones no se agregarán a la lista.

A continuación, se muestra el cuadro de diálogo y el usuario puede empezar a personalizar la barra de herramientas.

Cuando el cuadro de diálogo está abierto, la aplicación puede recibir una variedad de códigos de notificación, en función de las acciones del usuario:

  • TBN_QUERYINSERT. El usuario ha cambiado la ubicación de una herramienta en la barra de herramientas o ha agregado una herramienta. Devuelve FALSE para evitar que la herramienta se inserte en esa ubicación.
  • TBN_DELETINGBUTTON. El usuario está a punto de quitar una herramienta de la barra de herramientas.
  • TBN_CUSTHELP. El usuario ha realizado clic en el botón Ayuda.
  • TBN_TOOLBARCHANGE. El usuario ha agregado, movido o eliminado una herramienta.
  • TBN_RESET. El usuario ha realizado clic en el botón Restablecer.

Una vez destruido el cuadro de diálogo, la aplicación recibirá un código de notificación TBN_ENDADJUST .

En el ejemplo de código siguiente se muestra una manera de implementar la personalización de la barra de herramientas.

// 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; 
        }
    }

Herramientas de arrastrar y colocar

Los usuarios también pueden reorganizar los botones de una barra de herramientas presionando la tecla MAYÚS y arrastrando el botón a otra ubicación. El control de la barra de herramientas controla automáticamente el proceso de arrastrar y colocar. Muestra una imagen fantasma del botón mientras se arrastra y reorganiza la barra de herramientas después de colocarla. Los usuarios no pueden agregar botones de esta manera, pero pueden eliminar un botón si lo quitan de la barra de herramientas.

Aunque el control de la barra de herramientas normalmente realiza esta operación automáticamente, también envía a la aplicación dos códigos de notificación: TBN_QUERYDELETE y TBN_QUERYINSERT. Para controlar el proceso de arrastrar y colocar, controle estos códigos de notificación de la siguiente manera:

  • El código de notificación de TBN_QUERYDELETE se envía en cuanto el usuario intenta mover el botón, antes de que se muestre el botón fantasma. Devuelve FALSE para evitar que se mueva el botón. Si devuelve TRUE, el usuario podrá mover la herramienta o eliminarla quitando la barra de herramientas. Si se puede mover una herramienta, se puede eliminar. Sin embargo, si el usuario elimina una herramienta, el control de barra de herramientas enviará a la aplicación un código de notificación TBN_DELETINGBUTTON , momento en el que puede elegir volver a insertar el botón en su ubicación original, lo que cancelará la eliminación.
  • El código de notificación TBN_QUERYINSERT se envía cuando el usuario intenta colocar el botón en la barra de herramientas. Para evitar que el botón que se mueve se quite a la izquierda del botón especificado en la notificación, devuelva FALSE. Este código de notificación no se envía si el usuario quita la herramienta de la barra de herramientas.

Si el usuario intenta arrastrar un botón sin presionar también la tecla MAYÚS, el control de la barra de herramientas no controlará la operación de arrastrar y colocar. Sin embargo, enviará a la aplicación un código de notificación TBN_BEGINDRAG para indicar el inicio de una operación de arrastre y un código de notificación TBN_ENDDRAG para indicar el final. Si desea habilitar esta forma de arrastrar y colocar, la aplicación debe controlar estos códigos de notificación, proporcionar la interfaz de usuario necesaria y modificar la barra de herramientas para reflejar los cambios.

Guardar y restaurar barras de herramientas

En el proceso de personalizar una barra de herramientas, es posible que la aplicación tenga que guardar información para poder restaurar la barra de herramientas a su estado original. Para iniciar el guardado o la restauración de un estado de la barra de herramientas, envíe al control de la barra de herramientas un mensaje de TB_SAVERESTORE con lParam establecido en TRUE. El valor lParam de este mensaje especifica si está solicitando una operación de guardado o restauración. Una vez enviado el mensaje, hay dos maneras de controlar la operación de guardado y restauración:

  • Con los controles comunes versión 4.72 y anteriores, debe implementar un controlador de TBN_GETBUTTONINFO . El control de barra de herramientas envía este código de notificación para solicitar información sobre cada botón a medida que se restaura.
  • La versión 5.80 incluye una opción para guardar o restaurar. Al principio del proceso y, a medida que se guarda o restaura cada botón, la aplicación recibirá un código de notificación TBN_SAVE o TBN_RESTORE . Para usar esta opción, debe implementar controladores de notificaciones para proporcionar la información de estado y mapa de bits necesaria para guardar o restaurar correctamente el estado de la barra de herramientas.

Los estados de la barra de herramientas se guardan en un flujo de datos que consta de bloques de datos definidos por Shell que alternan con bloques de datos definidos por la aplicación. Un bloque de datos de cada tipo se almacena para cada botón, junto con un bloque opcional de datos globales que las aplicaciones pueden colocar al principio de la secuencia. Durante el proceso de guardado, el controlador de TBN_SAVE agrega los bloques definidos por la aplicación al flujo de datos. Durante el proceso de restauración, el controlador de TBN_RESTORE lee cada bloque y proporciona al Shell la información que necesita para reconstruir la barra de herramientas.

Cómo controlar una notificación de TBN_SAVE

El primer TBN_SAVE código de notificación se envía al principio del proceso de guardado. Antes de guardar los botones, los miembros de la estructura NMTBSAVE se establecen como se muestra en la tabla siguiente.

Miembro Configuración
iItem –1
cbData Cantidad de memoria necesaria para los datos definidos por Shell.
cButtons Número de botones.
pData Cantidad calculada de memoria necesaria para los datos definidos por la aplicación. Normalmente, se incluyen algunos datos globales, además de datos para cada botón. Agregue ese valor a cbData y asigne suficiente memoria a pData para almacenarlo todo.
pCurrent Primer byte sin usar del flujo de datos. Si no necesita información de la barra de herramientas global, establezca pCurrent = pData para que apunte al inicio del flujo de datos. Si necesita información global de la barra de herramientas, almacénela en pData y, a continuación, establezca pCurrent al principio de la parte sin usar del flujo de datos antes de devolverla.

 

Si desea agregar información de la barra de herramientas global, colóquela al principio del flujo de datos. Avance pCurrent al final de los datos globales para que apunte al principio de la parte sin usar del flujo de datos y devuelva.

Después de volver, shell comienza a guardar la información del botón. Agrega los datos definidos por shell para el primer botón de pCurrent y, a continuación, avanza pCurrent al principio de la parte sin usar.

Después de guardar cada botón, se envía un código de notificación de TBN_SAVE y se devuelve NMTBSAVE con estos miembros establecidos de la siguiente manera.

Member Configuración
iItem Índice de base cero del número de botón.
pCurrent Puntero al primer byte sin usar del flujo de datos. Si desea almacenar información adicional sobre el botón, almacénela en la ubicación a la que apunta pCurrent y actualice pCurrent para que apunte a la primera parte sin usar del flujo de datos después de eso.
TBBUTTON Estructura TBBUTTON que describe el botón que se está guardando.

 

Cuando reciba el código de notificación, debe extraer cualquier información específica del botón que necesite de TBBUTTON. Recuerde que, al agregar un botón, puede usar el miembro dwData de TBBUTTON para contener datos específicos de la aplicación. Cargue los datos en el flujo de datos en pCurrent. Avance pCurrent al final de los datos, apuntando de nuevo al principio de la parte sin usar de la secuencia y vuelva.

A continuación, shell va al botón siguiente, agrega su información a pData, avanza pCurrent, carga TBBUTTON y envía otro código de notificación de TBN_SAVE . Este proceso continúa hasta que se guardan todos los botones.

Restaurar barras de herramientas guardadas

El proceso de restauración invierte básicamente el proceso de guardado. Al principio, la aplicación recibirá un código de notificación de TBN_RESTORE con el miembro iItem de la estructura NMTBRESTORE establecida en –1. El miembro cbData se establece en el tamaño de pData y cButtons se establece en el número de botones.

El controlador de notificaciones debe extraer la información global que se colocó al principio de pData durante el guardado y avanzar pCurrent al inicio del primer bloque de datos definidos por Shell. Establezca cBytesPerRecord en el tamaño de los bloques de datos que usó para guardar los datos del botón. Establezca cButtons en el número de botones y vuelva.

El siguiente NMTBRESTORE es para el primer botón. El miembro pCurrent apunta al inicio del primer bloque de datos de botón y iItem se establece en el índice del botón. Extraiga esos datos y avance pCurrent. Cargue los datos en TBBUTTON y devuelva. Para omitir un botón de la barra de herramientas restaurada, establezca el miembro idCommand de TBBUTTON en cero. El Shell repetirá el proceso para los botones restantes. Además de los mensajes NMTBSAVE y NMTBRESTORE , también puede usar mensajes como TBN_RESET para guardar y restaurar una barra de herramientas.

En el ejemplo de código siguiente se guarda una barra de herramientas antes de personalizarla y se restaura si la aplicación recibe un mensaje de 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;
}

Usar controles de barra de herramientas

Valores de índice de imagen de botón estándar de la barra de herramientas

Demostración de controles comunes de Windows (CppWindowsCommonControls)