Fixing tabbing in webbrowser? lazarus / 34-Windows ---------------------------------------------------------------------- Timewarp · 2012-08-31 10:13 I've been trying to fix tab key in TEvsWebbrowser without success. When navigated to page with a form, it should be possible to move between fields by using tab. (but nothing happens) My first try was to handle CMDialogKey, I'm not even sure this is the problem? But anyway this code does not work in Lazarus. Event never fires, seems like a bug? Code: [Select]procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY; .. procedure TForm1.CMDialogKey(var Message: TCMDialogKey); begin  if GetKeyState(VK_MENU)>=0 then  begin   case Message.CharCode of    VK_Tab:    begin     Message.Result:=0;     exit;    end;    end;  end;  inherited; end; I also tried setting breakpoins to wincontrol.inc, but those keyevents never fires, when focus is inside TEvsWebbrowser. Which procedure/function receives keyboard messages first in Lazarus? Something must be "eating" message, before it gets to browser?! I can get vk_tab key message like this, but passing it to TranslateAccelerator also does nothing. Or I'm doing something wrong? Code: [Select]var KBHook: HHook; .. KBHook:=SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, GetCurrentThreadId()); .. function KeyboardHookProc(Code, wParam, lParam: LongInt): LongInt; stdcall; var IOIPAO: IOleInPlaceActiveObject;     Dispatch: IDispatch; begin  if wParam=VK_tab then  begin   Dispatch:=(form1.ActiveXContainer1.comserver as IWebbrowser2).Application;   if (Dispatch<>nil) and (not (form1.ActiveXContainer1.comserver as IWebbrowser2).Busy) then   begin    Dispatch.QueryInterface(IOleInPlaceActiveObject, IOIPAO);    if IOIPAO<>nil then    begin     IOIPAO.TranslateAccelerator(TMsg(Pointer(lParam)^));     IOIPAO:=nil;     Result:=1;     exit;    end;   end;  end;  Result:=CallNextHookEx(KBHook, Code, wParam, lParam);  end; ---------------------------------------------------------------------- Timewarp · 2012-09-01 13:07 Finally got it working. in case anyone else needs it: Code: [Select]function KeyboardHookProc(Code, wParam, lParam: LongInt): LongInt; stdcall; var IOIPAO: IOleInPlaceActiveObject;     Dispatch: IDispatch;     msg: tmsg; begin  if (Code<0) then  begin   Result:=CallNextHookEx(KBHook, Code, wParam, lParam);   exit;  end;  if wParam=VK_TAB then  begin   Dispatch:=(form1.ActiveXContainer1.comserver as IWebbrowser2).application;   if (Dispatch<>nil) and (not (form1.ActiveXContainer1.comserver as IWebbrowser2).Busy) then   begin    Dispatch.QueryInterface(IOleInPlaceActiveObject, IOIPAO);    if IOIPAO<>nil then    begin     if (lParam shr 31)=0 then msg.message:=WM_KEYDOWN else msg.message:=WM_KEYUP;     msg.wParam:=wParam;     msg.lParam:=lParam;     IOIPAO.TranslateAccelerator(msg);     IOIPAO:=nil;     result:=1;     exit;    end;   end;  end;  Result:=CallNextHookEx(KBHook, Code, wParam, lParam); end;