如何发送一个(或是一串)键盘消息到系统中(100分)

  • 主题发起人 主题发起人 bbdog
  • 开始时间 开始时间
B

bbdog

Unregistered / Unconfirmed
GUEST, unregistred user!
&nbsp; &nbsp;我想写一个键盘监听程序。每当检查到按下了n键时,发送一个(或是一串)<br>新的键盘消息到系统中(比如发送一个按下了a键后产生的消息)。<br>&nbsp; &nbsp; 实际的运行效果为:启动程序后便开始监听键盘消息,在此以后又启动了某<br>字处理程序(如记事本)并在其中输入字符,如果输入的字符为n,则应在字处理<br>程序中显示为a(或是abc)<br>&nbsp; &nbsp; 不知该如何做才能实现,请各位大虾帮助解决,谢了。<br>&nbsp; &nbsp; 注:只用给出keyboardproc回调函数中,在检测条件成立后,发送一个(或<br>一串)新的键盘消息给系统的代码即可(所发送的键盘消息最好是系统级的,即<br>不是发送到指定的程序中,而是所有的当前应用程序都可以接收到,并加以处理。<br>如果只能发送到指定的程序也还是行的)。<br>
 
也听一下
 
在Tform1中的Private段中加入如下代码 <br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; hotkeyid :integer;<br>&nbsp; &nbsp; procedure WMhotkeyhandle(var msg:Tmessage); message wm_hotkey; //响应敏感键按键消息<br>然后:<br>procedure TForm1.FormCreate(Sender: TObject); //创建时<br>begin<br>&nbsp; hotkeyid:=GlobalAddAtom(pchar('UserDefineHotKey'))-$C000;//减去$C000是为了保证取值范围的限制<br>&nbsp; registerhotkey(handle,hotkeyid,0,$41); &nbsp;//‘A’键<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject); //关闭时<br>begin<br>&nbsp;unregisterhotkey(handle,hotkeyid);<br>&nbsp;DeleteAtom(HotKeyID);<br>end;<br><br>procedure TForm1.WMhotkeyhandle(var msg: Tmessage);<br>var<br>&nbsp; S:string;<br>&nbsp; I:integer;<br>begin<br>&nbsp;if (msg.LParamHi=$41) then<br>&nbsp;begin<br>&nbsp; msg.Result:=1; //该消息已经处理<br>&nbsp; S:='ABC';<br>&nbsp; for i:=1 to length(s) do<br>&nbsp; &nbsp; SendMessage(GetFocus, WM_CHAR, Ord(s), 0);<br>&nbsp; end;<br>end;<br><br>这代码只能对本程序的输入起作用,但其它程序按下A键时它也有反应,<br>但就是不发出字符。如果知道也告诉我。
 
to tinytao:<br>&nbsp; &nbsp;GetFocus得到的只是当前激活的窗口句柄,应该进一步得到edit类控件的句柄<br>才行吧。
 
应该是SendMessage(GetFocus, WM_CHAR, Ord(s), 0);中GetFocus用的不对。<br>
 
GetFocus如何用?我只认为它是返回输入焦点的句柄。<br>谁有好方法。
 
&nbsp; &nbsp;希望大家继续讨论,我本人也在进行和种测试。<br>&nbsp; &nbsp; 我想应该是编写一个键盘挂钩程序,在该程序中截<br>获键盘消息后,再发送新的键盘消息给系统。<br>&nbsp; &nbsp; 还有几天要参加自学考试了,没有更多的时间进行<br>下一步的测试。过几天再来和大家交流。<br>&nbsp; &nbsp; 大家请畅所欲言。
 
一定要用SendMessage吗? <br>好像用keybroad_event可以直接发出按键信息,不用管焦点在哪里.
 
&lt;h3&gt;listen&lt;/h3&gt;
 
tinytao,先用EnumWindowproc和EnumWindow来找到输入字符的窗口的句柄<br>再sendmessage(handle, WM_CHAR, Ord(s), 0),这样或许就可以了吧?
 
冰封:能详细点吗?
 
具体我也不是很清楚啦,因为我对SendMessage、EnumWindows和EnumWindowsProc不熟悉,<br>我的想法是EnumWindowS和EnumWndowsProc两个函数是用来寻找窗口句柄的嘛,先找到输入<br>字符的窗口句柄,然后GetFocus换成窗口句柄,不知道这样行不行?<br>
 
&lt;p align="left"&gt;用EnumWindows和EnumWindowsProc办法很笨,我四年就前用过。&lt;br&gt;<br>必须针对特定的窗口才能使用。不能对任意的窗口使用。请注意&lt;br&gt;<br>问题是对系统发键盘消息,然后再由系统分配到应该得到的窗口。&lt;/p&gt;<br><br>&lt;p align="left"&gt;<br>&lt;font color="#FF0000"&gt;<br>大家帮帮忙,给看一下&lt;/font&gt;&lt;/p&gt;<br><br>&lt;p align="left"&gt;<br>&amp;nbsp;<br>&lt;font color="#FF0000" size="4"&gt;<br>&lt;a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=506445"&gt;<br>“寻找简单的方法,filter消息”&lt;/a&gt;<br>&lt;/font&gt;&lt;/p&gt;<br><br>&lt;p align="left"&gt;如有违反论坛规则,还请版主砍掉并批评指出&lt;/p&gt;
 
强力推荐——在Delphi的安装盘中有一个sndkey32.pas文件,专门发送键盘事件,很爽!<br>所在路径:Info/Extras/SendKeys<br><br>例子:SendKeys('123 A a !?',false);<br><br>根本不用管什么Handle——它用的是KeyboardEvent——直接被“当前应用程序”处理。
 
我已经成功了,只要注意以下2点:<br>1.在DLL中钩挂“WH_KEYBOARD”。<br>2.一定要用SendMessage发送特定字符。<br>已下是把“B“转换成”abc“的HOOK回调函数:<br>function MyHook(iCode: Integer;<br>&nbsp; wParam: WPARAM;<br>&nbsp; lParam: LPARAM): LRESULT; stdcall; export;<br>const<br>&nbsp; MyKeyMask = $80000000;<br>begin<br>&nbsp;result:=0; <br>&nbsp; If iCode &lt; 0 Then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br>&nbsp; &nbsp; &nbsp; if ((lParam and MyKeyMask) = 0) and &nbsp;<br>&nbsp; &nbsp; (wParam = Ord('B')) then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := 1;<br>&nbsp; &nbsp;sendmessage(getfocus,wm_char, Ord('a'), 0);<br>&nbsp; sendmessage(getfocus,wm_char, Ord('b'), 0);<br>&nbsp; sendmessage(getfocus,wm_char, Ord('c'), 0);<br>&nbsp; &nbsp;end;<br>end;<br> <br>
 
&nbsp; &nbsp;谢谢各位的回答,非常感谢。<br><br>to mywyn:<br>&nbsp; &nbsp; 不知能否在某个格斗游戏中实现‘一击必杀’呢?就是在按下某键后<br>改成发送一串必杀技的键盘消息(最好能在侍魂2 中试一下霸王丸的绝技<br>‘天霸封神斩’),谢谢。<br><br>
 
&nbsp; 请问如何发送汉字?
 
后退
顶部