第44章
FrameWin-框架窗口控件
本期教程讲解STemWin支持的框架窗口控件。
44. 1 框架窗口控件介绍
44 2 官方WIDGET_FrameWin实例
44. 3 总结
44.1
框架窗口控件介绍
框架窗口为您的应用提供一个PC应用程序的窗口外观。这些窗口由周围框架、标题栏和用户区组成。标题栏的颜色改变以显示窗口是否激活,如下图所示:

如下图所示,可将预定义的按钮附加到标题栏,也可将自己的按钮附加到标题栏:

设置皮肤后显示效果如下:

44.1.1 框架窗口的结构
下图显示了框架窗口的详细结构和外观:

框架窗口实际上由2种窗口组成;主窗口和子窗口。子窗口称为客户端窗口。处理回调函数时意识到此点非常重要:存在具有2种不同回调函数的2种窗口。创建子窗口时,这些子窗口通常作为客户端窗口的子窗口而创建;它们的父窗口因此是客户端窗口。
细节
|
描述
|
B
|
框架窗口的边框尺寸。默认的边框尺寸为3像素。
|
H
|
标题栏的高度。取决于标题所用字体的尺寸。
|
D
|
标题栏和客户端窗口的间距。(1像素)
|
标题栏
|
标题栏是框架窗口的一部分,不是单独的窗口。
|
客户端窗口
|
客户端窗口是一个单独的窗口,作为框架窗口的子窗口创建。
|
44.2
官方WIDGET_FrameWin实例
官方的这个实例简单的演示了FrameWin的部分功能,这个例子在模拟器中的位置:

源代码如下:
#include
#include
#include "GUI.h"
#include "FRAMEWIN.h"
#define SPEED 1200
#define MSG_CHANGE_MAIN_TEXT (WM_USER + 0) (1)
static FRAMEWIN_Handle _hFrame;
static WM_CALLBACK* _pcbOldFrame;
static char _acMainText[100];
static int _LockClose = 1;
static void _ChangeMainText(char* pStr, int Delay) {(2)
WM_MESSAGE Message;
Message.MsgId = MSG_CHANGE_MAIN_TEXT;
Message.Data.p = pStr;
GUI_Delay(Delay);
WM_SendMessage(WM_HBKWIN, &Message);
WM_InvalidateWindow(WM_HBKWIN);
GUI_Delay(Delay/3);
}
static void _cbChild(WM_MESSAGE * pMsg) {(3)
WM_HWIN hWin = (FRAMEWIN_Handle)(pMsg->hWin);
switch (pMsg->MsgId) {
case WM_PAINT:
//
// Handle the paint message
//
GUI_SetBkColor(GUI_WHITE);
GUI_SetColor(GUI_BLACK);
GUI_SetFont(&GUI_FontComic24B_ASCII);
GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
GUI_Clear();
GUI_DispStringHCenterAt("Client window",
WM_GetWindowSizeX(hWin) / 2,
WM_GetWindowSizeY(hWin) / 2);
break;
default:
WM_DefaultProc(pMsg);
}
}
static void _cbFrame(WM_MESSAGE * pMsg) { (4)
switch (pMsg->MsgId) {
case WM_NOTIFY_PARENT:
if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
int Id = WM_GetId(pMsg->hWinSrc); // Id of widget
if (Id == GUI_ID_CLOSE) {
if (_LockClose) {
return;
}
_hFrame = 0;
}
}
break;
}
if (_pcbOldFrame) {
(*_pcbOldFrame)(pMsg);
}
}
static void _cbBkWindow(WM_MESSAGE * pMsg) {(5)
switch (pMsg->MsgId) {
case MSG_CHANGE_MAIN_TEXT:
strcpy(_acMainText, (char const *)pMsg->Data.p);
WM_InvalidateWindow(pMsg->hWin);
break;
case WM_PAINT:
GUI_SetBkColor(GUI_BLACK);
GUI_Clear();
GUI_SetColor(GUI_WHITE);
GUI_SetFont(&GUI_Font24_ASCII);
GUI_DispStringHCenterAt("WIDGET_FrameWin - Sample", 160, 5);
GUI_SetFont(&GUI_Font8x16);
GUI_DispStringHCenterAt(_acMainText, 160, 40);
GUI_SetFont(&GUI_Font6x8);
GUI_DispStringHCenterAt("The function FRAMEWIN_Create creates both the\n"
"frame window and the client window.", 160, 190);
break;
default:
WM_DefaultProc(pMsg);
}
}
static void _DemoFramewin(void) {(6)
int i;
char acInfoText[] = "-- sec to play with window";
WM_HWIN hChild;
WM_SetCallback(WM_HBKWIN, _cbBkWindow);
//
// Create and configure frame window
//
_ChangeMainText("FRAMEWIN_Create", SPEED);
_hFrame = FRAMEWIN_Create("Frame window", 0, WM_CF_SHOW, 50, 75, 220, 100);(7)
_pcbOldFrame = WM_SetCallback(_hFrame, _cbFrame);(8)
hChild = WM_GetClientWindow(_hFrame);(9)
WM_SetCallback(hChild, _cbChild);(10)
FRAMEWIN_SetMoveable(_hFrame, 1);(11)
//
// Create buttons
//
FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_LEFT, 0);(12)
FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 2);
//
// Modify frame window attributes
//
_ChangeMainText("FRAMEWIN_SetActive", SPEED);
FRAMEWIN_SetActive(_hFrame, 1);(13)
_ChangeMainText("FRAMEWIN_SetFont", SPEED);
FRAMEWIN_SetFont(_hFrame, &GUI_Font16B_ASCII); (14)
FRAMEWIN_SetTitleHeight(_hFrame, 20);
_ChangeMainText("FRAMEWIN_SetTextColor", SPEED);
FRAMEWIN_SetTextColor(_hFrame, GUI_YELLOW); (15)
_ChangeMainText("FRAMEWIN_SetTextAlign", SPEED);
FRAMEWIN_SetTextAlign(_hFrame, GUI_TA_HCENTER);(16)
_ChangeMainText("FRAMEWIN_Minimize", SPEED);
FRAMEWIN_Minimize(_hFrame);(17)
_ChangeMainText("FRAMEWIN_Maximize", SPEED);
FRAMEWIN_Maximize(_hFrame); (18)
_ChangeMainText("FRAMEWIN_Restore", SPEED);
FRAMEWIN_Restore(_hFrame);(19)
_ChangeMainText("FRAMEWIN_SetTitleVis", SPEED);
for (i = 0; i < 5; i++) {
FRAMEWIN_SetTitleVis(_hFrame, 0); (20)
GUI_Delay(200);
FRAMEWIN_SetTitleVis(_hFrame, 1);
GUI_Delay(200);
}
//
// Time to play with frame window
//
_LockClose = 0;
for (i = 250; (i > 0) && _hFrame; i--) {
acInfoText[0] = '0' + ((i + 9) / 100);
acInfoText[1] = '0' + (((i + 9) / 10) % 10);
_ChangeMainText(acInfoText, 0);
GUI_Delay(100);
}
if (_hFrame) {
_ChangeMainText("FRAMEWIN_Delete", SPEED);
FRAMEWIN_Delete(_hFrame);(21)
} else {
_ChangeMainText("", 50);
}
}
void MainTask(void) {
GUI_Init();
WM_EnableMemdev(WM_HBKWIN); (22)
while(1) {
_DemoFramewin();
}
}
1. 自定义的一个回调消息类型。
2. 用于给桌面窗口发送自定义的回调函数消息类型。发送后将桌面窗口变得无效,然后系统就会去执行桌面窗口回调函数中的WM_PAINT消息。
3. 框架窗口中客户窗口的回调函数。
4. 框架窗口的回调函数。
5. 桌面窗口的回调函数。
6. 框架窗口中部分API函数的演示函数。
7. 创建框架窗口。
8. 设置框架窗口的回调函数。
9. 得到框架窗口中客户端窗口句柄。
10. 设置客户端窗口的回调函数。
11. 设置框架窗口可移动。
12. 为框架窗口添加最小化,最大化和关闭按钮。
13. 激活框架窗口。
14. 设置框架窗口中标题的字体。
15. 设置框架窗口中标题的颜色。
16. 设置框架窗口中标题文本的对齐。
17. 最小化框架窗口。
18. 最大化框架窗口。
19. 恢复最小化或最大化的框架窗口。
20. 设置框架窗口的标题可见。
21. 删除框架窗口。
22. 使能桌面窗口的内存设备。
这个例子中变量_LockClose的作用也很重要,它的主要作用就是在演示框架窗口时锁住关闭按钮,防止在演示的时候,用户点击了关闭按钮。大家也特别注意框架窗口回调函数_cbFrame的处理。
实际显示效果如下:

44.3
总结
本期教程主要是跟大家讲解了框架窗口的使用,希望大家可以把本期教程中讲的这个例子跑跑,然后自己设计一个相关的例子进行试验学习。教程中只是使用了部分的框架窗口API,其它的API大家都可以试试。