C++Builder 內建 InputBox/InputQuery 缺點明顯:按鈕標題為英文、字型顯示不全、無密碼模式、無圖示支援。修改 VCL 原始碼維護成本高,利用自訂訊息機制可在不修改 VCL 前提下優雅擴展功能。
InputBox 顯示前,主視窗 PostMessage 送出自訂訊息WndProc 攔截訊息Screen->Forms[0]),修改其屬性與子控制項
#define MY_INPUT_BOX WM_USER + 101
public:
void __fastcall WndProc(TMessage &Msg);
void __fastcall TfrmMain::WndProc(TMessage &Msg) {
if (Msg.Msg == MY_INPUT_BOX) {
// WParam: 0=一般模式, 1=密碼框模式
// LParam: 0=一般模式, 1=帶圖片模式
TForm *frm = Screen->Forms[0];
if (frm != this) { // 確認是輸入框視窗
// 統一字型 (建議主視窗設為新細明體 9pt)
frm->Font->Assign(Font);
// 中文化按鈕
HWND hBtnOK = FindWindowEx(frm->Handle, NULL, "TButton", "OK");
HWND hBtnCancel = FindWindowEx(frm->Handle, NULL, "TButton", "Cancel");
if (hBtnOK) SetWindowText(hBtnOK, "確定(&O)");
if (hBtnCancel) SetWindowText(hBtnCancel, "取消(&C)");
// 加入圖片 (左下角)
if (Msg.LParam == 1) {
TImage *img = new TImage(frm); // Owner=frm, 自動釋放
img->Picture->Assign(Application->Icon);
img->Left = 11;
img->Top = 60;
img->Parent = frm;
img->Show();
}
// 密碼模式
if (Msg.WParam == 1) {
HWND hEdit = FindWindowEx(frm->Handle, NULL, "TEdit", NULL);
if (hEdit)
SendMessage(hEdit, EM_SETPASSWORDCHAR, WPARAM('*'), 0);
}
}
}
TForm::WndProc(Msg); // 傳遞給基類處理
}
void __fastcall TfrmMain::btnOldStyleClick(TObject *Sender) {
String strText = InputBox("原先的輸入對話框", "請輸入一些字符:", "");
if (strText.Trim().Length() > 0) ShowMessage(strText);
}
❌ 按鈕英文、字型醜陋、無密碼/圖片支援
void __fastcall TfrmMain::btnNewStyleClick(TObject *Sender) {
PostMessage(Handle, MY_INPUT_BOX, 0, 0); // 關鍵:發送自訂訊息
String strText = InputBox("新的輸入對話框", "請輸入一些字符:", "");
if (strText.Trim().Length() > 0) ShowMessage(strText);
}
✅ 中文按鈕、統一字型、顯示正常
void __fastcall TfrmMain::btnWithImageClick(TObject *Sender) {
PostMessage(Handle, MY_INPUT_BOX, 0, 1); // LParam=1 表示帶圖片
String strText = InputBox("帶圖片效果的輸入框", "請輸入一些字符:", "呵呵,帶圖片的");
if (strText.Trim().Length() > 0) ShowMessage(strText);
}
✅ 左下角顯示應用程式圖示
void __fastcall TfrmMain::btnPwdStyleClick(TObject *Sender) {
PostMessage(Handle, MY_INPUT_BOX, 1, 0); // WParam=1 表示密碼模式
String strText = InputBox("密碼輸入框", "請輸入您的密碼:", "123");
if (strText.Trim().Length() > 0) ShowMessage(strText);
}
✅ 輸入字元顯示為 *
FindWindowEx 依類別名/標題尋找子視窗,VCL 按鈕類別為 TButton,編輯框為 TEditEM_SETPASSWORDCHAR 編輯框訊息設定密碼遮罩字元TImage 指定 Owner=frm 確保對話框關閉時自動釋放資源WParam 控制功能模式,LParam 控制視覺增強,可擴展更多組合| 優點 | 缺點 |
|---|---|
| 零修改 VCL 原始碼 | 依賴 VCL 內部視窗結構 (TButton/TEdit 類別名) |
| 邏輯集中在主視窗,易維護 | 僅適用於單執行緒 UI 應用 |
| 支援任意組合擴展 | 若 VCL 版本大幅變更結構可能失效 |