GDI+模拟电子时钟全解析
2012-09-20 17:55
204 查看
模拟时钟 要求如下: 1. 修改窗体形状为圆形 2. 提供时针、分针、秒针,并且每秒都要重新绘制它们以显示在合适的位置 3. 能用鼠标左键拖动窗体来移动模拟时钟的位置 目的: 1、熟悉Pen、Brush、Color、Font、Bitmap等对象的常用属性和方法 2、掌握Graphics对象的常用绘图方法 先上个效果图,再慢慢详解。
首先制作圆形窗体,先用绘图工具绘出一张圆形的图,中间填充色,背景色为白色, 然后设置WinForm窗体选择窗体,找到BackgroundImage属性,点击打开新的窗口,选择下面的导入资源文件,选择你的不规则的BMP图片, 找到窗体的TansparencyKey,将它设置为你背景图片的背景色(白色色) 找到窗体的FormBorderStyle,将其设置为none,即不显示标题栏。 这个时候显示的是一个圆形的窗体,但是实际上不是圆形的,只是其他的边角被隐藏了,还需要通过this.Region=new Region(GraphicPath gpath)裁剪一下,这样才是真正你要的形状,在下边的代码中会详细介绍。 这是开始涉及具体的编写: private Thread timeThread;声明一个线程,不断的对页面进行重绘 private Point mouseOffset;定义鼠标的位置 private float r;定义所绘表盘的半径 private PointF center;定义中心点 private bool isMouseDown = false;标记鼠标是否按下 private Graphics g = null; 实现窗体的拖拽、移动:主要涉及了Mouse_Move ,Mouse_Down ,Mouse_Up事件,一一介绍: /// <summary> /// 鼠标按下事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form2_MouseDown(object sender, MouseEventArgs e) { int x, y; if (e.Button == MouseButtons.Left) { x = -e.X - SystemInformation.FrameBorderSize.Width; //ystemInformation.FrameBorderSize.Width获取正在拖动调整大小窗口周围绘制的大小调整边框的粗细水平分量 y = -e.Y - SystemInformation.FrameBorderSize.Height - SystemInformation.CaptionHeight; //SystemInformation.CaptionHeight 获取窗口的标准标题栏区域的高度 mouseOffset = new Point(x, y); isMouseDown = true; } } /// <summary> ///鼠标移动事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form2_MouseMove(object sender, MouseEventArgs e) { if (isMouseDown) { Point mPoint = Control.MousePosition; //获取鼠标光标的位置 mPoint.Offset(mouseOffset.X, mouseOffset.Y); //设定鼠标平移指定量 Location = mPoint; } } /// <summary> /// 鼠标抬起事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form2_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { isMouseDown = false; } } 至此就可以使用拖拉、移动。 结接下来就是主要实现表盘、指针的绘制和移动 //重写绘图事件 protected override void OnPaint(PaintEventArgs e) { g = e.Graphics; g.SmoothingMode = SmoothingMode.HighQuality; //高质呈现画面 //绘制出一个圆弧(这里是一个圆) g.DrawArc(new Pen(Color.Black, 0.5f), new RectangleF(center.X - r, center.Y - r, 2 * r - 3, 2 * r - 3), 0, 360); GraphicsPath round = new GraphicsPath(); //向当前图像追加一段圆弧 round.AddArc(new RectangleF(center.X - r, center.Y - r, 2 * r - 3, 2 * r - 3), 0, 360); Region = new Region(round);//用上边所画的图形创建一个区域(相当于将多余的区域裁剪) for (int i = 0; i < 59; i++) { g.ResetTransform(); //重置为单位矩阵 g.TranslateTransform(center.X, center.Y); // 通过左乘指定的平移来更改系统的坐标原点 g.RotateTransform(i*6); //旋转 ,每一秒旋转6度 if((i==0)||(i%5==4))//绘制表盘的刻度 { g.DrawLine(new Pen(Color.Black,2.5f),r-12,0,r-5,0); //小时标准刻度 } else { g.DrawLine(new Pen (Color.Black,0.5f),r-6,0,r-5,0);//分钟标准刻度 } } float hour, minute, second; hour = DateTime.Now.Hour; minute = DateTime.Now.Minute; second = DateTime.Now.Second; hour = hour + minute / 60f + second / 3600f; minute = minute + second / 60f; g.ResetTransform(); g.TranslateTransform(center.X, center.Y);//画时针 g.RotateTransform(hour * 30 + 270 - 6); g.DrawLine(new Pen(Color.Black,2.5f),0,0,r*0.5f,0f); //绘出时针 g.ResetTransform();//画分针 ,坐标系恢复到默认状态,Graphics对象回到默认坐标系中绘图。 g.TranslateTransform(center.X,center.Y);//通过左乘指定的平移来更改系统的坐标原点 g.RotateTransform(minute*6+270-6); g.DrawLine(new Pen(Color.Black,1.5f),0,0,r*0.6f,0f); g.ResetTransform();//画秒针 g.TranslateTransform(center.X,center.Y); g.RotateTransform(second * 6 + 270 - 6); g.DrawLine(new Pen(Color.Black,0.5f),0,0,r*0.7f,0f);//绘出秒针 base.OnPaint(e); } 最后写下线程执行函数,实现页面的不断重绘: private void DrawTime() { while (true) { Invalidate();//重绘整个画面 Thread.Sleep(950); } }
相关文章推荐
- C# GDI+模拟时钟全解析
- C++时钟类 模拟电子时钟 设置时间后可自动更新时间
- 立此存照(22)[C++]模拟电子时钟的小程序
- MFC和GDI+开发电子时钟小程序
- 控制台模拟电子时钟
- 一个小型的电子时钟模拟程序
- tomcat模拟域名解析
- 基于DS1302芯片---使用51单片机C语言编制的电子时钟(液晶1602显示)
- PMP模拟试题与解析(九)
- [小插曲]VC学习——基于MFC的模拟时钟程序
- 编程能力强化(4)——模拟SQL语句解析
- Python模拟Web Fetion登录解析
- css代码模拟时钟 +js对时
- 模拟电子表的功能
- scoped _ptr的模拟实现与解析
- 解析stm32的时钟
- 模拟时钟
- 模拟电子技术18 32------——放大电路 动态分析 静态工作点稳定---直流电流负反馈 实例题目 戴维南+估计法
- [转载]YS18-3荧光管电子时钟100%开源放送(软件源工程及代码.硬件原理图)
- [SilverLight1.1入门] Getting started:模拟时钟