第53章
RADIO-单选按钮控件
本期教程讲解STemWin支持的单选按钮控件。
53. 1 单选按钮控件介绍
53. 2 官方DIALOG_Radio实例
53. 3 使用官方GUIBulder建立单选按钮控件
53. 4 总结
53.1
进度条控件介绍
如同复选框一样,单选按钮也可用来选择选项。打开或选择单选按钮时,将出现圆点。与复选框的差别是,用户一次只能选择一个单选按钮。选择一个按钮时,控件中的其他按钮将关闭 (如右图所示)。一个单选按钮控件可能包含任意数量的按钮, 这些按钮始终处于垂直排列状态。下表显示的是RADIO按钮的默认外观:

设置皮肤后显示效果如下:

53.1.1 单选按钮支持的通知代码
以下事件是单选按钮控件作为WM_NOTIFY_PARENT消息的一部分发送给其父窗口的:
消息
|
描述
|
WM_NOTIFICATION_CLICKED
|
已被点击。
|
WM_NOTIFICATION_RELEASED
|
已被释放。
|
WM_NOTIFICATION_MOVED_OUT
|
已被点击,且指针已移出控件,但没有释放。
|
WM_NOTIFICATION_VALUE_CHANGED
|
单选按钮的值 (内容)已更改。
|
53.1.2 单选按钮支持的键盘反应
如果控件具有输入焦点,则它将对下列各键做出反应:
按键
|
反应
|
GUI_KEY_RIGHT
|
选定范围增加1。
|
GUI_KEY_DOWN
|
选定范围增加1。
|
GUI_KEY_LEFT
|
选定范围减小1。
|
GUI_KEY_UP
|
选定范围减小1。
|
53.2
官方DIALOG_Radio实例
官方的这个实例很好的演示了MULTIPAGE的使用,这个例子在模拟器中的位置:

源码如下(程序中进行了详细的注释):
#include
#include "GUI.h"
#include "DIALOG.h"
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "Radio button sample", 0, 30, 70, 260, 100, FRAMEWIN_CF_MOVEABLE },
{ RADIO_CreateIndirect, NULL, GUI_ID_RADIO0, 5, 10, 0, 0, 0, 3 },
{ TEXT_CreateIndirect, "Suspend", GUI_ID_TEXT0, 25, 10, 70, 20, TEXT_CF_LEFT },
{ TEXT_CreateIndirect, "Shut down", GUI_ID_TEXT1, 25, 30, 70, 20, TEXT_CF_LEFT },
{ TEXT_CreateIndirect, "Restart after", GUI_ID_TEXT2, 25, 50, 70, 20, TEXT_CF_LEFT },
{ TEXT_CreateIndirect, "seconds", GUI_ID_TEXT3, 130, 50, 70, 20, TEXT_CF_LEFT },
{ EDIT_CreateIndirect, "200", GUI_ID_EDIT0, 95, 47, 30, 19, 0, 3},
{ BUTTON_CreateIndirect, "OK", GUI_ID_OK, 180, 10, 60, 20 },
{ BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 180, 40, 60, 20 }
};
static void _cbBkWindow(WM_MESSAGE* pMsg) {
switch (pMsg->MsgId) {
case WM_PAINT:
GUI_SetBkColor(GUI_RED);
GUI_Clear();
GUI_SetColor(GUI_WHITE);
GUI_SetFont(&GUI_Font24_ASCII);
GUI_DispStringHCenterAt("DIALOG_Radio - Sample", 160, 5);
break;
default:
WM_DefaultProc(pMsg);
}
}
static void _cbCallback(WM_MESSAGE * pMsg) {
WM_HWIN hDlg;
WM_HWIN hItem;
int Sel;
int NCode;
int Id;
GUI_PID_STATE * pState;
hDlg = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0);
EDIT_SetDecMode(hItem, 30, 0, 999, 0, 0); // 选项编辑框的10进制模式
WM_DisableWindow(hItem);
break;
case WM_KEY:
switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) {
case GUI_KEY_ESCAPE:
GUI_EndDialog(hDlg, 1);
break;
case GUI_KEY_ENTER:
GUI_EndDialog(hDlg, 0);
break;
}
break;
case WM_TOUCH_CHILD:
Id = WM_GetId(pMsg->hWinSrc);
switch (Id) {
case GUI_ID_TEXT0:
case GUI_ID_TEXT1:
case GUI_ID_TEXT2:
pState = (GUI_PID_STATE *)((WM_MESSAGE *)pMsg->Data.p)->Data.p;
if (pState) {
if (pState->Pressed) {
WM_HWIN hRadio = WM_GetDialogItem(hDlg, GUI_ID_RADIO0);
RADIO_SetValue(hRadio, Id - GUI_ID_TEXT0);
}
}
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
switch (Id) {
case GUI_ID_OK:
GUI_EndDialog(hDlg, 0);
break;
case GUI_ID_CANCEL:
GUI_EndDialog(hDlg, 1);
break;
}
break;
case WM_NOTIFICATION_VALUE_CHANGED:
hItem = WM_GetDialogItem(hDlg, GUI_ID_RADIO0);
Sel = RADIO_GetValue(hItem);
hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0);
WM_SetEnableState(hItem, Sel == 2);
break;
}
break;
default:
WM_DefaultProc(pMsg);
}
}
void MainTask(void) {
GUI_Init();
WM_SetCallback(WM_HBKWIN, &_cbBkWindow);
WM_SetCreateFlags(WM_CF_MEMDEV); // Use memory devices on all windows to avoid flicker
while (1) {
GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
GUI_Delay(1000);
}
}
实际现象效果如下:

53.3
使用官方GUIBulder建立单选按钮控件
这里用GUIBulder5.22建立一个如下的界面(分辨率480*272):

鼠标放在单选按钮控件上面右击可以设置单选按钮:

具体每个选项的名字在右下角进行设置:

将生成的代码直接复制到模拟器或者开发板上面运行,实际显示效果如下(生成的代码在本期教程配套的例子中):

53.4
总结
本期教程主要是跟大家讲解了单选按钮控件的基础知识。希望大家可以把本期教程中讲的这两个例子跑跑,然后自己设计一个相关的例子进行试验学习。教程中只是使用了部分的单选按钮控件API,其它的API大家都可以试试。