Contributor: SWAG SUPPORT TEAM
Here is the poor man's version:
 procedure keybd_Event; far; external 'USER' index 289;
 procedure PostVKey(bVirtKey: byte; Up: Boolean);
 var
 AXReg,BXReg : Word;
 AXHigh, AXLow, BXHigh, BXLow : Byte;
function MakeWord(L,H: Byte): Word;
begin
 MakeWord := (H shl 8) + L;
end;
begin
 AXLow := bVirtKey;
 if up then AXHigh := 80ドル else AXHigh := 0ドル;
 AXreg := MakeWord(AXLow,AXHigh);
 BXLow := VkKeyScan(bVirtKey);
 BXHigh := 0;
 BXReg := MakeWord(BXLow,BXHigh);
 asm
 mov bx,BXreg;
 mov ax,AXReg;
 end;
 Keybd_Event;
end;
then to simulate Shift+Ins you need:-
PostVKey(VK_Shift,false);
PostVKey(VK_Insert,false);
PostVKey(VK_Insert,True);
PostVKey(VK_Shift,True);
Here is the Rolls-Royce version:
Note: This is commercial and copyrighted code. The source code may not be sold for profit
(unless Steve is doing the selling).
{This unit is to be included in the app that you are running.}
unit SKeys;
interface
type
 { Return values for SendKeys function }
 TSendKeyError = (sk_None, sk_FailSetHook, sk_InvalidToken, sk_UnknownError);
function SendKeys(S: String): TSendKeyError;
implementation
function SendKeys; external 'SendKey' index 2;
end.
(********************************************)
{Here is the DLL that is used.}
library SendKey;
uses
 SysUtils, WinTypes, WinProcs, Messages, Classes, KeyDefs;
type
 { Error codes }
 TSendKeyError = (sk_None, sk_FailSetHook, sk_InvalidToken, sk_UnknownError);
 { exceptions }
 ESendKeyError = class(Exception);
 ESetHookError = class(ESendKeyError);
 EInvalidToken = class(ESendKeyError);
 { a TList descendant that know how to dispose of its contents }
 TMessageList = class(TList)
 public
 destructor Destroy; override;
 end;
destructor TMessageList.Destroy;
var
 i: longint;
begin
 { deallocate all the message records before discarding the list }
 for i := 0 to Count - 1 do
 Dispose(PEventMsg(Items[i]));
 inherited Destroy;
end;
var
 { variables global to the DLL }
 MsgCount: word;
 MessageBuffer: TEventMsg;
 HookHandle: hHook;
 Playing: Boolean;
 MessageList: TMessageList;
 AltPressed, ControlPressed, ShiftPressed: Boolean;
 NextSpecialKey: TKeyString;
function MakeWord(L, H: Byte): Word;
{ macro creates a word from low and high bytes }
inline(
 5ドルA/ { pop dx }
 58ドル/ { pop ax }
 8ドルA/$E2); { mov ah, dl }
procedure StopPlayback;
{ Unhook the hook, and clean up }
begin
 { if Hook is currently active, then unplug it }
 if Playing then
 UnhookWindowsHookEx(HookHandle);
 MessageList.Free;
 Playing := False;
end;
function Play(Code: integer; wParam: word; lParam: Longint): Longint; export;
{ This is the JournalPlayback callback function. It is called by Windows }
{ when Windows polls for hardware events. The code parameter indicates what }
{ to do. }
begin
 case Code of
 hc_Skip: begin
 { hc_Skip means to pull the next message out of our list. If we }
 { are at the end of the list, it's okay to unhook the JournalPlayback }
 { hook from here. }
 { increment message counter }
 inc(MsgCount);
 { check to see if all messages have been played }
 if MsgCount>= MessageList.Count then
 StopPlayback
 else
 { copy next message from list into buffer }
 MessageBuffer := TEventMsg(MessageList.Items[MsgCount]^);
 Result := 0;
 end;
 hc_GetNext: begin
 { hc_GetNext means to fill the wParam and lParam with the proper }
 { values so that the message can be played back. DO NOT unhook }
 { hook from within here. Return value indicates how much time until }
 { Windows should playback message. We'll return 0 so that it's }
 { processed right away. }
 { move message in buffer to message queue }
 PEventMsg(lParam)^ := MessageBuffer;
 Result := 0 { process immediately }
 end
 else
 { if Code isn't hc_Skip or hc_GetNext, then call next hook in chain }
 Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
 end;
end;
procedure StartPlayback;
{ Initializes globals and sets the hook }
begin
 { grab first message from list and place in buffer in case we }
 { get a hc_GetNext before and hc_Skip }
 MessageBuffer := TEventMsg(MessageList.Items[0]^);
 { initialize message count and play indicator }
 MsgCount := 0;
 { initialize Alt, Control, and Shift key flags }
 AltPressed := False;
 ControlPressed := False;
 ShiftPressed := False;
 { set the hook! }
 HookHandle := SetWindowsHookEx(wh_JournalPlayback, Play, hInstance, 0);
 if HookHandle = 0 then
 raise ESetHookError.Create('Couldn''t set hook')
 else
 Playing := True;
end;
procedure MakeMessage(vKey: byte; M: word);
{ procedure builds a TEventMsg record that emulates a keystroke and }
{ adds it to message list }
var
 E: PEventMsg;
begin
 New(E); { allocate a message record }
 with E^ do begin
 Message := M; { set message field }
 { high byte of ParamL is the vk code, low byte is the scan code }
 ParamL := MakeWord(vKey, MapVirtualKey(vKey, 0));
 ParamH := 1; { repeat count is 1 }
 Time := GetTickCount; { set time }
 end;
 MessageList.Add(E);
end;
procedure KeyDown(vKey: byte);
{ Generates KeyDownMessage }
begin
 { don't generate a "sys" key if the control key is pressed (Windows quirk) }
 if (AltPressed and (not ControlPressed) and (vKey in [Ord('A')..Ord('Z')])) or
 (vKey = vk_Menu) then
 MakeMessage(vKey, wm_SysKeyDown)
 else
 MakeMessage(vKey, wm_KeyDown);
end;
procedure KeyUp(vKey: byte);
{ Generates KeyUp message }
begin
 { don't generate a "sys" key if the control key is pressed (Windows quirk) }
 if AltPressed and (not ControlPressed) and (vKey in [Ord('A')..Ord('Z')]) then
 MakeMessage(vKey, wm_SysKeyUp)
 else
 MakeMessage(vKey, wm_KeyUp);
end;
procedure SimKeyPresses(VKeyCode: Word);
{ This function simulates keypresses for the given key, taking into }
{ account the current state of Alt, Control, and Shift keys }
begin
 { press Alt key if flag has been set }
 if AltPressed then
 KeyDown(vk_Menu);
 { press Control key if flag has been set }
 if ControlPressed then
 KeyDown(vk_Control);
 { if shift is pressed, or shifted key and control is not pressed... }
 if (((Hi(VKeyCode) and 1)  0) and (not ControlPressed)) or ShiftPressed then
 KeyDown(vk_Shift); { ...press shift }
 KeyDown(Lo(VKeyCode)); { press key down }
 KeyUp(Lo(VKeyCode)); { release key }
 { if shift is pressed, or shifted key and control is not pressed... }
 if (((Hi(VKeyCode) and 1)  0) and (not ControlPressed)) or ShiftPressed then
 KeyUp(vk_Shift); { ...release shift }
 { if shift flag is set, reset flag }
 if ShiftPressed then begin
 ShiftPressed := False;
 end;
 { Release Control key if flag has been set, reset flag }
 if ControlPressed then begin
 KeyUp(vk_Control);
 ControlPressed := False;
 end;
 { Release Alt key if flag has been set, reset flag }
 if AltPressed then begin
 KeyUp(vk_Menu);
 AltPressed := False;
 end;
end;
procedure ProcessKey(S: String);
{ This function parses each character in the string to create the message list }
var
 KeyCode: word;
 Key: byte;
 index: integer;
 Token: TKeyString;
begin
 index := 1;
 repeat
 case S[index] of
 KeyGroupOpen : begin
 { It's the beginning of a special token! }
 Token := '';
 inc(index);
 while S[index]  KeyGroupClose do begin
 { add to Token until the end token symbol is encountered }
 Token := Token + S[index];
 inc(index);
 { check to make sure the token's not too long }
 if (Length(Token) = 7) and (S[index]  KeyGroupClose) then
 raise EInvalidToken.Create('No closing brace');
 end;
 { look for token in array, Key parameter will }
 { contain vk code if successful }
 if not FindKeyInArray(Token, Key) then
 raise EInvalidToken.Create('Invalid token');
 { simulate keypress sequence }
 SimKeyPresses(MakeWord(Key, 0));
 end;
 AltKey : begin
 { set Alt flag }
 AltPressed := True;
 end;
 ControlKey : begin
 { set Control flag }
 ControlPressed := True;
 end;
 ShiftKey : begin
 { set Shift flag }
 ShiftPressed := True;
 end;
 else begin
 { A normal character was pressed }
 { convert character into a word where the high byte contains }
 { the shift state and the low byte contains the vk code }
 KeyCode := vkKeyScan(MakeWord(Byte(S[index]), 0));
 { simulate keypress sequence }
 SimKeyPresses(KeyCode);
 end;
 end;
 inc(index);
 until index> Length(S);
end;
function SendKeys(S: String): TSendKeyError; export;
{ This is the one entry point. Based on the string passed in the S }
{ parameter, this function creates a list of keyup/keydown messages, }
{ sets a JournalPlayback hook, and replays the keystroke messages. }
var
 i: byte;
begin
 try
 Result := sk_None; { assume success }
 MessageList := TMessageList.Create; { create list of messages }
 ProcessKey(S); { create messages from string }
 StartPlayback; { set hook and play back messages }
 except
 { if an exception occurs, return an error code, and clean up }
 on E:ESendKeyError do begin
 MessageList.Free;
 if E is ESetHookError then
 Result := sk_FailSetHook
 else if E is EInvalidToken then
 Result := sk_InvalidToken;
 end
 else
 { Catch-all exception handler ensures than an exception }
 { doesn't walk up into application stack }
 Result := sk_UnknownError;
 end;
end;
exports
 SendKeys index 2;
begin
end.
(********************************************)
unit Keydefs;
interface
uses WinTypes;
const
 MaxKeys = 24;
 ControlKey = '^';
 AltKey = '@';
 ShiftKey = '~';
 KeyGroupOpen = '{';
 KeyGroupClose = '}';
type
 TKeyString = String[7];
 TKeyDef = record
 Key: TKeyString;
 vkCode: Byte;
 end;
const
 KeyDefArray : array[1..MaxKeys] of TKeyDef = (
 (Key: 'F1'; vkCode: vk_F1),
 (Key: 'F2'; vkCode: vk_F2),
 (Key: 'F3'; vkCode: vk_F3),
 (Key: 'F4'; vkCode: vk_F4),
 (Key: 'F5'; vkCode: vk_F5),
 (Key: 'F6'; vkCode: vk_F6),
 (Key: 'F7'; vkCode: vk_F7),
 (Key: 'F8'; vkCode: vk_F8),
 (Key: 'F9'; vkCode: vk_F9),
 (Key: 'F10'; vkCode: vk_F10),
 (Key: 'F11'; vkCode: vk_F11),
 (Key: 'F12'; vkCode: vk_F12),
 (Key: 'INSERT'; vkCode: vk_Insert),
 (Key: 'DELETE'; vkCode: vk_Delete),
 (Key: 'HOME'; vkCode: vk_Home),
 (Key: 'END'; vkCode: vk_End),
 (Key: 'PGUP'; vkCode: vk_Prior),
 (Key: 'PGDN'; vkCode: vk_Next),
 (Key: 'TAB'; vkCode: vk_Tab),
 (Key: 'ENTER'; vkCode: vk_Return),
 (Key: 'BKSP'; vkCode: vk_Back),
 (Key: 'PRTSC'; vkCode: vk_SnapShot),
 (Key: 'SHIFT'; vkCode: vk_Shift),
 (Key: 'ESCAPE'; vkCode: vk_Escape));
function FindKeyInArray(Key: TKeyString; var Code: Byte): Boolean;
implementation
uses SysUtils;
function FindKeyInArray(Key: TKeyString; var Code: Byte): Boolean;
{ function searches array for token passed in Key, and returns the }
{ virtual key code in Code. }
var
 i: word;
begin
 Result := False;
 for i := Low(KeyDefArray) to High(KeyDefArray) do
 if UpperCase(Key) = KeyDefArray[i].Key then begin
 Code := KeyDefArray[i].vkCode;
 Result := True;
 Break;
 end;
end;
end.


AltStyle によって変換されたページ (->オリジナル) /