简单的使ucGUI的EDIT控件支持密码框显示
ucGUI版本3.94
EDIT控件不支持密码框显示,而MULTIEDIT控件是可以调用MULTIEDIT_SetPasswordMode过程设置MULTIEDIT_SF_PASSWORD标志来显示支持密码框显示。比较不明白为什么EDIT而不加进这个功能。
其实我们自己可以很方便的改进一下就支持了。如何修改了呢,上网看到很多朋友说了很多方法,但却说在录入时截获WM_KEY的方法,我觉得那样的搞得很难处理了,其实这个很容易,我们想一下,我们只要EDIT控件显示密码时显示为星号或其它的什么就可以了,所以我们只要在ucGUI库画EDIT控件的消息过程里把画的内容画成星号就OK,当然你也可以显示其它的字符.好了,我们就这样改一下,和MULTIEDIT一样,我们加一个EDIT_SetPasswordMode的方法,设置EDIT_Obj里的 Flags,我们新加一个宏EDIT_CF_PASSWORD用来标记是否是密码框.
1:加下面这个这宏到EDIT.h里
#define EDIT_CF_PASSWORD 1 << 1
2:同时加入这个方法的声明
void EDIT_SetPasswordMode(EDIT_Handle hEdit,int off);
3:在 EDIT.c 里的实现
void EDIT_SetPasswordMode(EDIT_Handle hEdit,int off){
EDIT_Obj* pObj;
if(!WM_IsWindow(hEdit))
return;
WM_LOCK();
pObj = EDIT_H2P(hEdit);
if(pObj){
if(off == 1)
pObj->Flags |= EDIT_CF_PASSWORD;
else
pObj->Flags &= ~EDIT_CF_PASSWORD;
}
WM_UNLOCK();
}
3:修改EDIT.c 里的_Paint方法,红色字体是我新加入的,注意加入的位置,因为要计算字符的宽度问题
/*********************************************************************
*
* _Paint
*/
static void _Paint(EDIT_Obj* pObj, EDIT_Handle hObj) {
GUI_RECT rFillRect, rInside, r, rText, rInvert;
const char GUI_UNI_PTR * pText = NULL;
int IsEnabled, CursorWidth;
IsEnabled = WM__IsEnabled(hObj);
/* Set colors and font */
LCD_SetBkColor(pObj->Props.aBkColor[IsEnabled]);
LCD_SetColor(pObj->Props.aTextColor[0]);
GUI_SetFont(pObj->Props.pFont);
/* Calculate size */
WM__GetClientRectWin(&pObj->Widget.Win, &r);
WIDGET__GetInsideRect(&pObj->Widget, &rFillRect);
if (pObj->hpText) {
pText = (const char*) GUI_ALLOC_h2p(pObj->hpText);
}
int ik = GUI__GetNumChars(pText);
const char *temp = (const char*) malloc(ik + 1);
memset(temp,0,ik+1);
if(pObj->Flags & EDIT_CF_PASSWORD)
{
memset(temp,'*',ik);
pText = temp;
}
rInside = rFillRect;
rInside.x0 += pObj->Props.Border + EDIT_XOFF;
rInside.x1 -= pObj->Props.Border + EDIT_XOFF;
GUI__CalcTextRect(pText, &rInside, &rText, pObj->Props.Align);
/* Calculate position and size of cursor */
if (pObj->Widget.State & WIDGET_STATE_FOCUS) {
const char GUI_UNI_PTR * p = pText;
CursorWidth = ((pObj->XSizeCursor > 0) ? (pObj->XSizeCursor) : (1));
if (pText) {
U16 Char;
int i;
if ((pObj->EditMode != GUI_EDIT_MODE_INSERT) || (pObj->SelSize)) {
int NumChars, CursorOffset;
NumChars = GUI__GetNumChars(pText);
if (pObj->CursorPos < NumChars) {
if (pObj->SelSize) {
CursorWidth = 0;
for (i = pObj->CursorPos; i < (int)(pObj->CursorPos + pObj->SelSize); i++) {
CursorOffset = GUI_UC__NumChars2NumBytes(pText, i);
Char = GUI_UC_GetCharCode (pText + CursorOffset);
CursorWidth += GUI_GetCharDistX (Char);
}
if (!CursorWidth) {
CursorWidth = 1;
}
} else {
CursorOffset = GUI_UC__NumChars2NumBytes(pText, pObj->CursorPos);
Char = GUI_UC_GetCharCode(pText + CursorOffset);
CursorWidth = GUI_GetCharDistX(Char);
}
}
}
rInvert = rText;
for (i = 0; i != pObj->CursorPos; i++) {
Char = GUI_UC__GetCharCodeInc(&p);
rInvert.x0 += GUI_GetCharDistX(Char);
}
}
}
/* WM loop */
WM_ITERATE_START(NULL) {
/* Set clipping rectangle */
WM_SetUserClipRect(&rFillRect);
/* Display text */
WIDGET__FillStringInRect(pText, &rFillRect, &rInside, &rText);
/* Display cursor if needed */
if (pObj->Widget.State & WIDGET_STATE_FOCUS) {
GUI_InvertRect(rInvert.x0, rInvert.y0, rInvert.x0 + CursorWidth - 1, rInvert.y1);
}
WM_SetUserClipRect(NULL);
/* Draw the 3D effect (if configured) */
WIDGET__EFFECT_DrawDown(&pObj->Widget);
} WM_ITERATE_END();
free(temp);
}
哈哈!真的很简单明了吧!