Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
If you find these projects useful please consider becoming a sponsor with Patreon, GitHub or Liberapay.

SimulateKeyEvent

jc4golf
Posts: 32
Joined: Wed Jun 23, 2021 12:33 am

SimulateKeyEvent

Post by jc4golf »

I've been trying to send keystrokes to a website input element using the following, which doesn't work:

Code: Select all

  GHINID := '9731150';
  for i := 1 to GHINID.length do
  begin
    WVBrowser1.SimulateKeyEvent(ketRawKeyDown, 0, Ord(GHINID[i]), 0);
    WVBrowser1.SimulateKeyEvent(ketChar, 0, Ord(GHINID[i]), 0);
    WVBrowser1.SimulateKeyEvent(ketKeyUp, 0, Ord(GHINID[i]), 0);
  end;  
In Cef4Delphi I've been using the following, which does work on the same website input element:

Code: Select all

  GHINID := '9731150';
  for I := 1 to GHINID.Length do
  begin
    TempKeyEvent.kind := KEYEVENT_RAWKEYDOWN;
    TempKeyEvent.modifiers := 0;
    TempKeyEvent.windows_key_code := Ord(GHINID[I]);
    TempKeyEvent.native_key_code := 0;
    TempKeyEvent.is_system_key := Ord(false);
    TempKeyEvent.character := #0;
    TempKeyEvent.unmodified_character := #0;
    TempKeyEvent.focus_on_editable_field := Ord(false);
    Chromium1.SendKeyEvent(@TempKeyEvent);
    TempKeyEvent.kind := KEYEVENT_CHAR;
    Chromium1.SendKeyEvent(@TempKeyEvent);
    TempKeyEvent.kind := KEYEVENT_KEYUP;
    Chromium1.SendKeyEvent(@TempKeyEvent);
  end;
Do I need to send different parameters in WebView4Delphi?
User avatar
salvadordf
Posts: 4620
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SimulateKeyEvent

Post by salvadordf »

No. In fact, I implemented TWVBrowserBase.KeyboardShortcutSearch and TWVBrowserBase.KeyboardShortcutRefreshIgnoreCache with SimulateKeyEvent calls that use data extracted with SimpleOSRBrowser in CEF4Delphi.

Open SimpleOSRBrowser and use CefKeyEventLog in TForm1.AppEventsMessage to log all the keyboard event information. Then use that information in SimulateKeyEvent.
jc4golf
Posts: 32
Joined: Wed Jun 23, 2021 12:33 am

Re: SimulateKeyEvent

Post by jc4golf »

How do I use that CefKeyEventLog???
User avatar
salvadordf
Posts: 4620
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SimulateKeyEvent

Post by salvadordf »

Download CEF4Delphi again from GitHub. I just added the CefKeyEventLog calls to log keyboard events in the debug.log file.
jc4golf
Posts: 32
Joined: Wed Jun 23, 2021 12:33 am

Re: SimulateKeyEvent

Post by jc4golf »

Yes, thank you Salvador, I did figure it out by searching through the CEF4Delphi code. Now I just have to figure out how the native key code is generated.
jc4golf
Posts: 32
Joined: Wed Jun 23, 2021 12:33 am

Re: SimulateKeyEvent

Post by jc4golf »

Well, I can't get this to work. The parameters I get from the CefKeyEventLog info in debug.log don't have any modifier info. And when I try to compare what you did for F3 and Shift-F5, I get no modifiers for those either, yet your code has modifiers in KeyboardShortcutSearch and KeyboardShortcutRefreshIgnoreCache. How did you come up with those?
User avatar
salvadordf
Posts: 4620
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SimulateKeyEvent

Post by salvadordf »

I just run the SimpleOSRBrowser and I got this information in the debug log.

Pressing F3 :

Code: Select all

[0531/095730.151:INFO:CEF4Delphi(1)] kind: KEYEVENT_RAWKEYDOWN, modifiers: $00000100, windows_key_code: $00000072, native_key_code: $003D0001, is_system_key: False, character: $0000, unmodified_character: $0000, focus_on_editable_field: False
[0531/095730.217:INFO:CEF4Delphi(1)] kind: KEYEVENT_KEYUP, modifiers: $00000100, windows_key_code: $00000072, native_key_code: $C03D0001, is_system_key: False, character: $0000, unmodified_character: $0000, focus_on_editable_field: False
Pressing shift+F5 :

Code: Select all

[0531/100217.454:INFO:CEF4Delphi(1)] kind: KEYEVENT_RAWKEYDOWN, modifiers: $00000502, windows_key_code: $00000010, native_key_code: $002A0001, is_system_key: False, character: $0000, unmodified_character: $0000, focus_on_editable_field: False
[0531/100217.644:INFO:CEF4Delphi(1)] kind: KEYEVENT_RAWKEYDOWN, modifiers: $00000102, windows_key_code: $00000074, native_key_code: $003F0001, is_system_key: False, character: $0000, unmodified_character: $0000, focus_on_editable_field: False
[0531/100217.718:INFO:CEF4Delphi(1)] kind: KEYEVENT_KEYUP, modifiers: $00000102, windows_key_code: $00000074, native_key_code: $C03F0001, is_system_key: False, character: $0000, unmodified_character: $0000, focus_on_editable_field: False
[0531/100217.859:INFO:CEF4Delphi(1)] kind: KEYEVENT_KEYUP, modifiers: $00000100, windows_key_code: $00000010, native_key_code: $C02A0001, is_system_key: False, character: $0000, unmodified_character: $0000, focus_on_editable_field: False
The code in WebView4Delphi to simulate those key presses is this :

Code: Select all

function TWVBrowserBase.KeyboardShortcutSearch : boolean;
begin
  Result := SimulateKeyEvent(ketRawKeyDown, $100, VK_F3, integer($003D0001)) and
            SimulateKeyEvent(ketKeyUp,      $100, VK_F3, integer($C03D0001));
end;

function TWVBrowserBase.KeyboardShortcutRefreshIgnoreCache : boolean;
begin
  Result := SimulateKeyEvent(ketRawKeyDown, $502, VK_Shift, integer($002A0001)) and
            SimulateKeyEvent(ketRawKeyDown, $102, VK_F5,    integer($003F0001)) and
            SimulateKeyEvent(ketKeyUp,      $102, VK_F5,    integer($C03F0001)) and
            SimulateKeyEvent(ketKeyUp,      $100, VK_Shift, integer($C02A0001));
end;
The code comments for those two functions might have a clue why we see different information :
This key information was logged using a Spanish keyboard. It might not work with different keyboard layouts.
The GetCefKeyboardModifiers function in uCEFMiscFunctions checks what keys are pressed in that moment and it will fail if you put a breakpoint in it because your hand will move away from the keyboard while debugging.

The official sample application handles keyboard messages here :
https://github.com/chromiumembedded/cef/blob/8e79307a622dc513f084b4ac0b78caed08e0c1c0/tests/cefclient/browser/osr_window_win.cc#L531
https://github.com/chromiumembedded/cef/blob/8e79307a622dc513f084b4ac0b78caed08e0c1c0/tests/cefclient/browser/osr_window_win.cc#L786

The original GetCefKeyboardModifiers function is here :
https://github.com/chromiumembedded/cef/blob/8e79307a622dc513f084b4ac0b78caed08e0c1c0/tests/shared/browser/util_win.cc#L82

The modifier values you see in WebView4Dedlphi are calculated with the windows message parameters and the detected pressed keys like this :
  • $100 = EVENTFLAG_NUM_LOCK_ON
  • $502 = EVENTFLAG_NUM_LOCK_ON or EVENTFLAG_SHIFT_DOWN or EVENTFLAG_IS_LEFT
  • $102 = EVENTFLAG_NUM_LOCK_ON or EVENTFLAG_SHIFT_DOWN
jc4golf
Posts: 32
Joined: Wed Jun 23, 2021 12:33 am

Re: SimulateKeyEvent

Post by jc4golf »

Thank you for this information Salvador. I have gotten the parameters I've been looking for, but still the SimulateKeyEvent does not work. Could it be WebView is not letting the keystrokes get to the webpage?
User avatar
salvadordf
Posts: 4620
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: SimulateKeyEvent

Post by salvadordf »

Check that the browser is focused.

Some web pages check if the key presses are not too fast for a human. Perhaps adding delays could fix this issue.
jc4golf
Posts: 32
Joined: Wed Jun 23, 2021 12:33 am

Re: SimulateKeyEvent

Post by jc4golf »

The browser is focused and it doesn't seem to be a timing issue because it doesn't work for only one keystroke.
Post Reply