前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数字时钟

数字时钟

作者头像
DeROy
发布2020-05-11 17:49:05
1.6K0
发布2020-05-11 17:49:05
举报
文章被收录于专栏:编程学习基地编程学习基地

数字时钟

前言

数字时钟程序,制作的出发点是因为参考程序太简单了,又想起了一个抖音挺火的数字时钟,后就开始创作这个小程序,这个数字时钟程序我也不是凭空捏造出来的,我参考的是一个windows小程序,也是时钟例子,绘制一个时分秒的时钟样式。

本期的文章就介绍下数字时钟的制作过程,介绍的内容还是以未加缓存和动画的制作过程为主

后台回复关键字【数字时钟】获取更新之后的源程序和源代码,还有我参考的时钟程序

01

win32框架

首先呢,我还是用的上周发送的win32框架代码,在此基础上进行代码的添加操作

详情过程参照上周推送:

初识win32

正片开始

代码语言:javascript
复制

那么正片从现在开始,利用win32的GDI操作绘制抖音热门项目

数字时钟

02

绘制数字时钟

在上周的,我已经讲述了如何利用windows的API对窗口进行移动和追加菜单并对菜单功能进行实现,以及定时器的开启和使用。

开启了定时器之后,在WM_TIMER消息处进行时钟的绘制

在绘制之前我们需要了解下字体,因为数字时钟利用的是字体的旋转

我封装了一个绘制旋转 n° 的函数,函数如下

代码语言:javascript
复制
//绘制倾斜字体
void DrawText(HDC hdc, int x, int y, int org, wchar_t szText[])
{
  SetTextAlign(hdc, TA_BOTTOM | TA_LEFT);  //修改锚点
  HFONT ft = nullptr;            //字体句柄
  ft = CreateFont(0, 0, org * 10, 0, 100, false, false, false, GB2312_CHARSET, 0, 0, 0, 0, NULL);
  SelectObject(hdc, ft);
  TextOut(hdc, x, y, szText, wcslen(szText));
  DeleteObject(ft);
}

在这里我们需要创建一个旋转 n° 的字体,创建规则如下

代码语言:javascript
复制
hdc = GetDC(hWnd);
//默认系统字体 
HFONT ft = nullptr;    //字体句柄
ft = CreateFont(0,    //字符的高度,如果给0,按默认高度来设置
                0,    //字符的宽度,如果给0,按高度横纵比来匹配宽度
                0,    //文字的倾斜角度,10表示1度
                0,    //基线的倾斜角度
                100,  //字体的粗细,取值0-900,400以下为细体,700以上为粗体
                false,//斜体,取值false,true
                false,//下划线,取值false,true
                false,//水平线,取值false,true
                GB2312_CHARSET,//字符集
                0,//输出精度
                0,//裁剪精度
                0,//字体的输出质量
                0,//字体的间距和系列
                NULL);//字样名
SelectObject(hdc, ft);

将旋转角度设置成函数参数,从而控制字体的旋转角度,然而在我封装的那段函数里面有修改锚点操作,这是为什么呢

如果不进行该操作的话,字体旋转的锚点在左上角,旋转得到的字体不是预期的,对制作360°旋转的数字时钟达不到效果,我们需要设置锚点为左下角

就这样封装好一个可以在某个DC的x,y位置上绘制倾斜角度为org的字符串szText,这样我们就准备好了绘制数字时钟的基本条件

在WM_TIMER消息内

获取客户区信息

代码语言:javascript
复制

我们首先要得到DC和客户区大小,因为我们需要在窗口上完整的显示数字时钟,这需要数字时钟随客户区的大小改变而改变

代码语言:javascript
复制
    HDC hdc = GetDC(hwnd);
    RECT rt;
    GetClientRect(hwnd, &rt);   //获取客户区大小
    SetBkMode(hdc, TRANSPARENT);//设置文字背景透明

设置坐标轴和坐标原点

代码语言:javascript
复制
    //设置坐标轴
    int cx = rt.right;
    int cy = rt.bottom;
    SetViewportExtEx(hdc, cx, cy, NULL);
    //设置原点
    SetViewportOrgEx(hdc, rt.right / 2, rt.bottom / 2, NULL);

获取系统时间

代码语言:javascript
复制
    //获取系统时间
    wchar_t szTime[100];
    SYSTEMTIME currentTime;
    GetLocalTime(&currentTime);

定义变量

代码语言:javascript
复制
    //定义相关变量
    int i = 0;
    int initOrg = 0;    //定义初始旋转角度
    int minSize = 0;    //数字时钟最小半径
    int date_x = 0;     //时间显示的x坐标

在数字时钟制作过程中我的依据是通过一个圆圈的旋转使得x坐标轴上的时间为系统时间,上述变量中的变量initOrg是月份或者日期的第一个时间点的旋转角度

变量data_x是时间绘制的横向坐标,使得月份,日期,时,分,秒在不同的圆周内

其中minSize控制着data_x,使得数字时钟随客户区的大小改变而改变

确定时钟最小半径

代码语言:javascript
复制
    //确定时钟最小半径
    if (rt.bottom > rt.right)
    {
        minSize = rt.right / 2;
    }
    else
        minSize = rt.bottom / 2;

通过之前得到的客户区大小从而确定数字时钟的最小半径,其实这里定义成最大半径更好理解,不知道为什当时脑袋犯抽写成了最小半径,不想改了

这些准备工作完成之后就是真真的绘制环节

首先绘制年份,要将年份绘制在最中间,在之前已经将坐标原点设置在客户区的中间了,所以我们需要进行的操作就是

绘制年份

代码语言:javascript
复制
    //绘制年
    wsprintf(szTime, L"%d 年", currentTime.wYear);
    DrawText(hdc, -30, 0, 0, szTime);

这个很简单通过将之前获取的时间写入到szTime里面,然后绘制在坐标(-30,0)处

绘制月份

代码语言:javascript
复制
    //绘制月
    i = 1;
    date_x = minSize / 6;
    initOrg = -(currentTime.wMonth * 360 / 12) + 360 / 12;
    for (int org = initOrg; org < initOrg + 360; org += (360 / 12))
    {
        wchar_t tempArr[MAX_PATH];
        double temp = 3.1415926 * 2 * org / 360;
        int x = date_x * cos(temp);
        int y = -date_x * sin(temp);
        wsprintf(tempArr, L"%d", i++);
        DrawText(hdc, x, y, org, tempArr);
    }
    DrawText(hdc, date_x + 20, 0, 0, L"月");

这个月份的绘制就有点东西了啊,用到了数学里面的东西,首先月份是从1月开始,所以初始化i = 1;我将 年、月、日、时、分、秒绘制在6个同心圆处,相当于将minSize 6 等分,使得数字时钟看起来对称又有层次感

然后初始旋转角度initOrg是通过 当前的月份 * 每个月份的度数,至于后面为什么又要加上360/12,也就是30,是因为月份是从1开始的,当currentTime.wMonth = 1;时,初始旋转角度initOrg应该为0,也就是不旋转。

然后就是一个圆的循环,度数org从0增加到360°绘制月份,步长为 360/12 也就是30°,然后就是循环体内确定x,y坐标,就是圆圈上12个点的坐标,这里就是三角关系了,头文件加上math.h,定义变量temp将角度单位转化为弧度制,x,y坐标的计算方法就真的是纯数学了,不懂的可以去问初中数学老师。

后面的代码和这个月份的都是一个样的,CV,然后修改一些变量就可以了,我源代码里面写的还算清楚,可以参考下。

在我给出的百度文件下还有添加了简单动画和缓冲的源代码,有兴趣的可以了解下缓冲。

关键字【数字时钟】


编辑:梦凡

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程学习基地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档