SendMessage和PostMessage都不起作用,求助

cscity 2011-01-28 01:00:55
有个软件的Combo box可以用1/2/3按键来快速选择其下拉列表中的对应选项,但是我用SendMessage或PostMessage向其发送1/2/3的模拟按键消息都不起作用.

SendMessage(hwind,WM_SETFOCUS,0,0);
SendMessage(hwind,WM_KEYDOWN,0x33,0x00040001);
SendMessage(hwind,WM_KEYUP,0x33,0xC0040001);
SendMessage(hwind,WM_KILLFOCUS,0,0);

换成PostMessage也不行,句柄没问题,因为SendMessage(hwind,CB_SHOWDROPDOWN,1,0)是有反应的,直接发WM_CHAR消息也无效

我直接用键盘按1/2/3按键时,spy++拦截到的是这样的消息

<00028> 00680EA4 P WM_KEYDOWN nVirtKey:'2' cRepeat:1 ScanCode:03 fExtended:0 fAltDown:0 fRepeat:0 fUp:0 [wParam:00000032 lParam:00030001 time:147:08:51.578 point:(327, 295)]
<00029> 00680EA4 S CB_GETCOUNT wParam:00000000 lParam:00000000
<00030> 00680EA4 R CB_GETCOUNT cItems:3 [lResult:00000003]
<00031> 00680EA4 S CB_GETCURSEL wParam:00000000 lParam:00000000
<00032> 00680EA4 R CB_GETCURSEL index:0 [lResult:00000000]
<00033> 00680EA4 S CB_SETCURSEL index:1 [wParam:00000001 lParam:00000000]
<00034> 00680EA4 R CB_SETCURSEL lResult:0001 [lResult:00000001]
<00035> 00680EA4 P WM_KEYUP nVirtKey:'2' cRepeat:1 ScanCode:03 fExtended:0 fAltDown:0 fRepeat:1 fUp:1 [wParam:00000032 lParam:C0030001 time:147:08:51.625 point:(327, 295)]



但是我用SendMessage或PostMessage发送模拟按键时,用spy++却拦截不到CB_GETCOUNT,CB_GETCURSEL,CB_SETCURSEL消息,这是怎么回事呢,要怎样模拟1/2/3的按键才有效啊
...全文
815 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
许文君 2011-01-29
  • 打赏
  • 举报
回复
不要对COMBO去发送按键,它有自己的消息处理,你先直接对对话框的HWND发送WM_KEYDOWN看看。我估计对消息做了处理。其实源代码也就是先GETCOUNT 再SETCURSEL,没必要纠结非要如何。
yiruirui0507 2011-01-29
  • 打赏
  • 举报
回复
::SendMessage(hwind,CB_SELECTSTRING,-1,(LPARAM)"2");
jacky_qiu 2011-01-29
  • 打赏
  • 举报
回复
1.SendMessage 模拟按键有可能不会成功的。这里面的问题很复杂。
这里有些参考资料:
http://hi.baidu.com/qiujiejia/blog/item/06e5f24c43e7a9ebd62afc7d.html

2.你可以keybd_event模拟按键,这个基本是万能的,但缺点是必须先
设置为前台窗口或焦点窗口。
::SetForegroundWindow(combownd); //设置前台
keybd_event('1',0,0,0);
keybd_event('1',0,KEYEVENTF_KEYUP,0);

3.你用SendMessage不成功还有可能是因为你向combobox发送WM_KEYDOWN了
但Combobox里面还有一个Edit子窗口啊(用Spy++查看就知道了),你可以尝试向这个Edit窗口发送模拟按键消息。

4.愿顺利!阿弥陀佛!
cscity 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 bokutake 的回复:]
可能人家是用键盘钩子实现的,你用SendMessage肯定不行。
[/Quote]


不是键盘钩子,我用autoit的sendkey发送模拟按键就可以选中对应的项,但是用VC的sendmessage居然不行,可是sendkey只能用在前台程序上,所以我想改用sendmessage,
而且那个程序是做测试的,不是游戏,没有理由要Hook键盘
cscity 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 stonewater 的回复:]
SendMessage(hwind,WM_SETFOCUS,0,0);
PostMessage(hwind,WM_KEYDOWN,0x33,0x00040001);
PostMessage(hwind,WM_KEYUP,0x33,0xC0040001);
SendMessage(hwind,WM_KILLFOCUS,0,0);
试试呢,
你是一个程序往另一个程序发消息吗
[/Quote]

试了,还是不行,Combo box闪了一下,没反应

我是从一个程序操作另一个程序,另一个程序没有源代码

keybd_event()我没用过,要怎样用?另一个程序是不是一定要在前台?

辰岡墨竹 2011-01-28
  • 打赏
  • 举报
回复
可能人家是用键盘钩子实现的,你用SendMessage肯定不行。
stonewater 2011-01-28
  • 打赏
  • 举报
回复
不行就要用keybd_event这个函数了
先要使combobox设置焦点,再使用keybd_event函数
stonewater 2011-01-28
  • 打赏
  • 举报
回复
SendMessage(hwind,WM_SETFOCUS,0,0);
PostMessage(hwind,WM_KEYDOWN,0x33,0x00040001);
PostMessage(hwind,WM_KEYUP,0x33,0xC0040001);
SendMessage(hwind,WM_KILLFOCUS,0,0);
试试呢,
你是一个程序往另一个程序发消息吗
cscity 2011-01-28
  • 打赏
  • 举报
回复
难道SendMessage都不能模拟出真实按键的效果吗
cscity 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 stonewater 的回复:]
那几个消息应该是他在相应的函数里自己处理时产生的,因为正常情况下按"7"时,不可能选中"打开",所以他要判断输入的是否是7,然后再在所有的选项中定位到"打开",
CB_GETCOUNT是获取有多少项,估计一个一个比较确定index,然后CB_SETCURSEL定位到对应的项
[/Quote]


那我到底要怎要模拟这个"7"的按键呢
stonewater 2011-01-28
  • 打赏
  • 举报
回复
那几个消息应该是他在相应的函数里自己处理时产生的,因为正常情况下按"7"时,不可能选中"打开",所以他要判断输入的是否是7,然后再在所有的选项中定位到"打开",
CB_GETCOUNT是获取有多少项,估计一个一个比较确定index,然后CB_SETCURSEL定位到对应的项
cscity 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xuddk727 的回复:]
你确定是焦点在COMBOBOX下时按下有效?具体可以看看它怎么处理的消息。
我估摸着应该是向主窗口发送消息,或者直接keybd_event
[/Quote]

确定是当焦点在COMBOBOX下时按下才有效,否则无效

当我用键盘按1时,spy++可以拦截到的消息依次为
WM_KEYDOWN,CB_GETCURSEL,CB_GETCOUNT,CB_SETCURSEL,WM_KEYUP

而我用PostMessage或SendMessage模拟时,拦截到的消息依次为:
WM_KEYDOWN,WM_KEYUP,WM_CHAR

这就奇怪了,CB_GETCURSEL,CB_GETCOUNT,CB_SETCURSEL这三个消息到底是怎么触发的呢

因为我没有那个程序的源代码,我认为SendMessage应该可以达到实际按键的效果吧,但是要怎么做呢
许文君 2011-01-28
  • 打赏
  • 举报
回复
你确定是焦点在COMBOBOX下时按下有效?具体可以看看它怎么处理的消息。
我估摸着应该是向主窗口发送消息,或者直接keybd_event
cscity 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 visualeleven 的回复:]
SendMessage(HWND_COMBOBOX, CB_SETCURSEL, (WPARAM)nItem, 0);
[/Quote]

我知道CB_SETCURSEL消息是可以的,但是由于某个条目未必会出现,且出现顺序也不固定,所以用CB_SETCURSEL消息比较麻烦,且未必可靠

我更想用按键消息来解决这个问题
cscity 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 stonewater 的回复:]
::SendMessage(hwind.m_hWnd,CB_SELECTSTRING,-1,(LPARAM)"2");

还有,你的ComboBox中是不是就是1,2,3等条目
[/Quote]

此软件ComboBox中条目数量是变化的,顺序也不固定,相应条目只在特定情况下出现,但是可以设定一个数字键来选择对应条目,
比如设定:
按下数字键"7"时,就选中"打开",
按下数字键"5"时,就选中"关闭",
按下数字键"9"时,就选中"等待",

因为不知道某个条目所在序号,以及是否会出现,所以我比较倾向于发模拟按键消息

Eleven 2011-01-28
  • 打赏
  • 举报
回复
SendMessage(HWND_COMBOBOX, CB_SETCURSEL, (WPARAM)nItem, 0);
stonewater 2011-01-28
  • 打赏
  • 举报
回复
::SendMessage(hwind,CB_SELECTSTRING,-1,(LPARAM)"2");
stonewater 2011-01-28
  • 打赏
  • 举报
回复
::SendMessage(hwind.m_hWnd,CB_SELECTSTRING,-1,(LPARAM)"2");

还有,你的ComboBox中是不是就是1,2,3等条目

16,472

社区成员

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

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

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