OpenEdv-开源电子网

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

Ucosii+Ucgui3.90视窗,控件,消息机制和重绘的概念性理解分享及求助

[复制链接]

7

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2014-4-14
在线时间
0 小时
发表于 2014-7-27 20:48:51 | 显示全部楼层 |阅读模式

Ucosii+Ucgui3.90视窗,控件,消息机制和重绘的概念性理解问题
其中有黄色标记的部分表示本人目前还不是很确定,不知道有没有人对这部分有理解的,谢谢告诉我哈!

最近正用UCOSII+UCGUI3.90制作一个检测设备的人机界面,对ucgui的窗口机制有许多疑问,跪求UCGUI高手解释啊,在理解透彻点后,我会整理一份关于UCGUI的使用入门发到论坛里,谢谢大家哈。

 

首先UCGUIGUI_WINSUPPORT若为1则使用视窗管理,那么调用 GUI_Init(),函数里面会调用WM_INIT(),视窗管理将被初始化,此时会建立一个窗口,这个窗口是GUI默认存在的。任哲老师的ucgui教程里面这个被称为桌面窗口。然后查阅资料加测试发现这个桌面窗口的句柄为1,这一点毋容置疑,然后他的回调函数被指定为自带的一个回调函数,这个函数名为static void cbBackWin( WM_MESSAGE* pMsg) ,可以再WM.c中找到这个函数。创建完窗口之后调用了WM_SelectWindow()选定了桌面窗口,然后调用了WM_Activate()激活窗口。然后WM_Init()就返回了。


好了,初始化完成之后,我们就可以使用gui的各种api来创造我们的界面了。
比如显示字符函数显示数值函数绘图函数。这些一般来说没有问题。我在这里有个疑问。这些普通的函数作用时是否是作用于当前选定的窗口,因为当前选定了桌面窗口,因此在没有选择其他窗口之前,都是在桌面窗口的客户区画图写字?
接着我们开始使用窗口对象即控件,拿按钮来做例子。创建按钮控件有3个函数。一个是直接创建。一个是作为子窗口创建,还有一个是从资源表中创建。就我所看到的其余控件创建方法格式基本类似。应该也是三种。

追踪代码发现,第一种和第二种直接调用BUTTON_CreateEx()来创建,所不同的是,其中作为子窗口创建那么会指定父窗口,直接创建那么他的父窗口这个参数给的是WM_HMEM_NULL,追踪下可以发现WM_HMEM_NULL被define为(0)。也就是说父窗口句柄这个参数给的是0?但是任哲老师的书上说所有的窗口都是桌面窗口的子集,而桌面窗口的句柄应该为1,那么此处该作何解释呢,发现WM_Init有一句

NextDrawWin = WM__FirstWin = WM_HWIN_NULL;难道表示没有?

然后事实上在BUTTON_CreateEx()函数中是使用WM_CreateWindowAsChild()来创建窗口的,并且指定了回调函数BUTTON_Callback,可以再button.c中找到。看到这我有点觉得的确所有的控件其实就是一个个窗口,可以去其他.c文件比如EDIT.C。CheckBox.c看看发现确实他们的格式都一样,都是叫xx_CreateEx(),然后在里面调用了WM_CreateWindowAsChild()并且为其指定了在xx.c文件中写好的一个静态的回调函数。

然后如果他们有父窗口那么将父窗口句柄传递进去,如果没有,那么父窗口句柄给0?

第三种在资源表中创建,即创建一个对话框,函数原型如下:

WM_HWIN GUI_CreateDialogBox(const GUI_WIDGET_CREATE_INFO* paWidget, int NumWidgets, WM_CALLBACK* cb, WM_HWIN hParent,int x0, int y0)

 

第一个参数是资源表指针,第二个是资源数目,第三个为回调函数,第五个为对话框的父窗口句柄,后面2个位起始坐标。资源表中的第一个资源控件将被作为对话框的中其他窗体控件的父窗体。并且所有的控件因为创建的时候调用的是xx_CreateIndirect()这个函数,这个函数内部又会调用xx_CreateEx(),但是在xx_CreateEx()函数中,指定回调函数那个参数被设为了0,也就是说采用资源表创建对话框的时候,对话框中的每一个控件都是没有回调函数的,回调函数只有GUI_CreateDialogBox中指定的一个用户自己写的回调函数,也就是说用户需要为你所创建的控件中的所有控件的消息负责,应该是这个意思,但是不确定。


然后关于消息重绘机制,这部分疑问有点多。以下是个人理解,如有不对希望大神能够告诉我正确的理解,谢谢了。

创建一个按钮那么就相当于创建了一个窗口,不管是直接创建还是作为子窗口创建,系统都会为其分配好自带的回调函数。但是如果是在对话框中创建那么整一个对话框窗口相当于将很多控件合在了一块成为一个新的用户定义出来的控件,他的回调函数由用户指定。用户可以根据消息类型以及ID为对话框窗口中那些没有回调函数的一个个控件编写他们在消息到来时要做的事情。

 

另外ucguibuider4.0这个玩意用于创建一个新的对话框窗体非常不错,简单实用。然后有个问题GUI_ExecCreatedDialog创建阻塞对话框,GUI_CreateDialogBox创建非阻塞对话框?区别就是阻塞对话框是要用户立即响应,否则无法切换到其他地方是么?

 

另外在ucguibuider4.0中出来的code直接导入到一个任务中,的确可以使用,不过就是他到底是什么时候重绘的呢?有了回调函数,难道都不需要在任务中加入UCOS用来释放cpuOSTimeDly了么

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-7-27 23:30:24 | 显示全部楼层
回复 支持 反对

使用道具 举报

20

主题

562

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
670
金钱
670
注册时间
2012-2-28
在线时间
0 小时
发表于 2014-7-28 11:33:51 | 显示全部楼层
问题一:当调用这些底层的绘制点、线等的函数地方,均是在DIALOG的用户级回调函数对WM_PAINT消息处理时绘制的,系统此时已经自动选中窗体WINDOW、FRAME的Client窗口为当前窗口,所以直接绘制的内容就呈现在DIALOG上
问题二:创建窗口时,若父窗口句柄为0,则以桌面窗口WM_HBKWIN为父窗口
问题三:重绘时,如果NextDrawWin为0,表示从桌面窗口重新开始遍历窗口树,来绘制那些无效窗口
问题四:父窗口句柄给0,见问题二
问题五:这个指定的回调函数为DIALOG的用户级回调函数,用户在这里面插入相关代码处理DIALOG上的事件:如BUTTON被按下用户想执行什么操作,就在这里面插入
问题六:DIALOG上各个控件仍然具有自己的系统级回调函数,DIALOG用户级回调函数是μc/GUI留给用户处理DIALOG上的事件
问题七:阻塞型dialog是一个while死循环,只有被删除后,才能执行它后面的代码
问题八:UCGUIBUILDER只是为了方便用户对界面上的控件进行布局,可以直接使用。重绘,是在创建阻塞型DIALOG的那个死循环while中进行的。移植UCOS中,GUI_X_UCOS.C文件中有如下代码,可以在调用GUI_Delay();延时并且重绘的时候进行任务切换
void  GUI_X_Delay (int period) 
{
    INT32U  ticks;


    ticks = (period * 1000) / OS_TICKS_PER_SEC;
    OSTimeDly((INT16U)ticks);
}
努力,前进。
回复 支持 反对

使用道具 举报

115

主题

548

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2078
金钱
2078
注册时间
2013-11-27
在线时间
511 小时
发表于 2015-1-20 14:26:04 | 显示全部楼层
回复【3楼】5498折戟沉沙:
---------------------------------
我看到你之前回复的那个帖子,
是不是说所有的控件都是建立在对话框之上操作的?控件的一些状态就会都由对话框的回调函数,来获取?
然后你说的基本单元就是对话框,对话框包括两种,一种是框架 另一种是window这里的window是视窗吗?

还有就是 视窗和对话框有什么区别呢?控件可以在视窗上面创建吗?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 09:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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