子类化实现DialogBox中Edit控件的WM_CHAR消息
2009-06-10 09:22
387 查看
这两天用Win32SDK重新实现一次MyWowToc,目的就是实践一下SDK编程的学习成果,这下严重体会到了在GUI方面Delphi对Win32的封装技术真是太强大了,为啥子现在才学SDK呢,主要为了后面搞DDK相关的东东。接着说主题吧,MyWowToc主要就是为 模仿wowtoc1.41,模仿就得像点吧,人家在Interface Version文本框中是不能输入除数字外的其它字符的,虽然将EDIT样式设为ES_NUMBER即可,但是这里主要为了熟悉SDK开发过程,况且以后可能会有其它的字符控制要求,这就想用WM_CHAR消息来自己控制EIDT中的输入,这个在Delphi、VC#和VC中都是很容易实现的,VC麻烦点,那也就是继承一下CEDIT类然后处理onChar函数就行了。可是我现在做的主窗口是DialogBox,这家伙的窗口处理过程不能响应WM_KEYDOWN、WM_CHAR等几个和输入焦点有关的消息。用GG搜索了好多网页,可能关键字不对都没有找到解决方案,最后在看雪论坛有位高人提到用子类化可以解决,但是没有给出具体的方案来,最后搜索到一遍文章,名为“关于MFC子类化(SubClassWindow)”,看过以后,茅塞顿开啊,原来这么简单。。直接上实例代码吧 容易理解。
#include <windows.h>
WNDPROC wpOrigEditProc;
//处理对话框消息
BOOL CALLBACK DialogProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
//处理自定义EDIT控件消息
LRESULT CALLBACK EditProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
//入口函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//显示对话框
DialogBox(NULL,(LPCTSTR)IDD_DIALOG,NULL,(DLGPROC) DialogProc);
return 0;
}
BOOL CALLBACK DialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
//用于保存EDIT控件的句柄
HWND hwndEdit=NULL;
switch (message)
{
case WM_COMMAND:
//根据文本框中的字符数,控制另一个按钮的状态,字符为5时按钮可用,否则不可用
if(HIWORD (wParam) == EN_CHANGE&&LOWORD(wParam)==IDC_ADDONVER_EDIT)
{
if ((int)SendMessage((HWND)lParam,EM_LINELENGTH,-1,0)==5)
{
EnableWindow(hWnd,TRUE);
}
else
{
EnableWindow(hWnd,FALSE);
}
}
case WM_INITDIALOG:
//取得EDIT控件的句柄
hwndEdit=GetDlgItem(hDlg,IDC_ADDONVER_EDIT);
//实现子类化,具体参数说明请查MSDN
wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit,GWL_WNDPROC,(LONG) EditProc);
break;
case WM_DESTROY:
SetWindowLong(hwndEdit, GWL_WNDPROC,(LONG) wpOrigEditProc);
break;
case WM_CLOSE:
EndDialog(hDlg,0);
return 1;
default:
return 0;
}
return 0;
}
LRESULT CALLBACK EditProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
//这里就是一直希望可以自己处理的WM_CHAR消息了,0-9和BackSpace键放行
if (uMsg==WM_CHAR)
{
if(!(wParam<='9'&&wParam>='0'))
{
if(!(wParam==VK_BACK))
return 0;
}
}
//调用原来的默认消息处理函数,和DefWindowProc意思一样
return CallWindowProc(wpOrigEditProc, hWnd, uMsg,wParam, lParam);
}
#include <windows.h>
WNDPROC wpOrigEditProc;
//处理对话框消息
BOOL CALLBACK DialogProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
//处理自定义EDIT控件消息
LRESULT CALLBACK EditProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
//入口函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//显示对话框
DialogBox(NULL,(LPCTSTR)IDD_DIALOG,NULL,(DLGPROC) DialogProc);
return 0;
}
BOOL CALLBACK DialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
//用于保存EDIT控件的句柄
HWND hwndEdit=NULL;
switch (message)
{
case WM_COMMAND:
//根据文本框中的字符数,控制另一个按钮的状态,字符为5时按钮可用,否则不可用
if(HIWORD (wParam) == EN_CHANGE&&LOWORD(wParam)==IDC_ADDONVER_EDIT)
{
if ((int)SendMessage((HWND)lParam,EM_LINELENGTH,-1,0)==5)
{
EnableWindow(hWnd,TRUE);
}
else
{
EnableWindow(hWnd,FALSE);
}
}
case WM_INITDIALOG:
//取得EDIT控件的句柄
hwndEdit=GetDlgItem(hDlg,IDC_ADDONVER_EDIT);
//实现子类化,具体参数说明请查MSDN
wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit,GWL_WNDPROC,(LONG) EditProc);
break;
case WM_DESTROY:
SetWindowLong(hwndEdit, GWL_WNDPROC,(LONG) wpOrigEditProc);
break;
case WM_CLOSE:
EndDialog(hDlg,0);
return 1;
default:
return 0;
}
return 0;
}
LRESULT CALLBACK EditProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
//这里就是一直希望可以自己处理的WM_CHAR消息了,0-9和BackSpace键放行
if (uMsg==WM_CHAR)
{
if(!(wParam<='9'&&wParam>='0'))
{
if(!(wParam==VK_BACK))
return 0;
}
}
//调用原来的默认消息处理函数,和DefWindowProc意思一样
return CallWindowProc(wpOrigEditProc, hWnd, uMsg,wParam, lParam);
}
相关文章推荐
- 资源文件里加入dialogbox的控件收不到wm_create消息
- Edit Control 控件属性 消息 笔记
- 子类化:增强Edit控件为日期输入控件
- 利用WM_CTLCOLOR消息实现编辑控制(Edit Control)的文本与背景色的改变
- WM_CHAR、WM_KEYDOWN和WM_SYSKEYDOWN消息
- 用WM_COPYDATA消息来实现两个进程之间传递数据
- 对话框中不到WM_CHAR消息
- C# 使用WM_NCLBUTTONDOWN消息实现任意位置移动窗体
- OnClick事件的Sender参数的前世今生——TWinControl.WinProc优先捕捉到鼠标消息,然后使用IsControlMouseMsg函数进行消息转发给图形子控件(意外发现OnClick是由WM_LBUTTONUP触发的)
- MFC中EDIT控件实现换行
- 通过WM_CTLCOLOREDIT 控制EDIT控件外观
- 控件截获主对话框WM_KEYDOWN消息后按键所发出的警告音
- MFC启用WM_PAINT消息实现避免文本信息因窗口重绘而消失
- 子类化:增强Edit控件为日期输入控件
- 用跨进程子类化技术实现对其它进程消息的拦载
- 窗体背景的绘制(Windows窗体每次都会重绘其窗体背景,所以我们可以通过拦截窗体重绘背景的消息(WM_ERASEBKGND),并自定义方法来实现重绘窗体背景)
- 利用WM_NCHITTEST消息实现无标题窗口的拖动
- EditText或者其他控件怎们实现一个蛇形动画,或者左右动画呢?
- 在C#中用WM_COPYDATA消息来实现进程间通信
- 使用WM_PASTE 和 WM_CHAR 消息时中文乱码总结