向某个程序发送按键问题 ( 积分: 50 )

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

beyondup

Unregistered / Unconfirmed
GUEST, unregistred user!
我想给某个程序发送F1键(就是等于在所谓的某个程序中按下F1)怎么没用呀??<br>我是这么写的:<br> &nbsp; &nbsp;Sendmessage(Hw_Long,WM_KEYDOWN,VK_F1,-1);<br>后来我以为是不完善加上了Sendmessage(Hw_Long,WM_KEYUP,VK_F1,-1);<br>还是没用,请高手指点迷津,谢谢。
 
我想给某个程序发送F1键(就是等于在所谓的某个程序中按下F1)怎么没用呀??<br>我是这么写的:<br> &nbsp; &nbsp;Sendmessage(Hw_Long,WM_KEYDOWN,VK_F1,-1);<br>后来我以为是不完善加上了Sendmessage(Hw_Long,WM_KEYUP,VK_F1,-1);<br>还是没用,请高手指点迷津,谢谢。
 
自定义消息application. &nbsp; =...
 
Sendmessage(Hw_Long,WM_KEYDOWN or WM_KEYUP,VK_F1,0);<br><br>相当于按一次F1<br><br>如果不行,换 postmessage 试试
 
首先要确认hw_long有效,其次要确认hw_long能对F1有反应。
 
最后一个参数设为0试试呢:<br> &nbsp;SendMessage(h, WM_KEYDOWN, VK_F1, 0);<br> &nbsp;SendMessage(h, WM_KEYUP, &nbsp; VK_F1, 0);
 
sendmessage等估计解决不了问题,最好使用键盘钩子,我这里有个例子完全可以实现:<br>unit SendKey;<br><br>interface<br><br>uses<br> SysUtils, Windows, Messages, Classes, KeyDefs;<br><br>type<br> &nbsp;{ Error codes }<br> &nbsp;TSendKeyError = (sk_None, sk_FailSetHook, sk_InvalidToken, sk_UnknownError,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sk_AlreadyPlaying);<br> &nbsp;{ first vk code to last vk code }<br> &nbsp;TvkKeySet = set of vk_LButton..vk_Scroll;<br><br> &nbsp;{ exceptions }<br> &nbsp;ESendKeyError = class(Exception);<br> &nbsp;ESKSetHookError = class(ESendKeyError);<br> &nbsp;ESKInvalidToken = class(ESendKeyError);<br> &nbsp;ESKAlreadyPlaying = class(ESendKeyError);<br><br>function SendKeys(S: String): TSendKeyError;<br>procedure WaitForHook;<br>procedure StopPlayback;<br><br>var<br> &nbsp;Playing: Boolean = False;<br><br>implementation<br><br>uses Forms;<br><br>type<br> &nbsp;{ a TList descendant that know how to dispose of its contents }<br> &nbsp;TMessageList = class(TList)<br> &nbsp;public<br> &nbsp; &nbsp;destructor Destroy; override;<br> &nbsp;end;<br><br>const<br> &nbsp;{ valid &quot;sys&quot; keys }<br> &nbsp;vkKeySet: TvkKeySet = [Ord('A')..Ord('Z'), vk_Menu, vk_F1..vk_F12];<br><br>destructor TMessageList.Destroy;<br>var<br> &nbsp;i: longint;<br>begin<br> &nbsp;{ deallocate all the message records before discarding the list }<br> &nbsp;for i := 0 to Count - 1 do<br> &nbsp; &nbsp;Dispose(PEventMsg(Items));<br> &nbsp;inherited Destroy;<br>end;<br><br>var<br> &nbsp;{ variables global to the DLL }<br> &nbsp;MsgCount: word = 0;<br> &nbsp;MessageBuffer: TEventMsg;<br> &nbsp;HookHandle: hHook = 0;<br> &nbsp;MessageList: TMessageList = Nil;<br> &nbsp;AltPressed, ControlPressed, ShiftPressed: Boolean;<br><br>procedure StopPlayback;<br>{ Unhook the hook, and clean up }<br>begin<br> &nbsp;{ if Hook is currently active, then unplug it }<br> &nbsp;if Playing then<br> &nbsp; &nbsp;UnhookWindowsHookEx(HookHandle);<br> &nbsp;MessageList.Free;<br> &nbsp;Playing := False;<br>end;<br><br>function Play(Code: integer; wParam, lParam: Longint): Longint; stdcall;<br>{ This is the JournalPlayback callback function. &nbsp;It is called by Windows }<br>{ when Windows polls for hardware events. &nbsp;The code parameter indicates what }<br>{ to do. }<br>begin<br> &nbsp;case Code of<br><br> &nbsp; &nbsp;hc_Skip: begin<br> &nbsp; &nbsp;{ hc_Skip means to pull the next message out of our list. If we }<br> &nbsp; &nbsp;{ are at the end of the list, it's okay to unhook the JournalPlayback }<br> &nbsp; &nbsp;{ hook from here. }<br> &nbsp; &nbsp; &nbsp;{ increment message counter }<br> &nbsp; &nbsp; &nbsp;inc(MsgCount);<br> &nbsp; &nbsp; &nbsp;{ check to see if all messages have been played }<br> &nbsp; &nbsp; &nbsp;if MsgCount &gt;= MessageList.Count then<br> &nbsp; &nbsp; &nbsp; &nbsp;StopPlayback<br> &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;{ copy next message from list into buffer }<br> &nbsp; &nbsp; &nbsp;MessageBuffer := TEventMsg(MessageList.Items[MsgCount]^);<br> &nbsp; &nbsp; &nbsp;Result := 0;<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;hc_GetNext: begin<br> &nbsp; &nbsp;{ hc_GetNext means to fill the wParam and lParam with the proper }<br> &nbsp; &nbsp;{ values so that the message can be played back. &nbsp;DO NOT unhook }<br> &nbsp; &nbsp;{ hook from within here. &nbsp;Return value indicates how much time until }<br> &nbsp; &nbsp;{ Windows should playback message. &nbsp;We'll return 0 so that it's }<br> &nbsp; &nbsp;{ processed right away. }<br> &nbsp; &nbsp; &nbsp;{ move message in buffer to message queue }<br> &nbsp; &nbsp; &nbsp;PEventMsg(lParam)^ := MessageBuffer;<br> &nbsp; &nbsp; &nbsp;Result := 0 &nbsp;{ process immediately }<br> &nbsp; &nbsp;end<br><br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;{ if Code isn't hc_Skip or hc_GetNext, then call next hook in chain }<br> &nbsp; &nbsp; &nbsp;Result := CallNextHookEx(HookHandle, Code, wParam, lParam);<br> &nbsp;end;<br>end;<br><br>procedure StartPlayback;<br>begin<br> &nbsp;MessageBuffer := TEventMsg(MessageList.Items[0]^);<br> &nbsp;MsgCount := 0;<br> &nbsp;AltPressed := False;<br> &nbsp;ControlPressed := False;<br> &nbsp;ShiftPressed := False;<br> &nbsp;HookHandle := SetWindowsHookEx(wh_JournalPlayback, Play, hInstance, 0);<br> &nbsp;if HookHandle = 0 then<br> &nbsp; &nbsp;raise ESKSetHookError.Create('Couldn''t set hook')<br> &nbsp;else<br> &nbsp; &nbsp;Playing := True;<br>end;<br><br>procedure MakeMessage(vKey: byte; M: Cardinal);<br>var<br> &nbsp;E: PEventMsg;<br>begin<br> &nbsp;New(E);<br> &nbsp;with E^ do begin<br> &nbsp; &nbsp;message := M;<br> &nbsp; &nbsp;paramL := vKey;<br> &nbsp; &nbsp;paramH := MapVirtualKey(vKey, 0);<br> &nbsp; &nbsp;time := GetTickCount;<br> &nbsp; &nbsp;hwnd := 0;<br> &nbsp;end;<br> &nbsp;MessageList.Add(E);<br>end;<br><br>procedure KeyDown(vKey: byte);<br>begin<br> &nbsp;if AltPressed and (not ControlPressed) and &nbsp;(vKey in vkKeySet) then<br> &nbsp; &nbsp;MakeMessage(vKey, wm_SysKeyDown)<br> &nbsp;else<br> &nbsp; &nbsp;MakeMessage(vKey, wm_KeyDown);<br>end;<br><br>procedure KeyUp(vKey: byte);<br>begin<br> &nbsp;if AltPressed and (not ControlPressed) and (vKey in vkKeySet) then<br> &nbsp; &nbsp;MakeMessage(vKey, wm_SysKeyUp)<br> &nbsp;else<br> &nbsp; &nbsp;MakeMessage(vKey, wm_KeyUp);<br>end;<br><br>procedure SimKeyPresses(VKeyCode: Word);<br>begin<br> &nbsp;if AltPressed then<br> &nbsp; &nbsp;KeyDown(vk_Menu);<br> &nbsp;if ControlPressed then<br> &nbsp; &nbsp;KeyDown(vk_Control);<br> &nbsp;if (((Hi(VKeyCode) and 1) &lt;&gt; 0) and (not ControlPressed)) or ShiftPressed then<br> &nbsp; &nbsp;KeyDown(vk_Shift);<br> &nbsp;KeyDown(Lo(VKeyCode));<br> &nbsp;KeyUp(Lo(VKeyCode));<br> &nbsp;if (((Hi(VKeyCode) and 1) &lt;&gt; 0) and (not ControlPressed)) or ShiftPressed then<br> &nbsp; &nbsp;KeyUp(vk_Shift);<br> &nbsp;if ShiftPressed then begin<br> &nbsp; &nbsp;ShiftPressed := False;<br> &nbsp;end;<br> &nbsp;if ControlPressed then begin<br> &nbsp; &nbsp;KeyUp(vk_Control);<br> &nbsp; &nbsp;ControlPressed := False;<br> &nbsp;end;<br> &nbsp;if AltPressed then begin<br> &nbsp; &nbsp;KeyUp(vk_Menu);<br> &nbsp; &nbsp;AltPressed := False;<br> &nbsp;end;<br>end;<br><br>procedure ProcessKey(S: String);<br>var<br> &nbsp;KeyCode: word;<br> &nbsp;Key: byte;<br> &nbsp;index: integer;<br> &nbsp;Token: TKeyString;<br>begin<br> &nbsp;index := 1;<br> &nbsp;repeat<br> &nbsp; &nbsp;case S[index] of<br> &nbsp; &nbsp; &nbsp;KeyGroupOpen : begin<br> &nbsp; &nbsp; &nbsp; &nbsp;Token := '';<br> &nbsp; &nbsp; &nbsp; &nbsp;inc(index);<br> &nbsp; &nbsp; &nbsp; &nbsp;while S[index] &lt;&gt; KeyGroupClose do begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Token := Token + S[index];<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc(index);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (Length(Token) = 7) and (S[index] &lt;&gt; KeyGroupClose) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;raise ESKInvalidToken.Create('No closing brace');<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;if not FindKeyInArray(Token, Key) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;raise ESKInvalidToken.Create('Invalid token');<br> &nbsp; &nbsp; &nbsp; &nbsp;SimKeyPresses(MakeWord(Key, 0));<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;AltKey : begin<br> &nbsp; &nbsp; &nbsp; &nbsp;AltPressed := True;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;ControlKey : begin<br> &nbsp; &nbsp; &nbsp; &nbsp;ControlPressed := True;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;ShiftKey : begin<br> &nbsp; &nbsp; &nbsp; &nbsp;ShiftPressed := True;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;else begin<br> &nbsp; &nbsp; &nbsp; &nbsp;KeyCode := vkKeyScan(S[index]);<br> &nbsp; &nbsp; &nbsp; &nbsp;SimKeyPresses(KeyCode);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;inc(index);<br> &nbsp;until index &gt; Length(S);<br>end;<br><br>procedure WaitForHook;<br>begin<br> &nbsp;repeat Application.ProcessMessages until not Playing;<br>end;<br><br>function SendKeys(S: String): TSendKeyError;<br>begin<br> &nbsp;Result := sk_None;<br> &nbsp;try<br> &nbsp; &nbsp;if Playing then raise ESKAlreadyPlaying.Create('');<br> &nbsp; &nbsp;MessageList := TMessageList.Create;<br> &nbsp; &nbsp;ProcessKey(S);<br> &nbsp; &nbsp;StartPlayback;<br> &nbsp;except<br> &nbsp; &nbsp;on E:ESendKeyError do begin<br> &nbsp; &nbsp; &nbsp;MessageList.Free;<br> &nbsp; &nbsp; &nbsp;if E is ESKSetHookError then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := sk_FailSetHook<br> &nbsp; &nbsp; &nbsp;else if E is ESKInvalidToken then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := sk_InvalidToken<br> &nbsp; &nbsp; &nbsp;else if E is ESKAlreadyPlaying then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := sk_AlreadyPlaying;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Result := sk_UnknownError;<br> &nbsp;end;<br>end;<br><br>end.<br>---------------------------------------<br>unit Keydefs;<br><br>interface<br><br>uses Windows;<br><br>const<br> &nbsp;MaxKeys = 24;<br> &nbsp;ControlKey = '^';<br> &nbsp;AltKey = '@';<br> &nbsp;ShiftKey = '~';<br> &nbsp;KeyGroupOpen = '{';<br> &nbsp;KeyGroupClose = '}';<br><br>type<br> &nbsp;TKeyString = String[7];<br><br> &nbsp;TKeyDef = record<br> &nbsp; &nbsp;Key: TKeyString;<br> &nbsp; &nbsp;vkCode: Byte;<br> &nbsp;end;<br><br>const<br> &nbsp;KeyDefArray : array[1..MaxKeys] of TKeyDef = (<br> &nbsp; &nbsp;(Key: 'F1'; &nbsp; &nbsp; vkCode: vk_F1),<br> &nbsp; &nbsp;(Key: 'F2'; &nbsp; &nbsp; vkCode: vk_F2),<br> &nbsp; &nbsp;(Key: 'F3'; &nbsp; &nbsp; vkCode: vk_F3),<br> &nbsp; &nbsp;(Key: 'F4'; &nbsp; &nbsp; vkCode: vk_F4),<br> &nbsp; &nbsp;(Key: 'F5'; &nbsp; &nbsp; vkCode: vk_F5),<br> &nbsp; &nbsp;(Key: 'F6'; &nbsp; &nbsp; vkCode: vk_F6),<br> &nbsp; &nbsp;(Key: 'F7'; &nbsp; &nbsp; vkCode: vk_F7),<br> &nbsp; &nbsp;(Key: 'F8'; &nbsp; &nbsp; vkCode: vk_F8),<br> &nbsp; &nbsp;(Key: 'F9'; &nbsp; &nbsp; vkCode: vk_F9),<br> &nbsp; &nbsp;(Key: 'F10'; &nbsp; &nbsp;vkCode: vk_F10),<br> &nbsp; &nbsp;(Key: 'F11'; &nbsp; &nbsp;vkCode: vk_F11),<br> &nbsp; &nbsp;(Key: 'F12'; &nbsp; &nbsp;vkCode: vk_F12),<br> &nbsp; &nbsp;(Key: 'INSERT'; vkCode: vk_Insert),<br> &nbsp; &nbsp;(Key: 'DELETE'; vkCode: vk_Delete),<br> &nbsp; &nbsp;(Key: 'HOME'; &nbsp; vkCode: vk_Home),<br> &nbsp; &nbsp;(Key: 'END'; &nbsp; &nbsp;vkCode: vk_End),<br> &nbsp; &nbsp;(Key: 'PGUP'; &nbsp; vkCode: vk_Prior),<br> &nbsp; &nbsp;(Key: 'PGDN'; &nbsp; vkCode: vk_Next),<br> &nbsp; &nbsp;(Key: 'TAB'; &nbsp; &nbsp;vkCode: vk_Tab),<br> &nbsp; &nbsp;(Key: 'ENTER'; &nbsp;vkCode: vk_Return),<br> &nbsp; &nbsp;(Key: 'BKSP'; &nbsp; vkCode: vk_Back),<br> &nbsp; &nbsp;(Key: 'PRTSC'; &nbsp;vkCode: vk_SnapShot),<br> &nbsp; &nbsp;(Key: 'SHIFT'; &nbsp;vkCode: vk_Shift),<br> &nbsp; &nbsp;(Key: 'ESCAPE'; vkCode: vk_Escape));<br><br><br>function FindKeyInArray(Key: TKeyString; var Code: Byte): Boolean;<br><br>implementation<br><br>uses SysUtils;<br><br>function FindKeyInArray(Key: TKeyString; var Code: Byte): Boolean;<br>{ function searches array for token passed in Key, and returns the }<br>{ virtual key code in Code. }<br>var<br> &nbsp;i: word;<br>begin<br> &nbsp;Result := False;<br> &nbsp;for i := Low(KeyDefArray) to High(KeyDefArray) do<br> &nbsp; &nbsp;if UpperCase(Key) = KeyDefArray.Key then begin<br> &nbsp; &nbsp; &nbsp;Code := KeyDefArray.vkCode;<br> &nbsp; &nbsp; &nbsp;Result := True;<br> &nbsp; &nbsp; &nbsp;Break;<br> &nbsp; &nbsp;end;<br>end;<br><br>end.<br><br>for example:<br>unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls, SendKey,KeyDefs;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure FormKeyDown(Sender: TObject; var Key: Word;<br> &nbsp; &nbsp; &nbsp;Shift: TShiftState);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;SendKeys('{F1}');<br>end;<br><br>procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;<br> &nbsp;Shift: TShiftState);<br>begin<br> &nbsp;if Key=112 then ShowMessage('F1');<br>end;<br><br>end.<br><br>注意:form1.keypreview:=true;<br><br>如果向其他程序发送:<br> &nbsp; &nbsp;H := FindWindow('Caption', nil); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// find window<br> &nbsp; &nbsp;if SetForegroundWindow(H) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// bring it to front<br> &nbsp; &nbsp; &nbsp;SendKeys('{F1}');
 
你用keybd_event()试试看吧,应该可以的。第二个参数设置成1,表示对当前窗口发送键盘按钮。这个API本身就是用来模拟键盘事件的
 
向不属于一个进程的程序发送消息最好用PostMessage,这个函数的功能是把指定的消息放到某个进程的消息队列去,不等程序处理就直接返回。我写过一个自动应答的程序就是用这个方法向别的程序发送回车键WORD值“13”。<br>F1键的WORD值是112。<br>另:F1键是系统定义的“帮助”功能键,如果你只是想打开那个程序的“帮助”,可以直接试试发送“WM_HELP”消息。
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部