UCGUI3.98版本里面多了GRAPH的控件,如下图所示的左边,使用该控件可以不断地在窗体中绘制图线。然而右边的转速表盘由于不是gui给我们提供的控件,而是自己动手编程绘制的图形,所以没有可供调用的函数使其指针实时地自动转动。因此,通过借鉴GRAPH控件的接口函数从而自己编写表盘的数据加载函数。
Graph控件是在回调函数的被初始化的,而在mian函数里面的超级循环通过调用 _AddValues(hGraph);来增加数据显示,
看函数原型,只有GRAPH_DATA_YT_AddValue()这个函数是真正地将数据添加到窗体里面进行显示的,之前的代码都是用来产生随机数据的。
因为在VC里面,ucgui被建立为了一个后缀为.lib的库文件,没有办法看到源代码。那么我们就把ucgui3.98版本的源代码放在在Sourceinsight里面顺藤摸瓜看去下。
typedef struct {
GRAPH_DATA_OBJ GraphDataObj;
WM_HMEM hData;
int Align;
} GRAPH_DATA_YT_OBJ;
GRAPH_DATA_YT_OBJ由上诉代码所示为一个将GRAPH空间设置为YT模式下数据保存的结构体,我们暂时不用去管他。继续往下看
WM_LOCK()
#define WM_LOCK() GUI_LOCK()
所以应该是禁止GUI的调度,等于进入了临界区。
pDataYtObj = (GRAPH_DATA_YT_OBJ *)GUI_ALLOC_h2p(hDataObj);
GUI_ALLOC_h2p()这个函数的功能在网上搜到是把句柄转换为指针,那么这句代码就是把类型为GRAPH_DATA_Handle的句柄hDataObj转换为结构体GRAPH_DATA_YT_OBJ的指针。
if (pDataYtObj) 判断指针是否为空
pData = (I16 *)GUI_ALLOC_h2p(pDataYtObj-> hData);
把结构体pDataYtObj中的句柄hData转换为指针并赋值给pData
GRAPH__AddValue(&pDataYtObj->GraphDataObj, pData, &Value, sizeof(I16));
if (pDataObj->PaintObj.hGraph) 判断结构体pDataObj的成员PaintObj中的hGraph是否为空(注意:PaintObj也为一个结构体)。hGraph指向的应该是一个Graph类型的窗体
if (pDataObj->NumItems == pDataObj->MaxNumItems) 判断已有的项目数量(也就是画的数据点数)是否达到了最大的项目数量。
Memmove是在string.h库中的一个函数,介绍如下:
原型:void *memmove( void* dest, const void* src, size_tcount );
用法:#include 功能:由src所指内存区域复制count个字节到dest所指内存区域。 说明:src和dest所指内存区域可以重叠,但复制后dest内容会被更改。函数返回指向dest的指针。 memmove((U8 *)pData, (U8 *)pData + Size, Size * (pDataObj->MaxNumItems - 1)); memmove((U8 *)pData + Size * (pDataObj->NumItems - 1), pValue, Size); } else { memmove((U8 *)pData + Size * pDataObj->NumItems++, pValue, Size); } 上面的语句是根据现在的点数是不是达到了最大的数量,将数据插入到要画的数组当中。 _InvalidateGraph(pDataObj->PaintObj.hGraph); 分析这段代码,主要实现的功能就是得到控件Graph内的一块区域,然后使之无效掉。那么在回调函数当中就会重绘无效掉的那部分区域。 解决方案:将表盘那部分建立一个子窗体,每次有新的数据就无效掉子窗体,而不是整个窗体,这样节省内存开销。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- sceh.cn 版权所有 湘ICP备2023017654号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务