您好,欢迎来到尚车旅游网。
搜索
您的当前位置:首页GRAPH控件学习

GRAPH控件学习

来源:尚车旅游网


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 或#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

本站由北京市万商天勤律师事务所王兴未律师提供法律服务