关于keybd_event的疑问(100分)

  • 主题发起人 主题发起人 cAkk
  • 开始时间 开始时间
cAkk恕我学艺不精,keybd_event只是模拟键按下,能发送中文么?<br>键盘上可没有什么汉字,要不要先激活一个输入法?嘻嘻说笑了。
 
可是,不是说delphi带的那个sendkey函数可以和VB的sendkey函数媲美吗?<br>VB的sendkey就可以发送任意字符串.
 
同意Fencer的说法,我觉得用Keybd_event恐怕不行,这种情况肯定要用到IME的消息。为什么不能用SendMessag呢。
 
sendmessage需要指定具体的句柄,而VB的sebdkey不用,谁有focus就发给谁.<br><br>另外,我认为肯定和IMM无关,因为VB的sendkey可以做到.
 
要实现谁有focus就发给谁恐怕还真不容易。<br>说实话别说用keybd_event发送中文就是发<br>送大小写混合的英文也很费事。
 
VB的sendkey可是很容易做到的.
 
为了计算string中中英混排的字符数,我不得不将其转换到widesting中,不知有没有更好的方法.
 
是不是VB的Sendkey是用发送WM_IME_CHAR等消息实现的?
 
不管用什么方法了,只要能实现VB的功能就得分.
 
用SendMessage肯定没有问题,您老又不让用,handle用FindWindow.FindWindowEx来找也不是太麻烦。
 
receyes: 不是不能用sendmessage,而是sendmessage根本不能实现.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sendmessage总要先找到这个窗口吧? 但是你根本无法知道<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;当前有焦点的是什么? 可能是一个edit,可能是IE的地址栏,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;可能是IE的form表单,甚至还可能是一个telnet窗口.
 
这个问题可以解决了,不知VB的SENDKEY是不是这样作的。<br><br>1 如果Clipboard有CF_TEXT文本,就取出来,暂时保存。<br>2 将要SENDKEY的文本放到Clipboard上。<br>3 关键的两句:<br><br>&nbsp; AttachThreadInput(GetCurrentThreadID,<br>&nbsp; &nbsp; &nbsp; &nbsp;GetWindowThreadProcessId(GetForegroundWindow,nil),True);<br>&nbsp; SendMessage(GetFocus,WM_PASTE,0,0);<br><br>4 恢复原来Clipboard上的文本。<br><br>BTW:这样作可以在当前光标处插入任意文本,<br>&nbsp; &nbsp; &nbsp;而SendMessage(GetFocus,WM_SETTEXT,0,lpsz)<br>&nbsp; &nbsp; &nbsp;会替换整个TEXT,不可取。
 
o*o: 利用剪贴版虽然可能可以实现,但却是一种不负责任的办法,试想: <br>&nbsp; &nbsp; &nbsp;如果在你替换剪贴版内容和恢复剪贴版内容之间这段时间,正好该<br>&nbsp; &nbsp; &nbsp;内容的主人需要读取剪贴版怎么办?<br><br>我的个人看法,类似剪贴版这种全局性的公用的东西,不要用程序去修改他,<br>只有用户自己才有这个权力修改内容(比如用户按ctrl-ins)<br><br>而且,VB的sendkey肯定不是这么用的,因为他还能发送功能键,比如{END},<br>这说明他发送的应该是键码.<br><br>我有个建议,用VB做一个使用sendkey的程序,然后用他给某一个windows<br>发送中文字符串,我们用spy++监视那个windows的消息,看看他接受到的是什么消息?<br>暂时我没有时间测试这个,如果大家有兴趣就试一试.
 
<br>这几行是我前几天写的,不过cAKK说不用SendMessage,所以我就没贴上来,现在<br>用它来抛砖引玉吧。这段简单代码用SendMessage向记事本发送"大富翁"三个字:<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; hNote,hEdit: HWND;<br>begin<br>&nbsp; hNote := FindWindow('notepad',nil);<br>&nbsp; hEdit := FindWindowEx(hNote,0,'Edit',nil);<br>&nbsp; SendMessage(hEdit,WM_IME_CHAR,$0000B4F3,$00000001);<br>&nbsp; SendMessage(hEdit,WM_IME_CHAR,$0000B8BB,$00000001);<br>&nbsp; SendMessage(hEdit,WM_IME_CHAR,$0000CECC,$00000001);<br>end;<br><br>
 
但是如果不是记事本呢? 是什么程序(控件)根本不能事先知道.
 
不会吧?Delphi的SendKey是用Keybd_Event实现的,Keybd_Event产生的字符肯定<br>要输到Active的窗口吧,如果什么都不知道怎么能把这个窗口设为Active呢?我想<br>Delphi的SendKey内部肯定要用到FindWindow.GetActiveWindow.GetFocus之类<br>的函数,待我晚上看一下SendKey的源程序。至于VB的SendKey能发送中文,我想是<br>通过IME实现的,而不是用Keybd_Event,不过搞不到中文VB的Source,只能猜测<br>了。<br>&nbsp; &nbsp; 新年快乐!<br>
 
后退
顶部