Reputation: 7390
There are lots of examples of how to use the Windows API to simulate pressing of keys. One option would be something like the code below.
However what i'm trying to achieve is one step further. The code below requires the app you want to send the keys, to be always the foreground window. I'm trying to sending keys to a window that is NOT in focus, so i can automate tasks / macros with this window minimized.
Is there any alternative ?
Thanks
procedure PostKeyEx32(key: Word; const shift: TShiftState;
specialkey: Boolean);
type
TShiftKeyInfo = record
shift: Byte ;
vkey: Byte ;
end;
ByteSet = set of 0..7 ;
const
shiftkeys: array [1..3] of TShiftKeyInfo =
((shift: Ord(ssCtrl) ; vkey: VK_CONTROL),
(shift: Ord(ssShift) ; vkey: VK_SHIFT),
(shift: Ord(ssAlt) ; vkey: VK_MENU)) ;
var
flag: DWORD;
bShift: ByteSet absolute shift;
j: Integer;
begin
for j := 1 to 3 do
begin
if shiftkeys[j].shift in bShift then
keybd_event(shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), 0, 0) ;
end;
if specialkey then
flag := KEYEVENTF_EXTENDEDKEY
else
flag := 0;
if key = 47 then
begin
keybd_event(VkKeyScan('/'), 1, 0, 0);
end
else
begin
keybd_event(key, MapvirtualKey(key, 0), flag, 0) ;
flag := flag or KEYEVENTF_KEYUP;
keybd_event(key, MapvirtualKey(key, 0), flag, 0) ;
end;
for j := 3 downto 1 do
begin
if shiftkeys[j].shift in bShift then
keybd_event(shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), KEYEVENTF_KEYUP, 0) ;
end;
end;
Upvotes: 1
Views: 1397
Reputation: 187
This is an example to send/handle WM_KEYUP messages by a specific window. But it is the same for any other message types (custom ones as well, just the params depends on its type) The destination window have to implement the message handler procedure.
procedure onKeyPressed( var message_ : TWMKeyUp ); message WM_KEYUP;
To send the messages, you have to use sendMessage
with the right parameters.
The first parameter is the handle of the window, the second one is the message ID, the 3rd and 4th ones depends on the message type defined by the message ID.
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure onKeyPressed( var message_ : TWMKeyUp ); message WM_KEYUP;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if ( edit1.text <> '' ) then
sendMessage( handle, WM_KEYUP, cardinal( edit1.text[1] ), 0 );
end;
procedure TForm1.onKeyPressed( var message_ : TWMKeyUp );
var
c : char;
begin
c := char( message_.CharCode );
label1.caption := label1.caption + c;
end;
Upvotes: 3
Reputation: 2216
For most apps WM_KEYDOWN and WM_KEYUP will be enough: http://www.delphigroups.info/2/80/324746.html
But for some apps you will require API hooks on functions like GetAsyncKeyState plus a way to load your dll into a target process: https://progamercity.net/delphi/647-delphi-dll-injection-functions.html. All that will be very suspicious from Antivirus software point of view.
Upvotes: 1