以下是一个基本的3层页面的代码示例,使用STM32和emWin库开发。该程序包括一个主页面,一个子页面和一个子子页面,并具有返回功能。此外,程序还显示当前时间并将其显示在主页面上。
```c
#include "stm32f4xx.h"
#include "GUI.h"
#include "DIALOG.h"
#include <time.h>
#define ID_WINDOW_MAIN (GUI_ID_USER + 0x00)
#define ID_BUTTON_MENU (GUI_ID_USER + 0x01)
#define ID_WINDOW_MENU (GUI_ID_USER + 0x02)
#define ID_BUTTON_SUB (GUI_ID_USER + 0x03)
#define ID_WINDOW_SUB (GUI_ID_USER + 0x04)
#define ID_BUTTON_BACK (GUI_ID_USER + 0x05)
#define ID_WINDOW_SUBSUB (GUI_ID_USER + 0x06)
#define ID_TEXT_TIME (GUI_ID_USER + 0x07)
static WM_HWIN hWinMain;
static WM_HWIN hWinMenu;
static WM_HWIN hWinSub;
static WM_HWIN hWinSubSub;
static void _cbWindowMain(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_CREATE:
hWinMain = pMsg->hWin;
BUTTON_CreateEx(10, 10, 80, 40, hWinMain, WM_CF_SHOW, 0, ID_BUTTON_MENU);
TEXT_CreateEx(100, 100, 100, 20, hWinMain, WM_CF_SHOW, 0, ID_TEXT_TIME, "00:00:00");
break;
case WM_PAINT:
GUI_SetBkColor(GUI_YELLOW);
GUI_Clear();
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
static void _cbButtonMenu(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_NOTIFY_PARENT:
if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
hWinMenu = GUI_CreateDialogBox(_aDialogCreateMenu, GUI_COUNTOF(_aDialogCreateMenu), NULL, hWinMain, 0, 0);
}
break;
default:
BUTTON_Callback(pMsg);
break;
}
}
static void _cbWindowMenu(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_CREATE:
BUTTON_CreateEx(10, 10, 80, 40, pMsg->hWin, WM_CF_SHOW, 0, ID_BUTTON_SUB);
BUTTON_CreateEx(10, 60, 80, 40, pMsg->hWin, WM_CF_SHOW, 0, ID_BUTTON_BACK);
break;
case WM_PAINT:
GUI_SetBkColor(GUI_LIGHTBLUE);
GUI_Clear();
break;
case WM_DELETE:
hWinMenu = 0;
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
static void _cbButtonSub(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_NOTIFY_PARENT:
if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
hWinSub = GUI_CreateDialogBox(_aDialogCreateSub, GUI_COUNTOF(_aDialogCreateSub), NULL, hWinMenu, 0, 0);
}
break;
default:
BUTTON_Callback(pMsg);
break;
}
}
static void _cbButtonBack(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_NOTIFY_PARENT:
if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
GUI_EndDialog(hWinMenu, 0);
}
break;
default:
BUTTON_Callback(pMsg);
break;
}
}
static void _cbWindowSub(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_CREATE:
BUTTON_CreateEx(10, 10, 80, 40, pMsg->hWin, WM_CF_SHOW, 0, ID_BUTTON_BACK);
break;
case WM_PAINT:
GUI_SetBkColor(GUI_LIGHTGREEN);
GUI_Clear();
break;
case WM_DELETE:
hWinSub = 0;
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
static void _cbWindowSubSub(WM_MESSAGE * pMsg) {
switch (pMsg->MsgId) {
case WM_CREATE:
break;
case WM_PAINT:
GUI_SetBkColor(GUI_LIGHTMAGENTA);
GUI_Clear();
break;
case WM_DELETE:
hWinSubSub = 0;
break;
default:
WM_DefaultProc(pMsg);
break;
}
}
static const GUI_WIDGET_CREATE_INFO _aDialogCreateMain[] = {
{WINDOW_CreateIndirect, "Main", ID_WINDOW_MAIN, 0, 0, 320, 240, 0, 0, _cbWindowMain},
{BUTTON_CreateIndirect, "Menu", ID_BUTTON_MENU, 230, 10, 80, 40, 0, 0, _cbButtonMenu},
};
static const GUI_WIDGET_CREATE_INFO _aDialogCreateMenu[] = {
{WINDOW_CreateIndirect, "Menu", ID_WINDOW_MENU, 0, 0, 320, 240, 0, 0, _cbWindowMenu},
{BUTTON_CreateIndirect, "Sub", ID_BUTTON_SUB, 10, 10, 80, 40, 0, 0, _cbButtonSub},
{BUTTON_CreateIndirect, "Back", ID_BUTTON_BACK, 10, 60, 80, 40, 0, 0, _cbButtonBack},
};
static const GUI_WIDGET_CREATE_INFO _aDialogCreateSub[] = {
{WINDOW_CreateIndirect, "Sub", ID_WINDOW_SUB, 0, 0, 320, 240, 0, 0, _cbWindowSub},
{WINDOW_CreateIndirect, "SubSub", ID_WINDOW_SUBSUB, 10, 10, 300, 220, 0, 0, _cbWindowSubSub},
{BUTTON_CreateIndirect, "Back", ID_BUTTON_BACK, 10, 190, 80, 40, 0, 0, _cbButtonBack},
};
void SysTick_Handler(void) {
static time_t last_time = 0;
time_t current_time = time(NULL);
if (current_time != last_time) {
last_time = current_time;
struct tm *t = localtime(¤t_time);
char buf[9];
snprintf(buf, 9, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
TEXT_SetText(WM_GetDialogItem(hWinMain, ID_TEXT_TIME), buf);
}
}
int main(void) {
SystemInit();
BSP_Init();
GUI_Init();
WM_CreateWindowFromList(_aDialogCreateMain);
SysTick_Config(SystemCoreClock / 1000);
while (1) {
GUI_Delay(100);
}
}
```
在上面的代码中,我们定义了四个窗口:主窗口,菜单窗口,子窗口和子子窗口。我们还定义了一些回调函数来处理窗口消息。主窗口包含一个菜单按钮和一个用于显示当前时间的文本框。菜单按钮被点击时,菜单窗口将被创建。菜单窗口包含一个子页面按钮和一个返回按钮。子页面按钮被点击时,子窗口将被创建。返回按钮被点击时,菜单窗口将被销毁。子窗口包含一个返回按钮。返回按钮被点击时,子窗口将被销毁,并返回到菜单窗口。子子窗口只是一个简单的窗口,没有任何按钮或其他控件。
在主函数中,我们首先初始化系统和BSP库。然后,我们初始化GUI库并创建主窗口。最后,我们启用SysTick中断以便更新时间并保持GUI活动。
注意:该程序使用了标准库的time.h头文件来获取当前时间。在使用此程序之前,请确保已正确配置系统时钟并启用了RTC。