ZT:通过消息实现自定义输入框(InputBox)

C++Builder提供了两个显示输入对话框的函数:InputBoxInputQuery(其中InputBox也是通过调用InputQuery实现),这个输入对话框有很多缺点,在以前的文章中我曾提到过利用修改VCL源码来实现自定义输入对话框,后来在Torry.net看到一篇文章是利用自定义消息的方法来实现,原文是Delphi代码,ccrun(老妖)用C++改写,并适当修改让显示效果更好一些:

基本思路:在输入对话框显示出来以前,Post一条消息给主窗体,由主窗体负责修改输入对话框窗体的属性和输入文字编辑框的属性,在主窗体中通过重载WndProc函数来响应自定义消息。

代码及效果图如下:
.h文件中:
public:
void __fastcallWndProc(TMessage&Msg);

.cpp文件中:
//自定义一个消息,通知主窗体进行输入框的设置
#defineMY_INPUT_BOXWM_USER+101
//---------------------------------------------------------------------------
//重载主窗体的WndProc实现自定义消息的处理
void__fastcallTfrmMain::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按钮的标题
HANDLEhBtnOK=FindWindowEx(frm->Handle,NULL,"TButton","OK");
HANDLEhBtnCancel=FindWindowEx(frm->Handle,NULL,"TButton","Cancel");
if(hBtnOK)
SetWindowText(hBtnOK,"确定(&O)");
if(hBtnCancel)
SetWindowText(hBtnCancel,"取消(&C)");

//是否需要显示一个图片
if(Msg.LParam==1)
{
//新增一个图片在窗体左下角,指定其Owner为输入框窗体,
//这样当输入框窗体关闭时自动释放TImage的资源

TImage*img=newTImage(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)
{
HANDLEhEdit=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__fastcallTfrmMain::btnOldStyleClick(TObject*Sender)
{
StringstrText=InputBox("原先的输入对话框","请输入一些字符:","");
if(strText.Trim().Length()>0)
ShowMessage(strText);
}

(图1) 可以看到窗体上字符显示不全,并且两个按钮的标题也是英文的。

//---------------------------------------------------------------------------
改良后的效果(图2)
void __fastcallTfrmMain::btnNewStyleClick(TObject*Sender)
{
PostMessage(Handle,MY_INPUT_BOX,0,0);//重点是这一句
StringstrText=InputBox("新的输入对话框","请输入一些字符:","");
if(strText.Trim().Length()>0)
ShowMessage(strText);
}

(图2) 经过改良后,字符显示就比较漂亮了,按钮标题也是中文的。

//---------------------------------------------------------------------------
带图片的效果 (图3)
void __fastcallTfrmMain::btnWithImageClick(TObject*Sender)
{
//Msg.LParam=1:带图片的模式
PostMessage(Handle,MY_INPUT_BOX,0,1);
StringstrText=InputBox("带图片效果的输入框", "请输入一些字符:","呵呵,带图片的");
if(strText.Trim().Length()>0)
ShowMessage(strText);
}

(图3)带图片效果的输入框

//---------------------------------------------------------------------------
密码输入框效果(图4)
void __fastcallTfrmMain::btnPwdStyleClick(TObject*Sender)
{
//Msg.WParam=1:密码框模式
PostMessage(Handle,MY_INPUT_BOX,1,0);
StringstrText=InputBox("密码输入框","请输入您的密码:","123");
if(strText.Trim().Length()>0)
ShowMessage(strText);
}

(图4) 密码输入框的效果

你可能感兴趣的:(C++,c,C#,Delphi,C++Builder)