搜索
bottom↓
回复: 21

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

[复制链接]

出0入0汤圆

发表于 2018-5-29 09:31:58 | 显示全部楼层 |阅读模式
本帖最后由 hpdell 于 2018-5-29 11:08 编辑

请教下,使用 GUI_MEMDEV_Rotate 旋转显示表盘指针图片 ?
使用函数 GUI_MEMDEV_Rotate ,图片旋转始终都是以图片的中心为基准的,有没有什么方法可以改一下啊 ?

另外,指针图片是不是需要做成 镜像的图片 ,吧镜像部分搞成透明 ??????

效果如下:









显示代码如下:

void GUI_MEMDEV_ColckRotaeShow(void)
{
        int      t0;   // 用于三个指针的计数
        int      t1;
        int      t2;

        GUI_MEMDEV_Select(hMemDest);
        GUI_MEMDEV_Write  (hMemLcd);  //将给定存储设备的内容写入当前选定的存储设备中,

        GUI_MEMDEV_Rotate(hMemSourceBk,
                                                hMemDest,
                                                0,  //      显示地址由 hMemDest、hMemLcd 决定
                                                0,  //      显示地址由 hMemDest、hMemLcd 决定
                                                0,  //      因为显示表盘不需要旋转,所以此次的值为0
                                                1000);

        // 第一个指针计数,用于旋转秒针
        t0 = 360 - (RotateSecond * 6);

        // 第二个指针计数,用于旋转分针
        t1 = 360 - (RotateMinute *6) -(RotateSecond /10);  //秒针每移动10秒,分钟移动的角度为1度
                                                               
       
  /*
           把小时 sTime.Hours%12是吧24小时制式sTime.Hours转化为12小时制,*30(因为小时时针每小时运行30度),
                 ((sTime.Minutes /10)*6) 这句是分钟每移动10分钟,小时时针移动 6度
        */
        t2 = 360 - (((RotateHour)%12) * 30) - ((RotateMinute /10)*6);


        GUI_MEMDEV_RotateHQ(hMemHour,
                                                hMemDest,
                                                100+56, // (RectDest.x1 - RectSource.x1) / 2,
                                                83,  //(RectDest.y1 - RectSource.y1) / 2,
                                                t2 * 1000,
                                                1000);



        GUI_MEMDEV_RotateHQ(hMemMinute,
                                                hMemDest,
                                                100+56, // (RectDest.x1 - RectSource.x1) / 2,
                                                43,  //(RectDest.y1 - RectSource.y1) / 2,
                                                t1 * 1000,
                                                1000);


        GUI_MEMDEV_RotateHQ(hMemSecond,
                                                hMemDest,
                                                100+59, // (RectDest.x1 - RectSource.x1) / 2,
                                                174/4+32,  //(RectDest.y1 - RectSource.y1) / 2,
                                                t0 * 1000,
                                                1000);



        GUI_MEMDEV_Select(0);                                                                                 
        GUI_MULTIBUF_Begin();                                                                                 
        GUI_MEMDEV_CopyToLCD            (hMemDest);                                                                                 
        GUI_MULTIBUF_End();

        RotateSecond ++;

        if(RotateSecond >= 60)
        {
                RotateSecond = 0;
                RotateMinute++;
                if(RotateMinute >= 60)
                {
                        RotateMinute =0;
                        RotateHour++;
                        if(RotateHour >= 24)
                        {
                                RotateHour=0;
                        }
                }
        }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出30入54汤圆

发表于 2018-5-29 09:38:51 | 显示全部楼层
那就旋转再加上位移呗,拿公式算一下,要么就把图片变成以孔为中心

出130入20汤圆

发表于 2018-5-29 09:50:55 | 显示全部楼层
emwin贴图做表盘指针?挺好看的

出0入0汤圆

 楼主| 发表于 2018-5-29 10:52:48 | 显示全部楼层
cloudboy 发表于 2018-5-29 09:38
那就旋转再加上位移呗,拿公式算一下,要么就把图片变成以孔为中心

不管怎么移位,他都以图片中心旋转的,

出0入0汤圆

 楼主| 发表于 2018-5-29 10:55:22 | 显示全部楼层
shuiluo2 发表于 2018-5-29 09:50
emwin贴图做表盘指针?挺好看的

多谢多谢啊,有什么解决的好方法没有啊 ?

出0入0汤圆

发表于 2018-5-29 11:23:29 来自手机 | 显示全部楼层
flash可以调整图片旋转中心点,这个只能改图了

出0入0汤圆

 楼主| 发表于 2018-5-29 13:06:09 | 显示全部楼层
xs2010 发表于 2018-5-29 11:23
flash可以调整图片旋转中心点,这个只能改图了

如果实在没有好的办法,只能重新做 指针图片了啊

出130入20汤圆

发表于 2018-5-29 13:46:05 | 显示全部楼层
hpdell 发表于 2018-5-29 10:55
多谢多谢啊,有什么解决的好方法没有啊 ?

应该是只能做图片了

出0入0汤圆

发表于 2018-5-29 14:18:11 | 显示全部楼层
最简单的,是楼主说的增加透明区域。

出0入0汤圆

 楼主| 发表于 2018-5-29 14:44:22 | 显示全部楼层
styleno1 发表于 2018-5-29 14:18
最简单的,是楼主说的增加透明区域。


刚刚改了一下图片,现在貌似可以了










目前看来只能这样解决了

如果以后谁有更好的办法 就告诉我一下啊



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2018-12-18 11:28:50 | 显示全部楼层
怎么解决的,可以分享一下代码吗,谢谢

出0入0汤圆

发表于 2018-12-20 12:28:40 来自手机 | 显示全部楼层
楼上的,小心id不保啊

出0入0汤圆

 楼主| 发表于 2018-12-20 12:28:57 | 显示全部楼层
tongtong2009999 发表于 2018-12-18 11:28
怎么解决的,可以分享一下代码吗,谢谢


你好,最终修改了图片,

代码如下:

// 使用 流位图显示
//app图标描述结构体
typedef struct{
        const char         *pFileNamePath;   // 图标文件名路径
       
} CLOCK_BITMAP_ITEM_STREAM;

/*
流数据取数据说明如下:
1. 先准备好需要的图标图片,*.bmp,*.png格式的,必须带透明通道的图片
2. 使用 st 提供的工具软件 BmpCvtST.exe (版本v532或v5.40都行) 打开已准备好的图片
3. 打开后什么也不修改直接 点击 Files->Save as ... 选择 *.dta 格式 按保存
4. a: 如果选择 True color with alpha  格式保存的,是按照 每个像素 4 字节取码的 +16Byte
   b: 如果选择 High color with Alpha(565) 格式保存的,是按照 rgb565格式保存,另外还多了一个字节的透明通道数据
      实际是按照 3字节保存数据 +16Byte
5. 比如一个图片像素为 96*96,那么按照 565格式取码后的大小为 96*3*96+16大小
*/
static const CLOCK_BITMAP_ITEM_STREAM ClockStreamBitmapItemTab1[]={
// 图片旋转 只支持 argb8888 格式,切记切记
        "0:ClockSrteam/dta_ARGB8888/omega_367x332_SourceFile_ARGB8888.dta",
        "0:ClockSrteam/dta_ARGB8888/HourCen_ARGB8888.dta",        
        "0:ClockSrteam/dta_ARGB8888/MinuteCen_ARGB8888.dta",   
        "0:ClockSrteam/dta_ARGB8888/SecondCen_ARGB8888.dta",        
};


typedef struct
{
        const int xSize;
        const int ySize;
}  _ClockPosStreamTypeDef;

const _ClockPosStreamTypeDef  _ClockPosStream[]={

        367, 332,
        23,  166,
        25,  244,
        17,  268
};

typedef struct
{
        GUI_MEMDEV_Handle hMem1_Clock[4];      // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
        GUI_MEMDEV_Handle hMem1_ClockDest;    // 目标内存
        GUI_MEMDEV_Handle hMem1_ClockLcd;     // 显示内存
       
        GUI_BITMAP       Bitmap[4];  // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
        GUI_LOGPALETTE   Palette[4];

        uint8_t  *_acComBuff ;
        uint8_t  *_acClockBuf[4] ;   // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针

} _ClockPramTypeDef;

_ClockPramTypeDef  * _ClockParm = NULL;

#define DEG2RAD_180      (float)((float)3.1415926f / 180)   // 0.0174532924
#define MAG          3

/*
*********************************************************************************************************
*        函 数 名: InitDialogRTC
*        功能说明: 对话框回调函数的初始化消息
*        形    参: pMsg   消息指针变量
*        返 回 值: 无
*********************************************************************************************************
*/
void InitDialogRTC(void)
{
        GUI_MEMDEV_RTC_ClockInit();
}


/*
函数名称:GUI_MEMDEV_RTC_ClockInit
函数功能:初始化内存设备,在GUI_Init 之后调用也可以在 WM_INIT_DIALOG 这个里面调用一次
          初始化只执行一次即可
参数:无
返回值:无

*/
static void GUI_MEMDEV_RTC_ClockInit(void)
{
        FIL  CLOCK_File;
        FRESULT result;
        UINT bw;       
        int  i=0;
       
  if (BSP_SD_IsDetected() != SD_PRESENT)
  {
    printf((const char *)"RTC SD 卡不存在,请插入 ... ... ?\r\n");
    return ;
  }        
       
        //此内存申请后就不释放了,因为程序一直在运行
        _ClockParm = (_ClockPramTypeDef *)mymalloc(SRAMEX, sizeof(_ClockPramTypeDef) );   //SRAMDTCM
       
        for(i=0;i<4;i++)
        {
                        result = f_open(&CLOCK_File, ClockStreamBitmapItemTab1.pFileNamePath,  FA_READ );
                        if (result != FR_OK)
                        {
                                printf("open file fail %d\n",result );
                                myfree(SRAMEX,(void *) _ClockParm);
                                return;
                        }
                        _ClockParm->_acClockBuf = GUI_MYmalloc(CLOCK_File.obj.objsize );
                        _ClockParm->_acComBuff   = _ClockParm->_acClockBuf;       
                        result = f_read(&CLOCK_File, _ClockParm->_acComBuff, CLOCK_File.obj.objsize, &bw);
                        if (result != FR_OK)
                        {
                                __IO int cc;
                                for(cc=0;cc<i;cc++)
                                {
                                        _ClockParm->_acComBuff   = _ClockParm->_acClockBuf[cc];
                                        GUI_MYfree((void *) _ClockParm->_acComBuff);                 //使用完后释放内存       
                                }
                                f_close(&CLOCK_File);
                                myfree(SRAMEX,(void *) _ClockParm);
                                return ;
                        }
                        f_close(&CLOCK_File);       
        }
       
        for(i=0;i<4;i++)
        {
                // 适用与 emwin  > v5.32 argb / abgr 库 版本
                // 显示表盘背景,  在单片机上绘制 32bit BMP 图片数据文件,必须使用GUI_MEMDEV_CreateFixed32 这个函数
                        // 图片旋转只支持 32bit 格式的图片,切记切记   2018.06.14   21:10
                _ClockParm->hMem1_Clock = GUI_MEMDEV_CreateFixed32(0,   //创建具有 32bpp 颜色深度和 GUICC_8888 颜色转换的内存设备
                                                                                                                                                                                                                          0,
                                                                                                                                                _ClockPosStream.xSize,
                                                                                                                                                _ClockPosStream.ySize );       

                GUI_MEMDEV_Select(_ClockParm->hMem1_Clock);
                _ClockParm->_acComBuff   = _ClockParm->_acClockBuf;
                GUI_SetBkColor(GUI_TRANSPARENT );   //清除背景色 0xFFC0C0C0  GUI_TRANSPARENT
                GUI_Clear();       
                GUI_CreateBitmapFromStream(&_ClockParm->Bitmap, &_ClockParm->Palette, _ClockParm->_acComBuff);
                GUI_DrawBitmap(&_ClockParm->Bitmap, 0, 0);                       
        }
       
        _ClockParm->hMem1_ClockDest = GUI_MEMDEV_CreateFixed32(  1024-367,   //最终显示的 x 地址
                                                                                                                                                                                                                                        24,                                               //最终显示的 y 地址
                                                                                                                                                _ClockPosStream[0].xSize,           //与显示最大表盘尺寸宽度一致即可
                                                                                                                                                _ClockPosStream[0].ySize );  

        _ClockParm->hMem1_ClockLcd = GUI_MEMDEV_CreateFixed32(   1024-367,   //最终显示的 x 地址
                                                                                                                                                                                                                                        24,                                                //最终显示的 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;
                GUI_MYfree((void *) _ClockParm->_acComBuff);                 //使用完后释放内存       
        }
//        myfree(SRAMEX,(void *) _ClockParm);  //这个 _ClockParm 参数不能够释放,因为程序一直在运行
       
        /* 配置回之前选择的目标窗口 */
//        WM_SelectWindow(hWinOld);       
}


/*
*********************************************************************************************************
*        函 数 名: Clock_DrawDisp
*        功能说明: 更新时钟表盘
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void Clock_DrawDisp(WM_MESSAGE * pMsg)
{
        int      t0;   // 用于三个指针的计数
        int      t1;
        int      t2;
        char buf[30];
       
        WM_HWIN hWin = pMsg->hWin;
       
        // Get the RTC current Time
        HAL_RTC_GetTime(&RtcHandle, &sTime, RTC_FORMAT_BIN);           // 时间与日期需要同时获取,切记切记,
        // Get the RTC current Date                                                                                             
        HAL_RTC_GetDate(&RtcHandle, &sDate, RTC_FORMAT_BIN);       
       
        t0 = 360 - (sTime.Seconds * 6);    // 第一个指针计数,用于旋转秒针

        // 第二个指针计数,用于旋转分针
        t1 = 360 - (sTime.Minutes *6) -(sTime.Seconds /10);  //秒针每移动10秒,分钟移动的角度为1度

  /*
           把小时 sTime.Hours%12是吧24小时制式sTime.Hours转化为12小时制,*30(因为小时时针每小时运行30度),
                 ((sTime.Minutes /10)*5) 这句是分钟每移动10分钟,小时时针移动 5度
        */
        t2 = 360 - (((sTime.Hours)%12) * 30) - ((sTime.Minutes /10)*5);       
               

        GUI_MEMDEV_Select(_ClockParm->hMem1_ClockDest);
        GUI_MEMDEV_Write  (_ClockParm->hMem1_ClockLcd);  //将给定存储设备的内容写入当前选定的存储设备中,
                                                  //即hMem1_ClockLcd -> hMem1_ClockDest

        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,
                                                157, // 显示时针计算方法,表盘的中心x坐标-时针的中心x坐标,偏移量
                                                                                              //已经在创建时设定好的,也就是以创建时的坐标为基准
                                                83,  
                                                t2 * 1000,
                                                1000);

        GUI_MEMDEV_Rotate(_ClockParm->hMem1_Clock[2],
                                                _ClockParm->hMem1_ClockDest,
                                                156,  
                                                44,   
                                                t1 * 1000,
                                                1000);

        GUI_MEMDEV_Rotate(_ClockParm->hMem1_Clock[3],
                                                _ClockParm->hMem1_ClockDest,
                                                161,
                                                32 ,  
                                                t0 * 1000,
                                                1000);

        GUI_MEMDEV_Select(0);                                                                                 
        GUI_MULTIBUF_Begin();                                                                                 
        GUI_MEMDEV_CopyToLCD            (_ClockParm->hMem1_ClockDest);                //将内容显示到 LCD 屏幕上                                                                 
        GUI_MULTIBUF_End();

        /* 更新 表盘里面的 星期  */
        sprintf(buf,
              "%s",
                    RtcWeek[sDate.WeekDay]);       
        TEXT_SetText(WM_GetDialogItem(hWin, GUI_ID_TEXT2), buf);

        /* 更新 表盘里面的 日期  */
        sprintf(buf,
              "%s",
                    apDaysRiQi[sDate.Date-1]);       
        TEXT_SetText(WM_GetDialogItem(hWin, GUI_ID_TEXT3), buf);       
       
       
}

出0入0汤圆

 楼主| 发表于 2018-12-20 12:30:02 | 显示全部楼层
st8051 发表于 2018-12-20 12:28
楼上的,小心id不保啊

刚刚删除了,以重新发布了

出0入0汤圆

发表于 2018-12-21 15:21:04 | 显示全部楼层
ICONVIEW图标可以选择吗

出0入0汤圆

发表于 2018-12-21 15:21:37 | 显示全部楼层
C:\Users\Administrator\Desktop\新建文件夹

出0入0汤圆

发表于 2018-12-21 16:42:31 | 显示全部楼层
C:\Users\Administrator\Desktop\新建文件夹\1

怎么旋转emwin 指针图标。。。。。。

出0入0汤圆

发表于 2020-6-21 17:34:35 | 显示全部楼层
hpdell 发表于 2018-12-20 12:28
你好,最终修改了图片,

代码如下:

我也遇到同样的问题,谢谢,分享代码

出0入0汤圆

 楼主| 发表于 2020-6-21 19:54:42 | 显示全部楼层
本帖最后由 hpdell 于 2020-6-21 20:03 编辑
lyshlrzh8888 发表于 2020-6-21 17:34
我也遇到同样的问题,谢谢,分享代码


13 漏的代码就是啊,

如果你的还是不能够旋转,估计是你的其他代码有问题吧

表针旋转时,是以表针的中心位置开始,不用人为的设置,

比如 你的 表示 x=20, y=210, 那么旋转 会自动以 x/2, y/2 为中心旋转的,




以这个图片为例,表针的圆孔为整个表针的 中心位置并延伸至表针的的中心孔一样的长度,并做成透明色即可



这个表针时带透明通道的,使用 BmpCvtST v5.44.exe 这个软件查看比较清楚
你们看看这个表针就明白了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2020-6-21 21:50:12 来自手机 | 显示全部楼层
学习了,谢谢分享经验

出0入0汤圆

发表于 2020-6-24 10:19:39 | 显示全部楼层
hpdell 发表于 2020-6-21 19:54
13 漏的代码就是啊,

如果你的还是不能够旋转,估计是你的其他代码有问题吧

13楼的代码缺少数组下标,我改了如下帮我看看,我的表针显示透明部分为黑色
/*-------- 使用 流位图显示, app图标描述结构体 --------------*/

typedef struct
{
        const char        *pFileNamePath;   // 图标文件名路径
        
} CLOCK_BITMAP_ITEM_STREAM;

/*-----------------------------------------------------------
流数据取数据说明如下:
        1. 先准备好需要的图标图片,*.bmp,*.png格式的,必须带透明通道的图片
        2. 使用 st 提供的工具软件 BmpCvtST.exe (版本v532或v5.40都行) 打开已准备好的图片
        3. 打开后什么也不修改直接 点击 Files->Save as ... 选择 *.dta 格式 按保存
        4. a: 如果选择 True color with alpha  格式保存的,是按照 每个像素 4 字节取码的 +16Byte
    b: 如果选择 High color with Alpha(565) 格式保存的,是按照 rgb565格式保存,另外还多了一个字节的透明通道数据 实际是按照 3字节保存数据 +16Byte
        5. 比如一个图片像素为 96*96,那么按照 565格式取码后的大小为 96*3*96+16大小
-----------------------------------------------------------*/
static const CLOCK_BITMAP_ITEM_STREAM ClockStreamBitmapItemTab1[]=
{
        // 图片旋转 只支持 ARGB8888 格式,切记切记
        "0:/ICON/Clock_Icon/ARGB8888/ClockFace_294.dta",
        "0:/ICON/Clock_Icon/ARGB8888/ClockHour_30_74.dta",        
        "0:/ICON/Clock_Icon/ARGB8888/ClockMinute_18_115.dta",   
        "0:/ICON/Clock_Icon/ARGB8888/ClockSecond_10_156.dta",         
};

typedef struct
{
         const int xSize;
         const int ySize;
       
}_ClockPosStreamTypeDef;

const _ClockPosStreamTypeDef  _ClockPosStream[]=
{
        294, 294,
        30,  74,
        18,  115,
        10,  156
};

typedef struct
{
        GUI_MEMDEV_Handle         hMem1_Clock[4];     // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
        GUI_MEMDEV_Handle         hMem1_ClockDest;    // 目标内存
        GUI_MEMDEV_Handle         hMem1_ClockLcd;     // 显示内存

        GUI_BITMAP               Bitmap[4];                  // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
        GUI_LOGPALETTE           Palette[4];

        uint8_t  *_acComBuff ;
        uint8_t  *_acClockBuf[4] ;                           // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针

} _ClockPramTypeDef;

_ClockPramTypeDef  * _ClockParm = NULL;

/*-------------- 星期的显示 ---------------------*/

static const char *ucWeekDay[7] =
{
        "一",
        "二",
        "三",
        "四",
        "五",
        "六",
        "日"
};

/*******************************************************************************
*函数名称        : GUI_MEMDEV_RTC_ClockInit
*功能描述        : 初始化内存设备,在GUI_Init()之后调用, 也可以在 WM_INIT_DIALOG 这个里面调用一次, 初始化只执行一次即可
*输入参数        : 无
*输出参数        : 无
*返 回 值        : 无
-------------------------------------------------------------------------------*/
static void GUI_MEMDEV_RTC_ClockInit(void)
{
        FIL                        CLOCK_File;
        FRESULT         result;
        UINT                 bw;        
        int                  i = 0;

        // 此内存申请后就不释放了,因为程序一直在运行
        _ClockParm = (_ClockPramTypeDef *)myMalloc( SRAMEX, sizeof(_ClockPramTypeDef));   // SRAMDTCM

        for( i=0; i<4; i++ )
        {
                result = f_open( &CLOCK_File, ClockStreamBitmapItemTab1.pFileNamePath, FA_READ );
                if ( result != FR_OK )
                {
                        printf("open file fail %d\n", result );
                        myFree( SRAMEX,(void *) _ClockParm );
                        return;
                }
                _ClockParm->_acClockBuf = myMalloc( SRAMEX, CLOCK_File.obj.objsize );
                _ClockParm->_acComBuff   = _ClockParm->_acClockBuf;        
                result = f_read( &CLOCK_File, _ClockParm->_acComBuff, CLOCK_File.obj.objsize, &bw );
                if ( result != FR_OK )
                {
                        __IO int cc;
                        for( cc=0; cc<i; cc++ )
                        {
                                _ClockParm->_acComBuff   = _ClockParm->_acClockBuf[cc];
                                myFree( SRAMEX, (void *) _ClockParm->_acComBuff );                 // 使用完后释放内存        
                        }
                        f_close( &CLOCK_File );
                        myFree( SRAMEX, (void *) _ClockParm );
                        return ;
                }
                f_close( &CLOCK_File );        
        }

        for( i=0; i<4; i++ )
        {
                // 适用与 emwin  > v5.32 ARGB / ABGR 库 版本
                // 显示表盘背景,  在单片机上绘制 32bit BMP 图片数据文件,必须使用 GUI_MEMDEV_CreateFixed32 这个函数
                // 图片旋转只支持 32bit 格式的图片,切记切记   2018.06.14   21:10
                _ClockParm->hMem1_Clock = GUI_MEMDEV_CreateFixed32( 0,   // 创建具有 32bpp 颜色深度和 GUICC_8888 颜色转换的内存设备
                                                                                                                                0,
                                                                                                                                _ClockPosStream.xSize,
                                                                                                                                _ClockPosStream.ySize );        

                GUI_MEMDEV_Select( _ClockParm->hMem1_Clock);
                _ClockParm->_acComBuff = _ClockParm->_acClockBuf;
               
//                GUI_SetBkColor( GUI_TRANSPARENT );   // 清除背景色 0xFFC0C0C0  GUI_TRANSPARENT
//                GUI_Clear();
        
                GUI_CreateBitmapFromStream( &_ClockParm->Bitmap, &_ClockParm->Palette, _ClockParm->_acComBuff );
                GUI_DrawBitmap( &_ClockParm->Bitmap, 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);
        }
}

出0入0汤圆

 楼主| 发表于 2020-6-24 17:12:49 | 显示全部楼层
lyshlrzh8888 发表于 2020-6-24 10:19
13楼的代码缺少数组下标,我改了如下帮我看看,我的表针显示透明部分为黑色
/*-------- 使用 流位图显示, ...

//                GUI_SetBkColor( GUI_TRANSPARENT );   // 清除背景色 0xFFC0C0C0  GUI_TRANSPARENT
//                GUI_Clear();
        
这个不能够屏蔽
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 18:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表