unit ReceiverUnit;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;typeTReceivForm = class(TForm)Memo1: TMemo;procedure FormCreate(Sender: TObject);protectedprocedure WMCopyData(var Message: TWMCopyData); message WM_COPYDATA;private{ Private 宣言 }public{ Public 宣言 }end;procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState;specialkey: Boolean);varReceivForm: TReceivForm;implementation{$R *.DFM}//-----------------------------------------------// 押下キーデータのレコード型// 送信側とデータのサイズと型を一致させておく//-----------------------------------------------typeTKeyDataInfo = recordhRevWnd : HWND;Key : Byte;shift : TShiftStateend;//=============================================================================// フォーム生成時の処理//=============================================================================procedure TReceivForm.FormCreate(Sender: TObject);beginMemo1.Lines.Text := '日本語 ABC テスト文字列';Memo1.SelStart := 8;Memo1.HideSelection := False;// 他のアプリから見つけやすいように ID 値を設定しておく// 最後に設定することSetWindowLong(Memo1.Handle, GWL_ID, 1000);end;//=============================================================================// 受信データの処理// 受信データを元に WM_KEYDOWN, WM_KEYUP メッセージを対象のコントロールにsポスト//=============================================================================procedure TReceivForm.WMCopyData(var Message: TWMCopyData);varLKeyInfo : TKeyDataInfo;LKey : Byte;LShift : TShiftState;beginif Message.CopyDataStruct.dwData = 1234thenbegin// 受信データを取得LKeyInfo := TKeyDataInfo(Message.CopyDataStruct^.lpData^);LKey := LKeyInfo.Key;LShift := LKeyInfo.shift;PostKeyExHWND(LKeyInfo.hRevWnd, LKey, LShift, False);end;end;{***********************************************************}{3. With keybd_event API}procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState;specialkey: Boolean);{************************************************************* Procedure PostKeyEx** Parameters:* hWindow: target window to be send the keystroke* key : virtual keycode of the key to send. For printable* keys this is simply the ANSI code (Ord(character)).* shift : state of the modifier keys. This is a set, so you* can set several of these keys (shift, control, alt,* mouse buttons) in tandem. The TShiftState type is* declared in the Classes Unit.* specialkey: normally this should be False. Set it to True to* specify a key on the numeric keypad, for example.* If this parameter is true, bit 24 of the lparam for* the posted WM_KEY* messages will be set.* Description:* This procedure sets up Windows key state array to correctly* reflect the requested pattern of modifier keys and then posts* a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then* Application.ProcessMessages is called to process the messages* before the keyboard state is restored.* Error Conditions:* May fail due to lack of memory for the two key state buffers.* Will raise an exception in this case.* NOTE:* Setting the keyboard state will not work across applications* running in different memory spaces on Win32 unless AttachThreadInput* is used to connect to the target thread first.*Created: 02/21/96 16:39:00 by P. Below************************************************************}typeTBuffers = array [0..1] of TKeyboardState;varpKeyBuffers: ^TBuffers;lParam: LongInt;begin(* check if the target window exists *)if IsWindow(hWindow) thenbegin(* set local variables to default values *)pKeyBuffers := nil;lParam := MakeLong(0, MapVirtualKey(key, 0));(* modify lparam if special key requested *)if specialkey thenlParam := lParam or$1000000;(* allocate space for the key state buffers *)New(pKeyBuffers);try(* Fill buffer 1 with current state so we can later restore it.Null out buffer 0 to get a "no key pressed" state. *)GetKeyboardState(pKeyBuffers^[1]);FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);(* set the requested modifier keys to "down" state in the buffer*)if ssShift in shift thenpKeyBuffers^[0][VK_SHIFT] := $80;if ssAlt in shift thenbegin(* Alt needs special treatment since a bit in lparam needs also be set *)pKeyBuffers^[0][VK_MENU] := $80;lParam := lParam or$20000000;end;if ssCtrl in shift thenpKeyBuffers^[0][VK_CONTROL] := $80;if ssLeft in shift thenpKeyBuffers^[0][VK_LBUTTON] := $80;if ssRight in shift thenpKeyBuffers^[0][VK_RBUTTON] := $80;if ssMiddle in shift thenpKeyBuffers^[0][VK_MBUTTON] := $80;(* make out new key state array the active key state map *)SetKeyboardState(pKeyBuffers^[0]);(* post the key messages *)if ssAlt in Shift thenbeginPostMessage(hWindow, WM_SYSKEYDOWN, key, lParam);PostMessage(hWindow, WM_SYSKEYUP, key, lParam or$C0000000);endelsebeginPostMessage(hWindow, WM_KEYDOWN, key, lParam);PostMessage(hWindow, WM_KEYUP, key, lParam or$C0000000);end;(* process the messages *)Application.ProcessMessages;(* restore the old key state map *)SetKeyboardState(pKeyBuffers^[1]);finally(* free the memory for the key state buffers *)if pKeyBuffers <> nilthenDispose(pKeyBuffers);end; { If }end;end; { PostKeyEx }end.