首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

修改 VCL 源碼打造中文化與密碼遮罩的 InputQuery 對話框

     編輯:VC 教學

前言

C++Builder 內建的 InputBox 與 InputQuery 雖方便,但有兩大缺點:按鈕固定為英文「OK/Cancel」,且不支援密碼輸入遮罩(星號)。本文示範如何複製並修改 VCL 核心單元 Dialogs.pas 中的 InputQuery 函式,實現全中文介面、可調整字體大小、以及透過特定預設字串觸發密碼模式的客製化輸入對話框。

修改步驟概覽

  1. 複製 $(BCB)\Source\Vcl\Dialogs.pas 至專案目錄。
  2. 編輯 InputQuery 函式(約 1857–1927 行),替換為客製化版本。
  3. 專案加入修改後的 Dialogs.pas(Project → Add to Project)。
  4. 關閉「Build with runtime packages」(Project → Options → Packages)。
  5. 編譯執行,即可使用中文化、支援密碼遮罩的輸入對話框。

客製化 InputQuery 完整代碼

function InputQuery(const ACaption, APrompt: string;
    var Value: string): Boolean;
var
    Form: TForm;
    Prompt: TLabel;
    Edit: TEdit;
    DialogUnits: TPoint;
    ButtonTop, ButtonWidth, ButtonHeight: Integer;
begin
    Result := False;
    Form := TForm.Create(Application);
    with Form do
    try
        // 1. 設定中文字體與大小
        Font.Name := '新細明體';  // 繁體中文環境建議使用新細明體或微軟正黑體
        Font.Size := 9;
        Canvas.Font := Font;
        DialogUnits := GetAveCharSize(Canvas);

        BorderStyle := bsDialog;
        Caption := ACaption;
        ClientWidth := MulDiv(180, DialogUnits.X, 4);
        Position := poScreenCenter;

        // 2. 建立提示標籤
        Prompt := TLabel.Create(Form);
        with Prompt do
        begin
            Parent := Form;
            Caption := APrompt;
            Left := MulDiv(8, DialogUnits.X, 4);
            Top := MulDiv(8, DialogUnits.Y, 8);
            Constraints.MaxWidth := MulDiv(164, DialogUnits.X, 4);
            WordWrap := True;
        end;

        // 3. 建立編輯框,支援密碼模式
        Edit := TEdit.Create(Form);
        with Edit do
        begin
            Parent := Form;
            Left := Prompt.Left;
            Top := Prompt.Top + Prompt.Height + 5;
            Width := MulDiv(164, DialogUnits.X, 4);
            MaxLength := 255;
            Text := Value;
            // 若傳入預設字串為 "Password" 則啟用星號遮罩
            if Text = 'Password' then
                PasswordChar := '*';
            SelectAll;
        end;

        // 4. 建立「確定」按鈕
        ButtonTop := Edit.Top + Edit.Height + 15;
        ButtonWidth := MulDiv(50, DialogUnits.X, 4);
        ButtonHeight := MulDiv(14, DialogUnits.Y, 8);
        with TButton.Create(Form) do
        begin
            Parent := Form;
            Caption := '確定';          // 中文化
            ModalResult := mrOk;
            Default := True;
            SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth, ButtonHeight);
        end;

        // 5. 建立「取消」按鈕
        with TButton.Create(Form) do
        begin
            Parent := Form;
            Caption := '取消';          // 中文化
            ModalResult := mrCancel;
            Cancel := True;
            SetBounds(MulDiv(92, DialogUnits.X, 4), Edit.Top + Edit.Height + 15,
                ButtonWidth, ButtonHeight);
            Form.ClientHeight := Top + Height + 13;
        end;

        // 6. 顯示模態對話框並回傳結果
        if ShowModal = mrOk then
        begin
            Value := Edit.Text;
            Result := True;
        end;
    finally
        Form.Free;
    end;
end;

使用範例

// 一般輸入對話框
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    String strTemp = "";
    InputQuery("標題", "提示訊息", strTemp);
    ShowMessage(strTemp);
}

// 密碼輸入對話框:預設值傳 "Password" 即啟用星號遮罩
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    String strTemp = "Password";  // 觸發密碼模式的關鍵字
    InputQuery("密碼驗證", "請輸入密碼", strTemp);
    ShowMessage(strTemp);
}

設計考量與優缺點

優點缺點/注意事項
完全中文化介面,符合本地化需求需修改 VCL 源碼,升級 BCB 版本時需重新套用修改
支援密碼遮罩,且不影響一般輸入框以 "Password" 字串判斷屬硬編碼,若使用者真輸入 "Password" 會誤觸發
字體、大小、版面可自訂關閉 runtime packages 會增加執行檔體積
解決 Win98/2000 字體顯示不全問題若專案多語系,建議改用資源字串而非硬編碼中文

進階改良建議

  • 將觸發密碼模式的關鍵字改為不可見的 Unicode 控制字元或專屬前綴(如 #PWD#),避免衝突。
  • 將按鈕標題、字體名稱改為從資源檔或常數讀取,支援多語系切換。
  • 加入 OnKeyPress 事件攔截 Enter/Esc 鍵,強化鍵盤操作體驗。
  • 若不想修改 VCL,可自行撰寫 TInputDialog 元件封裝相同邏輯,較易維護。

此法雖屬「修改 VCL 源碼」的偏方,但在舊版 BCB 專案快速中文化、解決字體相容性問題時極為實用,掌握其原理後可舉一反三客製化其他內建對話框。

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