篇名 : 電腦計時器之淺談與簡易應用作者 : 簡育騰 高雄高工 資訊三甲 1
壹 前言 電腦計時器之淺談與簡易應用 當初還沒學物件導向之前, 從沒想過, 在現實生活中, 我們常常會用到碼表或者鬧鐘, 可以用電腦計時器設計出來 舉例來說 : 用電腦計時器設計出來的碼表, 可以非常的精準, 甚至可以顯示到小數點後面好幾位數, 更可以儲存多筆的紀錄, 並可輕易的呼叫出需要的紀錄 電腦計時器還可以設計出很多不一樣的東西, 例如 : 倒數計時器 鬧鐘 棋類比賽鐘 等等的多種計數物件, 應用之廣泛真是不勝枚舉, 這次要探討的是一些電腦計時器的常見應用, 並理解 timer 之觀念與應用, 且理解 stopwatch 的觀念並設計碼表, 使其可計時與擷取紀錄 貳 正文一 電腦計時器物件介紹 1 timer 間隔的長短由 Interval 屬性定義, 其值是以毫秒為單位 當啟用這個元件時, 每個間隔都會引發 Tick 事件, 將程式輸入在 tick 事件下面, 當觸發 tick 事件時, 該程式就會執行一次 Timer 元件的主要方法是開啟和關閉計時器的 Start 和 Stop 當關閉計時器時, 計時器就會重設, 沒有任何方法可以暫停 Timer 元件 timer 常見的屬性 Timer.AutoReset 屬性 如果 Timer 應於每次耗盡間隔時引發 tick 事件, 則為 true; 如果應該僅於第一次耗盡間隔後引發 tick 事件一次, 則為 false 預設值為 true Timer.Enabled 屬性 設定 timer 是否被啟用, 值有 true 和 false Timer.Interval 屬性 設定 timer 每次觸發 tick 事件間隔的時間, 單位是 ms Timer.Site 屬性 timer 常見的方法 Timer.Change 2
多載 變更開始的時間和計時器的方法引動過程之間的時間間隔 Timer.Dispose 多載 將 Timer 目前的執行個體所使用的資源全部釋出 Timer 常見的事件 Timer.Disposed 加入事件處理常式來接聽 (Listen) 元件上的 Disposed 事件 Timer.Tick 發生在指定的計時器間隔已耗用, 且計時器被啟用時 2 stopwatch 傳回的 Stopwatch 執行個體已停止, 而且執行個體的已耗用時間屬性為零 請使用 Start 方法, 開始利用新的 Stopwatch 執行個體來測量已耗用時間 請使用 StartNew 方法, 初始化新的 Stopwatch 執行個體並立即啟動它 Stopwatch 常見的屬性 Stopwatch.Elapsed 取得目前執行個體所測量的已耗用時間總和 Stopwatch.ElapsedMilliseconds 取得目前執行個體所測量的已耗用時間總和, 以毫秒為單位 Stopwatch.ElapsedTicks 取得目前執行個體所測量的已耗用時間總和, 以計時器刻度為單位 Stopwatch.IsRunning 取得值, 表示 Stopwatch 計時器是否執行中 值為 true 或 false 3
Stopwatch 常見的方法 Stopwatch.Timestamp 取得計時器機制中的目前刻度數 Stopwatch.Reset 停止時間間隔測量並將已耗用時間重設為零 Stopwatch.Start 啟動或繼續測量間隔的已耗用時間 Stopwatch.Stop 停止測量間隔的已耗用時間 二 數位碼表及比賽用計時器演算法 1 計時器物件介紹及演算法 (1). 需要物件 : Timer Label Button Stopwatch Picturebox (2). 演算法 : 透過 Stopwatch 的計數功能做計數動作, 利用 Button 決定開始 停止 顯示之動作, Timer 負責更新 Label 的值,Label 則是用來顯示 Stopwatch 現在的值 三 程式實作 1 碼表 A 操作過程 第一步 : 建立可用於 Windows 應用程式的控制項專案 (Windows 控制項程式庫 ) 第二步 : 放入物件, 此程式需要 3 個 label 5 個 button 1 個 windows form 1 個 listbox, 在控制項內放入 2 個 label 3 個 button, 此時 1 個 label 是要顯示目前時間已經過了多久, 另一個 label 則是顯示目前記錄了幾筆資料 3 個按鈕分別是 " 開始 " " 顯示 " " 清除 " 在 windows form 放入 1 個 label 2 個 button 1 個 listbox, 此時 label 顯示 " 碼表記錄時間 ",2 個 botton 分別是 " 刷新 " " 關閉 ",listbox, 則是顯示每筆紀錄的時間 第三步 : 各個物件命名 4
第四步 : 寫入該程式碼於各個元件 電腦計時器之淺談與簡易應用 B 畫面 圖一 完成畫面 圖二 操作過程 圖三 操作結果 C 程式碼 & 註解 a 控制項 Public Class LichiStopWatch Private Stopwatch As New Stopwatch ' 提供一組方法和屬性 (Property), 您可以使用這些方法和屬性, 精確地測量已耗用時間 Private bstopwatchenabled As Boolean ' 決定是否要啟動碼表內部的計時裝置, 即 Stopwatch 物件 Private ncounter As Integer ' 已存多少筆紀錄 Private shistoryrecord As String ' 存每一次凍結時經過的時間, 每一筆紀錄已分號隔開 5
' 以下定義屬性 LichiStopWatchEnabled, 決定是否要啟動碼表內部的計時裝置, 即 Stopwatch 物件 Property LichiStopwatchEnabled() As Boolean Return bstopwatchenabled Set(ByVal value As Boolean) If bstopwatchenabled <> value Then Call Start_Stop_Click(Start_Stop, System.EventArgs.Empty) End Set ' 以下定義屬性 LichiStopWatchFreeze, 決定碼表的數字是否凍結在某一時間點 Property LichiStopwatchFreeze() As Boolean Return Timer1.Enabled Set(ByVal value As Boolean) If Timer1.Enabled <> value Then Call Freeze_Continue_Click(Freeze_Continue, System.EventArgs.Empty) End Set ' 以下定義屬性 LichiStopWatchUsedAmount, 傳回已存多少筆紀錄 ReadOnly Property LichiStopwatchUsedAmount() As Integer Return ncounter ' 以下定義屬性 LichiStopWatchHistoryRecord, 存每一次凍結的時間, 每一筆紀錄已分號隔開 ReadOnly Property LichiStopwatchHistoryRecord() As String Return shistoryrecord ' 以下定義屬性 LichiStopWatchIsHighResolution, 傳回內部的 Stopwatch 是否以高解析度效能計數器為基礎 ReadOnly Property LichiStopwatchIsHighResolution() As Boolean 6
Return Stopwatch.IsHighResolution ' 以下定義屬性 LichiStopWatchFrequency, 傳回內部 Stopwatch 每秒有多少的刻度數 ReadOnly Property LichiStopwatchFrequency() As Long Return Stopwatch.Frequency ' 以下定義屬性 LichiStopWatchNanosecPerTick, 傳回內部的 Stopwatch 每一刻度數有多少個奈秒 (nanosecond) ReadOnly Property LichiStopwatchNanosecPerTick() As Long Return 1000000000 / Stopwatch.Frequency ' 以下定義屬性 LichiStopWatchBackColor, 控制碼表的背景顏色 Property LichiStopwatchStopwatchBackColor() As Color ' 讀取屬性時應從何處取得 Return Me.BackColor Set(ByVal Value As Color) ' 寫入屬性值時應存於何處 Me.BackColor = Value End Set ' 以下定義屬性 LichiStopWatchForeColor, 控制碼表的數字與按鈕文字顏色 Property LichiStopwatchStopwatchForeColor() As Color Return ElapsedPanel.ForeColor Set(ByVal Value As Color) ElapsedPanel.ForeColor = Value CounterPanel.ForeColor = Value Start_Stop.ForeColor = Value Freeze_Continue.ForeColor = Value Clear.ForeColor = Value End Set ' 以下定義屬性 LichiStopWatchButtonBackColor, 控制碼表按鈕的背景顏色 Property LichiStopwatchStopwatchButtonBackColor() As Color 7
' 讀取屬性時應從何處取得 Return Start_Stop.BackColor Set(ByVal Value As Color) ' 寫入屬性值時應存於何處 Start_Stop.BackColor = Value Freeze_Continue.BackColor = Value Clear.BackColor = Value End Set ' 以下定義事件 LichiStopWatchView 事件, 於按下 CounterPanel 時觸發 Public Event LichiStopwatchView() Private Sub Start_Stop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Start_Stop.Click If Not bstopwatchenabled Then ' 開始計時並顯示經過的時間 ElapsedPanel.Text = "00.00:00:00.00" bstopwatchenabled = True Stopwatch.Start() Call Freeze_Continue_Click(sender, System.EventArgs.Empty) Start_Stop.Text = " 停止 " ' 停止計時 bstopwatchenabled = False Stopwatch.Stop() ' 判斷是否要記錄 Call Freeze_Continue_Click(sender, System.EventArgs.Empty) Stopwatch.Reset() Start_Stop.Text = " 開始 " 'ElapsedPanel.Text = "00.00:00:00.00" Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick Dim ts As TimeSpan = Stopwatch.Elapsed ElapsedPanel.Text = String.Format("{0:00}.{1:00}:{2:00}:{3:00}.{4:00}", ts.days, ts.hours, ts.minutes, ts.seconds, ts.milliseconds / 10) Public Sub New() ' 此為 Windows Form 設計工具所需的呼叫 8
InitializeComponent() ' 在 InitializeComponent() 呼叫之後加入任何初始設定 Stopwatch.Stop() Timer1.Interval = 10 Timer1.Enabled = False bstopwatchenabled = False Me.LichiStopwatchStopwatchBackColor = Color.PaleGreen Me.LichiStopwatchStopwatchButtonBackColor = Color.AliceBlue Me.LichiStopwatchStopwatchForeColor = Color.Black If Not Timer1.Enabled Then Freeze_Continue.Text = " 顯示 " Freeze_Continue.Text = " 凍結 " If bstopwatchenabled Then Start_Stop.Text = " 停止 " Start_Stop.Text = " 開始 " ncounter = 0 CounterPanel.Text = String.Format("{0:00}", ncounter) shistoryrecord = String.Empty Private Sub Freeze_Continue_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Freeze_Continue.Click If bstopwatchenabled Then If Not Timer1.Enabled Then ' 結束凍結狀態讓經過的時間繼續顯示 Timer1.Enabled = True Freeze_Continue.Text = " 凍結 " ' 將經過的時間紀錄下來並凍結顯示的時間 Timer1.Enabled = False ncounter = ncounter + 1 CounterPanel.Text = String.Format("{0:00}", ncounter) If shistoryrecord = String.Empty Then shistoryrecord = ElapsedPanel.Text shistoryrecord = shistoryrecord & ";" & ElapsedPanel.Text 9
Freeze_Continue.Text = " 顯示 " If Timer1.Enabled Then ' 將經過的時間紀錄下來並凍結顯示的時間 Timer1.Enabled = False ncounter = ncounter + 1 CounterPanel.Text = String.Format("{0:00}", ncounter) If shistoryrecord = String.Empty Then shistoryrecord = ElapsedPanel.Text shistoryrecord = shistoryrecord & ";" & ElapsedPanel.Text Freeze_Continue.Text = " 顯示 " Private Sub Clear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Clear.Click ' 清除凍結紀錄 ncounter = 0 shistoryrecord = String.Empty CounterPanel.Text = String.Format("{0:00}", ncounter) Private Sub CounterPanel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CounterPanel.Click ' 按下凍結紀錄個數按鈕時觸發 RaiseEvent LichiStopwatchView() End Class 參 結論 想當初高一的時候, 那個時候在學 QBASIC, 卻只能做一些運算, 跟我心中所想的 寫程式 差異漫大的, 我一直以為寫程式是你想要什麼東西, 就可以寫出來, 例如做個鬧鐘 行事曆 之類的, 就這樣抱著疑問升上了二年級 上了二年級後, 我之前想像的 寫程式 終於出現了, 是用 Visual Studio 2005 來寫程式, 版面比 QBASIC 好看很多, 多出了很多的物件, 例如 :timer label 等等 10
剛開始學習的時候, 說實在的, 還滿難適應的, 因為已經習慣了 QBASIC 簡潔的畫面, 跟單純的程式碼, 一下要跳到複雜的 VB, 還有著動不動就上百行的程式碼, 真的是漫痛苦的 好在老師是用他已經寫好的程式, 讓我們跟隨他的邏輯, 慢慢的來適應並學習 VB, 之後, 老師在等我們已經適應 VB 的時候, 就叫我們用電腦計時器, 設計出碼表來 經過老師的指導, 與跟同學的討論, 終於把碼表做了出來 在這個資訊發達的時代, 電腦計時器的重要性, 已經到了一個不可取代的位置, 可以用它設計出多樣的程式, 且說不定比我們現實中的東西還要精準 還要方便, 而且還可以加入個人化的事件, 例如 : 時間到撥放一首音樂... 之類的, 在現在這個幾乎人手一台電腦的時代, 幾乎已經是大多數的電腦玩家不可或缺的物件了 肆 引註資料 莊利吉 (2008), 生活小幫手 11