程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 通過消息實現自定義輸入框(InputBox)

通過消息實現自定義輸入框(InputBox)

編輯:關於C++

C++Builder提供了兩個顯示輸入對話框的函數:InputBox和InputQuery(其中InputBox也是通過調用InputQuery實現),這個輸入對話框有很多缺點,在以前的文章中我曾提到過利用修改VCL源碼來實現自定義輸入對話框,後來在Torry.net看到一篇文章是利用自定義消息的方法來實現,原文是Delphi代碼,ccrun(老妖)用C++改寫,並適當修改讓顯示效果更好一些:

基本思路:在輸入對話框顯示出來以前,Post一條消息給主窗體,由主窗體負責修改輸入對話框窗體的屬性和輸入文字編輯框的屬性,在主窗體中通過重載WndProc函數來響應自定義消息。

代碼及效果圖如下:

.h文件中:

public:
void __fastcall WndProc(TMessage &Msg);

.cpp文件中:

// 自定義一個消息,通知主窗體進行輸入框的設置
#define MY_INPUT_BOX WM_USER + 101
//---------------------------------------------------------------------------
// 重載主窗體的WndProc實現自定義消息的處理
void __fastcall TfrmMain::WndProc(TMessage &Msg)
{
 if(Msg.Msg == MY_INPUT_BOX)
 {
  // Msg.WParam
  // 0: 普通模式, 1: 密碼框模式
  // Msg.LParam
  // 0: 普通模式, 1: 帶圖片的模式
  TForm *frm = Screen->Forms[0];
  if(frm != this) // 輸入框窗體
  {
   // 將輸入對話框的字體設為和主窗體一樣,建議將主窗體字體設為宋體9號
   frm->Font->Assign(Font);
   // 改變OK和Cancel按鈕的標題
   HANDLE hBtnOK = FindWindowEx(frm->Handle, NULL, "TButton", "OK");
   HANDLE hBtnCancel = FindWindowEx(frm->Handle, NULL, "TButton", "Cancel");
   if(hBtnOK)
    SetWindowText(hBtnOK, "確定(&O)");
   if(hBtnCancel)
    SetWindowText(hBtnCancel, "取消(&C)");
   // 是否需要顯示一個圖片
   if(Msg.LParam == 1)
   {
    // 新增一個圖片在窗體左下角,指定其Owner為輸入框窗體,
    // 這樣當輸入框窗體關閉時自動釋放TImage的資源
    TImage *img = new TImage(frm);
    img->Picture->Assign(Application->Icon);
    img->Left = 11;
    img->Top = 60;
    img->Parent = frm;
    img->Show();
   }
   
   // 是否為密碼框式 // 63 63 72 75 6E 2E 63 6F 6D
   if(Msg.WParam == 1)
   {
    HANDLE hEdit = FindWindowEx(frm->Handle, NULL, "TEdit", NULL);
    if(hEdit)
     SendMessage(hEdit, EM_SETPASSWORDCHAR, WPARAM('*'), 0);
   }
  }
 }
 TForm::WndProc(Msg);
}
原先的InputBox(圖1)void __fastcall TfrmMain::btnOldStyleClick(TObject *Sender)
{
 String strText = InputBox("原先的輸入對話框", "請輸入一些字符: ", "");
 if(strText.Trim().Length() > 0)
  ShowMessage(strText);
}

(圖1) 可以看到窗體上字符顯示不全,並且兩個按鈕的標題也是英文的。

改良後的效果(圖2)

void __fastcall TfrmMain::btnNewStyleClick(TObject *Sender)
{
 PostMessage(Handle, MY_INPUT_BOX, 0, 0); // 重點是這一句
 String strText = InputBox("新的輸入對話框", "請輸入一些字符: ", "");
 if(strText.Trim().Length() > 0)
  ShowMessage(strText);
}

(圖2) 經過改良後,字符顯示就比較漂亮了,按鈕標題也是中文的。

帶圖片的效果 (圖3)

void __fastcall TfrmMain::btnWithImageClick(TObject *Sender)
{
 // Msg.LParam = 1: 帶圖片的模式
 PostMessage(Handle, MY_INPUT_BOX, 0, 1);
 String strText = InputBox("帶圖片效果的輸入框", "請輸入一些字符: ", "呵呵,帶圖片的");
 if(strText.Trim().Length() > 0)
  ShowMessage(strText);
}

(圖3)帶圖片效果的輸入框

密碼輸入框效果(圖4)

void __fastcall TfrmMain::btnPwdStyleClick(TObject *Sender)
{
 // Msg.WParam = 1: 密碼框模式
 PostMessage(Handle, MY_INPUT_BOX, 1, 0);
 String strText = InputBox("密碼輸入框", "請輸入您的密碼: ", "123");
 if(strText.Trim().Length() > 0)
  ShowMessage(strText);
}

(圖4) 密碼輸入框的效果

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved