c语言 表盘指针旋转,请教下,表盘指针图片旋转 ??

该博客介绍了如何在嵌入式系统中实现时钟的实时显示和动画效果。通过GUI库EMWin,创建内存设备并进行旋转、复制等操作,动态更新时钟指针的位置,同时展示了对话框的创建、回调函数的编写以及按键事件的处理。文章还涉及到内存管理、定时器更新以及背景图片的显示。
摘要由CSDN通过智能技术生成

, 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);

}

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值