mfc中点击button右边窗口重绘_STemWin开发过程中遇到的二三事

本文记录了在使用STemWin开发过程中遇到的三个问题:1) Keil的ANSI编码导致中文显示异常,通过改为UTF-8无签名编码解决;2) DialogBox窗口不支持定时器,采用无效化窗口强制重绘实现动态更新;3) 使用Python脚本批量将图标转换为C代码。
摘要由CSDN通过智能技术生成

前言

最近负责的产品是一个小型网关,搭载了一块3.5寸的显示屏,需要实时显示一部分数据,还能进行参数设置,为了方便的管理多个窗口和界面的内容展示,所以这里采用了STemWin,因为使用的主控芯片是STM32F29,所以可以免费使用STemWin,开发过程中遇到了部分问题,这里记录一下,方便自己查阅,也希望可以帮助到正在看文章的你。

记录

1.Keil字符编码对中文显示的影响

在开发过程中发现中文字符显示有问题,但是中文字库都是已经转换好的,刚开始不知道是什么原因,通过与同事探讨才发现了问题所在。

原因

文件默认的字符编码格式与字库索引的编码格式不同导致的。

大家应该知道我们平常使用Keil的时候中文注释会出现乱码,一个中文字符会被拆分成两个字符,因为这是使用的 Encode in ANSI 编码格式,我们来看一下 Encode in ANSI 编码格式的百科:

ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~0xFFFF来编码,即扩展的ASCII编码。为使计算机支持更多语言,通常使用 0x80~0xFFFF 范围的 2 个字节来表示 1 个字符。比如:汉字 ‘中’ 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。

可以看出,由于一个中文符号被拆分成两个字节来保存,所以就导致假如你用中文注释的时候,会因为删除中间的一个字符导致后面的字符全乱码,大家可以自己尝试下。正式由于这个原因,导致我想要在显示屏上显示中文字符的时候没法正确索引到正确汉字的位置,从而无法显示出中文来。

解决办法

解决办法也很简单,我们只需要将字符的编码格式修改一下即可,如下图:

fc73221ea9bf5077fc9f1f6d28e2dc64.png

Encode in ANSI修改为Encode in UTF-8 without signature即可,下面是中文显示效果:

ca199ed3d0a35a408642a9cf19895f22.png

不过还有几个字没有制作进字库当中去,所以没有显示,大家能猜出是哪几个字吗?

2.DialogBox窗口不支持定时器

因为想在某个子窗口上实时更新一些数据,原本以为直接用STemWin的定时器就可以搞定了,由于子窗口是通过 GUI_CreateDialogBox 函数创建的,也就是我们常说的对话框,但是居然不起作用!但是安富莱的例程也是这样用的,这就有点让我摸不到头脑了。搜索了一下,发现大家也都遇到类似的问题,但是都没有很好的解决方案,经过跟领导的探讨,终于通过另一种方式将这个问题解决掉了,这里分享出来给大家参考,当然不一定是最好的方案,但是因为项目急,暂且先用着吧。

解决办法

建立一个子窗口,当然这个子窗口是一个空窗口,我们在这个子窗口的定时器中不断无效化你要定时刷新的界面,从而达到窗口重绘的效果,下面展示部分代码:

//主要处理定时器的回调static void _cbTimerWindow(WM_MESSAGE *pMsg){  static WM_HTIMER hTimerTime2;  switch(pMsg->MsgId)  {    case WM_CREATE:      /@@* Create timer */      hTimerTime2 = WM_CreateTimer(pMsg->hWin, ID_TIMER_TIME2, 1000, 0);      break;    case WM_TIMER:      /@@* Reset Timer */      //我们通过无效化你要刷新数据界面,从而进入窗口重绘选项,之所以这样做,是因为直接在Dialog中定时器不起作用      WM_InvalidateWindow(WM_GetClientWindow(TempWin));      WM_RestartTimer(pMsg->Data.v, 1000);      break;    case WM_DELETE:      WM_DeleteTimer(hTimerTime2);      break;    default:      WM_DefaultProc(pMsg);  }}//下图左侧的按钮界面的回调函数static void _cbDeviceInfoMenuDialog(WM_MESSAGE *pMsg){  WM_HWIN hItem;  int     NCode;  int     Id;  // USER START (Optionally insert additional variables)  // USER END  switch(pMsg->MsgId)  {    case WM_INIT_DIALOG:      //      // Initialization of 'DeviceInfo'      //      hItem = pMsg->hWin;      FRAMEWIN_SetTitleVis(hItem, 0);      // USER START (Optionally insert additional code for further widget initialization)      BUTTON_SetFont(WM_GetDialogItem(hItem, ID_BUTTON_0), &GUI_FontHeiTi_12);      BUTTON_SetFont(WM_GetDialogItem(hItem, ID_BUTTON_1), &GUI_FontHeiTi_12);      BUTTON_SetFont(WM_GetDialogItem(hItem, ID_BUTTON_2), &GUI_FontHeiTi_12);      BUTTON_SetFont(WM_GetDialogItem(hItem, ID_BUTTON_3), &GUI_FontHeiTi_12);      //下面这条语句就是建立的子窗口,其中区域建议大家选在你要更新的界面区域中,我们在_cbTimerWindow这个回调函数中处理定时器      WM_CreateWindowAsChild(80, 45, 200, 40, pMsg->hWin, WM_CF_SHOW | WM_CF_HASTRANS, _cbTimerWindow, 0);      // USER END      break;    case WM_NOTIFY_PARENT:      Id    = WM_GetId(pMsg->hWinSrc);      NCode = pMsg->Data.v;      switch(Id)      {        case ID_BUTTON_0: // Notifications sent by 'DateTime'          switch(NCode)          {            // USER START (Optionally insert additional code for further notification handling)            case WM_NOTIFICATION_GOT_FOCUS:            //按钮0获取到焦点展示界面1              BUTTON_SetTextColor(WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0), BUTTON_CI_UNPRESSED, GUI_RED);              TempWin = GUI_CreateDialogBox(_aDatetimeCreate, GUI_COUNTOF(_aDatetimeCreate), _cbDatetimeDialog, WM_GetParent(pMsg->hWin), 0, 0);              break;            case WM_NOTIFICATION_LOST_FOCUS:            //按钮0失去焦点结束界面1              BUTTON_SetTextColor(WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0), BUTTON_CI_UNPRESSED, GUI_BLACK);              GUI_EndDialog(TempWin, 0);              break;              // USER END          }          break;      }      break;    // USER START (Optionally insert additional message handling)    case WM_KEY:      switch(((WM_KEY_INFO *)(pMsg->Data.p))->Key)      {        case GUI_KEY_ESCAPE:          brea;      }      break;    // USER END    default:      WM_DefaultProc(pMsg);      break;  }}//主要处理界面的刷新static void _cbDatetimeDialog(WM_MESSAGE *pMsg){  WM_HWIN hItem;  // USER START (Optionally insert additional variables)  char dateTimeTemp[48] = {0};  // USER END  hItem = pMsg->hWin;  switch(pMsg->MsgId)  {    case WM_INIT_DIALOG:      //      // Initialization of 'Datetime'      //      //      FRAMEWIN_SetTitleVis(hItem, 0);      //      // Initialization of 'Date'      //      hItem = WM_GetDialogItem(hItem, ID_TEXT_YEAR);      TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);      // USER START (Optionally insert additional code for further widget initialization)      // USER END      break;    // USER START (Optionally insert additional message handling)    case WM_KEY:    case WM_PAINT:      //每次进入更新当前时间      GUI_DrawBitmap(&bmdate, 10, 10);      sprintf(dateTimeTemp, "%4d年", pClock_DateTime->TYY);      TEXT_SetFont(WM_GetDialogItem(hItem, ID_TEXT_YEAR), &GUI_FontHeiTi_20);      TEXT_SetText(WM_GetDialogItem(hItem, ID_TEXT_YEAR), dateTimeTemp);      sprintf(dateTimeTemp, "%02d月", pClock_DateTime->TMD);      TEXT_SetFont(WM_GetDialogItem(hItem, ID_TEXT_MONTH), &GUI_FontHeiTi_20);      TEXT_SetText(WM_GetDialogItem(hItem, ID_TEXT_MONTH), dateTimeTemp);      sprintf(dateTimeTemp, "%02d日", pClock_DateTime->TDD);      TEXT_SetFont(WM_GetDialogItem(hItem, ID_TEXT_DATE), &GUI_FontHeiTi_20);      TEXT_SetText(WM_GetDialogItem(hItem, ID_TEXT_DATE), dateTimeTemp);      sprintf(dateTimeTemp, "%02d时", pClock_DateTime->THH);      TEXT_SetFont(WM_GetDialogItem(hItem, ID_TEXT_HOURS), &GUI_FontHeiTi_20);      TEXT_SetText(WM_GetDialogItem(hItem, ID_TEXT_HOURS), dateTimeTemp);      sprintf(dateTimeTemp, "%02d分", pClock_DateTime->TMM);      TEXT_SetFont(WM_GetDialogItem(hItem, ID_TEXT_MINUTE), &GUI_FontHeiTi_20);      TEXT_SetText(WM_GetDialogItem(hItem, ID_TEXT_MINUTE), dateTimeTemp);      sprintf(dateTimeTemp, "%02d秒", pClock_DateTime->TSS);      TEXT_SetFont(WM_GetDialogItem(hItem, ID_TEXT_SECOND), &GUI_FontHeiTi_20);      TEXT_SetText(WM_GetDialogItem(hItem, ID_TEXT_SECOND), dateTimeTemp);      //系统自上电依赖运行的时间,以天数为最小单位      GUI_SetFont(&GUI_FontHeiTi_20);      GUI_SetColor(GUI_BLACK);      sprintf(dateTimeTemp, "系统已运行%3d天", 48);      GUI_DispStringAt(dateTimeTemp, 40, 125);      break;    // USER END    default:      WM_DefaultProc(pMsg);      break;  }}

经过测试,上面的代码是可以正常运行并使用的,目前只能通过这种方式先解决了,后面有时间再研究一下,下面是效果演示:

90ac8a037e0073cc7081d63d866da8cf.gif

3.批量转换图标到代码脚本

项目用到了不少图标,这些图标都是我从iconfont上下载的,这上面有很多不错的图标,建议大家有需求也可以去看一下,由于我下载的小图标有点多,而且一个个的转换起来有点复杂,所以就用Python写了个小脚本,批量将图片转换成C代码,当然脚本也很简单,主要就是调用了一下BmoCvt.exe这个官方给的工具,下面分享给大家:

# -*- coding: utf-8 -*-# author: IAMLIUBO# blog: https://blogs.oopswow.comimport os import sys,timefrom PIL import ImageIMAGE_FILTE = ".PNG .png .JPEG .jpeg .jpg .BMP .bmp"CODE_DIR = "C_CODE/"def ConvertImage2Code(path):    image_list = os.listdir(path)    if not os.path.exists(path + "/../" + CODE_DIR):        os.mkdir(path + "/../" + CODE_DIR)    for i in image_list:        if os.path.splitext(i)[1] in IMAGE_FILTE:            code_save_path = CODE_DIR + i.split('.')[0]            command = "BmpCvt.exe " + i + " -saveas" + code_save_path + ",1,16 -exit"            os.system(command)    print("Convert done!")def main():    if len(sys.argv) < 2:         print("No image folder path provided"              "Usage:"              "      python Image2Code4STemWin.py [image folder path]")        exit()    if not os.path.exists("BmpCvt.exe"):        print("Please put BmpCvt.exe to this folder.")        exit()    print("Image to C code script for STemWin by IAMLIUBO."        " 1.Convert the image to C code(true color with alpha channel use BmpCvt.exe).")    ConvertImage2Code(sys.argv[1])if __name__ == '__main__':    main()

记得使用的时候将BmpCvt.exe这个工具放到当前目录下,然后指定图像文件的路径即可,像下面一样:

python Image2Code4STemWin.py images

完成后会在当前目录下生成一个C_CODE文件夹,里面就是转换完成后的代码文件了。

自动化思想很重要呀,有时候程序要比人更可靠,而且非常适合重复性工作。

随时更新…

Post author: IAMLIUBOPost date: Wed Mar 25 2020 15:10:52 GMT+0800Post link: https://blogs.oopswow.com/2020/03/25/STemWin-development-issue-record/Copyright Notice: All articles in this blog are licensed under CC BY-NC-ND 4.0 unless stating additionally.Commercial reprint please contact me by email.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值