OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 15288|回复: 16

emWin文件浏览TreeView控件问题

[复制链接]

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2013-10-27
在线时间
12 小时
发表于 2014-8-8 11:03:48 | 显示全部楼层 |阅读模式
5金钱
调试程序发现程序卡死在hParent=TREEVIEW_GetItem(hTree, hNode, TREEVIEW_GET_PARENT);里,直接进入
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

程序:
/*********************************************************************
*                                                                    *
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                                                                    *
**********************************************************************
*                                                                    *
* C-file generated by:                                               *
*                                                                    *
*        GUI_Builder for emWin version 5.22                          *
*        Compiled Jul  4 2013, 15:16:01                              *
*        (c) 2013 Segger Microcontroller GmbH & Co. KG               *
*                                                                    *
**********************************************************************
*                                                                    *
*        Internet: www.segger.com  Support: support@segger.com       *
*                                                                    *
**********************************************************************
*/

// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"
#include "MyTask.h"

#define FILE_PATH_MAX   _MAX_LFN + 1
//#define FileBrowerList   "0:/SYSTEM/ConfigFile/FileBrowerList.txt"

static WM_HWIN hWin_parent;

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0   (GUI_ID_USER + 0x00)
#define ID_TREEVIEW_0   (GUI_ID_USER + 0x01)


/*********************************************************************
*
*       Static data
*
**********************************************************************
*/
/************************************************************************************
*函数:  ScanFiles
*作者:  alan
*日期:  2014.07.07
*参数:  path:遍历路径名
        hFile:记录文件路径的文件指针结构体
*返回:  None
*描述:  遍历此文件夹及子文件夹下所有文件
************************************************************************************/
static FRESULT ScanFiles(char* path,WM_HWIN hTree, TREEVIEW_ITEM_Handle hNode,FILE_TYPE fileType,u32 *fileNum)
{
    FRESULT res;
    FILINFO fno;
    DIR dir;
    UINT rw;
    int i;
    char *fn;   /* This function is assuming non-Unicode cfg. */
    char file_name[FILE_PATH_MAX]={0};
    TREEVIEW_ITEM_Handle hItem;
    
#if _USE_LFN
    static char lfn[FILE_PATH_MAX]={0};   /* Buffer to store the LFN */
    fno.lfname = lfn;
    fno.lfsize = sizeof(lfn);
#endif

    res = f_opendir(&dir, (const TCHAR*)path);                       /* Open the directory */
    if (res == FR_OK)
    {
        i = strlen((const char*)path);
        for (;;) 
        {
            res = f_readdir(&dir, &fno);                   /* Read a directory item */
            if (res != FR_OK || fno.fname[0] == 0) break;  /* Break on error or end of dir */
            if (fno.fname[0] == '.') continue;             /* Ignore dot entry */ //忽略上级目录
#if _USE_LFN
            fn = *fno.lfname ? fno.lfname : fno.fname;
#else
            fn = fno.fname;
#endif
            if (fno.fattrib & AM_DIR) /* It is a directory */
            {
                if(hTree != NULL && hNode != NULL)
                {
                    //目录,创建结点
                    hItem = TREEVIEW_ITEM_Create(TREEVIEW_ITEM_TYPE_NODE,fn,0);
                    //把结点加入到目录树中
                    TREEVIEW_AttachItem(hTree,hItem,hNode,TREEVIEW_INSERT_FIRST_CHILD);
                }
                //在路径最后添加文件夹路径名
                sprintf(&path, "/%s", fn);
                //遍历此新文件夹下的文件
                res = ScanFiles(path,hTree,hItem,fileType,fileNum);
                if (res != FR_OK) break;//打开失败,跳出循环
                path = 0;//末尾添加结束字符
            } 
            else /* It is a file. */
            {
                if(fileType == TEXTFILE )
                {
                    //判断如果不是txt文件,跳出本函数
                    if(!(strstr(fn,".txt")||strstr(fn,".TXT")
                        ||strstr(fn,".c")||strstr(fn,".c")
                        ||strstr(fn,".cpp")||strstr(fn,".CPP")
                        ||strstr(fn,".h")||strstr(fn,".h")))
                    {
                        return res;
                    }
                }
                //判断如果不是Image文件,跳出本函数
                else if(fileType ==IMAGEFILE)
                {
                    if(!(strstr(fn,".bmp")||strstr(fn,".BMP")||
                        strstr(fn,".jpg")||strstr(fn,".JPG")||
                        strstr(fn,".gif")||strstr(fn,".GIF")||
                        strstr(fn,".png")||strstr(fn,".PNG")))
                    {
                        return res;
                    }
                }
                /* 根据要求是否创建目录树 */
                if(hTree != NULL && hNode != NULL)//创建目录树
                {
                    hItem = TREEVIEW_ITEM_Create(TREEVIEW_ITEM_TYPE_LEAF,fn,0);//文件,创建树叶
                    TREEVIEW_AttachItem(hTree,hItem,hNode,TREEVIEW_INSERT_FIRST_CHILD);//把树叶添加到目录树
//                    (*fileNum)++;//记录文件数目
                }
                else
                {
                    (*fileNum)++;//记录文件数目
                }
            }

        }
        f_closedir(&dir);
    }
    return res;
}

void Fill_FileList(char *path,WM_HWIN hTree, TREEVIEW_ITEM_Handle hNode,FILE_TYPE fileType,u32 *fileNum)
{
    TREEVIEW_ITEM_Handle hTreeItem_Flash;
    TREEVIEW_ITEM_Handle hTreeItemCur;
    char p_path[FILE_PATH_MAX]={0};  //目录名 指针
// FIL hFile;  //文件句柄
FRESULT fres;   //返回结果
    
    hTreeItemCur=hNode;
    strcpy(p_path,path);    //复制目录名到指针
    fres = ScanFiles(p_path,hTree,hNode,fileType,fileNum);    //递归扫描文件
    
    hTreeItem_Flash = TREEVIEW_ITEM_Create(TREEVIEW_ITEM_TYPE_NODE, "Flash[1:]", 0);
    TREEVIEW_AttachItem(hTree, hTreeItem_Flash, hTreeItemCur, TREEVIEW_INSERT_BELOW);
    strcpy(p_path,"1:");    //复制目录名到指针
    fres = ScanFiles(p_path,hTree,hTreeItem_Flash,fileType,fileNum);    //递归扫描文件
}
/*********************************************************************
*
*       _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    { FRAMEWIN_CreateIndirect, "FileBrower", ID_FRAMEWIN_0, 0, 0, 240, 320, 0, 0x64, 0 },
    { TREEVIEW_CreateIndirect, "Treeview", ID_TREEVIEW_0, 0, 0, 230, 293, 0, 0x0, 0 },
};

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/

// USER START (Optionally insert additional static code)
void get_pathname(WM_HWIN hTree,TREEVIEW_ITEM_Handle hNode,u8* path)
{
    u8 hItemname[100]={0};
    u8 len=0;
    TREEVIEW_ITEM_Handle hParent;
    
    TREEVIEW_ITEM_GetText(hNode,hItemname,100);//当前句柄的文本
    if((0!=strcmp((char*)hItemname,"SDCard[0:]"))&&
       (0!=strcmp((char*)hItemname,"Flash[1:]")))//不是根目录
    {
        hParent=TREEVIEW_GetItem(hTree, hNode, TREEVIEW_GET_PARENT);//父句柄
        get_pathname(hTree, hParent,path);
    }
    else
    {
        if(0==strcmp((char*)hItemname,"SDCard[0:]"))    sprintf((char*)path,"%s","0:");
        else if(0==strcmp((char*)hItemname,"Flash[1:]"))   sprintf((char*)path,"%s","1:");
        return;
    }
    len=strlen((char*)path);
    sprintf((char*)(path+len),"/%s",hItemname);
}
// USER END

/*********************************************************************
*
*       _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
    
  TREEVIEW_ITEM_Handle   hTreeItem_SDCard;
  TREEVIEW_ITEM_Handle   hTreeItemCur;
  TREEVIEW_ITEM_INFO ItemInfo;
  TREEVIEW_ITEM_Handle hNode;
  WM_HWIN hItem;
  WM_HWIN hTree;
  int     NCode;
  int     Id;
  u32 FileNum=0;
  u8 *pathname;

  GUI_HMEM hMem_pathname;

  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
    //
    // Initialization of 'FileBrower'
    //
    hItem = pMsg->hWin;
    FRAMEWIN_SetFont(hItem, &GUI_FontHZ16);
    FRAMEWIN_SetTitleHeight(hItem, 20);
    FRAMEWIN_SetText(hItem, "FileBrower");
    FRAMEWIN_AddCloseButton(hItem, FRAMEWIN_BUTTON_RIGHT, 0);
    FRAMEWIN_AddMaxButton(hItem, FRAMEWIN_BUTTON_RIGHT, 1);
    FRAMEWIN_AddMinButton(hItem, FRAMEWIN_BUTTON_RIGHT, 2);
    FRAMEWIN_SetTextAlign(hItem, GUI_TA_LEFT | GUI_TA_VCENTER);
    FRAMEWIN_SetTextColor(hItem, 0x00000000);
    //
    // Initialization of 'Treeview'
    //
    hTree = WM_GetDialogItem(pMsg->hWin, ID_TREEVIEW_0);
    TREEVIEW_SetAutoScrollV(hTree, 1);    //使用自动滑动条
    TREEVIEW_SetAutoScrollH(hTree, 1);    //使用自动滑动条
    TREEVIEW_SetSelMode(hTree, TREEVIEW_SELMODE_ROW);
    TREEVIEW_SetFont(hTree,&GUI_FontHZ16);
  
    hTreeItemCur = TREEVIEW_GetItem(hTree, 0, TREEVIEW_GET_LAST);
    hTreeItem_SDCard = TREEVIEW_ITEM_Create(TREEVIEW_ITEM_TYPE_NODE, "SDCard[0:]", 0);
    TREEVIEW_AttachItem(hTree, hTreeItem_SDCard, hTreeItemCur, TREEVIEW_INSERT_BELOW);
    //FLASH
    Fill_FileList("0:",hTree,hTreeItem_SDCard,ALLFILE,&FileNum);
    break;
  case WM_NOTIFY_PARENT:
    Id    = WM_GetId(pMsg->hWinSrc);
    NCode = pMsg->Data.v;
    switch(Id) {
    case ID_TREEVIEW_0: // Notifications sent by 'Treeview'
      /* 查看选中了哪个项目 */
      hNode = TREEVIEW_GetSel(pMsg->hWinSrc);
      /* 获取该项目的信息 */
      TREEVIEW_ITEM_GetInfo(hNode,&ItemInfo);
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
        break;
      case WM_NOTIFICATION_RELEASED:
        if(ItemInfo.IsNode == 0)//点击的是目录树的叶子(即文件)
        {
            hMem_pathname = GUI_ALLOC_AllocZero(256);
            pathname = GUI_ALLOC_h2p(hMem_pathname);
            get_pathname(hTree, hNode,pathname);
            printf("\r\n%s\r\n",pathname);
            GUI_ALLOC_Free(hMem_pathname);
        }
        break;
      case WM_NOTIFICATION_MOVED_OUT:
        break;
      case WM_NOTIFICATION_SEL_CHANGED:
        break;
      }
      break;
    }
    break;
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       CreateFileBrower
*/
void CreateFileBrower(WM_HWIN hWin);
void CreateFileBrower(WM_HWIN hWin) {

    hWin_parent=hWin;
    
    GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);

}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/


最佳答案

查看完整内容[请看2#楼]

1、先用以下这个函数 (TREEVIEW_ITEM_GetInfo()): TREEVIEW_ITEM_INFO c_tree; //结构体变量定义 void TREEVIEW_ITEM_GetInfo(TREEVIEW_ITEM_Handle hItem,TREEVIEW_ITEM_INFO * pInfo); 获取:TREEVIEW_ITEM_INFO 的结构体信息。 2、TREEVIEW_ITEM_INFO 结构体中的成员变量:Level 如果成员变量[/backcolor]level 的值,跟传递给函数TREEVIEW_GetItem()的句柄是一样的,[/backcolor] [/ ...
既然来了,就留下您的痕迹呗......
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2014-8-8 11:03:49 | 显示全部楼层


1、先用以下这个函数 (TREEVIEW_ITEM_GetInfo())

TREEVIEW_ITEM_INFO  c_tree;  //结构体变量定义

void TREEVIEW_ITEM_GetInfo(TREEVIEW_ITEM_Handle hItem,TREEVIEW_ITEM_INFO * pInfo);

获取:TREEVIEW_ITEM_INFO 的结构体信息。

TreeView_item.png

2、TREEVIEW_ITEM_INFO 结构体中的成员变量:Level

     如果成员变量level 的值,跟传递给函数TREEVIEW_GetItem()的句柄是一样的,


     那么句柄应该就是下一个的,不是这个同级的子窗体句柄。


3、这样一来你再调用函数TREEVIEW_GetItem(),就不会出问题了!




  






回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-4-23
在线时间
0 小时
发表于 2014-8-8 12:10:17 | 显示全部楼层
void CreateFileBrower(WM_HWIN hWin);
void CreateFileBrower(WM_HWIN hWin) {

    hWin_parent=hWin;
    
    GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);

}

此处传入的hWin是传入父窗口句柄, GUI_CreateDialogBox 创建时的父窗口是WM_HBKWIN(桌面),前面的代码没认真看,我觉得应该是这里有问题。
回复

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2013-10-27
在线时间
12 小时
 楼主| 发表于 2014-8-8 13:16:19 | 显示全部楼层
回复【2楼】taven_song:
---------------------------------
不是这里的问题 ,我特意将WM_HBKWIN作为父窗口的,一遍全屏显示。
hWin_parent=hWin;只是保存ICONVIEW作为父窗口;备用的。
既然来了,就留下您的痕迹呗......
回复

使用道具 举报

20

主题

562

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
670
金钱
670
注册时间
2012-2-28
在线时间
0 小时
发表于 2014-8-8 15:17:56 | 显示全部楼层
进入这个HardFault_Handler里面,一般都是因为内存溢出、爆栈之类的

你试着分配大一点的GUI_ALLOC_SIZE(μc/GUI上面这个表示存储空间的大小)

或者你让你那个目录的元素稍微少一些,应该就不会出问题了
努力,前进。
回复

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2013-10-27
在线时间
12 小时
 楼主| 发表于 2014-8-8 15:41:32 | 显示全部楼层
回复【4楼】5498折戟沉沙:
---------------------------------
我用的是外部1MB内存
既然来了,就留下您的痕迹呗......
回复

使用道具 举报

20

主题

562

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
670
金钱
670
注册时间
2012-2-28
在线时间
0 小时
发表于 2014-8-8 15:59:41 | 显示全部楼层
回复【5楼】glyxz1990:
---------------------------------
如果循环边界处理不好,陷入死循环,一直不停申请存储空间的话,最终导致爆栈,从而也会进入HardFault_Handler

你芯片的堆栈大小修改了吗?由于GUI中经常就是递归,所以系统预设的堆栈大小一般是不够的,需要改大一些
努力,前进。
回复

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2013-10-27
在线时间
12 小时
 楼主| 发表于 2014-8-8 16:19:18 | 显示全部楼层
回复【6楼】5498折戟沉沙:
---------------------------------
堆栈好像没改过,现在板子不能下载了!要先解决下载的问题。郁闷;
http://www.openedv.com/posts/list/0/37649.htm?privmsg=16045&&sysid=4#212790
你看下谢谢
既然来了,就留下您的痕迹呗......
回复

使用道具 举报

20

主题

562

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
670
金钱
670
注册时间
2012-2-28
在线时间
0 小时
发表于 2014-8-8 17:34:47 | 显示全部楼层
回复【7楼】glyxz1990:
---------------------------------
这个我不太清楚,以前我都是直接用串口下载进去的....

如果用GUI,修改堆栈是必须的,初试的堆栈大小只有0X400,这才1K,是不够GUI的递归的
努力,前进。
回复

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2013-10-27
在线时间
12 小时
 楼主| 发表于 2014-8-13 15:58:37 | 显示全部楼层
回复【8楼】5498折戟沉沙:
---------------------------------
我把堆栈都改为3Kbyte了,还是有问题。我把函数里的变量申请为静态变量后就好了,但是还有个问题就是,有时候我关掉窗口时会死掉。
现在有项目要做,搞GUI只能回家有空再搞了。
既然来了,就留下您的痕迹呗......
回复

使用道具 举报

20

主题

562

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
670
金钱
670
注册时间
2012-2-28
在线时间
0 小时
发表于 2014-8-13 18:37:38 | 显示全部楼层
回复【9楼】glyxz1990:
---------------------------------
哎,有的片子,就是这么个毛病,总是容易堆栈溢出;GUI太消耗资源了
努力,前进。
回复

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-8-3
在线时间
9 小时
发表于 2014-12-30 16:43:51 | 显示全部楼层
记号,学习了。
回复

使用道具 举报

3

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2019-5-22
在线时间
16 小时
发表于 2019-7-11 09:07:25 | 显示全部楼层
您好楼主,您知道是哪里错了吗?
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-10-14
在线时间
9 小时
发表于 2021-1-17 07:58:25 | 显示全部楼层
麻烦问一下,这个FILE_TYPE这个结构体是在哪里定义的?好像不是文件系统里面的结构体啊
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-10-14
在线时间
9 小时
发表于 2021-1-21 11:05:37 | 显示全部楼层
你好,楼主,请问您这个问题解决了吗?跟您一样,我遇到了这个问题,想参考一下您的解决方法
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-11-14
在线时间
7 小时
发表于 2021-3-24 16:54:08 | 显示全部楼层
楼主可以参考的看一下你的源码吗?万分感谢!!!
回复

使用道具 举报

108

主题

194

帖子

0

精华

高级会员

Rank: 4

积分
713
金钱
713
注册时间
2016-6-29
在线时间
165 小时
发表于 2021-5-22 16:57:22 | 显示全部楼层
楼主搞定没  ,能不能给个源码参考一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 09:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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