VB中的sendkeys函数 在DELPHI中如何实现?(50分)

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

runmark

Unregistered / Unconfirmed
GUEST, unregistred user!
VB中的sendkeys函数 在DELPHI中如何实现?<br>&nbsp;当然,一种方法是D5安装包里有一个snkey32.pas,可以实现。但是我现在我无法得到。<br>第二种方法是使用postmessage()api函数,但是无法发送组合键,例如:shift+home<br>请高手赐教。最好是有代码实例。多谢!
 
&nbsp; var<br>&nbsp; &nbsp; &nbsp;lpKeyState :TKeyboardState;<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp;GetKeyboardState(lpKeyState);<br>&nbsp; &nbsp; &nbsp;lpKeyState[VK_CONTROL] :=$80;<br>&nbsp; &nbsp; &nbsp;SetKeyboardState(lpKeyState);<br>&nbsp; &nbsp; &nbsp;PostMessage(ListBox1.handle,WM_KEYDOWN,VK_END,0);<br>&nbsp; &nbsp; &nbsp;ListBox1.SetFocus;<br>&nbsp; &nbsp; &nbsp;lpKeyState[VK_SHIFT] :=$01;<br>&nbsp; &nbsp; &nbsp;lpKeyState[VK_CONTROL] :=$01;<br>&nbsp; &nbsp; &nbsp;SetKeyboardState(lpKeyState);<br>&nbsp; &nbsp;end;
 
unit SendKey;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes;<br><br>var<br>&nbsp; Playing: Boolean;<br><br>function SendKeys(S: string): Boolean;<br>procedure StopPlayback;<br><br>implementation<br><br>uses Keydefs;<br><br>type<br>&nbsp; TvkKeySet = set of vk_LButton..vk_Scroll;<br>&nbsp; <br>&nbsp; TMessageList = class(TList)<br>&nbsp; public<br>&nbsp; &nbsp; destructor Destroy; override;<br>&nbsp; end;<br><br>const<br>&nbsp; vkKeySet: TvkKeySet = [Ord('A')..Ord('Z'), vk_Menu, vk_F1..vk_F12];<br><br>{ TMessageList }<br><br>destructor TMessageList.Destroy;<br>var<br>&nbsp; I: Longint;<br>begin<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;RecordingPaused: Boolean;<br>&nbsp; PlayCount: WORD;<br>&nbsp; PlayBuffer: TEventMsg;<br>&nbsp; PlayHandle: hHook;<br>&nbsp; PlayList: TMessageList;<br>&nbsp; AltPressed, ControlPressed, ShiftPressed: Boolean;<br><br>function KeyRecord(Code: Integer; wParam, lParam: Longint): Longint; stdcall;<br>begin<br>&nbsp; if Code = HC_ACTION then<br>&nbsp; begin<br><br>&nbsp; &nbsp; Result := 0;<br>&nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; Result := CallNextHookEx(RecHandle, Code, wParam, lParam);<br>end;<br><br>function Play(Code: Integer; wParam, lParam: Longint): Longint; stdcall;<br>begin<br>&nbsp; case Code of<br>&nbsp; &nbsp; HC_SKIP:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Inc(PlayCount);<br>&nbsp; &nbsp; &nbsp; &nbsp; if PlayCount &gt;= PlayList.Count then //StopPlayback<br>&nbsp; &nbsp; &nbsp; &nbsp; else PlayBuffer := TEventMsg(PlayList.Items[PlayCount]^);<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := 0;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; HC_GETNEXT:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; PEventMsg(lParam)^ := PlayBuffer;<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := 0<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; Result := CallNextHookEx(PlayHandle, Code, wParam, lParam);<br>&nbsp; end;<br>end;<br><br>procedure StartPlayback;<br>begin<br>&nbsp; PlayBuffer := TEventMsg(PlayList.Items[0]^);<br>&nbsp; PlayCount := 0;<br>&nbsp; AltPressed := False;<br>&nbsp; ControlPressed := False;<br>&nbsp; ShiftPressed := False;<br>&nbsp; PlayHandle := SetWindowsHookEx(wh_JournalPlayback, Play, hInstance, 0);<br>&nbsp; if PlayHandle = 0 then<br>&nbsp; &nbsp; raise Exception.Create('Failed to set hook!');<br>&nbsp; Playing := True;<br>end;<br><br>procedure StopPlayback;<br>begin<br>&nbsp; if Playing then<br>&nbsp; &nbsp; UnhookWindowsHookEx(PlayHandle);<br>&nbsp; PlayList.Free;<br>&nbsp; Playing := False;<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<br>&nbsp; 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; PlayList.Add(E);<br>end;<br><br>procedure GenKeyDown(vKey: Byte);<br>begin<br>&nbsp; if AltPressed and (not ControlPressed) and (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 GenKeyUp(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 GenKeyDown(vk_Menu);<br>&nbsp; if ControlPressed then GenKeyDown(vk_Control);<br>&nbsp; if (((Hi(VKeyCode) and 1) &lt;&gt; 0) and (not ControlPressed))<br>&nbsp; or ShiftPressed then<br>&nbsp; &nbsp; GenKeyDown(vk_Shift);<br>&nbsp; GenKeyDown(Lo(VKeyCode));<br>&nbsp; GenKeyUp(Lo(VKeyCode));<br>&nbsp; if (((Hi(VKeyCode) and 1) &lt;&gt; 0) and (not ControlPressed))<br>&nbsp; or ShiftPressed then<br>&nbsp; &nbsp; GenKeyUp(vk_Shift);<br>&nbsp; if ShiftPressed then ShiftPressed := False;<br>&nbsp; if ControlPressed then<br>&nbsp; begin<br>&nbsp; &nbsp; GenKeyUp(vk_Control);<br>&nbsp; &nbsp; ControlPressed := False;<br>&nbsp; end;<br>&nbsp; if AltPressed then<br>&nbsp; begin<br>&nbsp; &nbsp; GenKeyUp(vk_Menu);<br>&nbsp; &nbsp; AltPressed := False;<br>&nbsp; end;<br>end;<br><br>procedure ProcessPlayKey(S: string);<br>var<br>&nbsp; KeyCode: Word;<br>&nbsp; Key: Byte;<br>&nbsp; I: Integer;<br>&nbsp; Token: TKeyString;<br>begin<br>&nbsp; I := 1;<br>&nbsp; repeat<br>&nbsp; &nbsp; case S of<br>&nbsp; &nbsp; &nbsp; KeyGroupOpen:<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Token := '';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Inc(I);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while S &lt;&gt; KeyGroupClose do begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Token := Token + S;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Inc(I);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Length(Token) = 7) and (S &lt;&gt; KeyGroupClose) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create('No closing brace');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not FindKeyInArray(Token, Key) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create('Invalid token');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SimKeyPresses(MakeWord(Key, 0));<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; AltKey: AltPressed := True;<br>&nbsp; &nbsp; &nbsp; ControlKey: ControlPressed := True;<br>&nbsp; &nbsp; &nbsp; ShiftKey: ShiftPressed := True;<br>&nbsp; &nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; KeyCode := vkKeyScan(S);<br>&nbsp; &nbsp; &nbsp; &nbsp; SimKeyPresses(KeyCode);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Inc(I);<br>&nbsp; until I &gt; Length(S);<br>end;<br><br>function SendKeys(S: string): Boolean;<br>begin<br>&nbsp; Result := False;<br>&nbsp; try<br>&nbsp; &nbsp; if Playing then Exit;<br>&nbsp; &nbsp; PlayList := PlayList.Create;<br>&nbsp; &nbsp; ProcessPlayKey(S);<br>&nbsp; &nbsp; StartPlayback;<br>&nbsp; &nbsp; Result := True;<br>&nbsp; except<br>&nbsp; end;<br>end;<br>{<br>procedure WaitForPlay;<br>begin<br>&nbsp; repeat<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; until not Playing;<br>end;}<br><br>end.<br>
 
多谢两位的帮助. 以后还要多多指教.
 
后退
顶部