C++Builder 內建的 InputBox 與 InputQuery 雖方便,但有兩大缺點:按鈕固定為英文「OK/Cancel」,且不支援密碼輸入遮罩(星號)。本文示範如何複製並修改 VCL 核心單元 Dialogs.pas 中的 InputQuery 函式,實現全中文介面、可調整字體大小、以及透過特定預設字串觸發密碼模式的客製化輸入對話框。
$(BCB)\Source\Vcl\Dialogs.pas 至專案目錄。InputQuery 函式(約 1857–1927 行),替換為客製化版本。Dialogs.pas(Project → Add to Project)。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 字體顯示不全問題 | 若專案多語系,建議改用資源字串而非硬編碼中文 |
#PWD#),避免衝突。OnKeyPress 事件攔截 Enter/Esc 鍵,強化鍵盤操作體驗。TInputDialog 元件封裝相同邏輯,較易維護。此法雖屬「修改 VCL 源碼」的偏方,但在舊版 BCB 專案快速中文化、解決字體相容性問題時極為實用,掌握其原理後可舉一反三客製化其他內建對話框。