搜索
bottom↓
回复: 33

关于目前网上流传ucgui3.9*中消息框无法正确显示汉字问题!

[复制链接]

出0入0汤圆

发表于 2010-11-7 21:51:37 | 显示全部楼层 |阅读模式
我使用网上下载的源码,使用时其他功能没问题,发现消息框,在使用时无法正常显示汉字。源码如下
void GUI_GetTextExtend(GUI_RECT* pRect, const char GUI_UNI_PTR * s, int MaxNumChars) {
  int xMax      = 0;
  int NumLines  = 0;
  int LineSizeX = 0;
  U16 Char;
  pRect->x0 = GUI_Context.DispPosX;
  pRect->y0 = GUI_Context.DispPosY;  

  while (MaxNumChars--) {
    Char =GUI_UC__GetCharCodeInc(&s);
     if ((Char == '\n')/*|| (Char == '\0')*/) {
     if (LineSizeX > xMax) {
        xMax = LineSizeX;
      }
      LineSizeX = 0;
      NumLines++;
          if (!Char) {
        break;
      }
    }
       
        else
        {
      LineSizeX += GUI_GetCharDistX(Char);

    }
  }
  if (LineSizeX > xMax) {
    xMax = LineSizeX;
  }
  if (!NumLines) {
    NumLines = 1;
  }
  pRect->x1 = pRect->x0 + xMax - 1;
  pRect->y1 = pRect->y0 + GUI__GetFontSizeY() * NumLines - 1;
}
此为消息框中text文本内容显示函数!显示汉字不能换行或显示一半汉字。'/0'为本人屏蔽。大家用的时间注意。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-11-7 21:53:10 | 显示全部楼层

(原文件名:消息框.jpg)

出0入0汤圆

 楼主| 发表于 2010-11-7 21:54:52 | 显示全部楼层
不能换行了,先不动源码了。不知那位那里有修改好的源码。关于消息框的。

出0入0汤圆

发表于 2010-11-7 21:55:20 | 显示全部楼层
............................................

出0入0汤圆

 楼主| 发表于 2010-11-7 22:10:29 | 显示全部楼层
上传无修改源码生成窗口
(原文件名:非正常.jpg)

出0入0汤圆

 楼主| 发表于 2010-11-7 22:12:00 | 显示全部楼层
在使用消息框时间,大家咋使用的,有没有对源码进行修改。我不敢确定是我设置问题,还是源码问题。请指教

出0入0汤圆

发表于 2010-11-8 17:23:33 | 显示全部楼层
这里是UCGUI的一个BUG吧,不知你的汉字显示是如何处理的!是利用日文支持的两个字节那个解码文件做的还是别的什么方法?
如果是日文支持做的,那有点得注意就是GUI_GetTextExtend这个函数调用时是没有GUI_LOCK的,即是在GUI_MessageBox里调用也是
这样,因此在多任务中多字节文字的显示可能会出现GUI_MessageBox不正确显示,你可以在GUI_GetTextExtend开始和结束调用
GUI_LOCK();和GUI_UNLOCK();试下,并且在你的任务中调用下这个又节的设置函数GUI_UC_SetEncodeXXX();XXX为你自己写的双字节
显示解码函数!

出0入0汤圆

 楼主| 发表于 2010-11-8 20:28:14 | 显示全部楼层
我直接从网上找个汉字字库,然后就可以直接用了,没动过源码!字库文件ourdev_596227Y1H5WN.rar(文件大小:877K) (原文件名:三个汉字C程序文件.rar)

出0入0汤圆

发表于 2010-11-8 20:50:08 | 显示全部楼层
目前发现3.9有好几处BUG,未正式使用到产品中,因为未分析完全部代码

出0入0汤圆

发表于 2010-11-8 21:25:33 | 显示全部楼层
回复【8楼】again
目前发现3.9有好几处bug,未正式使用到产品中,因为未分析完全部代码
-----------------------------------------------------------------------

分析完全部代码,工作量不小。

出0入0汤圆

发表于 2010-11-8 21:25:46 | 显示全部楼层
我也遇到这个问题了!楼主flash够大,都装得下汉字库啊!我装在外部25080里面了!修改了内核,可以显示16*16和24*24点阵的汉子,不过messagebox不能用,我试了一下,标题栏可以显示出汉字,不过我的因为16*16点阵比较大,所以都超出标题栏了,而内容就全是乱码,我也试了用font工具生成ucgui可以识别的字体文件,不过messagebox显示出来也是乱码(DispString是好的),所以挺奇怪楼主几个c文件和我哪个字体文件是一个道理竟然可以显示!这块自己做个对话框算了,没必要非要用它的!
  我倒是想请教个问题,hWin=MessageBox("hello","text",0);

                      GUI_Delay(100);
                      GUI_EndDialog(hWin);  

  我想不用按键点确定,而是延时一段时间强行关闭一个对话框,有没有什么办法?
  现在根本走不到GUI_EndDialog这块儿啊!

出0入0汤圆

 楼主| 发表于 2010-11-8 22:52:40 | 显示全部楼层
回复【10楼】embeddev
-----------------------------------------------------------------------

你用的方法我没试验过,不好说。我的是可以显示但显示的不正常。等高人吧!

出0入0汤圆

发表于 2010-11-9 12:11:02 | 显示全部楼层
回复【11楼】changjianfeng  
-----------------------------------------------------------------------

GUI_FLASH const GUI_FONT GUI_FontHZ16 = {
      GUI_FONTTYPE_PROP_SJIS,
      16,
      16,
      1,  
      1,  
      (void GUI_FLASH *)&GUI_FontHZ16_PropASC
};

你的汉字显示是通过日文显示来做的,下面这段可以帮你:


#include "GUI_Protected.h"

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/
/*********************************************************************
*
*       DB2SJIS
*/
static U16 DB2GBK(U8 Byte0, U8 Byte1) {
  return Byte1 | (((U16)Byte0)<<8);
}
/*********************************************************************
*
*       _GetCharCode
*
* Purpose:
*   Return the UNICODE character code of the current character.
*/
static U16 _GetCharCode(const char GUI_UNI_PTR * s) {
  U16 r;
  U8 Char0 = *(const U8*)s++;
  if (Char0 & 0xff80) {                                                        /* Double byte sequence */
    U8  Char1 = *(const U8*)s;
    r = DB2GBK(Char0, Char1);
  } else {                                                                                /* Single byte (ASCII)  */
    r = Char0;
  }
  return r;
}

/*********************************************************************
*
*       _GetCharSize
*
* Purpose:
*   Return the number of bytes of the current character.
*/
static int _GetCharSize(const char GUI_UNI_PTR * s) {
  U8 Char = *s;
  if (Char & 0xff80) {
    return 2;
  } else {
    return 1;
  }
}

/*********************************************************************
*
*       _CalcSizeOfChar
*
* Purpose:
*   Return the number of bytes needed for the given character.
*/
static int _CalcSizeOfChar(U16 Char) {
  int r;
  if (Char & 0xff80) {                                        /* Double byte sequence */  
    r = 2;
  } else {                                                                /* Single byte (ASCII)  */
    r = 1;
  }
  return r;
}

/*********************************************************************
*
*       _Encode
*
* Purpose:
*   Encode character into 1/2/3 bytes.
*/
static int _Encode(char *s, U16 Char) {
  int r;
  r = _CalcSizeOfChar(Char);
  switch (r) {
  case 1:
    *s = (char)Char;
    break;
  case 2:
    *s++ = (U8)(Char & 0x00ff);
    *s   = (U8)(Char >> 8);
    break;
  }
  return r;
}

/*********************************************************************
*
*       _API_Table
*/
static const GUI_UC_ENC_APILIST _API_Table = {
  _GetCharCode,     /*  return character code as U16 (Unicode) */
  _GetCharSize,     /*  return size of character: 1/2/3        */
  _CalcSizeOfChar,  /*  return size of character: 1/2/3        */
  _Encode           /*  Encode character into 1/2/3 bytes      */
};

/*********************************************************************
*
*       Exported code
*
**********************************************************************
*/
/*********************************************************************
*
*       GUI_UC_SetEncodeSJIS
*/
void GUI_UC_SetEncodeSJIS(void) {
  #if GUI_SUPPORT_UNICODE
    GUI_LOCK();
    GUI_Context.pUC_API = &_API_Table;
    GUI_UNLOCK();
  #endif
}


请在你的每个任务开始部分加上这个函数调用GUI_UC_SetEncodeSJIS();
在GUI_GetTextExtend开始和结束调用GUI_LOCK();和GUI_UNLOCK();

还有一点你需要注意GUI_MessageBox使用的字体都是默认的字体,比如framewin的默认字体是不是汉字
text控件的默认字体是不是汉字。

至于为什么会这样,你应该看下源代码,一看就明白了。

出0入0汤圆

发表于 2010-11-9 12:20:10 | 显示全部楼层
回复【10楼】embeddev  
-----------------------------------------------------------------------

你可以利用MESSAGEBOX_Create自己定义个MessageBox
例如:

static WM_CALLBACK *pOldMsgCallback;

static void _cbMsg(WM_MESSAGE *pMsg)
{
   switch(pMsg->MsgId)
  {
  case WM_TIMER:
      GUI_EndDialog(pMsg->hWin, 0);
      break;
  
  case WM_DELETE:
      WM_DeleteTimer(UserTimerId);

  default:
      if (pOldMsgCallback)
      {
          pOldMsgCallback(pMsg);
      }
      break;
  }
  
}

WM_HWIN hMsg = MESSAGEBOX_Create();

pOldMsgCallback = WM_SetCallback(hMsg, _cbMsg);

WM_CreateTimer(hMsg, ...);

对于WM_CreateTimer 是你的事了,这最好有个OS来支持。

出0入0汤圆

 楼主| 发表于 2010-11-9 17:38:07 | 显示全部楼层
谢谢,我在细看一下。感激中

出0入0汤圆

 楼主| 发表于 2010-11-9 19:10:22 | 显示全部楼层
试验结果上传!图一




   GUI_UC_SetEncodeSJIS();
  GUI_MessageBox("收到**份新\n调车作业单",
                   "新作业单消息窗口", 255);

图1 (原文件名:1.jpg)


图2 (原文件名:2.jpg)






图二
GUI_UC_SetEncodeSJIS();
GUI_MessageBox("收到**份新\n    调车作业单",
                   "新作业单消息窗口", 255);

出0入0汤圆

 楼主| 发表于 2010-11-9 19:11:40 | 显示全部楼层
换行后,后面必须跟着3个空格。要不然就显示不完全。像图一一样。
而且好像,字也不是中间对齐

出0入0汤圆

 楼主| 发表于 2010-11-9 19:13:14 | 显示全部楼层
貌似窗口上的“新作业单消息窗口0”多个零出来。还没查,不知道咋回事

出0入0汤圆

发表于 2010-11-10 08:32:12 | 显示全部楼层
在GUI_GetTextExtend开始和结束调用GUI_LOCK();和GUI_UNLOCK()
这个你加了没有???

出0入0汤圆

 楼主| 发表于 2010-11-10 21:38:14 | 显示全部楼层

(原文件名:QQ截图未命名.png)
这样写对吗?

出0入0汤圆

 楼主| 发表于 2010-11-10 21:39:31 | 显示全部楼层
我就是按照您说的改的,比以前效果好,但是弄不清为什么会少二字。郁闷。谢谢你的热心帮助。

出0入0汤圆

发表于 2011-1-17 08:15:15 | 显示全部楼层
记号

出0入0汤圆

发表于 2011-1-17 08:37:58 | 显示全部楼层
gui

出0入0汤圆

发表于 2011-1-23 14:44:17 | 显示全部楼层
给你一个完美的解决方法,我花了一天的时间才把它弄好,MESSAGEBOX显示出问题,其实主要问题是出在GUI_GetTextExtend()这个函数上,我们看看下面的修改
void GUI_GetTextExtend(GUI_RECT* pRect, const char GUI_UNI_PTR * s, int MaxNumChars) {
  int xMax      = 0;
  int NumLines  = 0;
  int LineSizeX = 0;
  U16 Char;
  pRect->x0 = GUI_Context.DispPosX;
  pRect->y0 = GUI_Context.DispPosY;
  while (MaxNumChars--) {
          Char = GUI_UC__GetCharCodeInc(&s);   // <------------------先看这里,返回一个字节的机内码,但汉字是占两个字节机内码,而且汉字低字节机内码与ASCII机内码不重合
    if(Char >= 0x80)  // <----------加入以下代码 判断是否汉字
         Char = Char<<8 | GUI_UC__GetCharCodeInc(&s);  //<----------加入以下代码  再读出低字节机内码,重新组合成一个完全的汉字  
    if ((Char == '\n') || (Char == '\0')) {
      if (LineSizeX > xMax) {
        xMax = LineSizeX;
      }
      LineSizeX = 0;
      NumLines++;
      if (!Char) {
        break;
      }
    } else {
      LineSizeX += GUI_GetCharDistX(Char); //<----------------来到这里GUI_GetCharDistX(Char); 这个函数的主要作用是在字库中读出汉字的字宽,而这里的Char只有汉字的高字节机内码,因为字库里没有半个汉字机内码的信息,所以返回了0,所以LineSizeX是一直为0的.这就是Message显示汉字不全的原因
    }
  }
  if (LineSizeX > xMax) {
    xMax = LineSizeX;
  }
  if (!NumLines) {
    NumLines = 1;
  }
  
  
  pRect->x1 = pRect->x0 + xMax - 1;
  pRect->y1 = pRect->y0 + GUI__GetFontSizeY() * NumLines - 1;
}

至此MessageBox已经能完美支持中文了

出0入0汤圆

发表于 2011-1-23 20:18:09 | 显示全部楼层
/*********************************************************************
*
*       GUIPROP_GetCharDistX
*/
int GUIPROP_GetCharDistX(U16P c) {
  const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);
  return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Context.pAFont->XMag : 0;
}

这里还有一个小bug,因为在GBK码里ASCII码也被存储为2个字节,所以在字库里XSize为全角字符的大小,但到实际上显示时,是以半角的型式出现,所以在Message后会多出一些空白的地方,在这里GetCharDistX很明显是要得到XDist,但在这里却是XSize,所以要把return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Context.pAFont->XMag : 0; 改为 return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XDist * GUI_Context.pAFont->XMag : 0; 这样就可以将Message后的空隔去掉


还有,楼主的字库里内码为0020的点阵,请将其全部改为0x00,否则空格将出现问题

出0入0汤圆

 楼主| 发表于 2011-2-12 20:04:22 | 显示全部楼层
试验过了,楼上的方法问题依旧!

出0入0汤圆

 楼主| 发表于 2011-2-13 11:01:20 | 显示全部楼层
回复【23楼】wupaul2001
-----------------------------------------------------------------------

多谢,问题解决。

出0入0汤圆

发表于 2011-10-17 17:13:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-6-3 12:48:18 | 显示全部楼层
MARK.
                    

出0入0汤圆

发表于 2013-9-5 10:34:05 | 显示全部楼层
mark....   

出0入0汤圆

发表于 2013-11-28 08:41:26 | 显示全部楼层
正遇到同样的问题,参考下。

出0入0汤圆

发表于 2014-4-23 02:10:04 | 显示全部楼层
ucgui3.9*中消息框无法正确显示汉字,记号
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 13:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表