Ejemplo: app_three
Al igual que con todos los controles comunes, debemos llamar a InitCommonControl ANTES de intentar usarlos. Necesitaremos #include <commctrl.h> para poder usar esta funci�n y para obtener la funciones y declaraciones necesarias para el uso de los controles comunes. Tambi�n necesitaremos agregar comctl32.lib en la configuraci�n de nuestro enlazador (linker), si no se encuentra configurado de esa manera. Observa que InitCommonControls( ) es una vieja API, para obtener mas control podemos usar InitCommonControlsEx( ) la cual es requerida por los m�s recientes controles comunes. Sin embargo, debido a que no voy a usar ninguna de las caracter�sticas avanzadas, InitCommonControls( ) ser� adecuado y mas simple.
Podemos crear una barra de herramientas usando CreateToolbarEx( ) pero no es la idea... Lo que necesitamos hacer es crear la barra de herramientas...
hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
Esto es bastante simple, TOOLBARCLASSNAME es una constante definida por los encabezados (headers) de los controles comunes. hwnd es la ventana padre, la ventana en la que aparecer� la barra de herramientas. IDC_MAIN_TOOL es un identificador que podemos usar posteriormente para obtener el HWND de la barra de herramientas por medio de GetDlgItem( ).
// Send the TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility.
SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
Este mensaje es necesario para permitirle al sistema darse cuenta que versi�n de la librer�a de controles comunes estamos usando. Debido a que nuevas versiones agregan c�digo a la estructura, dando el tama�o de la misma el sistema puede darse cuenta que comportamiento estamos esperando.
Primero declaramos TBBUTTON y TBADDBITMAP
TBBUTTON tbb[3];
TBADDBITMAP tbab;
y luego agregamos los los bitmaps est�ndar a la barra de herramientas usando la lista de im�genes en la libreria de los controles comunes...
tbab.hInst = HINST_COMMCTRL;
tbab.nID = IDB_STD_SMALL_COLOR;
SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tbab);
Ahora que hemos cargado nuestras im�genes, podemos agregar algunos botones que las utilicen...
ZeroMemory(tbb, sizeof(tbb));
tbb[0].iBitmap = STD_FILENEW;
tbb[0].fsState = TBSTATE_ENABLED;
tbb[0].fsStyle = TBSTYLE_BUTTON;
tbb[0].idCommand = ID_FILE_NEW;
tbb[1].iBitmap = STD_FILEOPEN;
tbb[1].fsState = TBSTATE_ENABLED;
tbb[1].fsStyle = TBSTYLE_BUTTON;
tbb[1].idCommand = ID_FILE_OPEN;
tbb[2].iBitmap = STD_FILESAVE;
tbb[2].fsState = TBSTATE_ENABLED;
tbb[2].fsStyle = TBSTYLE_BUTTON;
tbb[2].idCommand = ID_FILE_SAVEAS;
SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb);
Aqu� hemos agregado los botones New, Open y Save As usando las im�genes est�ndar, lo cual es una buena idea debido a que las personas suelen verlas y ya saben que significan.
Los �ndices de las lista de im�genes est�n definidos en los encabezados de los controles comunes y tambi�n son listados en MSDN.
Hemos asignado a cada bot�n un ID (ID_FILE_NEW, etc...) lo cual es id�ntico a los IDs de los items equivalentes en el Men�. Estos botones generar�n mensajes WM_COMMAND identicos a los del Men�, por lo tanto no se requiere alg�n procesamiento extra! Si fueramos a agregar un bot�n para un comando que no aparece en el Men�, simplemente definimos un nuevo ID y agregamos un manejador a WM_COMMAND.
Si te est�s preguntando por qu� he pasado wParam a TB_ADDBUTTONS, bueno, est� realizando un c�lculo del n�mero de botones en el arreglo tbb para que no necesitemos especificar un valor. Si en lugar de esto, lo que hacemos es poner un 3, bien, estar�a correcto pero que sucede si queremos agregar otros botones... deber�amos cambiar este numero por 4 y en programaci�n eso no es muy bueno... queremos que los cambios provoquen la menor cantidad de cambios. Por ejemplo, si el tama�o de TBBUTON tiene 16 bits, debido a que tenemos 3 botones el tama�o del tbb deber�a ser de 16*3 = 48. Del mismo modo, 48/16 da el n�mero de botones, 3 en este caso.
hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
hwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);
Y luego (opcionalmente) especificamos el numero de secciones que deseamos. Si no especificamos ninguna, simplemente tendr� una que usa el ancho entero de la barra. Podemos especificar o recuperar el texto usando SetWindowText( ) como con lo hac�amos con muchos de los otros controles. Si especificamos m�s de una secci�n, necesitamos especificar el ancho de cada una y luego usar SB_SETTEXT para especificar el texto de cada secci�n.
Para definir los anchos declaramos un arreglo de enteros donde cada valor es el ancho en pixeles de una secci�n. Si queremos que una secci�n use el espacio restante fijamos como valor -1.
El wParam nuevamente es para calcular cuantos elementos hay en el arreglo. Una vez que hemos terminado de agregar secciones, fijamos el primer valor (de �ndice 0) para verla en acci�n.
WM_SIZE anterior, se van a solapar con el control edit que hemos agregado en los ejemplos anteriores. En WM_SIZE, ponemos las barras de estado y de herramientas en posici�n y luego restamos el alto del area cliente para que podamos mover nuestro control edit para rellenar el espacio restante...
HWND hTool;
RECT rcTool;
int iToolHeight;
HWND hStatus;
RECT rcStatus;
int iStatusHeight;
HWND hEdit;
int iEditHeight;
RECT rcClient;
// Size toolbar and get height
hTool = GetDlgItem(hwnd, IDC_MAIN_TOOL);
SendMessage(hTool, TB_AUTOSIZE, 0, 0);
GetWindowRect(hTool, &rcTool);
iToolHeight = rcTool.bottom - rcTool.top;
// Size status bar and get height
hStatus = GetDlgItem(hwnd, IDC_MAIN_STATUS);
SendMessage(hStatus, WM_SIZE, 0, 0);
GetWindowRect(hStatus, &rcStatus);
iStatusHeight = rcStatus.bottom - rcStatus.top;
// Calculate remaining height and size edit
GetClientRect(hwnd, &rcClient);
iEditHeight = rcClient.bottom - iToolHeight - iStatusHeight;
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
SetWindowPos(hEdit, NULL, 0, iToolHeight, rcClient.right, iEditHeight, SWP_NOZORDER);
Desafortunadamente esta es una porci�n de c�digo bastante larga, pero es simple... las barras de herramiemntas se autoposicionar�n cuando env�emos el mensaje TB_AUTOSIZE y las barras de estado har�n lo mismo cuando enviemos WM_SIZE (las librer�as de los controles comunes no entienden nada a cerca de consistencia).
Versi�n en Espa�ol: Federico Pizarro - 2003