Toolbar Control
The use of toolbar is frequently seen in modern GUI applications. MiniGUI prepares the predefined toolbar control class for the application. In fact, MiniGUI provides three different predefined toolbar control classes, namely CTRL_TOOLBAR
, CTRL_NEWTOOLBAR
, and CTRL_COOLBAR
(in MiniGUIExt
library) control classes.
CTRL_TOOLBAR
is the early toolbar control class, which is obsolete and replaced by CTRL_NEWTOOLBAR
control class. Including CTRL_TOOLBAR
class in MiniGUI is just for compatibility, and new applications should not use it. We introduce CTRL_NEWTOOLBAR
control class in this chapter, and introduce CTRL_COOLBAR
control class in Chapter 36.
Calling CreateWindow
function with CTRL_NEWTOOLBAR
as the control class name can create a toolbar control. The running effect of this control is shown in Figure 1.

Figure 1 Toolbar control
Creating Toolbar Control
Before creating a toolbar control, we should fill a NTBINFO
structure first, and pass the pointer to the structure to the window procedure of the control class through dwAddData
argument of CreateWindow
function. NTBINFO
structure is mainly used to define the information of the bitmap used by a toolbar, as shown in Table 1.
Table 1 NTBINFO
structure
Member
Meaning
Note
image
Image for displaying the bitmaps of the buttons.
nr_cells
Number of bitmap cells in the image, that is to say, number of lines in total
nr_cols
Number of cell columns in the image, that is to say, number of states of each bitmap cell
1 means the cells have only normal state; 2 means the cells have normal and highlight states; 3 means the cells have not disabled state. 4 or 0 means the cells have all the four possible states.
w_cell
Width of bitmap cell
If w_cell
is zero, it will be equal to (width_of_image
/ nr_cols
)
h_cell
Height of bitmap cell
If h_cell
is zero, it will be equal to (height_of_image
/ nr_cells
)
We must organize the bitmaps on the toolbar buttons (we called bitmap cells) in a single bitmap object, and should organize them into a structure as shown in Figure 2. Here, the first column illustrates the normal states of all the bitmap cells possibly used by the toolbar buttons; the second column illustrates the highlighted states of all the bitmap cells possibly used by the toolbar buttons; the third column illustrates the pushed state, and the fourth column illustrates the disabled (grayed) state. Each row of the bitmap illustrates all the states of a single button bitmap cell.

Figure 2 Bitmap object used for a toolbar control
The toolbar control selects the appropriate bitmap cell in the bitmap object to display the button according to the button state in the toolbar.
Styles of Toolbar
The toolbar control class supports the following styles:
NTBS_HORIZONTAL
: Display toolbar horizontally. This is the default style.NTBS_VERTICAL
: Display toolbar vertically, as shown in Figure 3.NTBS_MULTLINE
: Toolbar can display multiple lines. When type of tool item isNTBIF_NEWLINE
, it will display the added tool item in another row or column, as shown in Figure 3.NTBS_WITHTEXT
: Display the text under or at the right side of the button, and display the text under the button bitmap by default. In this case, the application must specify the corresponding text when adding a button. The bitmap will be popped when the button is active with this style.NTBS_TEXTRIGHT
: When using it withNTBS_WITHTEXT
style, this style specifies the text to display at the right side of the button bitmap. The toolbar in Figure 1 hasNTBS_TEXTRIGHT
style. The bitmap and text will be popped when the button is active with this style.NTBS_DRAWSTATES
: Draws the button states with different 3D frames, and does not use the highlight, pushed and disabled bitmap cell.NTBS_DRAWSEPARATOR
: Draws the separator bar. The separator bar used to separate buttons in the toolbar will not be drawn by default, but increase the distance between two buttons. When the toolbar has this style, it will draw a narrow separator bar.

Figure 3 Toolbar control display vertically and in multiple columns
Messages of Toolbar
Adding an Item
An item can be added by sending NTBM_ADDITEM
message and passing NTBITEMINFO
structure to the toolbar control. Table 2 gives the meanings of the members of NTBITEMINFO
.
Table 2 NTBITEMINFO
structure
*Members *
Meanings
Note
which
Used for NTBM_GETITEM
and NTBM_SETITEM
messages.
flags
This member is used to specify the type and state of an item. The type can be one of the following values:
1. NTBIF_PUSHBUTTON
: A normal push button
2. NTBIF_CHECKBUTTON
: A check box button
3. NTBIF_HOTSPOTBUTTON
: A button with hotspot
4. NTBIF_NEWLINE
: A new line separator when the style NTBS_MULTILINE
specified.
5. NTBIF_SEPARATOR
: A separator.
The item has only one state, namely NTBIF_DISABLED
, indicating the item is disabled.
The value of this member should be OR’d
value by one of the type identifier and the state identifier.
id
Identifier of the button. When the user clicked a button, the identifier would be sent as the notification code of the notification message of the toolbar to the parent window or the notification callback function.
text
This member will be used to pass the text of the button when the control has NTBS_WITHTEXT
style.
tip
Not used and reserved.
bmp_cell
Specify which bitmap cell in the bitmap object is used by the button. This index of first bitmap cell is zero.
This button will use the bitmap cell in the bmp_cell
line to display the state of the button.
hotspot_proc
If the item is a button with hotspot, this member defines the callback function when the user clicked the hotspot.
rc_hotspot
If the item is a button with hotspot, this member defines the rectangle region of the hotspot in the button, relative to the upper-left corner of the button.
When the user clicked the hotspot rectangle region, it is regarded as activating the hotspot.
add_data
Additional data of the item.
The member will be ignored when adding an item. The following program illustrates how to add a normal push button, an initially grayed button, an separator bar, and a button with hotspot to a toolbar control:
HWND ntb1;
NTBINFO ntb_info;
NTBITEMINFO ntbii;
RECT hotspot = {16, 16, 32, 32};
/* Fill NTBINFO Structure */
ntb_info.nr_cells = 4;
ntb_info.w_cell = 0;
ntb_info.h_cell = 0;
ntb_info.nr_cols = 0;
ntb_info.image = &bitmap1;
/* Create the toolbar control */
ntb1 = CreateWindow (CTRL_NEWTOOLBAR,
"",
WS_CHILD | WS_VISIBLE,
IDC_CTRL_NEWTOOLBAR_1,
0, 10, 1024, 0,
hWnd,
(DWORD) &ntb_info);
/* Add a normal button item */
ntbii.flags = NTBIF_PUSHBUTTON;
ntbii.id = IDC_NTB_TWO;
ntbii.bmp_cell = 1;
SendMessage(ntb1, TBM_ADDITEM, 0, (LPARAM)&ntbii);
/* Add a grayed button item */
ntbii.flags = NTBIF_PUSHBUTTON | NTBIF_DISABLED;
ntbii.id = IDC_NTB_THREE;
ntbii.bmp_cell = 2;
SendMessage (ntb1, TBM_ADDITEM, 0, (LPARAM)&ntbii);
/* Add a separator */
ntbii.flags = NTBIF_SEPARATOR;
ntbii.id = 0;
ntbii.bmp_cell = 0;
ntbii.text = NULL;
SendMessage (ntb1, TBM_ADDITEM, 0, (LPARAM)&ntbii);
/* Add a button with hotspot */
ntbii.flags = NTBIF_HOTSPOTBUTTON;
ntbii.id = IDC_NTB_FOUR;
ntbii.bmp_cell = 3;
ntbii.rc_hotspot = hotspot;
ntbii.hotspot_proc = my_hotspot_proc;
SendMessage (ntb1, TBM_ADDITEM, 0, (LPARAM)&ntbii);
Getting/Setting Information of an Item
Using NTBM_GETITEM
or NTBM_SETITEM
message can get or set the information of an item through its identifier. Use of the two messages is similar to NTBM_ADDITEM
, and the difference is wParam
as the ID of item and lParam
as point to a NTBITEMINFO
structure that which member in specifies the item information to be gotten or set. The member which can be the OR’d
of the following values:
MTB_WHICH_FLAGS
: Get or set the flag of an item, which is the flags field inNTBITEMINFO
structure.MTB_WHICH_ID
: Get or set the identifier of an itemMTB_WHICH_TEXT
: Get or set the item text. Note that when getting text, you must ensure that enough buffer to be passed by text field. For safety consideration, it should ensure that the size of the buffer is at leastNTB_TEXT_LEN+1
.MTB_WHICH_CELL
: Get or set the bitmap cell index used by the item.MTB_WHICH_HOTSPOT
: Get or set the hotspot rectangle of the item.MTB_WHICH_ADDDATA
: Get or set the additional data of the item.
For convenience, MiniGUI also provides NTBM_ENABLEITEM
message to enable or disable an item with the specified identifier, as shown in the following:
SendMessage (ntb1, NTBM_ENABLEITEM, 100, FALSE);
The above code disables (grays) the item with identifier of 100 in ntb1 toolbar control.
NTBM_SETBITMAP
Message
NTBM_SETBITMAP
MessageAn application can send NTBM_SETBITMAP
message to a toolbar control, in order to change the button bitmap on the toolbar. When sending the message, an application uses lParam
parameter to transfer a new NTBINFO
structure, in which the new toolbar button bitmap is defined, as shown in the following code:
NTBINFO ntbi;
...
SendMessage (ntb, NTBM_SETBITMAP, 0, (LPARAM)&ntbi);
Notification Codes of Toolbar
Toolbars will not generate a notification message until the user clicks a button. The notification code of the toolbar is the identifier of the button clicked by the user. When the user clicks the button with hotspot, the toolbar control will call directly the hotspot callback function corresponding to the button, and will not generate a notification message.
Sample Program
List 1 gives a sample program of toolbar control. This program creates a toolbar with three buttons. We can control the position of the circle in the window by clicking the left item and right item on the toolbar. The other item grayed initially is only for demonstration and has no function. The running effect of this program is shown in Figure 4. Please refer to newtoolbar.c
of the demo program package mg-samples
of this guide for the complete source code.
List 1 Sample program of toolbar control
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#define IDC_NTB_LEFT 100
#define IDC_NTB_RIGHT 110
#define IDC_NTB_UP 120
static int offset = 0;
static RECT rcCircle = {0, 40, 300, 300};
static void my_notif_proc (HWND hwnd, int id, int nc, DWORD add_data)
{
/* When the user clicked the left or right button, the circle in the window
* will move left or right correspondingly
*/
if (nc == IDC_NTB_LEFT) {
offset -= 10;
InvalidateRect (GetParent (hwnd), &rcCircle, TRUE);
}
else if (nc == IDC_NTB_RIGHT) {
offset += 10;
InvalidateRect (GetParent (hwnd), &rcCircle, TRUE);
}
}
static BITMAP ntb_bmp;
static void create_new_toolbar (HWND hWnd)
{
HWND ntb;
NTBINFO ntb_info;
NTBITEMINFO ntbii;
gal_pixel pixel;
ntb_info.nr_cells = 4;
ntb_info.w_cell = 0;
ntb_info.h_cell = 0;
ntb_info.nr_cols = 0;
ntb_info.image = &ntb_bmp;
/* Create the toolbar control */
ntb = CreateWindow (CTRL_NEWTOOLBAR,
"",
WS_CHILD | WS_VISIBLE,
100,
0, 0, 1024, 0,
hWnd,
(DWORD) &ntb_info);
/* Set notification callback */
SetNotificationCallback (ntb, my_notif_proc);
/* Set the background color of the toolbar control,
* and make it consistent with the background of the button bitmap
*/
pixel = GetPixelInBitmap (&ntb_bmp, 0, 0);
SetWindowBkColor (ntb, pixel);
InvalidateRect (ntb, NULL, TRUE);
/* Add two normal button items */
memset (&ntbii, 0, sizeof (ntbii));
ntbii.flags = NTBIF_PUSHBUTTON;
ntbii.id = IDC_NTB_LEFT;
ntbii.bmp_cell = 1;
SendMessage(ntb, TBM_ADDITEM, 0, (LPARAM)&ntbii);
ntbii.flags = NTBIF_PUSHBUTTON;
ntbii.id = IDC_NTB_RIGHT;
ntbii.bmp_cell = 2;
SendMessage (ntb, TBM_ADDITEM, 0, (LPARAM)&ntbii);
/* Add a separator */
ntbii.flags = NTBIF_SEPARATOR;
ntbii.id = 0;
ntbii.bmp_cell = 0;
ntbii.text = NULL;
SendMessage (ntb, TBM_ADDITEM, 0, (LPARAM)&ntbii);
/* Add an initially disabled button */
ntbii.flags = NTBIF_PUSHBUTTON | NTBIF_DISABLED;
ntbii.id = IDC_NTB_UP;
ntbii.bmp_cell = 0;
SendMessage (ntb, TBM_ADDITEM, 0, (LPARAM)&ntbii);
}
static int ToolBarWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case MSG_CREATE:
/* Load the bitmap object used by the toolbar */
if (LoadBitmap (HDC_SCREEN, &ntb_bmp, "new2.jpg"))
return -1;
create_new_toolbar (hWnd);
break;
case MSG_PAINT:
{
HDC hdc = BeginPaint (hWnd);
ClipRectIntersect (hdc, &rcCircle);
/* Draw a red circle */
SetBrushColor (hdc, PIXEL_red);
FillCircle (hdc, 140 + offset, 120, 50);
EndPaint (hWnd, hdc);
return 0;
}
case MSG_DESTROY:
UnloadBitmap (&ntb_bmp);
DestroyAllControls (hWnd);
return 0;
case MSG_CLOSE:
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/* Following codes to create the main window are omitted */

Figure 4 Use of toolbar control
<< Track Bar Control | Table of Contents | Property Sheet Control >>
Last updated