在開發視窗應用程式時,如何有效呈現表格型資料是一個常見需求。Pascal的Delphi環境提供了StringGrid控制項,這是一個強大的工具,可以用於顯示和收集表格式的字串資料。

StringGrid的基本屬性與操作

StringGrid控制項提供了一個直觀的網格介面,可用於顯示二維資料。以下是使用StringGrid的基本步驟:

// 建立一個具有3列5行的StringGrid
procedure CreateBasicGrid;
begin
  sgdMy.ColCount := 3;
  sgdMy.RowCount := 5;
  sgdMy.FixedCols := 1;
  sgdMy.FixedRows := 1;
  
  // 設定固定列和行的顏色
  sgdMy.FixedColor := clGreen;
  
  // 設定其他單元格的顏色
  sgdMy.Color := clWhite;
  
  // 填充一些單元格
  sgdMy.Cells[0, 0] := '專案';
  sgdMy.Cells[1, 0] := '數量';
  sgdMy.Cells[2, 0] := '單價';
  
  sgdMy.Cells[0, 1] := '筆記本';
  sgdMy.Cells[1, 1] := '5';
  sgdMy.Cells[2, 1] := '15';
end;

這段程式碼示範瞭如何建立和設定基本的StringGrid控制項。主要步驟包括:

  1. 設定網格的列數(ColCount)和行數(RowCount)
  2. 設定固定列數(FixedCols)和固定行數(FixedRows),這些區域通常用於顯示標題
  3. 設定固定區域和普通單元格的顏色
  4. 使用Cells屬性填充特定單元格的內容

在StringGrid中,索引從0開始,Cells[0, 0]表示左上角的單元格。第一個索引是列號,第二個索引是行號。

動態建立與設定StringGrid

在實際應用中,我們通常需要根據使用者輸入或程式需求動態設定StringGrid。以下是一個完整的例子,展示如何根據使用者輸入建立網格:

procedure GetGridParam(var n1, n2, n3, n4: integer);
begin
  n1 := StrToInt(frmGrid.edtLine.Text);
  n2 := StrToInt(frmGrid.edtStolb.Text);
  n3 := StrToInt(frmGrid.edtFline.Text);
  n4 := StrToInt(frmGrid.edtFstolb.Text);
end;

procedure CreateGrid(n1, n2, n3, n4: integer);
begin
  frmGrid.sgdMy.RowCount := n2;
  frmGrid.sgdMy.ColCount := n1;
  frmGrid.sgdMy.FixedCols := n4;
  frmGrid.sgdMy.FixedRows := n3;
end;

procedure TfrmGrid.btnTablClick(Sender: TObject);
var
  nl, ns, nfl, nfs: integer;
begin
  GetGridParam(nl, ns, nfl, nfs); // 取得網格引數
  CreateGrid(nl, ns, nfl, nfs);   // 建立指定引數的網格
end;

procedure TfrmGrid.btnCelRedClick(Sender: TObject);
begin
  frmGrid.sgdMy.Color := clRed;
end;

procedure TfrmGrid.btnFCGreenClick(Sender: TObject);
begin
  frmGrid.sgdMy.FixedColor := clGreen;
end;

這段程式碼展示瞭如何根據使用者輸入動態建立和設定StringGrid:

  1. GetGridParam函式從四個文字框中取得使用者輸入的引數:列數、行數、固定列數和固定行數。
  2. CreateGrid函式使用這些引數設定StringGrid控制項。
  3. btnTablClick是按鈕點選事件處理程式,它呼叫上述兩個函式來建立網格。
  4. btnCelRedClickbtnFCGreenClick是兩個按鈕的事件處理程式,分別用於將普通單元格設為紅色和固定單元格設為綠色。

這種動態設定方式使應用程式更具靈活性,能夠適應不同的資料展示需求。

StringGrid的實用屬性一覽

以下是StringGrid的一些核心屬性,瞭解這些有助於更好地控制網格的外觀和行為:

  • BorderStyle: 指定網格邊框的外觀(bsNone無邊框,bsSingle 1畫素邊框)
  • ColCount: 網格列數
  • DefaultColWidth: 預設列寬
  • RowCount: 網格行數
  • DefaultRowHeight: 預設行高
  • Color: 控制單元格顏色
  • FixedCols: 控制固定列數
  • FixedRows: 控制固定行數
  • FixedColor: 控制固定單元格的顏色
  • GridHeight: 網格高度
  • GridWidth: 網格寬度
  • GridLineWidth: 指定網格線寬度

實戰應用:實驗資料分析

下面是一個實際應用範例,展示如何使用StringGrid來記錄和分析物理實驗資料:

procedure TfrmExperiment.btnCalculateClick(Sender: TObject);
var
  i, expCount, scaleInterval: Integer;
  value, result, minResult, maxResult: Double;
  minIndex, maxIndex: Integer;
begin
  // 取得實驗次數和刻度間隔
  expCount := StrToInt(edtExpCount.Text);
  scaleInterval := StrToInt(edtScaleInterval.Text);
  
  // 設定網格引數
  sgdExperiment.Row

Delphi矩陣操作與StringGrid實戰技巧

在Delphi應用程式開發中,處理表格式資料是常見的需求。StringGrid元件提供了絕佳的視覺化方式來呈現和操作二維資料結構。本文將透過實際範例,帶領你探索StringGrid的強大功能以及相關的矩陣操作技巧。

StringGrid基礎操作例項

首先,讓我們從一個基本的StringGrid操作範例開始。這個範例展示如何建立一個具有使用者指定行列數的格子,並填入隨機數值,然後計算每一列中負數元素的數量。

實作第一個StringGrid應用

在這個範例中,我們需要:

  1. 兩個文字輸入框來設定列數和行數
  2. 一個StringGrid來顯示資料
  3. 一個TMemo元件來顯示結果
  4. 兩個按鈕來執行操作

以下是按鈕點選事件的處理程式碼:

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, n, m: integer;
begin
  n := StrToInt(Edit1.Text);
  m := StrToInt(Edit2.Text);
  
  StringGrid1.RowCount := n;
  StringGrid1.ColCount := m;
  
  for i := 0 to n-1 do
    for j := 0 to m-1 do
      StringGrid1.Cells[j, i] := IntToStr(Random(100)-50);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i, j, n, m, k: integer;
begin
  n := StringGrid1.RowCount;
  m := StringGrid1.ColCount;
  
  for i := 0 to n-1 do
  begin
    k := 0;
    for j := 0 to m-1 do
      if StrToInt(StringGrid1.Cells[j, i]) < 0 then
        k := k+1;
    Memo1.Lines.Append(IntToStr(k));
  end
end;

第一個程式中,Button1Click事件處理程式執行以下操作:

  • 從兩個文字輸入框中取得行數(n)和列數(m)
  • 設定StringGrid的行數和列數
  • 使用巢狀迴圈遍歷每個單元格,填入-50到49之間的隨機整數

第二個程式中,Button2Click事件處理程式執行以下操作:

  • 取得StringGrid的實際行數和列數
  • 逐行檢查每個單元格的值
  • 計算每行中負數的個數
  • 將結果附加到Memo控制項中顯示

這個範例展示瞭如何基本操作StringGrid,

二維陣列的實作與應用

在程式設計過程中,二維陣列是一種常用與重要的資料結構,尤其適合處理表格式資料。在Pascal語言中,二維陣列有其獨特的實作方式,接下來將介紹如何建立和操作二維陣列,以及如何將其與視覺化控制項結合使用。

二維陣列的宣告與初始化

在Pascal中,我們可以透過兩種方式宣告二維陣列:一種是直接使用二維陣列語法,另一種則是將二維陣列視為「陣列的陣列」。以下是後者的實作方式:

Const
  n = 3;  // 列數
  m = 6;  // 行數
Type
  array_1 = array[1..n] of integer;  // 定義一維陣列類別
  array_2 = array[1..m] of array_1;  // 定義二維陣列類別(陣列的陣列)

這段程式碼首先定義了常數n和m,分別代表陣列的列數和行數。接著定義了兩個陣列類別:array_1是一個包含n個整數的一維陣列;array_2則是包含m個array_1型別的陣列,形成了一個m×n的二維陣列結構。在Pascal中,這種「陣列的陣列」是實作二維陣列的常用方式,區別於其他語言中的直接二維陣列宣告。

隨機填充二維陣列

建立二維陣列後,常見的操作是填充資料。以下範例展示如何用隨機數填充二維陣列:

Var
  C: array_2;
Begin
  FillArray(c);     // 填充陣列C
  TableOutput(c);   // 將陣列C輸出到表格
end;

procedure FillArray(var arr: array_2);
var 
  i: integer;
begin
  Randomize;        // 初始化隨機數產生器
  for i:=1 to m do  // 對每一行進行迴圈
    FillColumn(arr[i]); // 填充第i行
end;

procedure FillColumn(var col: array_1);
var
  j: integer;
begin
  for j:=1 to n do        // 對每一列進行迴圈
    col[j] := Random(21)-10; // 產生-1010之間的隨機數
end;

這段程式碼展示瞭如何填充二維陣列。主程式呼叫FillArray函式處理整個陣列,而FillArray則針對每一行呼叫FillColumn函式。在FillColumn中,透過Random(21)-10產生-10到10之間的隨機整數(這是因為Random(21)會產生0到20的隨機數)。Randomize函式確保每次執行程式時都會產生不同的隨機數序列,這在實際應用中很重要,避免每次執行都得到相同的「隨機」結果。

使用StringGrid顯示二維陣列

在Delphi/Pascal中,StringGrid是顯示表格資料的理想控制項。以下是如何將二維陣列輸出到StringGrid的方法:

procedure TableOutput(arr: array_2);
var
  i, j: integer;
begin
  frm2arr.sgdMy.FixedCols := 0;  // 設定固定列數為0
  frm2arr.sgdMy.FixedRows := 0;  // 設定固定行數為0
  frm2arr.sgdMy.ColCount := m;   // 設定總列數
  frm2arr.sgdMy.RowCount := n;   // 設定總行數
  
  for i := 1 to m do
    for j := 1 to n do
      frm2arr.sgdMy.Cells[i-1, j-1] := IntToStr(arr[i][j]);
end;

這段程式碼展示瞭如何將二維陣列資料顯示在StringGrid控制項中。首先設定StringGrid的基本屬性:FixedColsFixedRows設為0表示沒有固定的標題列和標題行,ColCountRowCount則設定為陣列的維度。接著使用巢狀迴圈,將陣列中的每個元素轉換為字串並填入對應的儲存格。注意索引轉換:Pascal陣列索引從1開始,而StringGrid索引從0開始,所以要減1進行調整。

陣列轉置顯示

有時候,我們需要轉置陣列再顯示,這意味著將陣列的行和列互換:

procedure TableOutput(arr: array_2);
var
  i, j: integer;
begin
  frm2arr.SgdMy.ColCount := n;  // 設定列數為陣列的列數
  frm2arr.SgdMy.RowCount := m;  // 設定行數為陣列的行數
  
  for i := 1 to n do
    for j := 1 to m do
      frm2arr.SgdMy.Cells[i-1, j-1] := IntToStr(arr[j][i]);
end;

這個版本的TableOutput函式實作了陣列的轉置顯示。與前一個版本的主要區別在於:1) StringGrid的維度設定為n列m行,與原始陣列的m列n行相反;2) 存取陣列元素時使用arr[j][i]而非arr[i][j],實作了行列互換。這種轉置技巧在處理矩陣運算或改變資料呈現方式時非常有用。

二維陣列實作練習

以下是幾個二維陣列的實作練習,可以幫助鞏固對二維陣列操作的理解。

練習1:陣列統計分析

填充一個M列N行的二維陣列,範圍由使用者輸入,然後計算:

  • 所有元素的總和
  • 最大和最小元素
  • 每列元素的總和

這個練習需要實作多種陣列操作:填充、遍歷、查詢最值、分組計算等。

練習2:實數陣列與行和

填充一個N行M列的實數陣列,範圍由使用者輸入,然後:

  • 將陣列輸出到StringGrid
  • 計算每行元素的總和並顯示在每行的額外儲存格中

這個練習結合了陣列操作和UI顯示技巧,特別適合練習StringGrid的進階使用。

日期與時間處理

在許多應用程式中,日期和時間的處理是基本需求。Delphi提供了強大的日期時間處理功能,下面將介紹其核心概念和常用操作。

TDateTime資料型別

Delphi中使用特殊的TDateTime資料型別來處理日期和時間:

Var
  a, b: TDateTime;

TDateTime本質上是一個雙精確度浮點數,其整數部分代表自1899年12月30日以來經過的天數,小數部分則代表一天中的時間比例。例如,0.5代表中午12點,0.75代表下午6點。

這種設計使日期時間計算變得簡單:

  • 兩個日期相減得到的是天數差
  • 日期加上或減去一個數字,結果是向前或向後推算的日期

需要注意的是,處理負值TDateTime時需要特別小心。例如,1899年12月29日早上6點表示為-1.25,而不是-0.75(-1+0.25)。

日期時間解碼函式

Delphi提供了多種函式來解析TDateTime值:

// 解析日期部分
DecodeDate(Date: TDateTime; var Year, Month, Day: Word);

// 解析時間部分
DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word);

DecodeDate函式將TDateTime值分解為年、月、日三個部分。例如,如果變數A儲存的日期是2008年3月1日,則呼叫DecodeDate(A, y, m, d)後會得到y=2008, m=3, d=1。

DecodeTime函式則將TDateTime值分解為時、分、秒、毫秒四個部分。這兩個函式在需要單獨操作日期或時間的各個部分時非常有用。

取得當前日期時間

取得當前日期和時間是常見需求:

Var
  a, b, c: TDateTime;
Begin
  a := Date;  // 回傳當前日期
  b := Time;  // 回傳當前時間
  c := Now;   // 回傳當前日期和時間
End;

這三個函式分別取得系統當前的日期、時間或兩者。它們依賴於電腦的系統設定,因此如果系統日期時間不準確,這些函式回傳的值也會不準確。在需要高精確度時間的應用中,可能需要考慮與標準時間源同步。

日期時間與字串轉換

Delphi提供了完整的日期時間與字串互相轉換的函式:

// 時間轉字串
TimeToStr(t: TDateTime): String;

// 日期轉字串
DateToStr(t: TDateTime): String;

// 日期時間轉字串
DateTimeToStr(t: TDateTime): String;

// 字串轉時間
StrToTime(S: String): TDateTime;

// 字串轉日期
StrToDate(S: String): TDateTime;

// 字串轉日期時間
StrToDateTime(S: String): TDateTime;

這些函式實作了TDateTime與字串格式之間的互相轉換。格式化時會使用系統的地區設定,如LongTimeFormatShortDateFormat等。例如,DateToStr可能會將日期格式化為'03:04:2015’。

從字串轉換時需要注意一些規則:

  • 時間字串可以省略秒數,如'9:10’會被轉換為'9:10:00'
  • 日期必須有效
  • 如果年份只有兩位數,會被自動轉換為1930-2030範圍內的年份
  • 如果未指定年份,會使用當前年份
  • 日期和月份必須指定

其他日期時間函式

Delphi還提供了許多其他實用的日期時間函式:

// 取得星期幾(1=星期日,2=星期一,...
DayOfWeek(Date: TDateTime): Word;

// 解析日期並判斷是否閏年
DecodeDateFully(Date: TDateTime; var Year, Month, Day, DOW: Word): Boolean;

// 從年月日合成日期
EncodeDate(Year, Month, Day: Word): TDateTime;

// 從時分秒毫秒合成時間
EncodeTime(Hour, Min, Sec, Msec: Word): TDateTime;

這些函式提供了更專門的日期時間處理功能。DayOfWeek回傳星期幾的索引值,DecodeDateFully不僅解析日期還回傳是否閏年,EncodeDateEncodeTime則是從各個部分合成日期或時間值。這些函式在排程、日曆或需要精確日期計算的應用中特別有用。

日期時間運算

TDateTime型別支援多種運算:

  • 兩個日期相減得到的是中間相差的天數
  • 日期加上或減去整數,相當於向前或向後計算對應天數的日期
  • 時間可以透過多種方式進行計算

例如,計算1.5小時後的時間有兩種方式:

// 方式1:直接加上天數的比例(1.5小時等於1.5/24天)
新時間 := Time + 1.5/24;

// 方式2:使用時間字串轉換
新時間 := Time + StrToTime('1:30');

這兩種計算方式都能達到相同的效果。第一種方式直接使用了TDateTime的特性,將1.5小時轉換為天的比例(1.5/24);第二種方式則更直觀,直接使用時間字串。選擇哪種方式主要取決於程式的具體需求和開發者的偏好。

日期時間應用練習

讓我們透過兩個實際練習來加深對日期時間處理的理解。

練習1:找出最年輕的

時間控制的藝術:計時器元件的基礎與應用

在程式開發中,時間控制是一個常見但又極為重要的需求。無論是建立動畫效果、執行定期任務,還是處理時間相關的計算,計時器都是不可或缺的工具。在這篇文章中,我將探討計時器的使用方法、核心概念以及進階應用技巧。

計時器的基本原理與特性

計時器(Timer)是一個能夠在設定的時間隔後觸發事件的元件。當開發需要在特定時間後執行某些程式碼時,計時器提供了一個簡潔而強大的解決方案。

在介面開發工具中,計時器通常是一個不可見的元件,它在執行時不會在使用者介面上顯示,但會在後台持續計時並觸發已設定的事件。

計時器的核心屬性包括:

Enabled 屬性

這個布林值屬性決定計時器是否運作。當設為 True 時,計時器開始運作;設為 False 時,計時器停止。

Interval 屬性

這個屬性指定計時器的反應時間,單位為毫秒。例如,設定為 1000 表示計時器每秒觸發一次事件;設定為 5000 則表示每 5 秒觸發一次。

計時器的基本應用

讓我們從一個簡單的例子開始。假設我們想要在程式啟動 5 秒後將表單背景變為紅色:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  form1.Color := clRed;
end;

在這個例子中,我們需要將計時器的 Interval 屬性設為 5000(5秒),當計時器觸發時,表單的背景色將變為紅色。

這段程式碼定義了計時器觸發事件的處理程式。當計時器達到設定的時間隔(5000毫秒)時,系統會自動呼叫此程式,執行 form1.Color := clRed 這行程式碼,將表單背景顏色設為紅色。這是最基本的計時器應用,展示瞭如何在特定時間後執行動作。

動態控制計時器

計時器的真正威力在於我們可以在程式執行過程中動態控制它。例如,我們可以在使用者點選按鈕後才啟動計時器:

procedure TForm1.Button1Click(Sender: TObject);
begin
  timer1.Enabled := true;
end;

在這種情況下,我們需要在設計時將計時器的 Enabled 屬性設為 False。程式啟動後,計時器不會運作,直到使用者點選按鈕,計時器才會啟動,並在 5 秒後將表單變為紅色。

這段程式碼展示瞭如何透過按鈕點選事件來控制計時器的啟動。當使用者點選按鈕時,程式將計時器的 Enabled 屬性設為 true,從而啟動計時器。這種方式讓開發者能夠根據使用者操作來精確控制計時器的行為,而不是讓計時器在程式啟動時就立即運作。

創造動態視覺效果

計時器的一個常見應用是創造動態視覺效果。讓我們修改之前的例子,使表單背景色每隔一段時間就隨機變化:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  form1.Color := 256*256*random(256) + 256*random(256) + random(256);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  timer1.Enabled := true;
  timer1.Interval := 1500;
end;

在這個例子中,每 1.5 秒,表單的背景色就會變成一個隨機顏色。

計時器事件處理程式中的程式碼使用 random(256) 函式生成三個隨機數值(分別對應 RGB 色彩模型的紅、綠、藍三個分量),然後透過數學運算將它們組合成一個顏色值。這種技術可以創造出豐富多彩的視覺效果。

按鈕點選事件不僅啟動了計時器,還將計時器的間隔設定為 1500 毫秒(1.5秒),這樣每隔 1.5 秒顏色就會變換一次。這展示瞭如何在執行時動態調整計時器的屬性。

控制計時器的停止

要停止計時器,我們只需要將 Enabled 屬性設為 False:

procedure TForm1.Button2Click(Sender: TObject);
begin
  timer1.Enabled := false;
end;

這樣,我們就可以透過一個按鈕啟動計時器,透過另一個按鈕停止它。

這個簡單的程式碼片段展示瞭如何停止計時器的執行。當使用者點選第二個按鈕時,計時器的 Enabled 屬性被設定為 false,此時計時器停止運作,不再觸發事件。這種控制方式讓使用者能夠完全掌控程式中的時間相關功能。

單次觸發計時器

有時我們只希望計時器觸發一次,而不是持續觸發。這可以透過在計時器事件中關閉計時器來實作:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  form1.Color := 256*256*random(256) + 256*random(256) + random(256);
  timer1.Enabled := false;
end;

這樣,計時器會觸發一次,改變表單顏色,然後自動關閉。

這個程式碼片段展示瞭如何建立"一次性"計時器。關鍵在於在計時器事件處理程式的最後一行,將計時器自身的 Enabled 屬性設為 false。這樣,計時器在執行完指定動作後會立即停止,不再繼續觸發。這種模式非常適合只需執行一次的延時操作。

使用多個計時器

更複雜的時間控制需求可能需要使用多個計時器協同工作。例如,我們可以使用一個計時器來改變顏色,使用另一個計時器來在特定時間後停止第一個計時器:

procedure TForm1.Button1Click(Sender: TObject);
begin
  timer1.Enabled := true;
  timer1.Interval := 1500;
  timer2.Enabled := true;
  timer2.Interval := 20000;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  form1.Color := 256*256*random(256) + 256*random(256) + random(256);
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  timer1.Enabled := false;
  timer2.Enabled := false;
end;

在這個例子中,點選按鈕後,表單顏色會開始每 1.5 秒變化一次,然後在 20 秒後停止變化。

這個範例展示了多計時器協作的強大功能。第一個計時器(timer1)負責每 1.5 秒改變一次表單顏色,而第二個計時器(timer2)則負責在 20 秒後停止整個過程。

按鈕點選事件同時啟動兩個計時器,但設定了不同的時間隔。第二個計時器的事件處理程式會同時停用兩個計時器,確保在 20 秒後整個過程完全結束。這種多計時器協作模式可以實作更複雜的時間控制邏輯。

建立移動效果

計時器還可以用來建立移動效果。例如,我們可以使一個文字框從左向右移動:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  edit1.Left := edit1.Left + 15;
end;

每次計時器觸發時,文字框會向右移動 15 個畫素,建立一個平滑的移動效果。

這段程式碼展示瞭如何使用計時器建立動畫效果。每次計時器觸發時,程式會增加文字框的 Left 屬性值(水平位置),使其向右移動 15 個畫素。如果計時器設定為較短的間隔(如 50 毫秒),這種移動會看起來非常平滑,形成一個簡單但有效的動畫。這種技術可以擴充套件到更複雜的動畫和遊戲開發中。

實用的計時器應用範例

讓我們來看一些實用的計時器應用範例,這些例子展示了計時器在不同場景下的強大功能。

數字時鐘的實作

數字時鐘是計時器的一個典型應用。以下是一個簡單的數字時鐘實作:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  CurrentTime: TDateTime;
  TimeStr, DateStr, DayStr: string;
begin
  CurrentTime := Now;
  TimeStr := FormatDateTime('hh:nn:ss', CurrentTime);
  DateStr := FormatDateTime('yyyy-mm-dd', CurrentTime);
  
  case DayOfWeek(CurrentTime) of
    1: DayStr := '星期日';
    2: DayStr := '星期一';
    3: DayStr := '星期二';
    4: DayStr := '星期三';
    5: DayStr := '星期四';
    6: DayStr := '星期五';
    7: DayStr := '星期六';
  end;
  
  lblTime.Caption := TimeStr;
  lblDate.Caption := DateStr;
  lblDay.Caption := DayStr;
end;

這段程式碼實作了一個完整的數字時鐘功能。它使用 Now 函式取得當前的日期和時間,然後使用 FormatDateTime 函式將其格式化為時間字元串和日期字元串。

DayOfWeek 函式回傳一個介於 1 到 7 之間的整數,代表星期幾(1 代表星期日,7 代表星期六)。程式使用一個 case 陳述式將這個數值轉換為對應的星期文字。

最後,程式將格式化好的時間、日期和星期幾顯示在對應的標籤上。如果計時器間隔設為 1000 毫秒(1秒),這個時鐘將每秒更新一次,顯示當前的精確時間。

倒計時計時器

倒計時計時器在許多應用中都很有用,如遊戲、測驗或任何需要時間限制的場景:

var
  SecondsLeft: Integer;

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    SecondsLeft := StrToInt(Edit1.Text);
    lblTimer.Color := clWhite;
    timer1.Enabled := true;
  except
    ShowMessage('請輸入有效的秒數!');
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Dec(SecondsLeft);
  lblTimer.Caption := IntToStr(SecondsLeft);
  
  if SecondsLeft <= 0 then
  begin
    lblTimer.Color := clRed;
    // 如果到達零,計時器改為計算超時間
    SecondsLeft := Abs(SecondsLeft);
  end;
end;

這段程式碼實作了一個倒計時計時器,具有超時計算功能。首先,它在按鈕點選事件中從輸入框取得初始秒數,並啟動計時器。程式使用 try-except 塊來確保輸入的是有效的數字。

在計時器事件中,程式每秒減少計數器的值(使用 Dec 函式),並更新標籤顯示當前剩餘時間。當計數器達到或低於零時,標籤的背景色變為紅色,表示時間已經用完。

有趣的是,一旦計數器變為負數,程式使用 Abs 函式將其轉換為正數,這樣就開始計算超時間。這種技術在需要跟蹤超出允許時間的情況下非常有用。