Forum > Windows
Using SendMessage or Postmessage to simulate keyboard
Nimral:
Hi all,
Trying to send keystrokes to an application on Windows 11 I have this code ...
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var wndMain: HWND; r:LResult; scanCode:UINT; l:LPARAM; w:WPARAM; begin // wndMain := FindWindow(PChar(aClassName),nil); wndMain := FindWindow('Notepad',nil); DoShowStatus('Window Handle: ' + IntToStr(wndMain)); if wndMain <> 0 then begin l := 0; // scanCode := MapVirtualKey(VK_A, 0); // l := ($00000001 OR (scanCode SHL 16)); r := SendMessage(wndMain,WM_KEYDOWN,VK_A,l); // l := l OR $C0000000; r := SendMessage(wndMain,WM_KEYUP,VK_A,l); end;end;
The objective is to send a specific keystroke (I choose VK_A for testing) to an application, to try I choose notepad.
Finding the hwnd for notepad seems to work, a value is returned.
Unfortunately there is no reaction in Notepad, no keystrokes show up, though SendMessage returns 0. I tried PostMessage too, same behaviour. Regarding the bitmask for lParam, I took it from the AutoIt source code, but using it (commented out) doesn't change anything.
Can anyone provide a working code sample showing how I need to use SendMessage or PostMessage? From what I read I should prefer PostMessage.
Thnx, Armin.
GetMem:
@Nimarl
--- Quote ---The objective is to send a specific keystroke (I choose VK_A for testing) to an application, to try I choose notepad.
Finding the hwnd for notepad seems to work, a value is returned.
Unfortunately there is no reaction in Notepad, no keystrokes show up, though SendMessage returns 0. I tried PostMessage too, same behaviour. Regarding the bitmask for lParam, I took it from the AutoIt source code, but using it (commented out) doesn't change anything.
Can anyone provide a working code sample showing how I need to use SendMessage or PostMessage? From what I read I should prefer PostMessage.
--- End quote ---
1. You are sending the keystroke to the wrong window, notepad has a child window named "Edit".
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses windows; procedure TForm1.Button1Click(Sender: TObject);var wHandle: HWND;begin wHandle := FindWindow('notepad', nil); if wHandle = 0 then Exit; wHandle := FindWindowEx(wHandle, FindWindow('Edit', nil), nil, nil); if wHandle = 0 then Exit; SendMessage(wHandle, WM_CHAR, Word('a'), 0);end; 2. Replace SendMessage with PostMessage, the later is an asynchronous function, it won't block the message queue
Remy Lebeau:
--- Quote from: Nimral on December 22, 2022, 12:59:50 am ---Trying to send keystrokes to an application
--- End quote ---
You can't simulate keyboard input with PostMessage (or SendMessage, too)
Thaddy:
Alas, several consts and the INPUT struct are missing in Windows, so the SendInput() example from msdn won't work even if correctly translated to Pascal. Busy on it. Should be easy.
[edit] progress, it compiles (but does not work yet):
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$mode delphiunicode}{$apptype console}uses jwawindows;//**********************************************************************//// Sends Win + D to toggle to the desktop////**********************************************************************type Tinputs = array[0..3] of INPUT; const VK_D:word = $0044;procedure ShowDesktop;var inputs:TInputs; uSent:UINT;begin writeln('Sending Win-D'); ZeroMemory(@inputs, length(inputs)); inputs[0].type_ := INPUT_KEYBOARD; inputs[0].ki.wVk := VK_LWIN; inputs[1].type_ := INPUT_KEYBOARD; inputs[1].ki.wVk := VK_D; inputs[2].type_ := INPUT_KEYBOARD; inputs[2].ki.wVk := VK_D; inputs[2].ki.dwFlags := KEYEVENTF_KEYUP; inputs[3].type_ := INPUT_KEYBOARD; inputs[3].ki.wVk := VK_LWIN; inputs[3].ki.dwFlags := KEYEVENTF_KEYUP; uSent := SendInput(SizeOf(inputs),inputs, sizeof(INPUT)); if (uSent <> length(inputs)) then writeln(HRESULT_FROM_WIN32(GetLastError()));end;begin ShowDeskTop;end. Note this code should also work from a console, tested with the C++ code.
Probably an oversight, maybe someone can spot it? Maybe User Interface Privilege Isolation, a.k.a. UIPI?
KodeZwerg:
--- Quote from: GetMem on December 22, 2022, 06:27:42 am ---
--- Code: --- SendMessage(wHandle, WM_CHAR, Word('a'), 0);
--- End code ---
--- End quote ---
I am unsure what the OP try to do, maybe WM_SETTEXT is better.
Navigation
[0] Message Index
[#] Next page