|
A dialog box (or dialog) is normally a window that appears
in order to request input from the user. It may contain multiple widgets,
requesting information from the user through various selections, or it
may take the form of a message box which simply provides information (such
as a note or warning to the user) and an "OK" button.
Dialog basics
Input focus
The window manager remembers the window or window object
that was last selected by the user with the touch-screen, mouse, keyboard,
or other means. This window receives keyboard input messages and is said
to have the input focus.
The primary reason for keeping track of input focus is to determine where
to send keyboard commands. The window which has input focus will receive
events generated by the keyboard.
Blocking vs. non-blocking dialogs
Dialog windows can be blocking or non-blocking. A blocking
dialog blocks the thread of execution. It has input focus by default and
must be closed by the user before the thread can continue. A non-blocking
dialog, on the other hand, does not block the calling thread -- it allows
the task to continue while it is displayed.
Please note that in some other environments, blocking and non-blocking
dialogs may be referred to as modal and modeless, respectively.
Dialog procedure
A dialog box is a window, and it receives messages just
like all other windows in the system do. Most messages are handled by
the window callback routine of the dialog box automatically; the others
are passed to the callback routine specified upon creation of the dialog
box, which is known as the dialog procedure.
Dialog messages
There are two types of additional messages which are
sent to the dialog procedure: WM_INIT_DIALOG
and WM_NOTIFY_PARENT. The
WM_INIT_DIALOG message is sent to the dialog procedure immediately
before a dialog box is displayed. Dialog procedures typically use this
message to initialize widgets and carry out any other initialization tasks
that affect the appearance of the dialog box. The WM_NOTIFY_PARENT
message is sent to the dialog box by its child windows in order to notify
the parent of any events in order to ensure synchronization. The events
sent by a child depend on its type and are documented separately for every
type of widget.
Creating a dialog
Two basic things are required to create a dialog box:
a resource table that defines the widgets to be included, and a dialog
procedure which defines the initial values for the widgets as well as
their behavior. Once both items exist, you need only a single function
call (GUI_CreateDialogBox()
or GUI_ExecDialogBox())
to actually create the dialog.
Resource table
Dialog boxes may be created in a blocking manner (using
GUI_ExecDialogBox()) or as non-blocking (using GUI_CreateDialogBox()).
A resource table must first be defined which specifies all widgets to
be included in the dialog. The example shown below creates a resource
table. This particular sample was created manually, although it could
also be done by a GUI-builder:
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "Dialog", 0, 10, 10, 180, 230, FRAMEWIN_CF_MOVEABLE, 0 },
{ BUTTON_CreateIndirect, "OK", GUI_ID_OK, 100, 5, 60, 20 },
{ BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 100, 30, 60, 20 },
{ TEXT_CreateIndirect, "LText", 0, 10, 55, 48, 15, TEXT_CF_LEFT },
{ TEXT_CreateIndirect, "RText", 0, 10, 80, 48, 15, TEXT_CF_RIGHT },
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT0, 60, 55, 100, 15, 0, 50 },
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT1, 60, 80, 100, 15, 0, 50 },
{ TEXT_CreateIndirect, "Hex", 0, 10, 100, 48, 15, TEXT_CF_RIGHT },
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT2, 60, 100, 100, 15, 0, 6 },
{ TEXT_CreateIndirect, "Bin", 0, 10, 120, 48, 15, TEXT_CF_RIGHT },
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT3, 60, 120, 100, 15 },
{ LISTBOX_CreateIndirect, NULL, GUI_ID_LISTBOX0,10, 10, 48, 40 },
{ CHECKBOX_CreateIndirect, NULL, GUI_ID_CHECK0, 10, 140, 0, 0 },
{ CHECKBOX_CreateIndirect, NULL, GUI_ID_CHECK1, 30, 140, 0, 0 },
{ SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER0, 60, 140, 100, 20 },
{ SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER1, 10, 170, 150, 30 }
};
|
Any widget to be included in a dialog box must be created
indirectly with the WID-GET_CreateIndirect
function. "Window Objects (Widgets)".
Dialog procedure
The sample above has been created using the blank dialog
procedure shown below. This is the basic template which should be used
as a starting point when creating any dialog procedure:
/*********************************************************************
*
* Dialog procedure
*/
static void _cbCallback(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
default:
WM_DefaultProc(pMsg);
}
}
|
For this sample, the dialog box is displayed with the
following line of code:
GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0); |
The resulting dialog box looks as follows, or similar
(the actual appearance will depend on your configuration and default settings):

After creation of the dialog box, all widgets included
in the resource table will be visible, although as can be seen in the
previous screen shot, they will appear "empty". This is because the dialog
procedure does not yet contain code that initializes the individual elements.
The initial values of the widgets, the actions caused by them, and the
interactions between them need to be defined in the dialog procedure.
Initializing the dialog
The typical next step is to initialize the widgets with
their respective initial values. This is normally done in the dialog procedure
as a reaction to the WM_INIT_DIALOG message. The program excerpt below
illustrates things:
/*********************************************************************
*
* Dialog procedure
*/
static void _cbCallback(WM_MESSAGE * pMsg) {
int NCode, Id;
WM_HWIN hEdit0, hEdit1, hEdit2, hEdit3, hListBox;
WM_HWIN hWin = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
/* Get window handles for all widgets */
hEdit0 = WM_GetDialogItem(hWin, GUI_ID_EDIT0);
hEdit1 = WM_GetDialogItem(hWin, GUI_ID_EDIT1);
hEdit2 = WM_GetDialogItem(hWin, GUI_ID_EDIT2);
hEdit3 = WM_GetDialogItem(hWin, GUI_ID_EDIT3);
hListBox = WM_GetDialogItem(hWin, GUI_ID_LISTBOX0);
/* Initialize all widgets */
EDIT_SetText(hEdit0, "EDIT widget 0");
EDIT_SetText(hEdit1, "EDIT widget 1");
EDIT_SetTextAlign(hEdit1, GUI_TA_LEFT);
EDIT_SetHexMode(hEdit2, 0x1234, 0, 0xffff);
EDIT_SetBinMode(hEdit3, 0x1234, 0, 0xffff);
LISTBOX_SetText(hListBox, _apListBox);
WM_DisableWindow (WM_GetDialogItem(hWin, GUI_ID_CHECK1));
CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK0));
CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK1));
SLIDER_SetWidth( WM_GetDialogItem(hWin, GUI_ID_SLIDER0), 5);
SLIDER_SetValue( WM_GetDialogItem(hWin, GUI_ID_SLIDER1), 50);
break;
default:
WM_DefaultProc(pMsg);
)
}
|
The initialized dialog box now appears as follows, with
all widgets containing their initial values:
Defining dialog behavior
Once the dialog has been initialized, all that remains is to add code to
the dialog procedure which will define the behavior of the widgets, making
them fully operable. Continuing with the same example, the final dialog
procedure is shown below:
/*********************************************************************
*
* Dialog procedure
*/
static void _cbCallback(WM_MESSAGE * pMsg) {
int NCode, Id;
WM_HWIN hEdit0, hEdit1, hEdit2, hEdit3, hListBox;
WM_HWIN hWin = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
/* Get window handles for all widgets */
hEdit0 = WM_GetDialogItem(hWin, GUI_ID_EDIT0);
hEdit1 = WM_GetDialogItem(hWin, GUI_ID_EDIT1);
hEdit2 = WM_GetDialogItem(hWin, GUI_ID_EDIT2);
hEdit3 = WM_GetDialogItem(hWin, GUI_ID_EDIT3);
hListBox = WM_GetDialogItem(hWin, GUI_ID_LISTBOX0);
/* Initialize all widgets */
EDIT_SetText(hEdit0, "EDIT widget 0");
EDIT_SetText(hEdit1, "EDIT widget 1");
EDIT_SetTextAlign(hEdit1, GUI_TA_LEFT);
EDIT_SetHexMode(hEdit2, 0x1234, 0, 0xffff);
EDIT_SetBinMode(hEdit3, 0x1234, 0, 0xffff);
LISTBOX_SetText(hListBox, _apListBox);
WM_DisableWindow (WM_GetDialogItem(hWin, GUI_ID_CHECK1));
CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK0));
CHECKBOX_Check( WM_GetDialogItem(hWin, GUI_ID_CHECK1));
SLIDER_SetWidth( WM_GetDialogItem(hWin, GUI_ID_SLIDER0), 5);
SLIDER_SetValue( WM_GetDialogItem(hWin, GUI_ID_SLIDER1), 50);
break;
case WM_KEY:
switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) {
case GUI_ID_ESCAPE:
GUI_EndDialog(hWin, 1);
break;
case GUI_ID_ENTER:
GUI_EndDialog(hWin, 0);
break;
}
break;
case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc); /* Id of widget */
NCode = pMsg->Data.v; /* Notification code */
switch (NCode) {
case WM_NOTIFICATION_RELEASED: /* React only if released */
if (Id == GUI_ID_OK) { /* OK Button */
GUI_EndDialog(hWin, 0);
}
if (Id == GUI_ID_CANCEL) { /* Cancel Button */
GUI_EndDialog(hWin, 1);
}
break;
case WM_NOTIFICATION_SEL_CHANGED: /* Selection changed */
FRAMEWIN_SetText(hWin, "Dialog - sel changed");
break;
default:
FRAMEWIN_SetText(hWin, "Dialog - notification received");
}
break;
default:
WM_DefaultProc(pMsg);
}
}
|
API reference: dialogs
The table below lists the available dialog-related routines
in alphabetical order within their respective categories. Detailed descriptions
of the routines can be found in the sections that follow:
| GUI_CreateDialogBox |
GCreate a non-blocking dialog. |
| GUI_ExecCreatedDialog | Executes an already created dialog. |
| GUI_ExecDialogBox |
Create and execute a dialog. |
| GUI_EndDialog |
End a dialog box. |
| GUI_MessageBox |
Creates and executes a message box. |
| MESSAGEBOX_Create | Creates a message box. |

Copyright SEGGER Microcontroller GmbH & Co.KG.
All rights reserved.
For more information, please visit our web site
www.segger.com or contact us at info@segger.com
Last update:
December 7, 2007
|