注册 登录
编程论坛 C++教室

想对后台的记事本发送 Alt+E(打开编辑菜单),但一直不能成功

richardw 发布于 2014-09-07 16:33, 1619 次点击
前台的很好办,直接
SetForegroundWindow(m_hWnd);
SendMessage(m_hWnd, WM_SYSCOMMAND, SC_KEYMENU, (WPARAM)'E');
就可以,但不置前窗体的话,怎么发过去让记事本打开编辑菜单呢?
10 回复
#2
yuccn2014-09-07 19:02
SendMessage(m_hWnd, WM_SYSCOMMAND, SC_KEYMENU, (WPARAM)'E'); ‘E’这样不行吧,要找到键盘码才行的
#3
yuccn2014-09-07 19:07
应该有个key_event的,可以查询试试
#4
stop12042014-09-08 08:55
Ascii
E = 69
e = 101

而且要将字符转换为键代码则要强制转换为int型
(int )'e'  or  (int )'E'
#5
richardw2014-09-08 10:53
亲,先谢谢你对我的问题的关注,但你肯定没有试验吧,我原来发消息也这样子弄:
程序代码:

        PostMessage(m_hWnd, WM_SYSKEYDOWN, VK_MENU, MakeKeyLparam(VK_MENU, WM_SYSKEYDOWN));
        PostMessage(m_hWnd, WM_SYSKEYDOWN, 'E', MakeKeyLparam('E', WM_SYSKEYDOWN));         
        PostMessage(m_hWnd, WM_SYSCHAR, 'E', MakeKeyLparam('E', WM_SYSCHAR));               
        PostMessage(m_hWnd, WM_SYSKEYUP, 'E', MakeKeyLparam('E', WM_SYSKEYUP));            
        PostMessage(m_hWnd, WM_KEYUP, VK_MENU, MakeKeyLparam(VK_MENU, WM_KEYUP));           


但你试验一下就明白了,这些都不是关键,只要是有置前操作,就是把窗口搞成前台的SetForegroundWindow(m_hWnd);,那些都能成功

现在就是不知道如何给后台的程序发送成功

PS:keybd_event这些没句柄参数的,全都是给前台程序用的
#6
天使梦魔2014-09-08 15:20
如果是自己写的程序,方法多了,用共享内存,管道,等网上搜进程通信一大把
如果是未约定第三方程序,我就想到一个,钩子


SendMessage参数说明:
hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
#7
richardw2014-09-08 17:25
发送的对像不是自己做的程序,也没有条件改变它。

我可以得到它的窗口句柄 ,可以向它发送单个的键,比如ALT、F10、ABC之类的,只要是单键,都能发过去(它在后台的时候)

用钩子应该怎么实现发组合键?能大概地说一下思路吗?对钩子用得不多呢,谢谢啦
#8
天使梦魔2014-09-08 18:40
如果单键能发送那组合键也可以。
hook技术还是算了,我突然想起来必须使用dll,就是通过向对方注入自己的dll达到控制目标进程的目的,发送,截拦,任意消息。

不过话说回来,到底是因为窗口不前置后导致不响应快捷键还是发送消息的问题?
看看函数返回是什么
#9
richardw2014-09-08 21:36
单键可以,组合键还真不行。
就是一楼说的那个给后台记事本发消息的例子
SetForegroundWindow(m_hWnd);
SendMessage(m_hWnd, WM_SYSCOMMAND, SC_KEYMENU, (WPARAM)'E');

或者:
程序代码:
        SetForegroundWindow(m_hWnd);
        PostMessage(m_hWnd, WM_SYSKEYDOWN, VK_MENU, MakeKeyLparam(VK_MENU, WM_SYSKEYDOWN));
        PostMessage(m_hWnd, WM_SYSKEYDOWN, 'E', MakeKeyLparam('E', WM_SYSKEYDOWN));                       
        PostMessage(m_hWnd, WM_SYSKEYUP, 'E', MakeKeyLparam('E', WM_SYSKEYUP));            
        PostMessage(m_hWnd, WM_KEYUP, VK_MENU, MakeKeyLparam(VK_MENU, WM_KEYUP));  

都可以成功,如果把SetForegroundWindow取消,记事本是后台的话,这种组合键是发不成功的。

如果要给后台发单键,就很容易了,比如发F5(在记事本中添加当前时间)给后台记事本:
    PostMessage(m_hWnd, WM_KEYDOWN, VK_F5, MakeKeyLparam(VK_F5, WM_KEYDOWN));
    PostMessage(m_hWnd, WM_KEYUP, VK_F5, MakeKeyLparam(VK_F5, WM_KEYUP));


我原来也认为只要前台能发过去消息,后台也一样啦,结果一试,完全不是想像中的那回事。后台没反应呀

我用过全局或线程的HOOK,全都是DLL的,但都是一些很简单的应用,屏蔽、拦截或改键什么的

[ 本帖最后由 richardw 于 2014-9-8 21:38 编辑 ]
#10
richardw2014-09-09 15:31
是因为因为窗口不前置后导致不响应快捷键

所有返回值都是1
#11
天使梦魔2014-09-10 08:52
那就没办法了,通过按键响应需要窗口激活,窗口非激活状态也可能默认为线程暂停中.你做MFC时也应该知道假设做个定时器定时按键给自身,比如就是组合键弹出菜单,菜单功能键里有个弹出新窗口功能,如果整个窗口不前置非激活状态也不可能定时弹出的,当然定时器在工作,除非定时器的内容不是按键,而是呼叫窗口函数那即便不激活也能一直弹出.
1