第50章
MULTIEDIT-多行文本控件
本期教程讲解STemWin支持的多行文本控件。
50. 1 多行文本控件介绍
50. 2 官方WIDGET_Multiedit实例
50. 3 使用uCGUIBulder建立多行文本控件
50. 4 总结
50.1
多行文本控件介绍
通过MULTIEDIT小工具可编辑多行文本。它既可以被用作简单的文本编辑器,也可以用来显示静态文本。该小工具支持带滚动条和不带滚动条的滚动。下表显示MULTIEDIT小工具的外观:

50.1.1 多行文本支持的通知代码
以下事件是多行文本控件作为WM_NOTIFY_PARENT消息的一部分发送给其父窗口的:
消息
|
描述
|
WM_NOTIFICATION_CLICKED
|
已单击小工具。
|
WM_NOTIFICATION_RELEASED
|
已释放小工具。
|
WM_NOTIFICATION_MOVED_OUT
|
已单击小工具,并且指针已移出小工具,但没有释放。
|
WM_NOTIFICATION_SCROLL_CHANGED
|
可选滚动条的滚动位置已更改。
|
WM_NOTIFICATION_VALUE_CHANGED
|
小工具的文本已更改。
|
50.1.2 多行文本支持的键盘反应
如果控件具有输入焦点,则它将对下列各键做出反应:
按键
|
反应
|
GUI_KEY_UP
|
将光标向上移动一行。
|
GUI_KEY_DOWN
|
将光标向下移动一行。
|
GUI_KEY_RIGHT
|
将光标向右移动一个字符。
|
GUI_KEY_LEFT
|
将光标向左移动一个字符。
|
GUI_KEY_END
|
将光标移到当前行的末尾。
|
GUI_KEY_HOME
|
将光标移到当前行的开头。
|
GUI_KEY_BACKSPAC
|
如果小工具在读/写模式下工作,此按键将删除光标之前的字符。
|
GUI_KEY_DELETE
|
如果小工具在读/写模式下工作,此按键将删除光标之下的字符。
|
GUI_KEY_INSERT
|
在插入模式和覆盖模式之间切换。
|
GUI_KEY_ENTER
|
如果小工具在读/写模式下工作,此按键将在当前位置插入一个新行(’\n’)。如果小工具在只读模式下工作,光标将移到下一行的开头。
|
50.2 官方WIDGET_Multiedit实例
官方的这个实例很好的演示了Multiedit的使用,这个例子在模拟器中的位置:

源码如下(程序中进行了详细的注释,代码有点长,这里只贴出了主代码):
static void _DemoMultiedit(void) {
GUI_RECT Rect;
int WinFlags;
_hFrame = 1;
_Overwrite = 0;
_ReadOnly = 0;
_Password = 0;
_ChangeInfoText("Create framewin", SPEED);
_hFrame = FRAMEWIN_CreateEx(60, 80, 200, 120, WM_HBKWIN, WM_CF_SHOW, 0, 0, "Notepad", 0);
_hClient = WM_GetClientWindow(_hFrame);
_pcbFrameWin = WM_SetCallback(_hFrame, _cbFrameWin);
_pcbFrameWinClient = WM_SetCallback(_hClient, _cbFrameWinClient);
FRAMEWIN_SetMoveable(_hFrame, 1);
FRAMEWIN_SetActive(_hFrame, 1);
FRAMEWIN_SetTextAlign(_hFrame, GUI_TA_HCENTER | GUI_TA_VCENTER);
FRAMEWIN_SetFont(_hFrame, &GUI_Font8x12_ASCII);
FRAMEWIN_SetTitleHeight(_hFrame, 16);
if (_ChangeInfoText("Add framewin buttons", SPEED)) return;
FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_LEFT, 0);
FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 1);
WM_InvalidateWindow(_hFrame);
if (_ChangeInfoText("Add option buttons", SPEED)) return;
_hWrapButton = _CreateLButton("None", 0, 36, 16, _hClient, ID_NONEWRAP);
_CreateLButton("Word", 37, 36, 16, _hClient, ID_WORDWRAP);
_CreateLButton("Char", 74, 36, 16, _hClient, ID_CHARWRAP);
_CreateRButton("PSW", 52, 25, 16, _hClient, ID_PASSWORD);
_CreateRButton("OVR", 26, 25, 16, _hClient, ID_OVERWRITE);
_CreateRButton("R/O", 0, 25, 16, _hClient, ID_READONLY);
_SetButtonState(_hWrapButton, 1);
if (_ChangeInfoText("using\nMULTIEDIT_CreateEx", SPEED)) return;
WinFlags = WM_CF_SHOW | WM_CF_ANCHOR_RIGHT | WM_CF_ANCHOR_LEFT | WM_CF_ANCHOR_TOP | WM_CF_ANCHOR_BOTTOM;
WM_GetClientRectEx(_hClient, &Rect);
_hMEdit = MULTIEDIT_CreateEx(0, 0, 0, Rect.y1 - 16 + 1, _hClient, WinFlags, MULTIEDIT_CF_INSERT, 0, 0, "");
_pcbMultiEdit = WM_SetCallback(_hMEdit, _cbMultiEdit);
MULTIEDIT_SetAutoScrollH(_hMEdit, 1);
MULTIEDIT_SetAutoScrollV(_hMEdit, 1);
WM_SetFocus(_hMEdit);
if (_ChangeInfoText("using\nMULTIEDIT_SetText", SPEED)) return;
MULTIEDIT_SetText(_hMEdit, "This sample demonstrates the use of a multiedit widget!");
if (_ChangeInfoText("using\nMULTIEDIT_SetFont", SPEED)) return;
MULTIEDIT_SetFont(_hMEdit, &GUI_Font16_1);
if (_ChangeInfoText("using\nMULTIEDIT_SetTextColor", SPEED)) return;
MULTIEDIT_SetTextColor(_hMEdit, 0, 0xE00000);
if (_ChangeInfoText("using\nMULTIEDIT_SetBkColor", SPEED)) return;
MULTIEDIT_SetBkColor(_hMEdit, 0, 0xD0FFFF);
if (_ChangeInfoText("using\nMULTIEDIT_SetWrapWord", SPEED)) return;
MULTIEDIT_SetWrapWord(_hMEdit);
_SetButtonState(_hWrapButton, 0);
_hWrapButton = WM_GetDialogItem(_hClient, ID_WORDWRAP);
_SetButtonState(_hWrapButton, 1);
if (_ChangeInfoText("using\nMULTIEDIT_SetHBorder", SPEED)) return;
MULTIEDIT_SetHBorder(_hMEdit, 3);
if (_ChangeInfoText("using\nMULTIEDIT_SetPrompt", SPEED)) return;
MULTIEDIT_SetPrompt(_hMEdit, "Type: ");
if (_ChangeInfoText("Play with multiedit...", SPEED)) return;
while (_hFrame)
{
GUI_Delay(100);
}
}
void MainTask(void) {
GUI_Init();
#if GUI_SUPPORT_MEMDEV
WM_SetCreateFlags(WM_CF_MEMDEV);
#endif
GUI_CURSOR_Show();
WM_SetCallback(WM_HBKWIN, _cbBkWin);
while(1) {
_DemoMultiedit();
*_acInfoText = 0;
WM_InvalidateWindow(WM_HBKWIN);
GUI_Delay(SPEED);
}
}
实际显示效果如下:

50.3
使用uCGUIBulder建立多行文本控件
用uCGUIBulder4.0建立如下界面:

为列表框添加成员的方法如下:

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

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