教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第44章 emWin6.x窗口管理器官方实例简单讲解
为了帮助大家更好的理解窗口管理器的回调和消息机制,官方也提供了好几个这方面的例子,本章节我们将官方这几个例子也跟大家进行简单讲解,进一步帮助大家更好的学习窗口管理器。
44.1 初学者重要提示
44.2 官方WM_Redraw.c实例讲解
44.3 官方WM_Sample.c实例讲解(含大量窗口API操作)
44.4 官方WM_LateClipping.c实例讲解
44.5 官方WM_Video.c实例讲解
44.6 总结
44.1 初学者重要提示
1、 通过实例来学习emWin是最佳的学习捷径。
2、 本章节讲解的例子中用到的部分功能还没有讲解到,但是不影响大家学习窗口管理器相关的知识。没有讲解到的知识基本都会在后面章节中跟大家讲解。
3、 窗口管理器这块的API函数应该是emWin手册所有章节中函数最多的,以后需要用到什么功能了,查询就行,或者看官方的实例,哪个函数不理解了也可以查手册。下图是中文版手册里面API函数位置:
下图是英文版手册里面API函数的位置:
44.2 官方WM_Redraw.c实例讲解
这个DEMO在模拟器中的位置:
主要功能介绍:
这个例子与第43章43.3小节中的例子相似,分别演示桌面窗口配置了重绘操作和不配置重绘操作下,移动窗口的效果。其实不光在桌面窗口上面移动窗口要重绘,其它创建的窗口上面移动是一样的,也需要设置重绘。如果用户新窗口的窗口回调函数里面没有写重绘消息WM_PAINT,窗口管理器就会按照系统默认的颜色的进行重绘,如果用户写了WM_PAINT消息就会按照用户设置的进行重绘。
下面我们将这个代码分析一下:
#include "GUI.h" #include "WM.h" /********************************************************************* * * Defines * ********************************************************************** */ // // Recommended memory to run the sample with adequate performance // #define RECOMMENDED_MEMORY (1024L * 5) /******************************************************************* * * static code * ******************************************************************** */ /******************************************************************* * * _cbBkWindow */ static void _cbBkWindow(WM_MESSAGE* pMsg) { //--------------(1) switch (pMsg->MsgId) { case WM_PAINT: GUI_ClearRect(0, 50, 319, 239); //--------------(2) default: WM_DefaultProc(pMsg); } } /******************************************************************* * * _cbWindow */ static void _cbWindow(WM_MESSAGE* pMsg) { //--------------(3) GUI_RECT Rect; switch (pMsg->MsgId) { case WM_PAINT: WM_GetInsideRect(&Rect); //--------------(4) GUI_SetBkColor(GUI_RED); GUI_SetColor(GUI_YELLOW); GUI_ClearRectEx(&Rect); //--------------(5) GUI_DrawRectEx(&Rect); GUI_SetColor(GUI_BLACK); GUI_SetFont(&GUI_Font8x16); GUI_DispStringHCenterAt("Foreground window", 75, 40); break; default: WM_DefaultProc(pMsg); } } /******************************************************************* * * _MoveWindow */ static void _MoveWindow(const char* pText) { WM_HWIN hWnd; int i; // // Create foreground window // hWnd = WM_CreateWindow(10, 50, 150, 100, WM_CF_SHOW, _cbWindow, 0); //--------------(6) GUI_Delay(500); // // Move foreground window // for (i = 0; i < 40; i++) { WM_MoveWindow(hWnd, 2, 2); //--------------(7) GUI_Delay(10); } // // Show text before deleting window if we have one // if (pText) { GUI_DispStringAt(pText, 5, 50); GUI_Delay(2500); } // // Delete foreground window // WM_DeleteWindow(hWnd); //--------------(8) WM_Invalidate(WM_HBKWIN); //--------------(9) GUI_Exec(); } /******************************************************************* * * _DemoRedraw */ static void _DemoRedraw(void) { WM_CALLBACK * _cbOldBk; GUI_SetBkColor(GUI_BLACK); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("WM_Redraw - Sample", 160, 5); GUI_SetFont(&GUI_Font8x16); while(1) { // // Move a window over background // _MoveWindow("Background has not been redrawn"); //--------------(10) // // Clear background // GUI_ClearRect(0, 50, 319, 239); GUI_Delay(1000); // // Set callback for background window // _cbOldBk = WM_SetCallback(WM_HBKWIN, _cbBkWindow); //--------------(11) // // Move a window over background // _MoveWindow("Background has been redrawn"); // // Delete callback for Background window // WM_SetCallback(WM_HBKWIN, _cbOldBk); //--------------(12) } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { GUI_Init(); // // Check if recommended memory for the sample is available // if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) { GUI_ErrorOut("Not enough memory available."); return; } _DemoRedraw(); }
- 桌面窗口回调函数。
- 在桌面窗口回调函数的WM_PAINT消息中刷一块矩形区域。
- 另外一个新创建窗口的回调函数。
- 函数WM_GetInsideRect返回客户区的坐标,即实际可供用户使用的显示区。
- 调用函数GUI_ClearRectEx清屏一块矩形区。
- 函数WM_CreateWindow用来创建一个窗口,其中每个参数的含义需要大家详细研究官方手册,这里就不做解释了。
- 通过函数WM_MoveWindow()实现窗口位置的移动,注意这里移动的是相对距离。
- 删除创建的窗口。
- 通过函数WM_Invalidate(WM_HBKWIN)使得桌面窗口无效,然后调用函数GUI_Exec()就会通过窗口管理给桌面窗口回调函数发送WM_PAINT消息,从而执行重绘。
- 执行第一种情况:移动窗口,但是不做桌面窗口的重绘。
- 给桌面窗口设置专门的回调函数。
- 执行第二种情况:移动窗口,并执行桌面窗口的重绘。
这个实例主要演示了两种情况,一种是演示:移动窗口的情况下,但是不做桌面窗口的重绘。另一种是:移动窗口,并执行桌面窗口的重绘。通过这两种情况的演示可以帮助大家对回调函数有一个更好的认识。
第一种情况:没有执行桌面回调函数的显示效果
第二种情况:执行桌面回调函数的显示效果
44.3 官方WM_Sample.c实例讲解(含大量窗口API操作)
这个DEMO在模拟器中的位置:
主要功能介绍:
这个例子最主要的特点是将大部分窗口管理器的API函数都进行了调用,方便用户查看演示效果。如果那个函数不太会使用了,看这个例子也是比较方便。
下面我们将这个代码分析一下,这里捡几个重要的部分跟大家讲解一下:
44.3.1 桌面窗口回调函数自定义消息的使用
#define MSG_CHANGE_TEXT (WM_USER + 0) //--------------(1) /******************************************************************* * * _ChangeInfoText * * Function description * Sends a message to the background window and invalidate it, so * the callback of the background window display the new text. */ static void _ChangeInfoText(char * pStr) { //--------------(2) WM_MESSAGE Message; Message.MsgId = MSG_CHANGE_TEXT; Message.Data.p = pStr; WM_SendMessage(WM_HBKWIN, &Message); WM_InvalidateWindow(WM_HBKWIN); } /******************************************************************* * * _DrawInfoText * * Function description * Drawes the info text directly on the display. This function is for * the moments when no callback is set. */ static void _DrawInfoText(char * pStr) { //--------------(3) GUI_SetColor(GUI_WHITE); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("WindowManager - Sample", 160, 5); GUI_SetFont(&GUI_Font8x16); GUI_DispStringAtCEOL(pStr, 5, 40); } /******************************************************************* * * _cbBkWindow */ static void _cbBkWindow(WM_MESSAGE * pMsg) { switch (pMsg->MsgId) { case MSG_CHANGE_TEXT: //--------------(4) strcpy(_acInfoText, (char const *)pMsg->Data.p); //--------------(5) case WM_PAINT: //--------------(6) GUI_SetBkColor(GUI_BLACK); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("WindowManager - Sample", 160, 5); GUI_SetFont(&GUI_Font8x16); GUI_DispStringAt(_acInfoText, 5, 40); break; default: WM_DefaultProc(pMsg); } }
这部分代码主要学习消息发送函数WM_SendMessage的使用,43章的43.2小节学习了无参数的消息发送函数WM_SendMessageNoPara,而函数WM_SendMessage是带参数的。
- 用户自定义的消息ID,使用的时候一定要以WM_USER作为起始值,防止跟系统其他的数值冲突。如果还要实现其它自定义消息,在这个数值的基础上面定义即可。
- 通过用户自定义的消息实现给桌面窗口的回调函数发送数据。调用了函数WM_SendMessage(WM_HBKWIN, &Message)后会给桌面窗口的回调函数发送数据,再调用了函数WM_Invalidate(WM_HBKWIN)使得桌面窗口无效,然后调用函数GUI_Delay()就会通过窗口管理给桌面窗口回调函数发送WM_PAINT消息,从而执行重绘。
- 文本显示函数。
- 用户自定义消息ID。
- 字符串复制,将Data.p中的数据复制到_acInfoText中。
- 在WM_PAINT消息中显示文本acInfoText。
44.3.2 Redrawing部分演示
/******************************************************************* * * _LiftUp */ static void _LiftUp(int dy) {//--------------(1) int i; int tm; for (i = 0; i < (dy/4); i++) { tm = GUI_GetTime(); WM_MoveWindow(_hWindow1, 0, -4); WM_MoveWindow(_hWindow2, 0, -4); while ((GUI_GetTime() - tm) < 20) { WM_Exec(); } } } /******************************************************************* * * _LiftDown */ static void _LiftDown(int dy) { //--------------(2) int i; int tm; for (i = 0; i < (dy/4); i++) { tm = GUI_GetTime(); WM_MoveWindow(_hWindow1, 0, 4); WM_MoveWindow(_hWindow2, 0, 4); while ((GUI_GetTime() - tm) < 20) { WM_Exec(); } } } /******************************************************************* * * _DemoRedrawing * * Function description * Demonstrates how useful can be a callback */ static void _DemoRedrawing(void) { int i; int tm; int tDiff; _ChangeInfoText("Demonstrating redrawing"); GUI_Delay(SPEED); _LiftUp(40); GUI_Delay(SPEED/3); _ChangeInfoText("Using a callback for redrawing"); GUI_Delay(SPEED/3); for (i = 0; i < 55; i++) { tm = GUI_GetTime(); WM_MoveWindow(_hWindow1, 1, 1); WM_MoveWindow(_hWindow2, -1, -1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } for (i = 0; i < 55; i++) { tm = GUI_GetTime(); WM_MoveWindow(_hWindow1, -1, -1); WM_MoveWindow(_hWindow2, 1, 1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } GUI_Delay(SPEED/4); _LiftDown(30); GUI_Delay(SPEED/2); _ChangeInfoText("Without redrawing"); GUI_Delay(SPEED); _LiftUp(30); GUI_Delay(SPEED/4); WM_SetCallback(WM_HBKWIN, _cbBkWindowOld); for (i = 0; i < 55; i++) { tm = GUI_GetTime(); WM_MoveWindow(_hWindow1, 1, 1); WM_MoveWindow(_hWindow2, -1, -1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } for (i = 0; i < 55; i++) { tm = GUI_GetTime(); WM_MoveWindow(_hWindow1, -1, -1); WM_MoveWindow(_hWindow2, 1, 1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } GUI_Delay(SPEED/3); WM_SetCallback(WM_HBKWIN, _cbBkWindow); _LiftDown(40); GUI_Delay(SPEED); }
这部分代码实现了两个窗口在具有重绘和不具有重绘功能时的演示,还有一个重点是学习窗口移动函数WM_MoveWindow的使用,这个函数是实现相对移动,相对于窗口当前所在的位置。另外还一个窗口移动函数WM_MoveTo是绝对位置移动,设置移动到那个坐标点就移动到那个坐标点。
- 实现两个窗口向上移动。
- 实现两个窗口向下移动。
显示效果如下:
44.3.3 Resize部分演示
/******************************************************************* * * _DemoResizeWindow * * Function description * Demonstrates the use of WM_ResizeWindow */ static void _DemoResizeWindow(void) { int i; int tm; int tDiff; _ChangeInfoText("WM_ResizeWindow()"); GUI_Delay(SPEED); _LiftUp(30); for (i = 0; i < 20; i++) { tm = GUI_GetTime(); WM_ResizeWindow(_hWindow1, 1, 1); WM_ResizeWindow(_hWindow2, -1, -1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } for (i = 0; i < 40; i++) { tm = GUI_GetTime(); WM_ResizeWindow(_hWindow1, -1, -1); WM_ResizeWindow(_hWindow2, 1, 1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } for (i = 0; i < 20; i++) { tm = GUI_GetTime(); WM_ResizeWindow(_hWindow1, 1, 1); WM_ResizeWindow(_hWindow2, -1, -1); tDiff = 15 - (GUI_GetTime() - tm); GUI_Delay(tDiff); } _LiftDown(30); GUI_Delay(SPEED); }
这部分演示主要看窗口加大和减小函数WM_ResizeWindow()的使用,注意这个函数是对窗口的显示大小进行加大和减小,并不是进行放缩,显示效果如下:
44.4 官方WM_LateClipping.c实例讲解
这个DEMO在模拟器中的位置:
主要功能介绍:
这个例子依然主要演示回调函数的重绘机制,作为重绘机制方面的学习,比较有参考价值。
下面我们将这个代码分析一下:
#include "GUI.h" #include "WM.h" #include "FRAMEWIN.h" #include "BUTTON.h" /********************************************************************* * * Defines * ********************************************************************** */ // // Recommended memory to run the sample with adequate performance // #define RECOMMENDED_MEMORY (1024L * 5) /********************************************************************* * * Static data * ********************************************************************** */ static WM_HWIN _hWin1; static WM_HWIN _hWin2; static WM_HWIN _hBut1; static WM_HWIN _hBut2; static int _PaintCount1; static int _PaintCount2; static GUI_COLOR _aColors[] = { 0x0000FF, 0x00FF00, 0xFF0000, 0x00FFFF, 0xA000A0, 0xFFFF00 }; /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _cbBkWin */ static void _cbBkWin(WM_MESSAGE* pMsg) { //--------------(1) switch(pMsg->MsgId) { case WM_PAINT: //--------------(2) GUI_SetBkColor(GUI_BLACK); GUI_Clear(); GUI_SetColor(0x0060FF); GUI_DispStringAt("PaintCount (Early):", 0, 0); GUI_DispDecAt(_PaintCount1, 120, 0, 5); GUI_SetColor(0x00FFC0); GUI_DispStringAt("PaintCount (Late):", 0, 12); GUI_DispDecAt(_PaintCount2, 120, 12, 5); break; case WM_NOTIFY_PARENT: if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) { if (pMsg->hWinSrc == _hBut1) { //--------------(3) WM_InvalidateWindow(_hWin1); WM_InvalidateWindow(_hWin2); } else if (pMsg->hWinSrc == _hBut2) { //--------------(4) _PaintCount1 = 0; _PaintCount2 = 0; WM_InvalidateWindow(pMsg->hWin); } } break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * _cbTop */ static void _cbTop(WM_MESSAGE* pMsg) { //--------------(5) switch(pMsg->MsgId) { case WM_PAINT: GUI_SetBkColor(GUI_MAGENTA); GUI_Clear(); break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * _cbFrameWin1 */ static void _cbFrameWin1(WM_MESSAGE* pMsg) { //--------------(6) switch(pMsg->MsgId) { case WM_PAINT: GUI_SetBkColor(_aColors[_PaintCount1 % 6]); GUI_Clear(); GUI_SetColor(0x0060FF); GUI_FillCircle(25, 25, 15); GUI_SetColor(GUI_BLACK); GUI_DrawCircle(25, 25, 15); _PaintCount1++; WM_InvalidateWindow(WM_HBKWIN); break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * _cbFrameWin2 */ static void _cbFrameWin2(WM_MESSAGE* pMsg) { //--------------(7) switch(pMsg->MsgId) { case WM_PAINT: GUI_SetBkColor(_aColors[_PaintCount2 % 6]); GUI_Clear(); GUI_SetColor(0x00FFC0); GUI_FillCircle(25, 25, 15); GUI_SetColor(GUI_BLACK); GUI_DrawCircle(25, 25, 15); _PaintCount2++; WM_InvalidateWindow(WM_HBKWIN); break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * _ShowDemo */ static void _ShowDemo(void) { WM_HWIN hWin0; WM_HWIN hWin1; WM_HWIN hWin2; WM_HWIN hFrame1; WM_HWIN hFrame2; WM_HWIN hClient1; WM_HWIN hClient2; WM_SetCallback(WM_HBKWIN, _cbBkWin); //--------------(8) hFrame1 = FRAMEWIN_CreateEx( 10, 30, 140, 140, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Early Clipping", _cbFrameWin1); hFrame2 = FRAMEWIN_CreateEx(170, 30, 140, 140, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Late Clipping", _cbFrameWin2); hClient1 = WM_GetClientWindow(hFrame1); hClient2 = WM_GetClientWindow(hFrame2); _hWin1 = WM_CreateWindowAsChild(0, 0, WM_GetWindowSizeX(hClient1), WM_GetWindowSizeY(hClient1), hClient1, WM_CF_SHOW, _cbFrameWin1, 0); _hWin2 = WM_CreateWindowAsChild(0, 0, WM_GetWindowSizeX(hClient2), WM_GetWindowSizeY(hClient2), hClient2, WM_CF_SHOW | WM_CF_LATE_CLIP, _cbFrameWin2, 0); _hBut1 = BUTTON_CreateEx(10, 210, 140, 20, 0, WM_CF_SHOW, 0, 1); _hBut2 = BUTTON_CreateEx(170, 210, 140, 20, 0, WM_CF_SHOW, 0, 2); hWin0 = FRAMEWIN_CreateEx(60, 80, 40, 40, 0, WM_CF_SHOW | WM_CF_STAYONTOP, FRAMEWIN_CF_MOVEABLE, 0, "Top 0", _cbTop); hWin1 = FRAMEWIN_CreateEx(220, 80, 40, 40, 0, WM_CF_SHOW | WM_CF_STAYONTOP, FRAMEWIN_CF_MOVEABLE, 0, "Top 1", _cbTop); hWin2 = FRAMEWIN_CreateEx(140,170, 40, 40, 0, WM_CF_SHOW | WM_CF_STAYONTOP, FRAMEWIN_CF_MOVEABLE, 0, "Top 2", _cbTop); FRAMEWIN_SetResizeable(hWin0, 1); FRAMEWIN_SetResizeable(hWin1, 1); FRAMEWIN_SetResizeable(hWin2, 1); BUTTON_SetText(_hBut1, "Invalidate"); BUTTON_SetText(_hBut2, "Reset counters"); while(1) { GUI_Delay(50); } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { GUI_Init(); // // Check if recommended memory for the sample is available // if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) { GUI_ErrorOut("Not enough memory available."); return; } while(1) { _ShowDemo(); } }
1、桌面窗口回调函数。
2、桌面窗口回调函数中重绘消息WM_PAINT。
3、由于两个按钮是创建在桌面窗口上面的,所以按钮的WM_NOTIFICATION_RELEASED(通知代码消息类型)是在桌面窗口的回调函数中。这个按钮按下后将窗口_hWin1和窗口_hWin2无效,从而会执行这两个窗口的背景重绘功能。
4、同上,只不过这里实现的功能是将两个计数值清零,并使桌面窗口无效,从而执行桌面窗口的重绘消息。
5、此函数同时是hWin0,hWin1,hWin2三个框架窗口的回调函数。
6、此函数是框架窗口hFrame1的回调函数,回调函数中主要实现了重绘消息,重绘消息中记录了重绘的次数,并根据重绘次数修改背景颜色。
7、此函数是框架窗口hFrame2的回调函数,回调函数中主要实现了重绘消息,重绘消息中记录了重绘的次数,并根据重绘次数修改背景颜色。
8、(1) 先创建两个框架窗口hFrame1和hFrame2。
(2) 分别在这两个框架窗口中创建两个子窗口_hWin1和_hWin2。
(3) 创建两个按钮_hBut1和_hBut2。
(4) 创建三个框架窗口hWin0,hWin1和hWin2。
这个例子对于研究回调函数函数还是非常好的,大家可以在这个例子的基础上做一些修改,实现一些功能,显示效果如下:
44.5 官方WM_Video.c实例讲解
这个DEMO在模拟器中的位置:
主要功能介绍:
这个例子主要演示框架窗口的创建,删除,隐藏和显示,关于框架窗口暂时还没有讲到,后面章节会专门讲解,跟普通窗口差不多,只是多了一个标题栏,所以将其放在本章节进行讲解也是可以的,用来学习窗口相关的API函数操作。
下面我们将这个代码分析一下:
#include <stddef.h> #include <stdio.h> #include "WM.h" #include "GUI.h" #include "FRAMEWIN.h" #include "BUTTON.h" #include "TEXT.h" static void _cbFrameWinTest(WM_MESSAGE * pMsg); /********************************************************************* * * Defines * ********************************************************************** */ #define MAX_WINDOWS 50 // // Recommended memory to run the sample with adequate performance // #define RECOMMENDED_MEMORY (1024L * 5) /********************************************************************* * * Static data * ********************************************************************** */ static WM_HWIN _ahWin[MAX_WINDOWS]; static char _IsCompletelyVis; /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _CreateWindow */ static void _CreateWindow(void) { //--------------(1) unsigned i; WM_HWIN hWin; char ac[32]; int j; for (i = 0; i < MAX_WINDOWS; i++) { if (_ahWin[i] == 0) { j = i + 1; sprintf(ac, "Test window %d", j); hWin = FRAMEWIN_CreateEx(5 + 10 * i, 135 + 10 * i, 120, 60, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, ac, _cbFrameWinTest); FRAMEWIN_SetClientColor(hWin, GUI_INVALID_COLOR); _ahWin[i] = hWin; break; } } } /********************************************************************* * * _DeleteWindow */ static void _DeleteWindow(void) { //--------------(2) unsigned i; for (i = 0; i < MAX_WINDOWS; i++) { if (WM_IsVisible(_ahWin[i])) { WM_DeleteWindow(_ahWin[i]); _ahWin[i] = 0; break; } } } /********************************************************************* * * _ShowWindow */ static void _ShowWindow(void) { //--------------(3) unsigned i; for (i = 0; i < MAX_WINDOWS; i++) { if (_ahWin[i] != 0) { if (WM_IsVisible(_ahWin[i]) == 0) { WM_ShowWindow(_ahWin[i]); break; } } } } /********************************************************************* * * _HideWindow */ static void _HideWindow(void) { //--------------(4) unsigned i; for (i = 0; i < MAX_WINDOWS; i++) { if (WM_IsVisible(_ahWin[i])) { WM_HideWindow(_ahWin[i]); break; } } } /********************************************************************* * * Static code, callbacks * ********************************************************************** */ /********************************************************************* * * _cbBkWin */ static void _cbBkWin(WM_MESSAGE* pMsg) { //--------------(5) int Id; switch (pMsg->MsgId) { case WM_PAINT: GUI_SetBkColor(GUI_BLACK); GUI_Clear(); break; case WM_NOTIFY_PARENT: if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) { Id = WM_GetId(pMsg->hWinSrc); switch (Id) { case GUI_ID_BUTTON0: _CreateWindow(); break; case GUI_ID_BUTTON1: _DeleteWindow(); break; case GUI_ID_BUTTON2: _ShowWindow(); break; case GUI_ID_BUTTON3: _HideWindow(); break; } } break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * _cbFrameWinVideo */ static void _cbFrameWinVideo(WM_MESSAGE* pMsg) { //--------------(6) WM_HWIN hWin; WM_HWIN hText; int IsCompletelyVis; int IsCompletelyCovered; switch (pMsg->MsgId) { case WM_PAINT: if (_IsCompletelyVis) { GUI_SetBkColor(GUI_DARKGREEN); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_DispStringAt("Completely visible", 5, 5); } else { GUI_SetBkColor(GUI_GRAY); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_DispStringAt("Not completely visible", 5, 5); } break; case WM_NOTIFY_VIS_CHANGED: hText = WM_GetDialogItem(WM_HBKWIN, GUI_ID_TEXT1); hWin = WM_GetClientWindow(pMsg->hWin); IsCompletelyVis = WM_IsCompletelyVisible(hWin); IsCompletelyCovered = WM_IsCompletelyCovered(hWin); if (IsCompletelyCovered) { TEXT_SetText(hText, "completely covered"); } else { TEXT_SetText(hText, "not completely covered"); } if (_IsCompletelyVis != IsCompletelyVis) { _IsCompletelyVis = IsCompletelyVis; WM_InvalidateWindow(hWin); /* Only required if content changes if partially hidden */ } break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * _cbFrameWinTest */ static void _cbFrameWinTest(WM_MESSAGE* pMsg) { //--------------(7) switch (pMsg->MsgId) { case WM_PAINT: GUI_SetBkColor(GUI_DARKRED); GUI_Clear(); break; default: WM_DefaultProc(pMsg); } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { FRAMEWIN_Handle hWinVideo; BUTTON_Handle hBut; WM_HWIN hText; GUI_Init(); // // Check if recommended memory for the sample is available // if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) { GUI_ErrorOut("Not enough memory available."); return; } WM_SetCallback(WM_HBKWIN, _cbBkWin); //--------------(8) hText = TEXT_CreateEx(240, 85, 80, 26, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_TEXT0, "The client window is"); TEXT_SetTextColor(hText, GUI_WHITE); hText = TEXT_CreateEx(240, 111, 80, 26, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_TEXT1, NULL); TEXT_SetTextColor(hText, GUI_WHITE); // // Create buttons // hBut = BUTTON_CreateEx(240, 5, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0); BUTTON_SetText(hBut, "Create win"); hBut = BUTTON_CreateEx(240, 25, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON1); BUTTON_SetText(hBut, "Delete win"); hBut = BUTTON_CreateEx(240, 45, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON2); BUTTON_SetText(hBut, "Show win"); hBut = BUTTON_CreateEx(240, 65, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON3); BUTTON_SetText(hBut, "Hide win"); // // Create framewin video // hWinVideo = FRAMEWIN_CreateEx(5, 5, 170, 120, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Video window", _cbFrameWinVideo); FRAMEWIN_SetClientColor(hWinVideo, GUI_INVALID_COLOR); // // Create test windows // _CreateWindow(); _CreateWindow(); _CreateWindow(); while (1) { GUI_Delay(1000); } }
1、创建FrameWin。
2、删除FrameWin,主要是函数WM_DeleteWindow的使用。
3、显示FrameWin,主要是函数WM_IsVisible和WM_ShowWindow的使用。
4、隐藏FrameWin,主要是函数WM_HideWindow的使用。
5、桌面窗口回调函数,主要看WM_NOTIFY_PARENT消息,进入后再分为4个button的消息,分别实现框架窗口的创建,删除,显示和隐藏。
6、框架窗口FrameVideo的回调函数。
7、函数_CreateWindow里面所创建框架窗口的回调函数。
8、(1)创建两个文本控件。
(2)创建四个按钮,分别实现创建,删除,显示和隐藏窗口。
(3)创建框架窗口hWinVideo。
这个例子相对要简单很多,下面是这个例子的实际显示效果:
44.6 总结
本期教程就跟大家讲这么多,官方提供的这几个例子还是比较有参考价值的,希望初学者把这几个例子研究下,并在模拟器或者开发板上面多做这方面的练习。