UCGUI中edit
(第一次写文章,勿喷!)最近项目需要弄个LCD屏(单色屏)的界面,试了试自己写个简单的控制界面,太麻烦,于是就考虑移植个开源的GUI。平台用的是NIOS的ucos,很容易就想到了UCGUI,一家的吗,用着应该顺手。百度了一堆移植的资料,很顺利移植成功(如何移植的我就不详细说了)。既然移植成功了就开始界面设计(设计是在pc上完成的,也就是那个simulation)。先试了试各个控件,窗口,对话框的使用方法。当用到EDIT的时候不知道如何编辑浮点数,百度了半天也没有结果!于是就有了下文。
1,edit的基本使用(这里借用一下UCGUI的demo程序)
/*********************************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH *
* Solutions for real time microcontroller applications *
* *
* emWin GSC sample code *
* *
**********************************************************************
----------------------------------------------------------------------
File : WIDGET_Edit.c
Purpose : Example demonstrating the use of a EDIT widget
----------------------------------------------------------------------
*/
#include "GUI.h"
#include "EDIT.h"
/*******************************************************************
*
* static code
*
********************************************************************
*/
/*******************************************************************
*
* _DemoEdit
*
Edit a string until ESC or ENTER is pressed
*/
static void _DemoEdit(void) {
EDIT_Handle hEdit;
char aBuffer[28];
int Key;
GUI_SetBkColor(GUI_BLACK);
GUI_Clear();
GUI_SetColor(GUI_WHITE);
GUI_SetFont(&GUI_Font24_ASCII);
GUI_DispStringHCenterAt("WIDGET_Edit - Sample", 160, 5);
GUI_SetFont(&GUI_Font8x16);
GUI_DispStringHCenterAt("Use keyboard to modify string...", 160, 90);
/* Create edit widget */
hEdit = EDIT_Create( 50, 110, 220, 25, ' ', sizeof(aBuffer), 0 );
/* Modify edit widget */
EDIT_SetText(hEdit, "Press <ENTER> when done...");
EDIT_SetFont(hEdit, &GUI_Font8x16);
EDIT_SetTextColor(hEdit, 0, GUI_RED);
/* Set keyboard focus to edit widget */
WM_SetFocus(hEdit);
/* Handle keyboard until ESC or ENTER is pressed */
do {
WM_Exec();
Key = GUI_GetKey();
} while ((Key != GUI_KEY_ENTER) && (Key != GUI_KEY_ESCAPE));
/* Fetch result from edit widget */
if (Key == GUI_KEY_ENTER) {
EDIT_GetText(hEdit, aBuffer, sizeof(aBuffer));
}
/* Delete the edit widget */
EDIT_Delete(hEdit);
GUI_ClearRect(0, 50, 319, 239);
/* Display the changed string */
if (Key == GUI_KEY_ENTER) {
GUI_Delay(250);
GUI_DispStringHCenterAt("The string you have modified is:", 160, 90);
GUI_DispStringHCenterAt(aBuffer, 160, 110);
GUI_Delay(3000);
GUI_ClearRect(0, 50, 319, 239);
}
GUI_Delay(500);
}
/*******************************************************************
*
* MainTask
*
* Demonstrates the use of a EDIT widget
*
********************************************************************
*/
void MainTask(void) {
GUI_Init();
while (1) {
_DemoEdit();
}
}
具体函数的的使用我就不详细说了,下面来重点
2,edit如何获取输入的值
在edit.h中定义了如下函数:
/* Get/Set user input */
float EDIT_GetFloatValue(EDIT_Handle hObj);
void EDIT_GetText (EDIT_Handle hObj, char* sDest, int MaxLen);
I32 EDIT_GetValue (EDIT_Handle hObj);
void EDIT_SetFloatValue(EDIT_Handle hObj, float Value);
void EDIT_SetValue (EDIT_Handle hObj, I32 Value);
但是直接使用EDIT_GetFloatValue会发现和你想要的结果不一样。原来是忘了设置edit的模式了!如何设置?
(1)首先你要设置edit的MaxLen,也就是最大输入长度:EDIT_SetMaxLen
(2)设置为浮点模式:EDIT_SetFloatMode
具体例子如下:(这是用uCGUIBuilder创建的一个对话框程序,注释写的很清楚,一看你就会明白怎么使用)
/*
******************************************************************
** uCGUIBuilder **
** Version: 4.0.0.0 **
** 2012 / 04 **
** CpoyRight to: wyl **
** Email:ucguibuilder@163.com **
** This text was Created by uCGUIBuilder **
******************************************************************/
#include <stddef.h>
#include "GUI.h"
#include "DIALOG.h"
#include "WM.h"
#include "BUTTON.h"
#include "CHECKBOX.h"
#include "DROPDOWN.h"
#include "EDIT.h"
#include "FRAMEWIN.h"
#include "LISTBOX.h"
#include "MULTIEDIT.h"
#include "RADIO.h"
#include "SLIDER.h"
#include "TEXT.h"
#include "PROGBAR.h"
#include "SCROLLBAR.h"
#include "LISTVIEW.h"
#include "PassWordWindow.h"
//EventsFunctionList
//EndofEventsFunctionList
/*********************************************************************
*
* static data
*
**********************************************************************
*/
/*********************************************************************
*
* Dialog resource
*
* This table conatins the info required to create the dialog.
* It has been created by ucGUIbuilder.
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "Caption", 0, 0, 0, 320,240,FRAMEWIN_CF_MOVEABLE,0},
{ TEXT_CreateIndirect, "TEXT0", GUI_ID_TEXT0, 126,40, 73, 23, 0,0},
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT0, 52, 63, 60, 22, 0,0},
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT1, 52, 93, 60, 22, 0,6},
<span style="white-space:pre"> </span>//这个6就是那个MaxLen
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT2, 52, 123, 60, 22, 0,6},
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT3, 52,153, 60, 22, 0,6},
{ EDIT_CreateIndirect, NULL, GUI_ID_EDIT4, 52, 183,60, 22, 0,7},
};
/*****************************************************************
** FunctionName:void PaintDialog(WM_MESSAGE * pMsg)
** Function: to initialize the Dialog items
**
** call this function in _cbCallback --> WM_PAINT
*****************************************************************/
void PaintDialog(WM_MESSAGE * pMsg)
{
WM_HWIN hWin = pMsg->hWin;
}
/*****************************************************************
** FunctionName:void InitDialog(WM_MESSAGE * pMsg)
** Function: to initialize the Dialog items
**
** call this function in _cbCallback --> WM_INIT_DIALOG
*****************************************************************/
void InitDialog(WM_MESSAGE * pMsg)
{
WM_HWIN hWin = pMsg->hWin;
EDIT_Handle edit0=(EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT0);
<span style="white-space:pre"> </span>//通过hWin获取某个空间的句柄
EDIT_Handle edit1=(EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT1);
EDIT_Handle edit2=(EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT2);
EDIT_Handle edit3=(EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT3);
EDIT_Handle edit4=(EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT4);
//
//FRAMEWIN
//
FRAMEWIN_SetTitleVis(hWin,0);
EDIT_SetMaxLen(edit0,6);//设置MaxLen
EDIT_SetFloatMode(edit0, 3.1425,0,1000,4,0);
<span style="white-space:pre"> </span>//设置为float模式,4是小数点后面位数,最后一位默认是0
EDIT_SetFloatMode(edit1, 13.142,1,1000,3,0);
<span style="white-space:pre"> </span>//设置为float模式,4是小数点后面位数,最后一位默认是0,初始化的时候MaxLen已经设置过了这里不需要设置
EDIT_SetFloatMode(edit2, 113.14,2,1000,2,0);
EDIT_SetFloatMode(edit3, 1113.5,3,1000,2,0);
EDIT_SetFloatMode(edit4, 11113,4,90000,1,0);
EDIT_SetInsertMode(edit0,GUI_EDIT_MODE_OVERWRITE);
//EDIT_SetDecMode(edit0, 25,0,999,0,0);
//EDIT_SetValue();
//EDIT_SetInsertMode()
}
/*********************************************************************
*
* Dialog callback routine
*/
static void _cbCallback(WM_MESSAGE * pMsg)
{
int NCode, Id;
WM_HWIN hWin = pMsg->hWin;
WM_HWIN passwordHWin=0;
char data[20]={0};
float a=0;
switch (pMsg->MsgId)
{
case WM_PAINT:
PaintDialog(pMsg);
break;
case WM_INIT_DIALOG:
InitDialog(pMsg);
break;
case WM_KEY:
switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
{
case GUI_KEY_ESCAPE:
//GUI_EndDialog(hWin, 1);
//验证密码正确与否
passwordHWin = createPassWordWindow(hWin);
break;
case GUI_KEY_ENTER:
Id = WM_GetId(pMsg->hWinSrc);//这里edit的消息为什么会发给对话框?如何做的,看第三段 3(大同小异)
switch (Id)
{
case GUI_ID_EDIT0:
//EDIT_GetText((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT0),data,10);
a=EDIT_GetFloatValue((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT0));
<span style="white-space:pre"> </span>//获取输入的浮点数的值
break;
case GUI_ID_EDIT1:
//EDIT_GetText((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT1),data,10);
a=EDIT_GetFloatValue((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT0));
break;
case GUI_ID_EDIT2:
//EDIT_GetText((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT2),data,10);
a=EDIT_GetFloatValue((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT0));
break;
}
// WM_SetFocus(passwordHWin);
break;
case GUI_KEY_UP:
Id=0;
break;
}
break;
case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode = pMsg->Data.v;
switch (Id)
{
case GUI_ID_EDIT1:
if(NCode==WM_NOTIFICATION_VALUE_CHANGED)
param=EDIT_GetFloatValue((EDIT_Handle)WM_GetDialogItem(hWin, GUI_ID_EDIT0));
<span style="white-space:pre"> </span>//在这里也能获取
break;
case GUI_ID_OK:
if(NCode==WM_NOTIFICATION_RELEASED)
GUI_EndDialog(hWin, 0);
break;
case GUI_ID_CANCEL:
if(NCode==WM_NOTIFICATION_RELEASED)
GUI_EndDialog(hWin, 0);
break;
}
break;
default:
WM_DefaultProc(pMsg);
}
}
void createMainWindow(WM_HWIN *hWIN)
{
GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
}
显示结果
3,edit如何重新定义GUI_KEY_UP等操作
edit默认的接收的GUI_KEY_UP消息的操作好像是修改edit内容的值,不过我想要的。我想要的是通过上下键来选择不同的edit。
修改edit.c中的static void EDIT__Callback (WM_MESSAGE * pMsg) 函数
static void EDIT__Callback (WM_MESSAGE * pMsg) {
int IsEnabled;
EDIT_Handle hObj = (EDIT_Handle) pMsg->hWin;
EDIT_Obj* pObj = (EDIT_Obj*) GUI_ALLOC_h2p(hObj);
IsEnabled = WM__IsEnabled(hObj);
/* Let widget handle the standard messages */
if (WIDGET_HandleActive(hObj, pMsg) == 0) {
return;
}
switch (pMsg->MsgId) {
case WM_TOUCH:
_OnTouch(hObj, pObj, pMsg);
break;
case WM_PAINT:
GUI_DEBUG_LOG("EDIT: _Callback(WM_PAINT)\n");
_Paint(pObj, hObj);
return;
case WM_DELETE:
GUI_DEBUG_LOG("EDIT: _Callback(WM_DELETE)\n");
_Delete(pObj);
break; /* No return here ... WM_DefaultProc needs to be called */
case WM_KEY:
if (IsEnabled) {
if ( ((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt >0) {
int Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key;
switch (Key) {
case GUI_KEY_ENTER:
case GUI_KEY_ESCAPE:
case GUI_KEY_TAB:
case GUI_KEY_UP://修改这里。
case GUI_KEY_DOWN://修改这里。
//case GUI_KEY_BACKTAB:
break; /* Send to parent by not doing anything */
default:
EDIT_AddKey(hObj, Key);
return;
}
}
}
break;
}
WM_DefaultProc(pMsg);
}
这样消息就会直接往上发,发给谁呢?就上个例子而言,是发给我FRAMEWIN,然后再去修改FRAMEWIN.c中的
static void FRAMEWIN__cbClient(WM_MESSAGE* pMsg) {
WM_HWIN hWin = pMsg->hWin;
WM_HWIN hParent = WM_GetParent(pMsg->hWin);
FRAMEWIN_Obj* pObj = FRAMEWIN_H2P(hParent);
WM_CALLBACK* cb = pObj->cb;
switch (pMsg->MsgId) {
case WM_PAINT:
if (pObj->Props.ClientColor != GUI_INVALID_COLOR) {
LCD_SetBkColor(pObj->Props.ClientColor);
GUI_Clear();
}
/* Give the user callback a chance to draw.
* Note that we can not run into the bottom part, as this passes the parents handle
*/
if (cb) {
WM_MESSAGE Msg;
Msg = *pMsg;
Msg.hWin = hWin;
(*cb)(&Msg);
}
return;
case WM_SET_FOCUS:
if (pMsg->Data.v) { /* Focus received */
if (pObj->hFocussedChild && (pObj->hFocussedChild != hWin)) {
WM_SetFocus(pObj->hFocussedChild);
} else {
pObj->hFocussedChild = WM_SetFocusOnNextChild(hWin);
}
pMsg->Data.v = 0; /* Focus change accepted */
}
return;
case WM_GET_ACCEPT_FOCUS:
WIDGET_HandleActive(hParent, pMsg);
return;
case WM_KEY:
if (((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt > 0) {
int Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key;
switch (Key) {
case GUI_KEY_TAB:
pObj->hFocussedChild = WM_SetFocusOnNextChild(hWin);
return;
/*修改下面,根据GUI_KEY_TAB很容易想到改这里*/
case GUI_KEY_UP:
pObj->hFocussedChild=WM_SetFocusOnPrevChild(hWin);
return;
case GUI_KEY_DOWN:
pObj->hFocussedChild = WM_SetFocusOnNextChild(hWin);
return;
/*修改以上*/
}
}
break; /* Send to parent by not doing anything */
case WM_GET_BKCOLOR:
pMsg->Data.Color = pObj->Props.ClientColor;
return; /* Message handled */
case WM_GET_INSIDE_RECT: /* This should not be passed to parent ... (We do not want parents coordinates)*/
case WM_GET_ID: /* This should not be passed to parent ... (Possible recursion problem)*/
case WM_GET_CLIENT_WINDOW: /* return handle to client window. For most windows, there is no seperate client window, so it is the same handle */
WM_DefaultProc(pMsg);
return; /* We are done ! */
}
/* Call user callback. Note that the user callback gets the handle of the Framewindow itself, NOT the Client. */
if (cb) {
pMsg->hWin = hParent;
(*cb)(pMsg);
} else {
WM_DefaultProc(pMsg);
}
}
哈哈,就是跟GUI_KEY_TAB改成一样的就ok了。
最后至于你要想改成其他的效果,你就自己想想吧,这里我就抛个砖!
转载请注明出处,谢谢!如有疑问请联系583999964@qq.com