硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2362|回复: 10
收起左侧

[emWin] ICONVIEW_AddBMPItemEx函数的使用

[复制链接]

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2019-6-12 09:21:00 | 显示全部楼层 |阅读模式
ICONVIEW_AddBMPItemEx函数怎么用的,在文档里搜不到这个函数。网上也没有说明。
猜测应该是 int              ICONVIEW_AddBMPItemEx            (ICONVIEW_Handle hObj, const void * pBMP, GUI_GET_DATA_FUNC * pfGetData, const char * pText);
参数 pBMP 是传给 pfGetData 的第一个参数。与 函数 void IMAGE_SetPNGEx(IMAGE_Handle hObj, GUI_GET_DATA_FUNC * pfGetData, void * pVoid) 类似。

实际测试了一下,调用没问题,跟踪调试 pBMP参数确实传给了 pfGetData 的第一个参数。。
定义的pfGetData 原型如下。

int HmiGetExImgDat(void* p, const U8** ppData, unsigned NumBytesReq, U32 Off)
{
        char* fn = (char*)p;
        U8* buf = (U8*)*ppData;
        FILE* pf;
        long rlen = 0;

        /* 打开文件 */
        pf = fopen(fn, "rb");
        if (pf)
        {
                fseek(pf, Off, SEEK_SET);

                /* 读取文件到内存 */
                rlen = fread(buf, 1, NumBytesReq, pf);

                /* 关闭文件 */
                fclose(pf);
        }

        return rlen;
}


现在有个问题是 IMAGE_SetPNGEx 调用上面的函数可以正常显示。
ICONVIEW_AddBMPItemEx  调用上面的函数就会在 /* 读取到内存 */ 那里报错。

用的是模拟器。

有谁知道这个函数要怎么用不,还是有其他的地方有问题。
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
 楼主| 发表于 2019-6-12 09:51:33 | 显示全部楼层
本帖最后由 ihavedone 于 2019-6-12 09:52 编辑

我跟踪了所有变量,发现当出问题时,ppData的内容(也就是buf 的地址)不处于分配的 static U32 aMemory[GUI_NUMBYTES / 4];地址范围内。。。这应该是emWin自己分配内存的时候出错了。。。   要么是emWin的BUG,要么是使用之前应当进行什么设置。。。

有哪位用过这个函数的指导一下呢。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107868
QQ
发表于 2019-6-12 10:47:40 | 显示全部楼层
别用这个函数,效率太低,没有研究价值。
回复

使用道具 举报

3

主题

105

回帖

114

积分

初级会员

积分
114
发表于 2019-6-12 11:11:59 | 显示全部楼层
楼主请参见此贴http://www.armbbs.cn/forum.php?mod=viewthread&tid=93844七楼,正好是说给你听的。
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
 楼主| 发表于 2019-6-12 13:44:21 | 显示全部楼层
本帖最后由 ihavedone 于 2019-6-12 13:45 编辑
公仆 发表于 2019-6-12 11:11
楼主请参见此贴http://www.armbbs.cn/forum.php?mod=viewthread&tid=93844七楼,正好是说给你听的。

看了下你的帖子,确实是这个原因,画PNG的时候是emWin分配了内存并传入指针。其他图片就是随机的数,所以我这之前设置PNG的函数没问题,设置流位图就有问题。。
现在在之前那个地方不死机了,但是图片也没显示出来。。。不知道啥原因。PNG图片照样能正常显示,流位图图片显示不出来。
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
 楼主| 发表于 2019-6-12 13:59:18 | 显示全部楼层
本帖最后由 ihavedone 于 2019-6-12 14:40 编辑
eric2013 发表于 2019-6-12 10:47
别用这个函数,效率太低,没有研究价值。

开始使用 ICONVIEW_AddBMPItemEx 这个函数有问题,所以我用了流位图函数 int  ICONVIEW_AddStreamedBitmapItem   (ICONVIEW_Handle hObj, const void * pStreamedBitmap, const char * pText);
这个函数的第二个参数是流位图数据的首地址,但因为我的.dta文件是存储在外部设备中(模拟器是存储在文件中,开发板是外部Flash),那就必须先通过一个函数读取流文件到SRAM,并且返回首地址。

// 获取流位图
void* HmiGetStreamedBmp(U16 id)
{
        WM_HMEM hMem;
        void* ptr = NULL;
        char* fn = GetImageDir(id);
        FILE* pf;
        int len;

        /* 打开文件 */
        pf = fopen(fn, "rb");
        if (pf == NULL)
        {
                return ptr;
        }

        /* 获取文件长度 */
        fseek(pf, 0, SEEK_END);
        len = ftell(pf);
        fseek(pf, 0, SEEK_SET);

        /* 分配内存 */
        hMem = GUI_ALLOC_AllocZero(len);
        if (hMem == 0)
        {
                return ptr;
        }
        ptr = GUI_ALLOC_h2p(hMem);

        /* 读取文件到内存 */
        fread(ptr, 1, len, pf);

        /* 关闭文件 */
        fclose(pf);

        return ptr;
}


定义上面的函数后,再使用 ICONVIEW_AddStreamedBitmapItem(hItem, HmiGetStreamedBmp(IMG_MAIN_HOME), ""); 可以正常显示。。。

这里有个疑问就是,HmiGetStreamedBmp 中动态分配的内存,需不需要手动释放?如果要释放的话在哪里释放?

补充:我刚刚试了一下,动态分配的内存需要释放,不然搞两个界面切换,多切几次就分配不出内存了。。。剩下一个问题就是要怎么释放。
          安富莱的教程上只看到了流位图直接绘图,绘图完后释放内存。但是如果将流位图设置到了控件,那么需要在哪里释放呢。
          且释放需要提供 WM_HMEM 类型的变量,而关联到控件的位图已经转换成了首地址指针变量。可以直接用 GUI_ALLOC_p2h() 给转换回来吗?



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107868
QQ
发表于 2019-6-12 16:52:30 | 显示全部楼层
ihavedone 发表于 2019-6-12 13:59
开始使用 ICONVIEW_AddBMPItemEx 这个函数有问题,所以我用了流位图函数 int  ICONVIEW_AddStreamedBitma ...

这种东西存到外部,还得通过文件系统读取,太影响性能了。

你这个的话,你删除界面窗口的时候释放就行,你的返回函数不用返回ptr,你返回 WM_HMEM hMem;不是更好。
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
 楼主| 发表于 2019-6-12 17:20:26 | 显示全部楼层
eric2013 发表于 2019-6-12 16:52
这种东西存到外部,还得通过文件系统读取,太影响性能了。

你这个的话,你删除界面窗口的时候释放就行 ...

现在是在每个页面都把分配的内存记录下来,然后页面删除的时候按照记录的顺序挨个释放。
本来是打算看能不能把这个信息记录到控件空间里,就不用了维护全局变量了,结果发现这样搞更麻烦。。。
回复

使用道具 举报

615

主题

3078

回帖

4943

积分

至尊会员

积分
4943
发表于 2019-6-13 08:30:12 | 显示全部楼层
ihavedone 发表于 2019-6-12 17:20
现在是在每个页面都把分配的内存记录下来,然后页面删除的时候按照记录的顺序挨个释放。
本来是打算看能 ...

直接把 .dat 文件存入到 外部 flash 里面,每次开机时加载数据到 sdram    里面,再搞个指针指向sdram 的内存地址就可以了
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
 楼主| 发表于 2019-6-13 10:33:20 | 显示全部楼层
hpdell 发表于 2019-6-13 08:30
直接把 .dat 文件存入到 外部 flash 里面,每次开机时加载数据到 sdram    里面,再搞个指针指向sdram 的 ...

图片太多了,不能全部加载到内存。外部RAM只有1M,全部分配给emWin了,当多加载几个大图片就会分配不出来内存了。所以现在是设计的时候限制了每个界面的图片大小和数量,再程序里在退出界面的时候把所有分配的内存全部释放。目前用起来没问题。
回复

使用道具 举报

615

主题

3078

回帖

4943

积分

至尊会员

积分
4943
发表于 2019-6-13 14:35:56 | 显示全部楼层
ihavedone 发表于 2019-6-13 10:33
图片太多了,不能全部加载到内存。外部RAM只有1M,全部分配给emWin了,当多加载几个大图片就会分配不出来 ...

没有问题就好哇
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-16 17:39 , Processed in 0.197261 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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