| |
|
|
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 |
GUI_CreateDialogBox Create a non-blocking dialog. |
| GUI_ExecDialogBox |
GUI_ExecDialogBox Create a blocking dialog. |
| GUI_EndDialog |
End a dialog box. |
| GUI_MessageBox |
Create a message box. |
Return to main emWin page...
You can download an evaluation
version of emWin from our Literature/Download section....



|
|
 |
Segger News |
 |
 |
NEWS: Tools |
 |
 |
30-day free
evaluation |
 |
 |
Literature Centre |
 |
|
|