大家好,我正在学习emWin,尝试使用STM32F103VET做界面显示程序。做了一个打开txt文件进行显示的程序,暂时只是显示。文件内容已经读出来了,超过一页大小,加入了一个滚动条,但是我操作滚动条时显示剩余文本时显示就发生了错误,感觉最开始的文本没有清除,本应该滑动的问题在"后面"的感觉,字体还变小了,总之就是不正常,不知道我这个WM_PAINT有什么问题吗? #include <includes.h> #include "GUI.h" #include "WM.h" #include "DIALOG.h" #include "FRAMEWIN.h" #include "BUTTON.h" #include "TEXT.h" #include "listbox.h" #include "SLIDER.h" #include "key.h" #include "ff.h" #include <stddef.h> #include <string.h> /* ********************************************************************************************************* * EXTERNAL VARIABLES ********************************************************************************************************* */ extern char file_str[MAX_DIRFILE_NUM][10]; extern TCHAR dir_buff[MAX_DIRFILE_NUM][10]; extern FATFS myfs; extern DIR dirs; extern FILINFO finfo; extern int8_t stFAT32_Mounted; extern FIL myOpenFile; /* ********************************************************************************************************* * EXTERNAL FUNCTION DEFINATIONS ********************************************************************************************************* */ void TouchCalibrate(void); void TouchAppRun(void); void TouchAppInit(void); /* ********************************************************************************************************* * LOCAL DEFINITIONS ********************************************************************************************************* */ #define SCROLL_DET_PIXEL 10 /* ********************************************************************************************************* * LOCAL VARIABLES ********************************************************************************************************* */ char currPath[100] = {""}; //初始化为根目录 char apText[MAX_TXTFILE_LEN] = ""; GUI_COLOR DesktopColorOld; static GUI_RECT rect; SLIDER_Handle slider0; TEXT_Handle text0,text1; const GUI_FONT* pFont = &GUI_Font8x16_1; uint8_t open_f = 0; static const GUI_WIDGET_CREATE_INFO aDialogCreate[] = { //建立窗体, 大小是320X240 原点在0,0 { FRAMEWIN_CreateIndirect, "", 0, 0, 0, 320, 240 }, //建立文本框显示MP3播放速率 { TEXT_CreateIndirect, "", GUI_ID_TEXT0, 5, 165, 80, 20, TEXT_CF_LEFT }, //建立文本框显示MP3文件播放时长 { TEXT_CreateIndirect, "", GUI_ID_TEXT1, 230, 165, 70, 20, TEXT_CF_RIGHT }, //建立LISTBOX控件显示文件列表 { LISTBOX_CreateIndirect, "", GUI_ID_LISTBOX0, 3,5,310,130, 0, 0 ,WM_CF_SHOW}, //建立滑动条控件显示播放进度 { SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER0, 5, 140, 300, 25, 0, 0 }, //建立按扭控件 { BUTTON_CreateIndirect, "", GUI_ID_BUTTON0, 0, 180, 64, 38 }, { BUTTON_CreateIndirect, "", GUI_ID_BUTTON1, 64, 180, 64, 38 }, { BUTTON_CreateIndirect, "", GUI_ID_BUTTON2, 128, 180, 64, 38 }, { BUTTON_CreateIndirect, "", GUI_ID_BUTTON3, 192, 180 , 64, 38}, { BUTTON_CreateIndirect, "", GUI_ID_BUTTON4, 256, 180 , 64, 38 }, }; /* ********************************************************************************************************* * FUNCTIONS ********************************************************************************************************* */ /* ********************************************************************************************************* * _cbClient() * * Description : txt窗体的回调函数 * * Argument(s) : pMsg. * * Return(s) : none. * * Caller(s) : system. * * Note(s) : none. ********************************************************************************************************* */ static void _cbClient(WM_MESSAGE * pMsg) { WM_HWIN hWin; hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_PAINT: GUI_Clear(); GUI_SetColor(GUI_RED); GUI_SetTextMode(GUI_TM_TRANS); GUI_SetTextAlign(GUI_TA_LEFT); GUI_DispStringInRectWrap(apText,&rect,GUI_TA_LEFT, GUI_WRAPMODE_CHAR); break; } } /* ********************************************************************************************************* * _cbFrame() * * Description : txt窗体的回调函数 * * Argument(s) : pMsg. * * Return(s) : none. * * Caller(s) : system. * * Note(s) : none. ********************************************************************************************************* */ static void _cbFrame(WM_MESSAGE * pMsg) { WM_SCROLL_STATE ScrollState; WM_MESSAGE msg; WM_HWIN hWin; GUI_RECT ClientRect; hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_NOTIFY_PARENT: if (pMsg->Data.v == WM_NOTIFICATION_VALUE_CHANGED) {//WM_NOTIFICATION_SCROLL_CHANGED if (WM_GetId(pMsg->hWinSrc) == GUI_ID_VSCROLL) { WM_GetScrollState(pMsg->hWinSrc, &ScrollState); rect.y0 = 0 - (ScrollState.v * SCROLL_DET_PIXEL); rect.y1 = LCD_GetYSizeEx(0) - (ScrollState.v * SCROLL_DET_PIXEL); msg.hWin = WM_GetClientWindow(hWin); msg.hWinSrc = hWin; msg.MsgId = WM_PAINT; WM_GetClientRect(&ClientRect); msg.Data.p = &ClientRect; WM_SendMessage(WM_GetClientWindow(hWin),&msg); msg.hWin = hWin; msg.hWinSrc = hWin; msg.MsgId = WM_PAINT; WM_GetClientRect(&ClientRect); msg.Data.p = &ClientRect; WM_SendMessage(hWin,&msg); } } else { FRAMEWIN_Callback(pMsg); } break; // case WM_PAINT: // GUI_SetBkColor(GUI_BLACK); // GUI_Clear(); // break; default: FRAMEWIN_Callback(pMsg); break; } } /* ********************************************************************************************************* * DisplayAllDirFilesInCurDir() * * Description : 读取当前目录下所有目录和文件,显示到listbox中; 最多MAX_DIRFILE_NUM个(堆栈可能不够用) * * Argument(s) : none. * * Return(s) : none. * * Caller(s) : _cbCallback. * * Note(s) : 读取当前目录和文件的操作应该不算太慢,就不另外设置任务了。 ********************************************************************************************************* */ int8_t DisplayAllDirFilesInCurDir(LISTBOX_Handle *listbox) { uint8_t num = 0; char dir_name[MAX_NAME_LEN+2] = "/"; if(stFAT32_Mounted < 0) return _ERROR; f_getcwd(currPath, 100); LISTBOX_AddString(*listbox,".."); if(f_opendir(&dirs,"") == FR_OK) { while (f_readdir(&dirs, &finfo) == FR_OK) //循环依次读取文件名 { if(!finfo.fname[0]) break; //如果是文件名为空表示到目录的末尾。退出 if (finfo.fattrib & AM_ARC) //判断文件属性是否为存档型 { num++; LISTBOX_AddString(*listbox,(const char *)finfo.fname); } else if((finfo.fattrib & AM_DIR) && !(finfo.fattrib & AM_SYS) && !(finfo.fattrib & AM_HID)) //是否是目录 { num++; dir_name[1] = 0; if(strlen((const char *)finfo.fname) <= MAX_NAME_LEN) { strcat(dir_name,(const char *)finfo.fname); LISTBOX_AddString(*listbox,dir_name); } } if(num >= MAX_DIRFILE_NUM) break; } f_closedir (&dirs); } else { return _ERROR; } return _NO_ERROR; } void Delete_All_Items_InListBox(LISTBOX_Handle *listbox) { int sum = LISTBOX_GetNumItems(*listbox); for(int i = sum-1;i >= 0;i--) { LISTBOX_DeleteItem(*listbox,i); } } /* ********************************************************************************************************* * _cbCallback() * * Description : aDialogCreate对话框的回调函数 * * Argument(s) : pMsg. * * Return(s) : none. * * Caller(s) : system. * * Note(s) : none. ********************************************************************************************************* */ static void _cbCallback(WM_MESSAGE * pMsg) { WM_HWIN hWin; WM_HWIN hItem; BUTTON_Handle _ahButton[7]; int NCode, Id; char sel_path[MAX_NAME_LEN]; hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_INIT_DIALOG: FRAMEWIN_SetText(hWin,"zjr board"); /* 获得TEXT 部件的句柄 */ text0 = WM_GetDialogItem(hWin, GUI_ID_TEXT0); text1 = WM_GetDialogItem(hWin, GUI_ID_TEXT1); /* 获得slider 部件的句柄 */ slider0 = WM_GetDialogItem(hWin, GUI_ID_SLIDER0); /* 获得按钮 部件的句柄 */ _ahButton[0] = WM_GetDialogItem(hWin, GUI_ID_BUTTON0); _ahButton[1] = WM_GetDialogItem(hWin, GUI_ID_BUTTON1); _ahButton[2] = WM_GetDialogItem(hWin, GUI_ID_BUTTON2); _ahButton[3] = WM_GetDialogItem(hWin, GUI_ID_BUTTON3); _ahButton[4] = WM_GetDialogItem(hWin, GUI_ID_BUTTON4); //按键字体设置 BUTTON_SetFont(_ahButton[0],pFont); BUTTON_SetFont(_ahButton[1],pFont); BUTTON_SetFont(_ahButton[2],pFont); BUTTON_SetFont(_ahButton[3],pFont); BUTTON_SetFont(_ahButton[4],pFont); //按键文字 BUTTON_SetText(_ahButton[0],"Open"); BUTTON_SetText(_ahButton[1],"Close"); BUTTON_SetText(_ahButton[2],"MulSel"); BUTTON_SetText(_ahButton[3],"Cancel"); BUTTON_SetText(_ahButton[4],"Delete"); //按键前景色设置 BUTTON_SetTextColor(_ahButton[0],BUTTON_CI_UNPRESSED,GUI_RED); BUTTON_SetTextColor(_ahButton[1],BUTTON_CI_UNPRESSED,GUI_RED); BUTTON_SetTextColor(_ahButton[2],BUTTON_CI_UNPRESSED,GUI_RED); BUTTON_SetTextColor(_ahButton[3],BUTTON_CI_UNPRESSED,GUI_RED); BUTTON_SetTextColor(_ahButton[4],BUTTON_CI_UNPRESSED,GUI_RED); //按键背景色设置 BUTTON_SetBkColor(_ahButton[0],BUTTON_CI_DISABLED,GUI_GRAY); //按键背景颜色 BUTTON_SetBkColor(_ahButton[1],BUTTON_CI_DISABLED,GUI_GRAY); BUTTON_SetBkColor(_ahButton[2],BUTTON_CI_DISABLED,GUI_GRAY); BUTTON_SetBkColor(_ahButton[3],BUTTON_CI_DISABLED,GUI_GRAY); BUTTON_SetBkColor(_ahButton[4],BUTTON_CI_DISABLED,GUI_GRAY); BUTTON_SetBkColor(_ahButton[0],BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色 BUTTON_SetBkColor(_ahButton[1],BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色 BUTTON_SetBkColor(_ahButton[2],BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色 BUTTON_SetBkColor(_ahButton[3],BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色 BUTTON_SetBkColor(_ahButton[4],BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色 BUTTON_SetBkColor(_ahButton[0],BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色 BUTTON_SetBkColor(_ahButton[1],BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色 BUTTON_SetBkColor(_ahButton[2],BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色 BUTTON_SetBkColor(_ahButton[3],BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色 BUTTON_SetBkColor(_ahButton[4],BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色 hItem = WM_GetDialogItem(hWin, GUI_ID_LISTBOX0); //获得对话框里GUI_ID_LISTBOX0项目的句柄 LISTBOX_SetFont(hItem,pFont); //设置对话框里列表框的字体 LISTBOX_SetDefaultTextColor(LISTBOX_CI_UNSEL,GUI_BLACK); LISTBOX_SetDefaultTextColor(LISTBOX_CI_SEL,GUI_LIGHTRED); LISTBOX_SetDefaultTextColor(LISTBOX_CI_SELFOCUS,GUI_DARKRED); LISTBOX_SetBkColor(hItem,LISTBOX_CI_UNSEL,GUI_WHITE); LISTBOX_SetBkColor(hItem,LISTBOX_CI_SEL,GUI_LIGHTGREEN); LISTBOX_SetBkColor(hItem,LISTBOX_CI_SELFOCUS,GUI_LIGHTBLUE); LISTBOX_SetBkColor(hItem,LISTBOX_CI_DISABLED,GUI_GRAY); SCROLLBAR_CreateAttached(hItem, SCROLLBAR_CF_VERTICAL); //设置对话框里列表框-卷动方向为下拉 LISTBOX_SetAutoScrollH(hItem, 1); LISTBOX_SetAutoScrollV(hItem, 1); /* 将SD卡根目录下的TXT文件增加到列表框里 */ if(stFAT32_Mounted >= 0) { if(f_opendir(&dirs,"") == FR_OK) DisplayAllDirFilesInCurDir(&hItem); } break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); /*获得窗体部件的ID*/ NCode = pMsg->Data.v; /*动作代码 */ hItem = WM_GetDialogItem(hWin, GUI_ID_LISTBOX0); //获得对话框里GUI_ID_LISTBOX0项目的句柄 switch (NCode) { case WM_NOTIFICATION_RELEASED: //窗体部件动作被释放 if(Id == GUI_ID_BUTTON0) //Open { if(LISTBOX_GetMulti(hItem) == 0) { LISTBOX_GetItemText(hItem,LISTBOX_GetSel(hItem),sel_path,MAX_NAME_LEN); if(strcmp(sel_path,"..") == 0) { f_chdir(".."); Delete_All_Items_InListBox(&hItem); DisplayAllDirFilesInCurDir(&hItem); } else if(sel_path[0] == '/') { f_chdir(sel_path+1); Delete_All_Items_InListBox(&hItem); DisplayAllDirFilesInCurDir(&hItem); } else { WM_HWIN hTxtWin; SCROLLBAR_Handle hScroll; //滚动条 f_getcwd(currPath, 100); strcat(currPath,sel_path); if(f_open(&myOpenFile, currPath, FA_OPEN_EXISTING | FA_READ) == FR_OK) //不应该总读,需修改 { UINT len; if(f_read(&myOpenFile,apText,MAX_TXTFILE_LEN-1,&len) == FR_OK) { apText[len] = 0; f_close(&myOpenFile); } else { f_close(&myOpenFile); apText[0] = 0; } } else { apText[0] = 0; } hTxtWin = FRAMEWIN_CreateEx(0, 0, 320, 240, WM_HBKWIN, WM_CF_SHOW | WM_CF_HASTRANS, FRAMEWIN_CF_ACTIVE, 0, sel_path, _cbClient); FRAMEWIN_AddCloseButton(hTxtWin,FRAMEWIN_BUTTON_LEFT,0); FRAMEWIN_SetTextAlign(hTxtWin, GUI_TA_HCENTER); rect.x0 = 0; rect.x1 = LCD_GetXSizeEx(0) - SCROLLBAR_GetDefaultWidth(); rect.y0 = 0; rect.y1 = LCD_GetYSizeEx(0); hScroll = SCROLLBAR_CreateAttached(hTxtWin, SCROLLBAR_CF_VERTICAL); SCROLLBAR_SetNumItems(hScroll,50); SCROLLBAR_SetPageSize(hScroll, (LCD_GetYSizeEx(0)/SCROLL_DET_PIXEL)); WM_SetCallback(hTxtWin, _cbFrame); } } } else if(Id == GUI_ID_BUTTON1) //Close { } else if(Id == GUI_ID_BUTTON2) //MulSel { LISTBOX_SetMulti(hItem,1); } else if(Id == GUI_ID_BUTTON3) //Cancel { LISTBOX_SetMulti(hItem,0); } else if(Id == GUI_ID_BUTTON4) //Delete { if(LISTBOX_GetMulti(hItem) == 0) { LISTBOX_GetItemText(hItem,LISTBOX_GetSel(hItem),sel_path,MAX_NAME_LEN); if(strcmp(sel_path,"..") != 0) { f_getcwd(currPath, 100); if(sel_path[0] == '/') { strcat(currPath,sel_path); f_unlink(currPath); Delete_All_Items_InListBox(&hItem); DisplayAllDirFilesInCurDir(&hItem); } else { strcat(currPath,"/"); strcat(currPath,sel_path); f_unlink(currPath); Delete_All_Items_InListBox(&hItem); DisplayAllDirFilesInCurDir(&hItem); } } } else { int sum = LISTBOX_GetNumItems(hItem); f_getcwd(currPath, 100); for(int i = sum-1;i >= 1;i--) //..不能被删除 { if(LISTBOX_GetItemSel(hItem,i) == 1) { LISTBOX_GetItemText(hItem,i,sel_path,MAX_NAME_LEN); if(sel_path[0] == '/') { strcat(currPath,sel_path); } else { strcat(currPath,"/"); strcat(currPath,sel_path); } f_unlink(currPath); LISTBOX_DeleteItem(hItem,i); } } //DisplayAllDirFilesInCurDir(&hItem); } } break; default: break; } break; default: WM_DefaultProc(pMsg); break; } } void InitMyGuiWindow(void) { FRESULT rst; rst = f_mount(&myfs,"/",0); //将文件系统设置到0区; 0,不立刻mount, 1:立刻mounst if(rst == FR_OK) { stFAT32_Mounted = 1; } else { stFAT32_Mounted = -1; } GUI_Init(); GUI_SetColor(GUI_BLACK); GUI_SetBkColor(GUI_WHITE); GUI_Clear(); TouchCalibrate(); TouchAppInit(); WM_SetCreateFlags(WM_CF_MEMDEV); /* Automatically use memory devices on all windows */ DesktopColorOld = WM_SetDesktopColor(GUI_BLUE); /* Automatically update desktop window */ //必须做这个步骤,否则不会自动刷新最底层桌面WM_HBKWIN /* 建立窗体,包含了资源列表,资源数目, 并指定回调函数 */ GUI_CreateDialogBox(aDialogCreate, GUI_COUNTOF(aDialogCreate), _cbCallback, 0, 0, 0); //none-blocking manner } void myGUITaskRun(void) { OS_ERR err; TouchAppRun(); OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_STRICT, &err); //GUI_Delay(10); GUI_Exec(); } |
#define GUI_NUMBYTES 0x3000 这个GUI的空间大小我已经设成这么大了。
本来我已经用的最大号CPU了,但是我只是编了一个小程序就已经占用这么大地方了。再编大点的程序是否能行,有点担心。
case WM_PAINT:
GUI_Clear();
GUI_SetColor(GUI_RED);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_SetTextAlign(GUI_TA_LEFT);
GUI_DispStringInRectWrap(apText,&rect,GUI_TA_LEFT, GUI_WRAPMODE_CHAR);
break;