知道窗口句柄,如何向它发送CTRL+1 的复合键消息呢? ( 积分: 100 )

  • 主题发起人 主题发起人 RJU
  • 开始时间 开始时间
R

RJU

Unregistered / Unconfirmed
GUEST, unregistred user!
现在我想尝试控制一个外部程序,已经能获取它的主窗口句柄&nbsp;hwnd,<br>它有一个快捷键是ctrl&nbsp;+&nbsp;1&nbsp;,我怎么向它发送这个快捷键消息呢?<br>已经测试过,用sendmessage&nbsp;很容易发送单键(如发送按下'P'键)的消息,<br>但是复合键&nbsp;ctrl&nbsp;+&nbsp;1却总是发送不成功<br>查询了很多方法,好像只能把主窗口设置为焦点窗口再发送才可以<br>但是我的程序不允许这样<br>各位有什么好的解决方法阿&nbsp;谢谢啊
 
-----------网上转的<br>1、<br>可以用keybd_event啊.原型是:&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;VOID&nbsp;&nbsp;&nbsp;keybd_event(&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BYTE&nbsp;&nbsp;&nbsp;bVk,&nbsp;//&nbsp;&nbsp;&nbsp;virtual-key&nbsp;&nbsp;&nbsp;code&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BYTE&nbsp;&nbsp;&nbsp;bScan,&nbsp;//&nbsp;&nbsp;&nbsp;hardware&nbsp;&nbsp;&nbsp;scan&nbsp;&nbsp;&nbsp;code&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;dwFlags,&nbsp;//&nbsp;&nbsp;&nbsp;flags&nbsp;&nbsp;&nbsp;specifying&nbsp;&nbsp;&nbsp;various&nbsp;&nbsp;&nbsp;function&nbsp;&nbsp;&nbsp;options&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;dwExtraInfo&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;additional&nbsp;&nbsp;&nbsp;data&nbsp;&nbsp;&nbsp;associated&nbsp;&nbsp;&nbsp;with&nbsp;&nbsp;&nbsp;keystroke&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;第一个参数是要模拟的键的虚似键码.1-254之间.&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;第二个是定义该键的硬件扫描码.&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;第三个是一个标志位集.可用&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;DEYEVENTF_KEYUP若指定该值,该键将被释放,未指定的话,就表求该键被按下.&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;第四个参数定义与击键相关的附加32位值.&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;如:&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;keybd_event(VK_CONTROL,NULL,NULL,NULL);&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;keybd_event(86,NULL,NULL,NULL);&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;keybd_event(VK_CONTROL,NULL,KEYEVENTF_KEYUP,NULL);&nbsp;&nbsp;&nbsp;<br><br><br>供参考<br><br>2、Delphi中的SendKeys函数&nbsp;<br><br>--------------------------------------------------------------------------------<br><br>用过Visual&nbsp;Basic等编程语言的朋友们一定对其SendKeys函数非常熟悉。利用该函数可以把一个字符串发送到目标窗口(比如记事本)或控件(比如一个Edit控件)中,就好像是在目标窗口或控件中输入这个字符串一样。但是,在Delphi中却没有为我们提供这样的函数。其实,Borland的工程师们早就提供了一个方便的方法:在Delphi5.0企业版的安装盘的&nbsp;<br>/info/Extras/SendKeys/文件夹中,有一个sndKey32.Pas文件,&nbsp;<br>只需把该文件复制到Delphi的安装目录下/Lib/文件夹中,在工程中引用该文件后即可使用SendKeys函数.&nbsp;<br>其中两个主要的函数为:&nbsp;<br>SendKeys(KeyString:Pchar;Wait:Boolean):Boolean;&nbsp;<br>AppActivate(WindowName:Pchar):Boolean;&nbsp;<br>用法为:&nbsp;<br>SendKeys函数向当前拥有焦点的窗口或控件发送字符串,KeySering为字符串的内容。&nbsp;<br>Wait指示是否等待接收字符串的窗口或控件处理完毕后返回。一般设为False即可。&nbsp;<br>例如:SendKeys('abcdefg',false);&nbsp;<br>值得一提的是,SendKeys函数支持发送特殊字符和组合字符,例如方向键、Alt、Ctrl组合键。&nbsp;<br>使用时,只需用规定的前缀指明即可。+为Shift,^为Ctrl,%为Alt。&nbsp;<br>例如:&nbsp;<br>'+monday&nbsp;'&nbsp;意为发送Shift+m和onday&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+(monday)'意为发送Shift+monday&nbsp;<br>对于不可见字符(比如方向键、F1~F11、回车等),可用{}将其括起来。&nbsp;<br>&nbsp;&nbsp;例如:&nbsp;<br>'%{F4}'即发送Alt+F4的组合送给应用程序。&nbsp;<br>更详尽的说明请参照SndKey32.pas文件中的注释。&nbsp;<br>AppActivate函数的作用是将某个窗口设置为当前窗口。只需将该窗口的标题传过去即可。&nbsp;<br>&nbsp;&nbsp;若成功将某个窗口激活,则返回值为True.&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;例子:点击发送后,上面的Edit控件的内容会被发送到下面的Edit控件里面去。&nbsp;<br>&nbsp;&nbsp;程序很简单,只要两个Edit控件和一个Button控件。&nbsp;<br>源程序如下:&nbsp;<br>unit&nbsp;sendkey1;&nbsp;<br>interface&nbsp;<br>uses&nbsp;<br>&nbsp;&nbsp;Windows,&nbsp;Messages,&nbsp;SysUtils,&nbsp;Variants,&nbsp;Classes,&nbsp;Graphics,&nbsp;Controls,&nbsp;Forms,&nbsp;<br>&nbsp;&nbsp;Dialogs,sndkey32,&nbsp;StdCtrls;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//注意该行要添加sndker32!!&nbsp;<br>type&nbsp;<br>&nbsp;&nbsp;TForm1&nbsp;=&nbsp;class(TForm)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;Edit1:&nbsp;TEdit;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;Edit2:&nbsp;TEdit;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;Button1:&nbsp;TButton;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;Button1Click(Sender:&nbsp;TObject);&nbsp;<br>&nbsp;&nbsp;private&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;Private&nbsp;declarations&nbsp;}&nbsp;<br>&nbsp;&nbsp;public&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;Public&nbsp;declarations&nbsp;}&nbsp;<br>&nbsp;&nbsp;end;&nbsp;<br>var&nbsp;<br>&nbsp;&nbsp;Form1:&nbsp;TForm1;&nbsp;<br><br>implementation&nbsp;<br>{$R&nbsp;*.dfm}&nbsp;<br>procedure&nbsp;TForm1.Button1Click(Sender:&nbsp;TObject);&nbsp;<br>begin&nbsp;<br>Edit2.SetFocus;&nbsp;&nbsp;//将焦点置于Edit2&nbsp;<br>SendKeys(Pchar(Edit1.Text),False);&nbsp;&nbsp;//将Edit1中的字符串发送给Edit2&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//事先需进行转换&nbsp;<br>end;&nbsp;<br><br>end.&nbsp;<br><br>很简单,是不是?其实不仅Edit控件,像Memo、RichEdit等空件均可接收发送的字符。&nbsp;<br>&nbsp;&nbsp;<br><br>上面的例子只是在本应用程序内传递字符串,&nbsp;<br>下面的例子是将字符串发送给Microsoft&nbsp;Word。其所用控件与上例相差不大。&nbsp;<br>源程序为:&nbsp;<br>unit&nbsp;unit1;&nbsp;<br>interface&nbsp;<br>uses&nbsp;<br>&nbsp;&nbsp;Windows,&nbsp;Messages,&nbsp;SysUtils,&nbsp;Classes,&nbsp;Graphics,&nbsp;Controls,&nbsp;Forms,&nbsp;Dialogs&nbsp;<br>&nbsp;&nbsp;,sndkey32,&nbsp;StdCtrls;&nbsp;&nbsp;&nbsp;&nbsp;//不要忘了sndKey32!&nbsp;<br>type&nbsp;<br>&nbsp;&nbsp;TForm1&nbsp;=&nbsp;class(TForm)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;Button1:&nbsp;TButton;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;Edit1:&nbsp;TEdit;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;Button2:&nbsp;TButton;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;Button1Click(Sender:&nbsp;TObject);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;Button2Click(Sender:&nbsp;TObject);&nbsp;<br>&nbsp;&nbsp;private&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;Private&nbsp;declarations&nbsp;}&nbsp;<br>&nbsp;&nbsp;public&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;Public&nbsp;declarations&nbsp;}&nbsp;<br>&nbsp;&nbsp;end;&nbsp;<br>var&nbsp;<br>&nbsp;&nbsp;Form1:&nbsp;TForm1;&nbsp;<br>implementation&nbsp;<br><br>{$R&nbsp;*.DFM}&nbsp;<br>{&nbsp;该函数将焦点置于Word,若失败,返回False}&nbsp;<br>function&nbsp;SetFocusToWord:boolean;&nbsp;&nbsp;&nbsp;&nbsp;<br>var&nbsp;<br>&nbsp;&nbsp;&nbsp;f:boolean;&nbsp;<br>begin&nbsp;<br>&nbsp;&nbsp;&nbsp;f:=true;&nbsp;<br>&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;AppActivate('文档&nbsp;1&nbsp;-&nbsp;Microsoft&nbsp;Word')&nbsp;then&nbsp;<br>&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;字符串内容为:文档空格1空格-空格Microsoft空格Word&nbsp;<br>&nbsp;&nbsp;&nbsp;}&nbsp;<br>&nbsp;&nbsp;&nbsp;begin&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f:=False;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageDlg('没找到Word!',mtError,[mbOk],0);&nbsp;//显示错误&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;&nbsp;<br>&nbsp;&nbsp;&nbsp;end;&nbsp;<br>result:=f;&nbsp;<br>end;&nbsp;<br>procedure&nbsp;SetFormActive;&nbsp;//该子程序将焦点置回&nbsp;<br>begin&nbsp;<br>&nbsp;&nbsp;&nbsp;Appactivate('SendToWord');&nbsp;<br>&nbsp;&nbsp;&nbsp;form1.SetFocus;&nbsp;<br>&nbsp;&nbsp;&nbsp;form1.Edit1.SetFocus;&nbsp;<br>end;&nbsp;<br>procedure&nbsp;TForm1.Button1Click(Sender:&nbsp;TObject);&nbsp;<br>begin&nbsp;<br>&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;SetFocusToWord&nbsp;then&nbsp;exit;&nbsp;//没找到Word,退出&nbsp;<br>&nbsp;&nbsp;&nbsp;sendkeys(Pchar(form1.edit1.text),false);&nbsp;//找到了,发送字符串&nbsp;<br>&nbsp;&nbsp;&nbsp;SetFormActive;&nbsp;<br>end;&nbsp;<br><br>procedure&nbsp;TForm1.Button2Click(Sender:&nbsp;TObject);&nbsp;<br>begin&nbsp;<br>if&nbsp;not&nbsp;SetFocusToWord&nbsp;then&nbsp;exit;&nbsp;//没找到Word,退出&nbsp;<br>&nbsp;&nbsp;&nbsp;sendkeys('%{F4}',false);&nbsp;&nbsp;&nbsp;&nbsp;//发送Alt+F4,关闭Word&nbsp;<br>&nbsp;&nbsp;&nbsp;SetFormActive;&nbsp;<br>end;&nbsp;<br>end.&nbsp;<br>该例子只是简单演示一下,实际上大家可以改动激活word的部分(本文查找'文档&nbsp;1&nbsp;-&nbsp;Microsoft&nbsp;Word'来实现,&nbsp;<br>显得有些太简单了。)&nbsp;<br>Delphi本身也带有与Office协作的一系列控件,但只进行简单的协作,这样不是更简单么?&nbsp;<br>SendKeys函数的功能很强大,不然Borland也不会在安装盘中提供这个文件。更好的利&nbsp;<br>SendKeys的设想,就要看各位朋友的了!
 
不行啊<br>keybd_event&nbsp;要激活目标窗口<br>sendmessage&nbsp;怎么实现呢?
 
和Key_event原理类似,先KeyDown,再Key_up<br><br>PostMessage(Edit1.Handle,&nbsp;WM_KEYDOWN,&nbsp;VK_SHIFT&nbsp;,&nbsp;$002A0001);<br>PostMessage(Edit1.Handle,&nbsp;WM_KEYDOWN,&nbsp;ORD('A'),&nbsp;$001E0001);<br>PostMessage(Edit1.Handle,&nbsp;WM_KEYUP,&nbsp;ORD('A'),&nbsp;$C01E0001&nbsp;);<br>PostMessage(Edit1.Handle,&nbsp;WM_KEYUP,&nbsp;VK_SHIFT,&nbsp;$C02A0001&nbsp;);<br><br>但是如果窗体没有激活,未必能收到消息,没测试过
 
先谢谢0桁骀的回答<br>不过仍然没有实现<br>我用spy++跟踪发现<br>这个方法和它直接在目标程序按&nbsp;ctrl&nbsp;+&nbsp;1接收到的消息<br>有一点点区别<br>前面4个消息都一样的,接收到&nbsp;ctrl&nbsp;的&nbsp;按下,1按下,ctrl&nbsp;弹起,1弹起的消息<br>但是用posemessage&nbsp;,最后还会多一个消息<br>大概相当于&nbsp;posemessage(&nbsp;handle,&nbsp;wm_char&nbsp;,&nbsp;'1',&nbsp;0)的消息<br>似乎是'1'&nbsp;发送的是字符消息<br>这是什么原因呢,是不是因为这个而造成功不是发送复合键的原因呢?
 
windows.SetFocus(Hwnd);<br>&nbsp;&nbsp;keybd_event(VK_CONTROL,0,0,0);<br>&nbsp;&nbsp;keybd_event(VK_NUMPAD1,0,0,0);<br>&nbsp;&nbsp;keybd_event(VK_NUMPAD1,0,KEYEVENTF_KEYUP,0);<br>&nbsp;&nbsp;keybd_event(VK_CONTROL,0,windows.KEYEVENTF_KEYUP,0);
 
不好意思&nbsp;没看到你的主窗口还不是有焦点的.
 
SendMessage(Handle,&nbsp;MsgID,&nbsp;WM_HOTKEY,&nbsp;MakeLParam(MOD_CONTROL,&nbsp;149));<br>Handle:&nbsp;接收快捷键的窗体句柄<br>MsgID:&nbsp;接收快捷键的窗体注册该快捷键时的ID,如果是别人的程序,这个好象不易获取,你先试试<br>WM_HOTKEY:&nbsp;&nbsp;说明发送的是快捷键消息<br>MakeLParam&nbsp;创建LParam参数<br>MOD_CONTROL:&nbsp;&nbsp;按住Ctrl键<br>149:&nbsp;&nbsp;大键盘“!/1”键按下
 
多人接受答案了。
 
后退
顶部