, 0, 0 );
}
_ClockParm->hMem1_ClockDest = GUI_MEMDEV_CreateFixed32( 18, 28+79, // 最终显示的 x,y 地址
_ClockPosStream[0].xSize, // 与显示最大表盘尺寸宽度一致即可
_ClockPosStream[0].ySize );
_ClockParm->hMem1_ClockLcd = GUI_MEMDEV_CreateFixed32( 18, 28+79, // 最终显示的 x,y 地址
_ClockPosStream[0].xSize, // 与显示最大表盘尺寸宽度一致即可
_ClockPosStream[0].ySize );
//-----------------------------------------------------------------------------------------
GUI_MEMDEV_Select(0);
GUI_MEMDEV_CopyFromLCD( _ClockParm->hMem1_ClockLcd ); // 将 LCD 内容复制到存储设备
// 释放申请内存
for( i=0; i<4; i++ )
{
_ClockParm->_acComBuff = _ClockParm->_acClockBuf;
myFree( SRAMEX, (void *) _ClockParm->_acComBuff); // 使用完后释放内存
}
// myFree( SRAMEX,(void *) _ClockParm ); // 这个 _ClockParm 参数不能够释放,因为程序一直在运行
/* 配置回之前选择的目标窗口 */
// WM_SelectWindow( hWinOld );
}
/*******************************************************************************
*函数名称 : Clock_DrawDisp
*功能描述 : 更新时钟表盘
*输入参数 : 无
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
void Clock_DrawDisp(void)
{
int t0; // 用于三个指针的计数
int t1;
int t2;
// 时间与日期需要同时获取,切记切记,
RTC_GetTime();
RTC_GetDate();
t0 = 360 - (g_tRTC.Sec * 6); // 第一个指针计数,用于旋转秒针 (6度/秒,顺时针方向换算成逆时针方向)
t1 = 360 - (g_tRTC.Min *6) -(g_tRTC.Sec /10); // 第二个指针计数,用于旋转分针. 秒针每移动10秒,分钟移动的角度为1度
/*------------------------------------------------------------------------
g_tRTC.Hour%12 是把 24 小时制式转化为 12 小时制,*30是因为时针每小时运行 30 度,
((sTime.Minutes /10)*5) 这句是分钟每移动10分钟,小时时针移动 5 度
--------------------------------------------------------------------------*/
t2 = 360 - (((g_tRTC.Hour)%12) * 30) - ((g_tRTC.Min /10)*5);
GUI_MEMDEV_Select( _ClockParm->hMem1_ClockDest );
GUI_MEMDEV_Write( _ClockParm->hMem1_ClockLcd ); // 将给定存储设备的内容写入当前选定的存储设备中,
// 即hMem1_ClockLcd -> hMem1_ClockDest
StreamBitmapDisp( "0:/ICON/Clock_Icon/bk_blue2.dta", 0, 28 );
// GUI_BMP_ShowBkPicture(); // 使用 emwin v5.40 ABGR 版本,需要在此处重新绘制一下背景色,否则表盘不会显示透明功能
// 如果使用单色背景色,则此处不需要,但需要吧 GUI_CreateBitmapFromStream 此函数
// 之前屏蔽的函数打开即可,切记切记 2018.07.05 sws
GUI_MEMDEV_Rotate( _ClockParm->hMem1_Clock[0], _ClockParm->hMem1_ClockDest,
0, // 显示地址由 hMemDest、hMemLcd 决定
0, // 显示地址由 hMemDest、hMemLcd 决定
0, // 因为显示表盘不需要旋转,所以此次的值为0
1000);
GUI_MEMDEV_Rotate( _ClockParm->hMem1_Clock[1], _ClockParm->hMem1_ClockDest,
147-15, // 显示时针计算方法,表盘的中心x坐标 - 时针的中心x坐标,偏移量
// 已经在创建时设定好的,也就是以创建时的坐标为基准
147-34,
t2 * 1000,
1000 );
GUI_MEMDEV_Rotate( _ClockParm->hMem1_Clock[2], _ClockParm->hMem1_ClockDest,
147-9,
147-57,
t1 * 1000,
1000 );
GUI_MEMDEV_Rotate( _ClockParm->hMem1_Clock[3], _ClockParm->hMem1_ClockDest,
147-5,
147-78,
t0 * 1000,
1000 );
GUI_MEMDEV_Select(0);
GUI_MULTIBUF_Begin();
GUI_MEMDEV_CopyToLCD( _ClockParm->hMem1_ClockDest ); // 将内容显示到 LCD 屏幕上
GUI_MULTIBUF_End();
}
/*-------------- 对话框资源列表 ---------------------------------*/
// 特别注意:对话框资源列表的第一个控件必须是框架窗口或者窗口,其它的控件都不可以是第一个
static const GUI_WIDGET_CREATE_INFO _aDialogCreateRTC[] =
{
{ WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 28, 800, 452, 0, 0x0, 0 },
{ TEXT_CreateIndirect, "日期", GUI_ID_TEXT0, 270, 60, 200, 20, 0,0},
{ TEXT_CreateIndirect, "时间", GUI_ID_TEXT1, 420, 60, 200, 20, 0,0},
{ TEXT_CreateIndirect, "星期", GUI_ID_TEXT2, 270, 80, 200, 20, 0,0},
{ TEXT_CreateIndirect, "闹钟", GUI_ID_TEXT3, 420, 80, 200, 20, 0,0},
{ BUTTON_CreateIndirect, "DlgBack", ID_BUTTON_0, 691, 5, 100, 56, 0, 0, 0 }, // 返回按钮
{ BUTTON_CreateIndirect, "TimeSet", ID_BUTTON_1, 0, 390, 134, 62, 0, 0, 0 }, // 时间设置按钮
};
/*******************************************************************************
*函数名称 : _cbButtonBack
*功能描述 : “返回”按钮回调函数 ID_BUTTON_0
*输入参数 : *pMsg 消息指针
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
static void _cbButtonBack( WM_MESSAGE * pMsg )
{
WM_HWIN hWin;
hWin = pMsg->hWin;
switch ( pMsg->MsgId )
{
case WM_PAINT:
if ( BUTTON_IsPressed( hWin ))
{
StreamBitmapDisp("0:/ICON/Clock_Icon/clock_back_d.dta", 0, 0 );
}
else
{
StreamBitmapDisp("0:/ICON/Clock_Icon/clock_back_u.dta", 0, 0 );
}
break;
default:
BUTTON_Callback( pMsg );
}
}
/*******************************************************************************
*函数名称 : _cbButtonSet
*功能描述 : “时间设置”按钮回调函数 ID_BUTTON_1
*输入参数 : *pMsg 消息指针
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
static void _cbButtonSet( WM_MESSAGE * pMsg )
{
WM_HWIN hWin;
hWin = pMsg->hWin;
switch ( pMsg->MsgId )
{
case WM_PAINT:
if( BUTTON_IsPressed( hWin ))
{
GUI_SetAlpha( 0xB0 );
StreamBitmapDisp( "0:/ICON/Clock_Icon/clock_set1.dta", 0, 0 );
GUI_SetAlpha( 0 );
}
else
{
StreamBitmapDisp( "0:/ICON/Clock_Icon/clock_set1.dta", 0, 0 );
}
break;
default:
BUTTON_Callback( pMsg );
}
}
/*******************************************************************************
*函数名称 : Clock_Update
*功能描述 : 更新时间
*输入参数 : *pMsg 消息指针变量
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
static void Clock_Update( WM_MESSAGE *pMsg )
{
char buf[30];
WM_HWIN hWin = pMsg->hWin;
RTC_GetTime();
RTC_GetDate();
RTC_GetAlarmA();
/* 更新时间 */
sprintf( buf, "时间: %0.2d:%0.2d:%0.2d ", g_tRTC.Hour, g_tRTC.Min, g_tRTC.Sec );
TEXT_SetText( WM_GetDialogItem( hWin, GUI_ID_TEXT1 ), buf );
/* 更新日期 */
sprintf( buf, "日期: %0.4d/%0.2d/%0.2d", g_tRTC.Year, g_tRTC.Mon, g_tRTC.Day );
TEXT_SetText( WM_GetDialogItem( hWin, GUI_ID_TEXT0 ), buf );
/* 更新星期 */
sprintf( buf, "星期: %s", ucWeekDay[g_tRTC.Week-1]);
TEXT_SetText( WM_GetDialogItem( hWin, GUI_ID_TEXT2 ), buf );
/* 更新闹钟 */
sprintf( buf, "闹钟: %0.2d:%0.2d:%0.2d ", g_tAlarm.Hour, g_tAlarm.Min, g_tAlarm.Sec );
TEXT_SetText( WM_GetDialogItem( hWin, GUI_ID_TEXT3 ), buf );
}
/*******************************************************************************
*函数名称 : InitDialogRTC
*功能描述 : 时钟对话框回调函数中的初始化消息
*输入参数 : *pMsg 消息指针变量
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
static void InitDialogRTC( WM_MESSAGE * pMsg )
{
WM_HWIN hWin = pMsg->hWin;
WM_HWIN hItem;
WM_CreateTimer( WM_GetClientWindow( hWin ), // 接受信息的窗口的句柄
0, // 用户定义的Id。如果不对同一窗口使用多个定时器,此值可以设置为零
10, // 周期,此周期过后指定窗口应收到消息
0 ); // 留待将来使用,应为0
hItem = WM_GetDialogItem( pMsg->hWin, ID_BUTTON_0 ); // “返回”
WM_SetHasTrans( hItem );
WM_SetCallback( hItem, _cbButtonBack );
hItem = WM_GetDialogItem( pMsg->hWin, ID_BUTTON_1 ); // “时钟设置”
WM_SetHasTrans( hItem );
WM_SetCallback( hItem, _cbButtonSet );
TEXT_SetFont( WM_GetDialogItem( hWin, GUI_ID_TEXT0 ), &GUI_FontHZHT16 ); // "日期"
TEXT_SetFont( WM_GetDialogItem( hWin, GUI_ID_TEXT1 ), &GUI_FontHZHT16 ); // "时间"
TEXT_SetFont( WM_GetDialogItem( hWin, GUI_ID_TEXT2 ), &GUI_FontHZHT16 ); // "星期"
TEXT_SetFont( WM_GetDialogItem( hWin, GUI_ID_TEXT3 ), &GUI_FontHZHT16 ); // "闹钟"
GUI_MEMDEV_RTC_ClockInit();
}
/*******************************************************************************
*函数名称 : _cbCallbackRTC
*功能描述 : 回调函数
*输入参数 : *pMsg 消息指针变量
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
static void _cbCallbackRTC( WM_MESSAGE * pMsg )
{
int NCode, Id;
WM_HWIN hWin = pMsg->hWin;
GUI_RECT rRTC = {18, 28+79, 294+18-1, 294+28+79-1};
switch ( pMsg->MsgId )
{
case WM_PRE_PAINT: // WM_PAINT 消息发出前,WM 将此消息发送到窗口
/*--------------------------------------------------------------
一般的内存设备动画函数不使用多重缓冲。但在某些情况下,启用多个缓冲区是有意义的。
如果启用动画函数在显示器上绘制内存设备之前 / 之后使用 GUI_MULTIBUF_Begin() 和
GUI_MULTIBUF_Begin()。
-----------------------------------------------------------------*/
GUI_MULTIBUF_Begin();
break;
case WM_PAINT:
{
GUI_SetBkColor( GUI_BLACK );
GUI_Clear();
StreamBitmapDisp( "0:/ICON/Clock_Icon/bk_blue2.dta", 0, 0 ); // 背景
Clock_DrawDisp(); // 更新时钟表盘
break;
}
case WM_POST_PAINT: // WM_PAINT 消息处理后,WM 立即将此消息发送到窗口
/*--------------------------------------------------------------
一般的内存设备动画函数不使用多重缓冲。但在某些情况下,启用多个缓冲区是有意义的。
如果启用动画函数在显示器上绘制内存设备之前 / 之后使用 GUI_MULTIBUF_Begin() 和
GUI_MULTIBUF_Begin()。
-----------------------------------------------------------------*/
GUI_MULTIBUF_End();
break;
case WM_TIMER: // 定时1ms更新一次时间
WM_InvalidateRect( hWin, &rRTC ); // 使窗口的指定矩形区域无效
Clock_Update( pMsg ); // 更新时间
WM_RestartTimer( pMsg->Data.v, 1000 ); // 重新启动定时器
break;
case WM_INIT_DIALOG:
InitDialogRTC( pMsg ); // 时钟对话框回调函数中的初始化消息
break;
case WM_KEY:
switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key )
{
case GUI_KEY_ESCAPE:
GUI_EndDialog( hWin, 1 );
break;
case GUI_KEY_ENTER:
GUI_EndDialog( hWin, 0 );
break;
}
break;
case WM_NOTIFY_PARENT:
Id = WM_GetId( pMsg->hWinSrc );
NCode = pMsg->Data.v;
switch ( Id )
{
case ID_BUTTON_0: // "返回"按钮,此例子未使用
switch( NCode )
{
case WM_NOTIFICATION_CLICKED:
//GUI_EndDialog( hWin, 0);
break;
}
break;
case ID_BUTTON_1: // "时间设置"
switch( NCode )
{
case WM_NOTIFICATION_CLICKED:
App_SetTimeAlarm(); // 创建设置时间/闹钟对话框
break;
}
break;
}
break;
default:
WM_DefaultProc( pMsg );
}
}
/*******************************************************************************
*函数名称 : MainTask_Calendar01
*功能描述 : 时钟GUI主函数
*输入参数 : 无
*输出参数 : 无
*返 回 值 : 无
-------------------------------------------------------------------------------*/
void MainTask_Calendar01(void)
{
GUI_CURSOR_Show();
GUI_SetBkColor( GUI_BLACK );
GUI_Clear();
// 创建时钟对话框
GUI_CreateDialogBox( _aDialogCreateRTC, GUI_COUNTOF(_aDialogCreateRTC), &_cbCallbackRTC, 0, 0, 0 );
while(1)
{
GUI_Delay(10);
}
}