ZT:通过消息实现自定义输入框(InputBox)
2006-04-11 17:47
501 查看
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);
}
//---------------------------------------------------------------------------
// 抱歉,这个提示又来了,为了防止不负责任的转载者,只好在此留些信息。
// by ccrun(老妖) info@ccrun.com
// 欢迎访问 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) 密码输入框的效果
基本思路:在输入对话框显示出来以前,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);
}
//---------------------------------------------------------------------------
// 抱歉,这个提示又来了,为了防止不负责任的转载者,只好在此留些信息。
// by ccrun(老妖) info@ccrun.com
// 欢迎访问 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) 密码输入框的效果
相关文章推荐
- 通过消息实现自定义输入框(InputBox)
- 通过rosjava实现android订阅ROS自定义消息
- 窗体背景的绘制(Windows窗体每次都会重绘其窗体背景,所以我们可以通过拦截窗体重绘背景的消息(WM_ERASEBKGND),并自定义方法来实现重绘窗体背景)
- 通过自定义属性存储数据实现输入框获得焦点与失去焦点改变value值
- 一个流行且实用的JS表单验证提示,演示了怎么自定义错误信息的显示方式,同时通过写FormValid.showError类方法来实现错误显示方式自定义: errMsg 是一个错误消息的数组,这样方便自定
- 实现显示字数的输入框介绍关于自定义组合view的实现
- iPhone开发——通过代码自定义cell实现qq聊天界面
- 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他
- Android-自定义TitleBar 和 BadgeView (消息红点提示)的实现
- C# 通过IEnumberable接口和IEnumerator接口实现自定义集合类型foreach功能
- android 通过WebSocket 实现长连接通讯消息
- MFC中不同对话框间使用SendMessage发送自定义消息的具体实现
- MFC自定义消息的实现方法
- vc自定义消息的发送与接收的方法实现
- 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- android 通过回调实现 完全自定义Dialog 简单易用
- jQuery实现手机自定义弹出输入框
- 实现真正的非全屏窗口和自定义消息对话框
- 通过自定义.xml文件实现各种效果的SeekBar
- 通过Js实现输入框数字校验