首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Delphi 編輯框與位圖按鈕的 Enter 鍵衝突問題分析與解決

     編輯:更多程式設計知識

現象描述

表單上有 `Edit1`、`Edit2` 兩個編輯框與一個 `BitBtn1`。
`Edit1.OnKeyPress`:按 Enter 時設 `Edit2.Text := 'Edit1有效'`。
`BitBtn1.OnClick`:設 `Edit2.Text := 'Edit1無效'`。
當 `BitBtn1.Kind = bkOK`(顯示綠色勾號)時,在 `Edit1` 按 Enter,**竟觸發 `BitBtn1.OnClick`**,導致顯示「Edit1無效」,`Edit1` 的 `OnKeyPress` 完全失效。

根本原因

Delphi 表單的預設按鈕機制:
當某按鈕的 `Kind` 為 `bkOK`、`bkYes` 等「確認類」時,該按鈕成為表單的 **Default Button**(對應 `Form.DefaultButton` 屬性)。使用者在表單任一編輯框按 Enter,系統會模擬點擊該預設按鈕,直接觸發其 `OnClick` 事件,**繞過** 當前控制項的 `OnKeyPress`/`OnKeyDown` 等鍵盤事件。

驗證與重現

  1. 新建專案,放入 `Edit1`、`Edit2`、`BitBtn1`。
  2. 設 `BitBtn1.Kind = bkOK`。
  3. 編寫上述事件代碼。
  4. 執行,在 `Edit1` 輸入文字後按 Enter → `Edit2` 顯示「Edit1無效」。

解決方案

方法適用情境操作步驟
移除預設按鈕行為不需要 Enter 觸發按鈕設 `BitBtn1.Kind = bkCustom`,或在 `FormCreate` 設 `Form1.DefaultButton := nil`。
在 OnKeyPress 處理 Enter 並設 Key = #0需保留編輯框自行處理 Enter
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
  begin
    Edit2.Text := 'Edit1有效';
    Key := #0; // 吞掉 Enter,阻止表單預設按鈕處理
  end;
end;
使用 Form.KeyPreview = True集中在表單層級攔截鍵盤設 `Form.KeyPreview := True`,在 `FormKeyPress` 判斷 `ActiveControl` 為 `Edit1` 時處理 Enter。

最佳實務建議

  • **避免在資料輸入表單將確認類按鈕設為 `bkOK`**,除非確實希望 Enter=送出表單。
  • 若需 Enter 在編輯框間移動焦點,可在 `OnKeyPress` 設 `Key := #0` 並呼叫 `SelectNext(ActiveControl, True, True)`。
  • 定期檢視 `Form.DefaultButton`、`Form.CancelButton` 屬性,確保符合使用者體驗預期。

延伸知識

同樣地,`Kind = bkCancel` 的按鈕會成為 `Form.CancelButton`,按 Esc 會觸發其 `OnClick`。此機制源自 Windows 對話框標準行為,Delphi 透過 `TForm` 封裝實現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved