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

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

編輯:vc教程

C++Builder提供了兩個顯示輸入對話框的函數:InputBoxInputQuery(其中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) // 輸入框窗體
        {
            // 將輸入對話框的字體設為和主窗體一樣,建議將主窗體字體設為宋體Array號
            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)");
// 本文轉自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=620&d=w74av8
            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);
}
//---------------------------------------------------------------------------
// 抱歉,這個提示又來了,為了防止不負責任的轉載者,只好在此留些信息。
// by ccrun(老妖) [email protected]
// 歡迎訪問 C++Builder研究 - http://www.ccrun.com
//---------------------------------------------------------------------------
原先的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