emWin 2天速成实例教程005_控件聚焦和用户消息的使用方法

备注:(1)打开工程目录下的"Exe\GUISimulationDebug.exe"即可看到效果。(2)看完教程000~005就基本会用emWin做项目,其他章节可以需要时再参考。

  emWin的控件具有聚焦(Focus)功能,聚焦功能对于操作界面来说有时候是不需要的,但有时候是必不可少的。比如需要用键盘操作界面时,没有控件聚焦就没法决定操作哪个控件了,有聚焦的话可以通过TAB键将焦点移动到需要操作的控件,然后执行需要的操作。控件聚焦是emWin内部自己处理的,我们作为用户是不需要理会的,但有时候我们需要将聚焦指定到哪个特定控件,我们就可以用WM_SetFocus()函数实现。

  消息是emWin的基本元素,emWin是通过消息和我们自己的程序交互的,emWin可以发消息通知我们什么事情发生了,当然我们也可以发送消息给emWin告诉它要做什么。emWin有固定的消息,比如:WM_INIT_DIALOG(创建窗体时通知我们需要设置控件哪些参数)、WM_PAINT(通知我们窗体刷新绘制完毕)、WM_NOTIFY_PARENT(通知我们有控件被点击)等等…;当然emWin还可以让我们自己定义消息,这个是非常有用的,比如你在程序某个地方需要通知某个窗体做什么改变,这个时候你就自己定义一个消息,然后用WM_SendMessage()函数向这个窗体发送消息,在这个窗体的回调函数中加入这个消息和需要处理的事情即可。

  在例程中,点击”FocusTo Edit”之后,本该聚焦到该按键的,但在程序中使用WM_SetFocus()函数将焦点指定到了Edit控件;点击”Send Message”按键之后,在程序中使用WM_SendMessage()函数发送一个WM_MSGUSER消息给自己的父窗口,再在WM_MSGUSER消息中改变Edit的值(这样做只是举例而已,其实是可以直接改变Edit的值)。

  另外,如果你用到键盘控制界面的话,聚焦就非常重要了!如果一个页面失去聚焦的话,页面将无法响应键盘的操作,程序也无法跑到按键触发消息(WM_KEY)!在例程程序中,WM_HideWindow()和WM_ShowWindow()之后,页面并不会聚焦到当前页面,加入下面的函数就是为了聚焦到当前页面:




因为ID_BUTTON_0控件是在Framewin的Client窗口(有疑问请看:教程003),而hPage[1]是Framewin主窗口的句柄,因此要获取ID_BUTTON_0控件的句柄应该怎么做?在emWin中理解Framewin的Client区概念是非常必要的(其实就是记得有一个Client区就行)!





在emWin的说明书描述中,消息实际上是一个结构体,并且以pMsg指针的形式传递给回调函数:

static void_cbDialog(WM_MESSAGE * pMsg)

{

......

}


 

1)MsgId表示是什么消息,比如emWin的固定消息:WM_INIT_DIALOG(创建窗体时通知我们需要设置控件哪些参数)、WM_PAINT(通知我们窗体刷新绘制完毕)、WM_NOTIFY_PARENT(通知我们有控件被点击)等等…,当然还可以是我们自己起名的消息:

message.MsgId =WM_MSGUSER;

WM_SendMessage(hWin,&message);

 

2) hWin是目标窗口句柄,即要发送消息到哪个窗口:

WM_SendMessage(hWin,&message);

需要注意的是要区分好哪个才是目标窗口,比如是要发送给hFramewin的主窗口还是发送给hFramewin的Client窗口:

WM_SendMessage(hFramewin,&message);

WM_SendMessage(WM_GetClientWindow(hFramewin),&message);


但是对于pMsg->hWin,不管static void _cbDialog(WM_MESSAGE* pMsg)是Framewin主窗口的回调函数还是Client窗口的回调函数,pMsg->hWin表示的都是Framewin主窗口的句柄(觉得奇怪也没办法,emWin就是这样设计的)。

 

3) hWinSrc是源窗口/控件句柄,即消息是由谁发出的,在回调函数中有下面一句程序,用来获取发出消息的那个控件的ID:

Id    = WM_GetId(pMsg->hWinSrc);

比如当你按下一个Button控件,在emWin底层内部,会发送一个消息到这个按键的父窗口,那么pMsg->hWinSrc自然就是这个Button的句柄。

 

4)在你要向某个窗口发送消息的时候,还想附带个数据怎么办?这时候就可以用到Data.v或Data.p元素,Data.v可以储存一个数,Data.p可以指向一个数据群。

比如在TIMER例程中有这样一句话:WM_RestartTimer(pMsg->Data.v,100);,在emWin底层内部,emWin把TIMER的句柄存到Data.v了,既然这个消息是TIMER发出的,那么该TIMER句柄为什么不是pMsg->hWinSrc?因为TIMER不是一个控件或窗口,所以把句柄存到Data.v传过去。


源码/软件下载

猜你喜欢

转载自blog.csdn.net/neqee/article/details/53285080