emWin显示txt文件问题
大家好,我正在学习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;
extern TCHAR dir_buff;
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 = {""}; //初始化为根目录
charapText = "";
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 = "/";
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) 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 = 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;
int NCode, Id;
char sel_path;
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 = WM_GetDialogItem(hWin, GUI_ID_BUTTON0);
_ahButton = WM_GetDialogItem(hWin, GUI_ID_BUTTON1);
_ahButton = WM_GetDialogItem(hWin, GUI_ID_BUTTON2);
_ahButton = WM_GetDialogItem(hWin, GUI_ID_BUTTON3);
_ahButton = WM_GetDialogItem(hWin, GUI_ID_BUTTON4);
//按键字体设置
BUTTON_SetFont(_ahButton,pFont);
BUTTON_SetFont(_ahButton,pFont);
BUTTON_SetFont(_ahButton,pFont);
BUTTON_SetFont(_ahButton,pFont);
BUTTON_SetFont(_ahButton,pFont);
//按键文字
BUTTON_SetText(_ahButton,"Open");
BUTTON_SetText(_ahButton,"Close");
BUTTON_SetText(_ahButton,"MulSel");
BUTTON_SetText(_ahButton,"Cancel");
BUTTON_SetText(_ahButton,"Delete");
//按键前景色设置
BUTTON_SetTextColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_RED);
BUTTON_SetTextColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_RED);
BUTTON_SetTextColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_RED);
BUTTON_SetTextColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_RED);
BUTTON_SetTextColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_RED);
//按键背景色设置
BUTTON_SetBkColor(_ahButton,BUTTON_CI_DISABLED,GUI_GRAY); //按键背景颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_DISABLED,GUI_GRAY);
BUTTON_SetBkColor(_ahButton,BUTTON_CI_DISABLED,GUI_GRAY);
BUTTON_SetBkColor(_ahButton,BUTTON_CI_DISABLED,GUI_GRAY);
BUTTON_SetBkColor(_ahButton,BUTTON_CI_DISABLED,GUI_GRAY);
BUTTON_SetBkColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_UNPRESSED,GUI_WHITE); //设置对话框里按键CLEAR未被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色
BUTTON_SetBkColor(_ahButton,BUTTON_CI_PRESSED,GUI_DARKBLUE); //设置对话框里按键CLEAR被按下的字体颜色
BUTTON_SetBkColor(_ahButton,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 == '/')
{
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 = 0;
f_close(&myOpenFile);
}
else
{
f_close(&myOpenFile);
apText = 0;
}
}
else
{
apText = 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 == '/')
{
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 == '/')
{
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();
}
我使用了UCOS-III, GUI任务的堆栈已经设很大了,已经设为3000了。再大的话已经设置不了了。
#define GUI_NUMBYTES0x3000 这个GUI的空间大小我已经设成这么大了。
本来我已经用的最大号CPU了,但是我只是编了一个小程序就已经占用这么大地方了。再编大点的程序是否能行,有点担心。 建议用最小系统在模拟器上实现基本显示功能,apText可以用固定的字符串来代替,字符字库可以从英文的开始,等最小系统实现后,再一步一步移植到平台上。
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;
页:
[1]