版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第C#繪制時鐘的方法本文實例為大家分享了使用C#寫一個時鐘,供大家參考,具體內(nèi)容如下
時鐘是這樣的
一共使用四個控件即可:
WinFrom窗體應用程序代碼:
usingSpeechLib;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Drawing.Drawing2D;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows.Forms;
namespaceMyClockTest
publicpartialclassForm1:Form
{
//創(chuàng)建對象myclock
MyClockmyclock=newMyClock();
//定義date1,共電子表使用--獲取到當下時間點
DateTimedate1=DateTime.Now;//Now為靜態(tài)只讀屬性(屬性可計算)
//定義中心點center和半徑radius--時鐘的圓心和半徑大小
Pointcenter=newPoint(160,200);//圓心點的坐標
intradius=150;//半徑150
//定義判定是否擊中表盤的bool變量--鼠標點擊拖拽功能
booldown=false;
//記錄鼠標點擊的點
Pointpre;
//程序入口
publicForm1()
{
InitializeComponent();
}
//開始畫時鐘
privatevoidOnPaint(objectsender,PaintEventArgse)
{
//這里不使用Graphics,而選擇使用BufferedGraphics:
//Graphics和BufferedGraphics對比:
//5000次下時Graphics效率高一些;5000次以后BufferedGraphics效率高一些
//Bitmapbmp=newBitmap(width,height);
//Graphicsg2=Graphics.FromImage(bmp);
//myclock.Draw(g2);
//g2.CreateGraphics();
//g2.DrawImage(bmp,0,0);
//bmt.dispose();
//Imageiamge=newBitmap(this.Width,this.Height);
//Graphicsg1=Graphics.FromImage(iamge);
//g1.Clear(Form.DefaultBackColor);
//C#雙緩沖解釋:
//簡單說就是當我們在進行畫圖操作時,系統(tǒng)并不是直接把內(nèi)容呈現(xiàn)到屏幕上,而是先在內(nèi)存中保存,然后一次性把結果輸出來。
//如果沒用雙緩沖的話,你會發(fā)現(xiàn)在畫圖過程中屏幕會閃的很厲害,因為后臺一直在刷新,
//而如果等用戶畫完之后再輸出就不會出現(xiàn)這種情況,具體的做法,其實也就是先創(chuàng)建一個位圖對象,然后把內(nèi)容保存在里面,最后把圖呈現(xiàn)出來。
//解決空間重繪時閃爍的問題,并在改變大小時重繪圖形
this.SetStyle(ControlStyles.OptimizedDoubleBuffer|ControlStyles.ResizeRedraw|ControlStyles.AllPaintingInWmPaint,true);
//矩形繪圖區(qū)域
Rectanglerect=e.ClipRectangle;
//關于BufferedGraphicsContext類:
//
手工設置雙緩沖.netframework提供了一個類BufferedGraphicsContext負責單獨分配和管理圖形緩沖區(qū)。
//
每個應用程序域都有自己的默認BufferedGraphicsContext實例來管理此應用程序的所有默認雙緩沖。
//
大多數(shù)情況下,每個應用程序只有一個應用程序域,所以每個應用程序通常只有一個默認BufferedGraphicsContext。
//關于此處的繪圖:
//通過管理BufferedGraphicsContext實現(xiàn)雙緩沖的步驟如下:
//(1)獲得對BufferedGraphicsContext類的實例的引用。
//(2)通過調(diào)用BufferedGraphicsContext.Allocate方法創(chuàng)建BufferedGraphics類的實例。
//(3)通過設置BufferedGraphics.Graphics屬性將圖形繪制到圖形緩沖區(qū)。
//(4)當完成所有圖形緩沖區(qū)中的繪制操作時,可調(diào)用BufferedGraphics.Render方法將緩沖區(qū)的內(nèi)容呈現(xiàn)到與該緩沖區(qū)關聯(lián)的繪圖圖面或者指定的繪圖圖面。
//(5)完成呈現(xiàn)圖形之后,對BufferedGraphics實例調(diào)用釋放系統(tǒng)資源的Dispose方法。
BufferedGraphicsContextcurrent=BufferedGraphicsManager.Current;//(1)
BufferedGraphicsbg;
bg=current.Allocate(e.Graphics,e.ClipRectangle);//(2)
Graphicsg=bg.Graphics;//(3)
//定義畫布
//Graphicsg=CreateGraphics();
//消除鋸齒
//g.SmoothingMode=SmoothingMode.AntiAlias;
g.SmoothingMode=SmoothingMode.HighQuality;//高質(zhì)量
g.PixelOffsetMode=PixelOffsetMode.HighQuality;//高像素偏移質(zhì)量
//每次繪畫后的背景色填充定義畫電子鐘的字體
g.Clear(this.BackColor);
Fontfont=newFont("TimesNewRoman",20);
//在每次繪畫時,更新時間,半徑及中心點
myclock.Date=DateTime.Now;
myclock.Week=DateTime.Now;
myclock.P=center;
myclock.R=radius;
//調(diào)用myclock中的Draw函數(shù)畫出鐘
myclock.Draw(g);
//直接調(diào)用DrawString函數(shù),顯示電子表,并且設置顯示格式
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")
{
SpVoicevoice=newSpVoice();
voice.Speak("現(xiàn)在時間為"+Convert.ToString(DateTime.Now.Month)+"月"+Convert.ToString(DateTime.Now.Day)+"日"+Convert.ToString(DateTime.Now.Hour)+"點"+Convert.ToString(DateTime.Now.Minute)+"分",SpeechVoiceSpeakFlags.SVSFDefault);
}
}
//更新時鐘的時間
privatevoidOnTime(objectsender,EventArgse)
{
//使用timer控件來更新時間---1s/次
//更新鐘的時間
myclock.Date=DateTime.Now;
myclock.Week=DateTime.Now;
//更新電子表的時間
date1=DateTime.Now;
//刷新---每走動一秒都更新畫布(重繪)
Invalidate();
//Refresh();
}
//鼠標單擊到時鐘上的坐標
privatevoidForm1_MouseDown(objectsender,MouseEventArgse)
{
//記錄點擊的點,并且計算是否擊中時鐘--記錄點擊時的坐標
pre=newPoint(e.X,e.Y);
down=myclock.HitTest(pre,center,radius);
}
//在點擊后,鼠標拖動時
privatevoidForm1_MouseMove(objectsender,MouseEventArgse)
{
//使用if來判斷是否擊中,若擊中,更新中心點
Pointp=newPoint(e.X,e.Y);
//如果點擊持續(xù)
if(down)
{
//更新圓心坐標點
center=newPoint(center.X+p.X-pre.X,center.Y+p.Y-pre.Y);
//pre=當前移動的點的坐標
pre=p;
//重繪
Invalidate();
//Refresh();
}
}
privatevoidForm1_MouseUp(objectsender,MouseEventArgse)
{
//取消擊中--拖拽結束
down=false;
}
privatevoidtrackBar1_Scroll(objectsender,EventArgse)
{
//使用trackBar1來控制半徑大小,并且更新---trackBar控件改變時鐘的大小
radius=trackBar1.Value;
Invalidate();
//refresh
}
//單擊:報時功能
privatevoidbutton1_Click(objectsender,EventArgse)
{
DateTimeda=newDateTime();
da=DateTime.Now;
//SpVoice報時
SpVoicevoice=newSpVoice();
voice.Speak("現(xiàn)在時間為"+Convert.ToString(da.Month)+"月"+Convert.ToString(da.Day)+"日"+Convert.ToString(da.Hour)+"點"+Convert.ToString(da.Minute)+"分",SpeechVoiceSpeakFlags.SVSFDefault);
}
}
//初始化時鐘:類應該寫在外面(此處不規(guī)范)
publicclassMyClock
{
enumtime{XII,III,VI,IX}//定義結構體--時鐘的4頂點
publicDateTimedate;//Now為靜態(tài)只讀{get}屬性(屬性可計算),智能作為右值--電子表時間
publicDateTimeweek;//周
publicPointp;//圓心點的坐標
publicintr;//半徑
publicMyClock()
{
//定義一個構造函數(shù),賦予date當前時間
date=DateTime.Now;
week=DateTime.Now;
p=newPoint(160,200);//圓心點的坐標
r=150;//半徑
}
//畫表盤
publicvoidDrawDial(Graphicsg)
{
//定義兩個pen,p1用來畫小刻度及表盤,p2用來畫大刻度
Penp1=newPen(Color.Black,2);
Penp2=newPen(Color.Green,2);
//時鐘頂點時間的字體大小
floatf=r/10;
//字體樣式字體大小
Fontfont=newFont("TimesNewRoman",f);
//定義兩個點數(shù)組來存儲刻度線的兩點---[60]數(shù)組中共存放了60個點的坐標
PointF[]pointf1=newPointF[60];
PointF[]pointf2=newPointF[60];
//
for(inti=0;ii++)
{
//通過for循環(huán)來給pointf1賦值---f1點就在圓形的邊上,r
floatx1=(float)(p.X+r*Math.Sin((i+1)*Math.PI*2/60));
floaty1=(float)(p.Y+r*Math.Cos((i+1)*Math.PI*2/60));
pointf1[i]=newPointF(x1,y1);
//使用if來判斷,能整除5就畫大刻度,不能就畫小刻度
if((i+1)%5==0)
{
floatx2=(float)(p.X+(r-r/20)*Math.Sin((i+1)*2*Math.PI/60));
floaty2=(float)(p.Y+(r-r/20)*Math.Cos((i+1)*2*Math.PI/60));
pointf2[i]=newPointF(x2,y2);
//畫大刻度
g.DrawLine(p2,pointf1[i],pointf2[i]);
}
else
{
floatx2=(float)(p.X+(r-r/40)*Math.Sin((i+1)*2*Math.PI/60));
floaty2=(float)(p.Y+(r-r/40)*Math.Cos((i+1)*2*Math.PI/60));
pointf2[i]=newPointF(x2,y2);
//畫小刻度
g.DrawLine(p2,pointf1[i],pointf2[i]);
}
}
//用pointf3來儲存四個點的位置表盤的4個頂點位置---橫坐標縱坐標調(diào)整距離到合適的位置上
PointF[]pointf3=
{
newPointF(pointf1[30].X-f/4,pointf1[30].Y+r/20),
newPointF(pointf1[15].X-r/20-2*f,pointf1[15].Y+f/3),
newPointF(pointf1[0].X-2*f,pointf1[0].Y-r/20-4*f/3),
newPointF(pointf1[45].X+r/20,pointf1[45].Y-r/20-4*f/3),
};
//畫出四個點相應的時間值
for(intm=0;mm++)
{
g.DrawString(((time)m).ToString(),font,Brushes.Black,pointf3[m]);
}
//代碼重復---代碼保持高內(nèi)聚低耦合---(time)將阿拉伯數(shù)字改成時間類型
//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);
}
//畫時針
publicvoidDrawHourPointer(Graphicsg)
{
//定義畫筆p1,設置其屬性,使其帶有箭頭,圓點尾部
Penp1=newPen(Color.Green,4);
p1.EndCap=LineCap.ArrowAnchor;//箭頭
p1.StartCap=LineCap.Round;//尾部
//獲取分鐘,轉化為int型
inti=Convert.ToInt32(date.Minute);
//獲取小時,并轉換為int型,同時對12取余,獲得十二小時制的小時數(shù)
intj=(Convert.ToInt32(date.Hour))%12;
//計算點值---(2*Math.PI)*j/720)根據(jù)分鐘表示時針的位置---1分鐘再小時里占比1/720---60分鐘*12個小時數(shù)=720
//點1的坐標
floatx1=(float)(p.X+(r-r/3)*Math.Sin((j*2*Math.PI/12)+(2*Math.PI)*i/720));
floaty1=(float)(p.Y-(r-r/3)*Math.Cos((j*2*Math.PI/12)+(2*Math.PI)*i/720));
//點2的坐標
floatx2=(float)(p.X-r/30*Math.Sin((j*2*Math.PI/12)+(2*Math.PI)*i/720));
floaty2=(float)(p.Y+r/30*Math.Cos((j*2*Math.PI/12)+(2*Math.PI)*i/720));
PointFpointf1=newPointF(x1,y1);
PointFpointf2=newPointF(x2,y2);
//用DrawLine畫時針
g.DrawLine(p1,pointf2,pointf1);
}
//畫分針
publicvoidDrawMinutePointer(Graphicsg)
{
//定義畫筆p1,設置其屬性,使其帶有箭頭,圓點尾部
//畫筆寬度為3---分針比時針細一點
Penp1=newPen(Color.Blue,3);
p1.EndCap=LineCap.ArrowAnchor;
p1.StartCap=LineCap.Round;
//獲取當前分鐘,并轉換為int型
inti=Convert.ToInt32(date.Minute);
//計算點值
//點1
floatx1=(float)(p.X+(r-r/5)*Math.Sin(i*2*Math.PI/60));
floaty1=(float)(p.Y-(r-r/5)*Math.Cos(i*2*Math.PI/60));
//點2
floatx2=(float)(p.X-r/20*Math.Sin(i*2*Math.PI/60));
floaty2=(float)(p.Y+r/20*Math.Cos(i*2*Math.PI/60));
PointFpointf1=newPointF(x1,y1);
PointFpointf2=newPointF(x2,y2);
//用DrawLine畫分針
g.DrawLine(p1,pointf2,pointf1);
}
//畫秒針
publicvoidDrawSecondPointer(Graphicsg)
{
Penp1=newPen(Color.Red,2);
p1.EndCap=LineCap.ArrowAnchor;
p1.StartCap=LineCap.Round;
//獲取當前秒,并轉換為int型
inti=Convert.ToInt32(date.Second);
//計算點值
floatx1=(float)(p.X+(r-r/20)*Math.Sin(i*2*Math.PI/60));
floaty1=(float)(p.Y-(r-r/20)*Math.Cos(i*2*Math.PI/60));
floatx2=(float)(p.X-r/15*Math.Sin(i*2*Math.PI/60));
floaty2=(float)(p.Y+r/15*Math.Cos(i*2*Math.PI/60));
PointFpointf1=newPointF(x1,y1);
PointFpointf2=newPointF(x2,y2);
//用DrawLine畫秒針---根據(jù)兩點之間畫線
g.DrawLine(p1,pointf2,pointf1);
}
//周和日期顯示---
表盤上
publicvoidDrawWeeks(Graphicsg)
{
//字體大小
floatf=r/15;
Fontfont=newFont("TimesNewRoman",f);
//放置位置
floatf1=(float)(p.X+r*Math.Sin(Math.PI)/2);
floatf2=(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);
}
publicvoidDraw(Graphicsg)
{
//定義函數(shù)Draw,畫出時鐘
//畫表盤
DrawDial(g);
//畫時針
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 小區(qū)消防安全評估指南
- 安全生產(chǎn)典范企業(yè)講解
- 2025-2026人教版小學二年級語文期末測試卷上
- 結構專業(yè)考試題及答案
- 2025-2026人教版三年級語文上學期卷
- 腸道菌群與NAFLD肝硬化PHG:MDT調(diào)節(jié)策略
- 2025-2026一年級語文上學期期末測試卷
- 腸狹窄術后腹腔感染的處理策略
- 腸梗阻合并糖尿病患者的血糖管理策略
- 衛(wèi)生院執(zhí)業(yè)監(jiān)督管理制度
- 安全生產(chǎn)目標及考核制度
- (2026版)患者十大安全目標(2篇)
- 2026年北大拉丁語標準考試試題
- 臨床護理操作流程禮儀規(guī)范
- 2025年酒店總經(jīng)理年度工作總結暨戰(zhàn)略規(guī)劃
- 空氣栓塞課件教學
- 2025年國家市場監(jiān)管總局公開遴選公務員面試題及答案
- 肌骨康復腰椎課件
- 患者身份識別管理標準
- 2025年10月自考04184線性代數(shù)經(jīng)管類試題及答案含評分參考
- 2025年勞動保障協(xié)理員三級技能試題及答案
評論
0/150
提交評論