第3版emWin教程第44章 emWin6.x窗口管理器官方实例简单讲解
Posted Simon223
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第3版emWin教程第44章 emWin6.x窗口管理器官方实例简单讲解相关的知识,希望对你有一定的参考价值。
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz!http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第44章 emWin6.x窗口管理器官方实例简单讲解
为了帮助大家更好的理解窗口管理器的回调和消息机制,官方也提供了好几个这方面的例子,本章节我们将官方这几个例子也跟大家进行简单讲解,进一步帮助大家更好的学习窗口管理器。
目录
44.3 官方WM_Sample.c实例讲解(含大量窗口API操作)
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\\ncovered");
} else {
TEXT_SetText(hText, "not completely\\ncovered");
}
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\\nwindow 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 总结
本期教程就跟大家讲这么多,官方提供的这几个例子还是比较有参考价值的,希望初学者把这几个例子研究下,并在模拟器或者开发板上面多做这方面的练习。
以上是关于第3版emWin教程第44章 emWin6.x窗口管理器官方实例简单讲解的主要内容,如果未能解决你的问题,请参考以下文章
第3版emWin教程第46章 emWin6.x窗口管理器之ToolTip的使用
第3版emWin教程第43章 emWin6.x窗口管理器实例(含自定义消息)
第3版emWin教程第42章 emWin6.x窗口管理器之回调消息类型