<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了使用C#寫一個時鐘,供大家參考,具體內容如下
時鐘是這樣的
一共使用四個控制元件即可:
WinFrom表單應用程式程式碼:
using SpeechLib; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MyClockTest { public partial class Form1 : Form { //建立物件myclock MyClock myclock = new MyClock(); //定義date1,共電子錶使用 -- 獲取到當下時間點 DateTime date1 = DateTime.Now; //Now 為靜態唯讀屬性(屬性可計算) //定義中心點center和半徑radius -- 時鐘的圓心和半徑大小 Point center = new Point(160, 200); // 圓心點的座標 int radius = 150; // 半徑 150 //定義判定是否擊中表盤的bool變數 -- 滑鼠點選拖拽功能 bool down = false; //記錄滑鼠點選的點 Point pre; //程式入口 public Form1() { InitializeComponent(); } //開始畫時鐘 private void OnPaint(object sender, PaintEventArgs e) { //這裡不使用Graphics,而選擇使用BufferedGraphics: //Graphics和BufferedGraphics對比: //5000次下時Graphics效率高一些;5000次以後BufferedGraphics效率高一些 //Bitmap bmp = new Bitmap(width ,height ); //Graphics g2 = Graphics.FromImage(bmp ); //myclock.Draw(g2); //g2.CreateGraphics(); //g2.DrawImage(bmp,0,0); //bmt.dispose(); //Image iamge = new Bitmap(this.Width ,this .Height ); //Graphics g1 = Graphics.FromImage(iamge); //g1.Clear(Form .DefaultBackColor ); //C#雙緩衝解釋: //簡單說就是當我們在進行畫圖操作時,系統並不是直接把內容呈現到螢幕上,而是先在記憶體中儲存,然後一次性把結果輸出來。 //如果沒用雙緩衝的話,你會發現在畫圖過程中螢幕會閃的很厲害,因為後臺一直在重新整理, //而如果等使用者畫完之後再輸出就不會出現這種情況,具體的做法,其實也就是先建立一個點陣圖物件,然後把內容儲存在裡面,最後把圖呈現出來。 //解決空間重繪時閃爍的問題,並在改變大小時重繪圖形 this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true); //矩形繪圖區域 Rectangle rect = e.ClipRectangle; //關於BufferedGraphicsContext類: // 手工設定雙緩衝.netframework提供了一個類BufferedGraphicsContext負責單獨分配和管理圖形緩衝區。 // 每個應用程式域都有自己的預設 BufferedGraphicsContext 範例來管理此應用程式的所有預設雙緩衝。 // 大多數情況下,每個應用程式只有一個應用程式域,所以每個應用程式通常只有一個預設 BufferedGraphicsContext。 //關於此處的繪圖: //通過管理BufferedGraphicsContext實現雙緩衝的步驟如下: //(1)獲得對 BufferedGraphicsContext 類的範例的參照。 //(2)通過呼叫 BufferedGraphicsContext.Allocate 方法建立 BufferedGraphics 類的範例。 //(3)通過設定 BufferedGraphics.Graphics 屬性將圖形繪製到圖形緩衝區。 //(4)當完成所有圖形緩衝區中的繪製操作時,可呼叫 BufferedGraphics.Render 方法將緩衝區的內容呈現到與該緩衝區關聯的繪圖圖面或者指定的繪圖圖面。 //(5)完成呈現圖形之後,對 BufferedGraphics 範例呼叫釋放系統資源的 Dispose 方法。 BufferedGraphicsContext current = BufferedGraphicsManager.Current; //(1) BufferedGraphics bg; bg = current.Allocate(e.Graphics, e.ClipRectangle); //(2) Graphics g = bg.Graphics; //(3) //定義畫布 //Graphics g = CreateGraphics(); //消除鋸齒 //g.SmoothingMode = SmoothingMode.AntiAlias; g.SmoothingMode = SmoothingMode.HighQuality; //高質量 g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高畫素偏移質量 //每次繪畫後的背景色填充 && 定義畫電子鐘的字型 g.Clear(this.BackColor); Font font = new Font("Times New Roman", 20); //在每次繪畫時,更新時間,半徑及中心點 myclock.Date = DateTime.Now; myclock.Week = DateTime.Now; myclock.P = center; myclock.R = radius; //呼叫myclock中的Draw函數畫出鍾 myclock.Draw(g); //直接呼叫DrawString函數,顯示電子錶,並且設定顯示格式 g.DrawString(date1.ToString(), font, Brushes.Black, 10, 10);//10,10表示字的左上角在哪 bg.Render(e.Graphics); //(4)---> 開啟繪製 bg.Dispose(); //(5)---> 繪製完成,釋放資源 //如果為整點,則報時 if (Convert.ToString(DateTime.Now.Minute) == "0" && Convert.ToString(DateTime.Now.Second ) == "0") { SpVoice voice = new SpVoice(); voice.Speak("現在時間為" + Convert.ToString(DateTime.Now.Month) + "月" + Convert.ToString(DateTime.Now.Day) + "日" + Convert.ToString(DateTime.Now.Hour) + "點" + Convert.ToString(DateTime.Now.Minute) + "分", SpeechVoiceSpeakFlags.SVSFDefault); } } //更新時鐘的時間 private void OnTime(object sender, EventArgs e) { //使用timer控制元件來更新時間 ---> 1s/次 //更新鐘的時間 myclock.Date = DateTime.Now; myclock.Week = DateTime.Now; //更新電子錶的時間 date1 = DateTime.Now; //重新整理 --- 每走動一秒都更新畫布(重繪) Invalidate(); //Refresh(); } //滑鼠單擊到時鐘上的座標 private void Form1_MouseDown(object sender, MouseEventArgs e) { //記錄點選的點,並且計算是否擊中時鐘 -- 記錄點選時的座標 pre = new Point(e.X, e.Y); down = myclock.HitTest(pre, center, radius); } //在點選後,滑鼠拖動時 private void Form1_MouseMove(object sender, MouseEventArgs e) { //使用if來判斷是否擊中,若擊中,更新中心點 Point p = new Point(e.X, e.Y); //如果點選持續 if (down) { //更新圓心座標點 center = new Point(center.X + p.X - pre.X, center.Y + p.Y - pre.Y); //pre = 當前移動的點的座標 pre = p; //重繪 Invalidate(); //Refresh(); } } private void Form1_MouseUp(object sender, MouseEventArgs e) { //取消擊中 -- 拖拽結束 down = false; } private void trackBar1_Scroll(object sender, EventArgs e) { //使用 trackBar1來控制半徑大小,並且更新 ---> trackBar控制元件改變時鐘的大小 radius = trackBar1.Value; Invalidate(); //refresh } //單擊:報時功能 private void button1_Click(object sender, EventArgs e) { DateTime da = new DateTime(); da = DateTime.Now; //SpVoice報時 SpVoice voice = new SpVoice(); voice.Speak("現在時間為" + Convert.ToString(da.Month) + "月" + Convert.ToString(da.Day) + "日" + Convert.ToString(da.Hour) + "點" + Convert.ToString(da.Minute) + "分", SpeechVoiceSpeakFlags.SVSFDefault); } } //初始化時鐘:類應該寫在外面(此處不規範) public class MyClock { enum time { XII, III, VI, IX } //定義結構體 -- 時鐘的4頂點 public DateTime date; //Now 為靜態唯讀{get}屬性(屬性可計算),智慧作為右值 -- 電子錶時間 public DateTime week; // 周 public Point p; // 圓心點的座標 public int r; // 半徑 public MyClock() { //定義一個建構函式,賦予date當前時間 date = DateTime.Now; week = DateTime.Now; p = new Point(160, 200); // 圓心點的座標 r = 150; // 半徑 } //畫表盤 public void DrawDial(Graphics g) { //定義兩個pen,p1用來畫小刻度及錶盤,p2用來畫大刻度 Pen p1 = new Pen(Color.Black, 2); Pen p2 = new Pen(Color.Green, 2); //時鐘頂點時間的字型大小 float f = r / 10; //字型樣式 && 字型大小 Font font = new Font("Times New Roman", f); //定義兩個點陣列來儲存刻度線的兩點 --- [60] 陣列中共存放了60個點的座標 PointF[] pointf1 = new PointF[60]; PointF[] pointf2 = new PointF[60]; // for(int i = 0; i < 59; i++) { //通過for迴圈來給pointf1賦值 ---> f1點就在圓形的邊上,r float x1 = (float)(p.X + r * Math.Sin((i + 1) * Math.PI * 2 / 60)); float y1 = (float)(p.Y + r * Math.Cos((i + 1) * Math.PI * 2 / 60)); pointf1[i] = new PointF(x1, y1); //使用if來判斷,能整除5就畫大刻度,不能就畫小刻度 if ((i + 1) % 5 == 0) { float x2 = (float)(p.X + (r - r / 20) * Math.Sin((i + 1) * 2 * Math.PI / 60)); float y2 = (float)(p.Y + (r - r / 20) * Math.Cos((i + 1) * 2 * Math.PI / 60)); pointf2[i] = new PointF(x2, y2); //畫大刻度 g.DrawLine(p2, pointf1[i], pointf2[i]); } else { float x2 = (float)(p.X + (r - r / 40) * Math.Sin((i + 1) * 2 * Math.PI / 60)); float y2 = (float)(p.Y + (r - r / 40) * Math.Cos((i + 1) * 2 * Math.PI / 60)); pointf2[i] = new PointF(x2, y2); //畫小刻度 g.DrawLine(p2, pointf1[i], pointf2[i]); } } //用pointf3來儲存四個點的位置 錶盤的4個頂點位置 ---> 橫座標 && 縱座標調整距離到合適的位置上 PointF[] pointf3 = { new PointF (pointf1 [30].X-f/4,pointf1 [30].Y +r/20), new PointF (pointf1 [15].X-r/20-2*f ,pointf1 [15].Y+f/3 ), new PointF (pointf1 [0].X-2*f ,pointf1 [0].Y -r/20-4*f/3), new PointF (pointf1 [45].X+r/20 ,pointf1 [45].Y -r/20-4*f/3), }; //畫出四個點相應的時間值 for (int m = 0; m < 4; m++) { g.DrawString(((time)m).ToString(), font, Brushes.Black, pointf3[m]); } //程式碼重複 ---> 程式碼保持高內聚低耦合 ---> (time)將阿拉伯數位改成時間型別 //g.DrawString(((time)0).ToString(), font, Brushes.Black, pointf3[0]); //g.DrawString(time.III.ToString(), font, Brushes.Black, pointf3[1]); //g.DrawString(time.VI.ToString(), font, Brushes.Black, pointf3[2]); //g.DrawString(time.IX.ToString(), font, Brushes.Black, pointf3[3]); //使用DrawEllipse畫表盤 --- pen 左上角的x座標 左上角的y座標 寬度 高度 ---> 畫圓 g.DrawEllipse(p1, p.X - r, p.Y - r, 2 * r, 2 * r); } //畫時針 public void DrawHourPointer(Graphics g) { //定義畫筆p1,設定其屬性,使其帶有箭頭,圓點尾部 Pen p1 = new Pen(Color.Green, 4); p1.EndCap = LineCap.ArrowAnchor; // 箭頭 p1.StartCap = LineCap.Round; // 尾部 //獲取分鐘,轉化為int型 int i = Convert.ToInt32(date.Minute); //獲取小時,並轉換為int型,同時對12取餘,獲得十二小時制的小時數 int j = (Convert.ToInt32(date.Hour)) % 12; //計算點值 --- (2 * Math.PI) * j / 720) 根據分鐘表示時針的位置 ---> 1分鐘再小時裡佔比1/720 ---> 60分鐘*12個小時數 = 720 //點1的座標 float x1 = (float)(p.X + (r - r / 3) * Math.Sin((j * 2 * Math.PI / 12) + (2 * Math.PI) * i / 720)); float y1 = (float)(p.Y - (r - r / 3) * Math.Cos((j * 2 * Math.PI / 12) + (2 * Math.PI) * i / 720)); //點2的座標 float x2 = (float)(p.X - r / 30 * Math.Sin((j * 2 * Math.PI / 12) + (2 * Math.PI) * i / 720)); float y2 = (float)(p.Y + r / 30 * Math.Cos((j * 2 * Math.PI / 12) + (2 * Math.PI) * i / 720)); PointF pointf1 = new PointF(x1, y1); PointF pointf2 = new PointF(x2, y2); //用DrawLine畫時針 g.DrawLine(p1, pointf2, pointf1); } //畫分針 public void DrawMinutePointer(Graphics g) { //定義畫筆p1,設定其屬性,使其帶有箭頭,圓點尾部 //畫筆寬度為3 ---> 分針比時針細一點 Pen p1 = new Pen(Color.Blue, 3); p1.EndCap = LineCap.ArrowAnchor; p1.StartCap = LineCap.Round; //獲取當前分鐘,並轉換為int型 int i = Convert.ToInt32(date.Minute); //計算點值 //點1 float x1 = (float)(p.X + (r - r / 5) * Math.Sin(i * 2 * Math.PI / 60)); float y1 = (float)(p.Y - (r - r / 5) * Math.Cos(i * 2 * Math.PI / 60)); //點2 float x2 = (float)(p.X - r / 20 * Math.Sin(i * 2 * Math.PI / 60)); float y2 = (float)(p.Y + r / 20 * Math.Cos(i * 2 * Math.PI / 60)); PointF pointf1 = new PointF(x1, y1); PointF pointf2 = new PointF(x2, y2); //用DrawLine畫分針 g.DrawLine(p1, pointf2, pointf1); } //畫秒針 public void DrawSecondPointer(Graphics g) { Pen p1 = new Pen(Color.Red, 2); p1.EndCap = LineCap.ArrowAnchor; p1.StartCap = LineCap.Round; //獲取當前秒,並轉換為int型 int i = Convert.ToInt32(date.Second); //計算點值 float x1 = (float)(p.X + (r - r / 20) * Math.Sin(i * 2 * Math.PI / 60)); float y1 = (float)(p.Y - (r - r / 20) * Math.Cos(i * 2 * Math.PI / 60)); float x2 = (float)(p.X - r / 15 * Math.Sin(i * 2 * Math.PI / 60)); float y2 = (float)(p.Y + r / 15 * Math.Cos(i * 2 * Math.PI / 60)); PointF pointf1 = new PointF(x1, y1); PointF pointf2 = new PointF(x2, y2); //用DrawLine畫秒針 ---> 根據兩點之間畫線 g.DrawLine(p1, pointf2, pointf1); } //周和日期顯示 ---> 錶盤上 public void DrawWeeks(Graphics g) { //字型大小 float f = r / 15; Font font = new Font("Times New Roman", f); //放置位置 float f1 = (float)(p.X + r * Math.Sin(Math.PI) / 2); float f2 = (float)(p.Y - r * Math.Cos(Math.PI) / 2); //DrawString ---> 畫字串 g.DrawString(week.DayOfWeek.ToString(), font, Brushes.Black, f1, f2); g.DrawString(week.Day.ToString(), font, Brushes.Black, f1 + 80, f2); } public void Draw(Graphics g) { //定義函數Draw,畫出時鐘 //畫表盤 DrawDial(g); //畫時針 DrawHourPointer(g); //畫分針 DrawMinutePointer(g); //畫秒針 DrawSecondPointer(g); //畫周和日期 DrawWeeks(g); } public bool HitTest(Point p, Point center, int r) { //HitTest函數表示滑鼠是否點在時鐘裡面 //通過計算滑鼠點選的點到中心點的距離和半徑的比較來判定是否擊中時鐘 //圓心到半徑的距離畫圓,便是圓的全部面積 double f1 = (double)(p.X - center.X); double f2 = (double)(p.Y - center.Y); //test即為滑鼠點選的點到中心點的距離 //根據勾股定理,求距離,直角三角形 a² + b² = c² double test = Math.Sqrt(f1 * f1 + f2 * f2); //斜邊長於圓的半徑,則在圓的範圍之外;斜邊小於圓的半徑,則在圓的範圍之內 if (test <= r) { return true; } else { return false; } } #region 屬性 //此處設定成了唯讀 ---> 不可寫 ---> 導致時鐘的DateTime時間無法寫入進來 //public DateTime Date { get; internal set; } //public DateTime Week { get; internal set; } //public Point P { get; internal set; } //public int R { get; internal set; } public DateTime Date { set { date = value; } } public Point P { set { p = value; } } public int R { set { r = value; } } public DateTime Week { set { week = value; } } #endregion } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45