1. 程式人生 > >emWin 2天速成實例教程005_控件聚焦和用戶消息的使用方法

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

emwin WM_SetFocus WM_SendMessage 自定義消息

備註:(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傳過去。


源碼/軟件下載


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