catch key press messages lazarus / 67-Windows ---------------------------------------------------------------------- laggyluk · 2017-11-10 09:11 Hi What I'm trying to do is capture all key presses on form and send them to chromium osr component for processing. tried Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure WndProc(var Message: TLMessage); override; but no luck, then I've tried Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT; stdcall; They both captured windows messages, mouse clicks etc but neither was receiving any of key press messages I'm interested in: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i WM_CHAR, WM_SYSCHAR,WM_SYSKEYDOWN,WM_SYSKEYUP,WM_KEYDOWN,WM_KEYUPWhy is that? ---------------------------------------------------------------------- laggyluk · 2017-11-10 09:21 I think I know why but still don't know the solution https://stackoverflow.com/questions/20408071/form-wm-keydown-and-wm- keyup-messages-arent-captured-in-wndproc there is no ProcessCmdKey method to override ---------------------------------------------------------------------- balazsszekely · 2017-11-10 10:44 Works fine here. Just press different keys or key combinations like Alt + F, etc... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Windows; var  FPrevWndProc: WNDPROC; function WndCallback(AHWND: HWND; uMsg: UINT; wParam: WParam; lParam: LParam): LRESULT; stdcall;begin  case uMsg of    WM_CHAR: Form1.Caption := 'WM_CHAR';    WM_SYSCHAR: Form1.Caption := 'WM_SYSCHAR';    WM_SYSKEYDOWN: Form1.Caption := 'WM_SYSKEYDOWN';    WM_SYSKEYUP: Form1.Caption := 'WM_SYSKEYUP';    WM_KEYDOWN: Form1.Caption := 'WM_KEYDOWN';    WM_KEYUP: Form1.Caption := 'WM_KEYUP';  end;  Result := CallWindowProc(FPrevWndProc, Ahwnd, uMsg, WParam, LParam);end; procedure TForm1.FormCreate(Sender: TObject);begin  FPrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrUInt(@WndCallback)));end; ---------------------------------------------------------------------- laggyluk · 2017-11-10 11:08 does work in blank project, dropping tmemo on form breaks it I'm using memo for logging only, can it be prevented from stealing messages? ---------------------------------------------------------------------- balazsszekely · 2017-11-10 11:11 You have a window handle, change it when the focus shifts from one control to another. FPrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrUInt(@WndCallback))); ---------------------------------------------------------------------- laggyluk · 2017-11-10 11:22 solved, thanks! Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.OnFocusChange(sender: tobject);begin  if screen.ActiveControl <>nil then   FPrevWndProc := Windows.WNDPROC(SetWindowLongPtr(screen.ActiveControl.Handle, GWL_WNDPROC, PtrUInt(@WndCallback)));end; ---------------------------------------------------------------------- ASerge · 2017-11-11 02:39 Quote from: laggyluk on November 10, 2017, 12:22:36 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.OnFocusChange(sender: tobject);begin  if screen.ActiveControl <>nil then   FPrevWndProc := Windows.WNDPROC(SetWindowLongPtr(screen.ActiveControl.Handle, GWL_WNDPROC, PtrUInt(@WndCallback)));end; Very bad decision. You overwrite the variable FPrevWndProc, and the WndCallback procedure calls the code not for its own window class. Use message hooks: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   private  procedure KeyMessage(const Msg: TMsg);  end; var  Form1: TForm1; implementation uses Windows; {$R *.lfm} var  GHook: HHOOK; function MessageHookProc(nCode: Integer; wParam: WPARAM;  lParam: LPARAM): LRESULT; stdcall;var  Msg: LCLType.PMsg absolute lParam;begin  if nCode >= 0 then    case Msg^.message of      WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_CHAR, WM_SYSCHAR:        Form1.KeyMessage(Msg^);    end;  Result := CallNextHookEx(GHook, nCode, wParam, lParam);end; procedure TForm1.FormCreate(Sender: TObject);begin  GHook := SetWindowsHookEx(WH_GETMESSAGE, @MessageHookProc, 0, MainThreadID);  if GHook = 0 then    RaiseLastOSError;end; procedure TForm1.FormDestroy(Sender: TObject);begin  if GHook <> 0 then  begin  UnhookWindowsHookEx(GHook);    GHook := 0;  end;end; procedure TForm1.KeyMessage(const Msg: LCLType.TMsg);begin  case Msg.message of    WM_KEYDOWN:      Memo1.Append('WM_KEYDOWN: ' + IntToStr(Msg.wParam));    WM_KEYUP:      Memo1.Append('WM_KEYUP: ' + IntToStr(Msg.wParam));    WM_SYSKEYDOWN:      Memo1.Append('WM_SYSKEYDOWN: ' + IntToStr(Msg.wParam));    WM_SYSKEYUP:      Memo1.Append('WM_SYSKEYUP: ' + IntToStr(Msg.wParam));    WM_CHAR:      Memo1.Append('WM_CHAR: ' + IntToStr(Msg.wParam) + ' "' + Chr(Msg.wParam) + '"');    WM_SYSCHAR:    Memo1.Append('WM_SYSCHAR: ' + IntToStr(Msg.wParam) + ' "' + Chr(Msg.wParam) + '"');  end;end; ---------------------------------------------------------------------- laggyluk · 2017-11-15 12:52 True and it resulted in occasional crashes. Your solution works better.