win32下,如何截获编辑框控件消息WM_KEYDOWN

right159 2012-05-18 09:00:44
void KeyChange( MSG msg )
{
switch( LOWORD(msg.wParam) )
{
case VK_DOWN:
SendMessage( msg.hwnd, EM_REPLACESEL, 0, (LPARAM)L"↓" );
break;
case VK_UP:
SendMessage( msg.hwnd, EM_REPLACESEL, 0, (LPARAM)L"↑" );
break;
case VK_LEFT:
SendMessage( msg.hwnd, EM_REPLACESEL, 0, (LPARAM)L"←" );
break;
case VK_RIGHT:
SendMessage( msg.hwnd, EM_REPLACESEL, 0, (LPARAM)L"→" );
break;
case VK_SPACE:
SendMessage( msg.hwnd, EM_REPLACESEL, 0, (LPARAM)L"〓" );
break;
}
}
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if( msg.message == WM_KEYDOWN )
{
if( GetParent( GetParent( msg.hwnd ) ) ) //判断是否为控件窗口
{
KeyChange( msg );
}
}
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

我想让对话框上的编辑框能响应方向键, 我是这样做的,在主消息循环里先判断WM_KEYDONW再判断控件窗口句柄然后发送消息替代原来编辑框文本内容,但没反映,难道对话框消息不是先从主消息循环这里开始的?


class CDialog
{
public:

CDialog();
static bool InitDialog( HWND hDlg, int *KeyValue );
static bool DefSet( HWND hDlg );
static bool FlishSet( HWND hDlg, LPTSTR UserName, int *KeyValue );

static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

static bool SetLimitText(HWND ChWnd, UINT nMax)
{
if( !IsWindow(ChWnd))
{
return false;
}
::SendMessage(ChWnd, EM_SETLIMITTEXT, nMax, 0);
return true;
}

void CreateDlg( int id, HWND hWnd )
{
DialogBox( hInst, MAKEINTRESOURCE(id), hWnd, (DLGPROC)About);
}
}; 另外,对话框窗口过程我写在类里面的。
...全文
582 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
right159 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

可以先用GetDlgItem获取edit的句柄,用SetWindowLong(edit句柄,GWL_WNDPROC,pNewWndproc)改变原edit的消息回调函数WndProc,具体见MSDN,或百度
[/Quote]

哦,你们的意思是要重新写个编辑框的窗口过程?。额,我不想那么麻烦,直接获取对应消息然后处理不行吗?
swent 2012-05-18
  • 打赏
  • 举报
回复
可以先用GetDlgItem获取edit的句柄,用SetWindowLong(edit句柄,GWL_WNDPROC,pNewWndproc)改变原edit的消息回调函数WndProc,具体见MSDN,或百度
right159 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

就是用你的窗口过程代替原来的窗口过程参考:SetWindowLong
[/Quote]

void CreateDlg( int id, HWND hWnd )
{
DialogBox( hInst, MAKEINTRESOURCE(id), hWnd, (DLGPROC)About);
}
对话框创建的不就是原来的吗? 一直都是about。如何代替?
schlafenhamster 2012-05-18
  • 打赏
  • 举报
回复
就是用你的窗口过程代替原来的窗口过程参考:SetWindowLong
right159 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

子类化Edit
[/Quote]

有没有具体的做法?,子类化不是太明白。
right159 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

楼主,我不是很明白你说的“发送消息替代原来编辑框文本内容”和“对话框窗口过程写在类里面”,你建立的是普通的win32还是MFC的,如果是普通的win32,那它的窗口过程应该是在注册窗口类的时候确定的
[/Quote]

建立的是win32, 注册的时候是确定,实现可以写在类里面的,现在就是想截获Edit控件的WM_KEYDOWN消息中的VK_方向键.. 就是说我在编辑框控件上按↑,编辑框文本内容上就会有↑ (原来编辑框不识别方向键)。
schlafenhamster 2012-05-18
  • 打赏
  • 举报
回复
子类化Edit
iytbihc 2012-05-18
  • 打赏
  • 举报
回复
楼主,我不是很明白你说的“发送消息替代原来编辑框文本内容”和“对话框窗口过程写在类里面”,你建立的是普通的win32还是MFC的,如果是普通的win32,那它的窗口过程应该是在注册窗口类的时候确定的
right159 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

C/C++ code
WNDPROC OldWndProc = NULL;

LRESULT CALLBACK NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_KEYDOWN:
{
Messa……
[/Quote]
直接在while (GetMessage(&msg, NULL, 0, 0))
{
if( msg.message == WM_KEYDOWN )
{
if( GetParent( GetParent( msg.hwnd ) ) ) //判断是否为控件窗口
{
KeyChange( msg );
}
}
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
弄到消息再处理不行吗?
Eleven 2012-05-18
  • 打赏
  • 举报
回复
WNDPROC OldWndProc = NULL;

LRESULT CALLBACK NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_KEYDOWN:
{
MessageBox(hWnd, _T("XX"), NULL, 0);
}
break;

default:
break;
}
return CallWindowProc(OldWndProc, hWnd, message, wParam, lParam);
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
HWND hEdit = GetDlgItem(hDlg, IDC_EDIT1);
if(hEdit)
{
OldWndProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (LONG)NewWndProc);
}
}
return TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。 消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。这个记录类型叫做TMsg,它在Windows单元中是这样声明的: type TMsg = packed record hwnd: HWND; //窗口句柄 message: UINT;//消息常量标识符 wParam: WPARAM ;// 32位消息的特定附加信息 lParam: LPARAM ;// 32位消息的特定附加信息 time: DWORD;//消息创建时的时间 pt: TPoint; //消息创建时的鼠标位置 end ; 消息中有什么? 是否觉得一个消息记录中的信息像希腊语一样?如果是这样,那么看一看下面的解释:hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可 视对象的句柄(窗口、对话框、按钮、编辑框等)。message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也 可以是自定义的常量。 wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 lParam 通常是一个指向内存中数据的指针。由于WParam、lParam和Pointer都是32位的,因此,它们之间可以相互转换。 WM_NULL =$0000 // WM_CREATE =$0001 //应用程序创建一个窗口 WM_DESTROY = $0002 //一个窗口被销毁 WM_MOVE = $0003 //移动一个窗口 WM_SIZE= $0005 //改变一个窗口的大小 WM_ACTIVATE= $0006 //一个窗口被激活或失去激活状态; WM_SETFOCUS= $0007 //获得焦点后 WM_KILLFOCUS= $0008 //失去焦点 WM_ENABLE= $000A //改变enable状态 WM_SETREDRAW= $000B //设置窗口是否能重画 WM_SETTEXT= $000C //应用程序发送此消息来设置一个窗口的文本 WM_GETTEXT = $000D //应用程序发送此消息来复制对应窗口的文本到缓冲区 WM_GETTEXTLENGTH = $000E //得到与一个窗口有关的文本的长度(不包含空字符) WM_PAINT = $000F //要求一个窗口重画自己 WM_CLOSE = $0010 //当一个窗口或应用程序要关闭时发送一个信号 WM_QUERYENDSESSION= $0011 //当用户选择结束对话框或程序自己调用ExitWindows函数 WM_QUIT= $0012 //用来结束程序运行或当程序调用postquitmessage函数 WM_QUERYOPEN = $0013 //当用户窗口恢复以前的大小位置时,把此消息发送给某个图标 WM_ERASEBKGND = $0014 //当窗口背景必须被擦除时(例在窗口改变大小时) WM_SYSCOLORCHANGE = $0015 //当系统颜色改变时,发送此消息给所有顶级窗口 WM_ENDSESSION = $0016 // 当系统进程发出WM_QUERYENDSESSION消息后,此消息发送给应用程序,通知它对话是否结束 WM_SYSTEMERROR = $0017 // WM_SHOWWINDOW= $0018 //当隐藏或显示窗口是发送此消息给这个窗口 WM_ACTIVATEAPP = $001C //发此消息给应用程序哪个窗口是激活的,哪个是非激活的; WM_FONTCHANGE= $001D //当系统的字体资源库变化时发送此消息给所有顶级窗口 WM_TIMECHANGE= $001E //当系统的时间变化时发送此消息给所有顶级窗口 WM_CANCELMODE= $001F //发送此消息来取消某种正在进行的摸态(操作) WM_SETCURSOR = $0020 //如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时,就发消息给某个窗口 WM_MOUSEACTIVATE = $0021 //当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给当前窗口 WM_CHILDACTIVATE = $0022 //发送此消息给MDI子窗口当用户点击此窗口的标题栏,或当窗口被激活,移动,改变大小 WM_QUEUESYNC= $0023 //此消息由基
特别感谢:山野 俊俊 小色 爱琴 Stone 黑月群测试帮助 乐源(参看了乐源MICROSKIN代码和思路) kyozy(封装的GDI+模块) 等、、、 2012.12.28.00:更新内容较多,请到官方下载! 2012.08.21.00: [+]增加宏函数Init_SUITypedf_AniImage 初始化SUITypedf_AniImage类型 [+]公开SUIWinOS()函数 用来获取当前系统 Win8识别由小色添加 [+]SUI_MsgBox()中增加信息框声音 [+]SUI_MsgBox()支持ctrl+c 可复制信息框内容 [+]SUI_Window.Ptr()增加lpSUI参数 回调子程序请参考SUI_Window.PtrSUICallBackDemo() 相当于子类化此窗口 [-]修改Metro风格下编辑框点燃状态的素材 [-]修正SUI_Window.AddEdit()中使用#SUI_EditType_PassWord样式时文本“”时创建Edit失败的Bug [-]修正当载入新窗口后关闭新窗口主窗口焦点丢失Bug,对hWnd合法性未检查 感谢[寥寥十七画。]提供此Bug [-]修正SUI_Window.Flash()刷新窗口可能存在的Bug [-]修正Win7下窗口为不可调时显示界面异常的Bug [-]修正Edit滑动外框时如果Progress滚动/光晕或有AniImage导致闪烁的绘制不全面问题 [-]修改所有例程到最新引擎 2012.08.20.00: [+]增加例程 SUIDemo(简单登陆框架)(BabyCrackMe界面).e SUIDemo(动画按钮例程).e [+]增加AniImage控件 可以作为动画框或动画按钮 SUI_Window.AddAniImage() SUI_Window.Control_AniImage() 来创建和控制AniImage [+]增加AniImage控件 #SUI_CallBack_AniImage_ 回调背景绘制处理事件 [+]SUI_Window.AddCheckBox()中增加bShadow参数 可设置CheckBox文本是否有阴影 [+]SUI_Window.AddEdit()中增加pImage bImageSize参数 用法与SUI_Window.AddButton()相同 [+]SUI_Window.Ptr()增加lpKeyDown lpKeyUp参数 回调参数等同于#WM_KEYDOWN #WM_KEYUP [+]SUI_Window.Data_Int()增加 #SUI_Member_Left #SUI_Member_Top #SUI_Member_Width #SUI_Member_Height 用来消息响应区域矩形 [+]SUI_Window.Control_Edit()增加pImage参数,可修改Edit图标 [+]公开SUIMeasureText()函数 用以测量测量文本矩形 [+]公开SUIDrawpGraphicText()函数 与SUIDrawGraphicText()不同的是它需要传入Graphic指针 [+]公开SUIDrawAniImageBkg()函数 用于绘制某按下背景 [+]公开P_SUITypedf_AniImage()函数 获取SUITypedf_AniImage指针 [-]修正SUI_Window.AddButton()中bImageSize参数自动识别计算图像失败的Bug [-]修正SUI_Window.Control_Image()中pHoverImage修改失效的Bug [-]修正Edit #SUI_EditType_PassWord样式下若选中全部密码再输入会导致乱码的Bug [-]修正部分情况下Edit提示音错误的Bug [+]修改所有例程支持最新版本引擎

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧