Page 1 of 1

Help Sending Keys to Embedded Trident Brower

Posted: 19 Jan 2015, 18:34
by ElectroniPizza
Hello,

I am trying my best with a project and have ironed out all issues I was having but the final issue I am having is that I cannot get AHK to send {Enter} to the embedded IE. My code is very similar to the code I found in the forums.

No matter the method whether its, ControlSend, Send, SendRaw etc.. the browser will not respond to any keystrokes if I ask AHK to do it. However if I manually use the keyboard I can of course hit enter and it works.

I know its something to do with the way it handles WM_KEYDOWN as this seems to translate a Send {Enter} into a Post Message for WM_KEYDOWN however my code just will not send any keys to the webpage.

There is no option to do wb.document.forms[0].submit() or any variation. The page has a keyboard handler and is written in Javascript, any help appreciated and big thanks to Jethrow,Lexikos, Sean, sinkfaze, tank all the info on the forums has been extremely helpful :D

Code: Select all


WM_KEYDOWN(wParam, lParam, nMsg, hWnd) 
{ 
   If   (wParam = 0x08 || wParam = 0x09 || wParam = 0x0D || wParam = 0x26 || wParam = 0x28 || wParam = 0x2E || wParam = 0x43 || wParam = 0x56 || wParam = 0x58) 
   WinGetClass, Class, ahk_id %hWnd% 
   If   (Class = "Internet Explorer_Server") 
   { 
      Global pipa 
      VarSetCapacity(Msg, 28), NumPut(hWnd,Msg), NumPut(nMsg,Msg,4), NumPut(wParam,Msg,8), NumPut(lParam,Msg,12), NumPut(A_EventInfo,Msg,16), NumPut(A_GuiX,Msg,20), NumPut(A_GuiY,Msg,24) 
      If   DllCall(NumGet(NumGet(1*pipa)+20), "Uint", pipa, "Uint", &Msg)=0 
      Return   0 
   } 
}

Code: Select all

/*
   written by tank updated by Jethrow
   
   AHK_L version 1.0.90.00 ansii 32 bit or higher
   
   Date : 10/18/2011
*/
main:
{
   Gosub,init
   url:="http://www.google.com"
   WB.Navigate(url)
   loop
      If   !WB.busy
         break
   return
}

init:
{
   ;// housekeeping routines
   ;// set the tear down procedure
   OnExit,terminate
   
   ;// Create a gui
   Gui, +LastFound +Resize +OwnDialogs
   
   ;// create an instance of Internet Explorer_Server
   ;// store the iwebbrowser2 interface pointer as *WB* & the hwnd as *ATLWinHWND*
   Gui, Add, ActiveX, w510 h600 x0 y0 vWB hwndATLWinHWND, Shell.Explorer
   
   ;// disable annoying script errors from the page
   WB.silent :=   true
   
   ;// necesary to accept enter and accelorator keys
   ;http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.ole.interop.ioleinplaceactiveobject(VS.80).aspx
   IOleInPlaceActiveObject_Interface:="{00000117-0000-0000-C000-000000000046}"
   
   ;// necesary to accept enter and accelorator keys
   ;// get the in place interface pointer
   pipa :=   ComObjQuery(WB, IOleInPlaceActiveObject_Interface)
   
   ;// necesary to accept enter and accelorator keys
   ;// capture key messages
   OnMessage(WM_KEYDOWN:=0x0100, "WM_KEYDOWN")
   OnMessage(WM_KEYUP:=0x0101, "WM_KEYDOWN")
   
   ;//Display the GUI
   gui,show, w510 h600 ,Gui Browser
   
   ;// return and allow the program
   return
}

;// capture the gui resize event
GuiSize:
{
   ;// if there is a resize event lets resize the browser
   WinMove, %   "ahk_id " . ATLWinHWND, , 0,0, A_GuiWidth, A_GuiHeight
   return
}

GuiClose:
terminate:
{
   ;// housekeeping
   ;// destroy the gui
   Gui, Destroy
   ;// release the in place interface pointer
   ObjRelease(pipa)
   ExitApp
}



WM_KEYDOWN(wParam, lParam, nMsg, hWnd)  ;// modeled after code written by lexikos
{
   global   wb, pipa
   static   fields :=   "hWnd,nMsg,wParam,lParam,A_EventInfo,A_GuiX,A_GuiY"
   WinGetClass, ClassName, ahk_id %hWnd%
   if   (ClassName = "Internet Explorer_Server")
   {
      ;// Build MSG Structure
      VarSetCapacity(Msg, 48)
      Loop Parse, fields, `,
         NumPut(%A_LoopField%, Msg, (A_Index-1)*A_PtrSize)
      ;// Call Translate Accelerator Method
      TranslateAccelerator :=   NumGet(NumGet(1*pipa)+5*A_PtrSize)
      Loop 2 ;// only necessary for Shell.Explorer Object
         r :=   DllCall(TranslateAccelerator, "Ptr",pipa, "Ptr",&Msg)
      until   wParam != 9 || wb.document.activeElement != ""
   
      if   r = 0 ;// S_OK: the message was translated to an accelerator.
         return   0
   }
}

Re: Help Sending Keys to Embedded Trident Brower  Topic is solved

Posted: 20 Jan 2015, 13:41
by jethrow
The page has a keyboard handler and is written in Javascript ...
I'd do one of the following:
  • Figure out the API behind the keyboard handler & utilize it for what you want to do.
  • Manually execute your keystrokes & determine the wParam, lParam, nMsg, hWnd values passed to WM_KEYDOWN. Then simply call WM_KEYDOWN with these parameter values.

Re: Help Sending Keys to Embedded Trident Brower

Posted: 20 Jan 2015, 16:01
by ElectronicPizza
  • Figure out the API behind the keyboard handler & utilize it for what you want to do.
  • Manually execute your keystrokes & determine the wParam, lParam, nMsg, hWnd values passed to WM_KEYDOWN. Then simply call WM_KEYDOWN with these parameter values.
Jethrow, thanks for your suggestion you were spot on ! I scoured the forums and managed to find this code, I think it's Sean's original WM_KEYDOWN but has been modified by Lexikos I think?

I used Micrsoft's SpyXX++ to actually find out the WM_KEYDOWN & WM_KEYUP wParam, IParam etc

Code: Select all

WM_KEYDOWN(wParam, lParam, nMsg, hWnd) ; WM_KEYDOWN Function to handle keys and send them to the in place interface pointer (pipa) "{00000117-0000-0000-C000-000000000046}"
{
   global wb
   static fields := "hWnd,nMsg,wParam,lParam,A_EventInfo,A_GuiX,A_GuiY"
   WinGetClass, ClassName, ahk_id %hWnd%
   if  (ClassName = "Internet Explorer_Server") ; // This uses the Class found using Microsoft SpyXX ++
   {
   ; // Get the in place interface pointer
      pipa := ComObjQuery(wb.document, "{00000117-0000-0000-C000-000000000046}")
   ; // Build MSG Structure
      VarSetCapacity(Msg, 48)
      Loop Parse, fields, `,             ;`
         NumPut(%A_LoopField%, Msg, (A_Index-1)*A_PtrSize)
   ; // Call Translate Accelerator Method
      TranslateAccelerator := NumGet(NumGet(1*pipa)+5*A_PtrSize)
      Loop 2 ;// only necessary for Shell.Explorer Object
         r := DllCall(TranslateAccelerator, "Ptr",pipa, "Ptr",&Msg) ; DllCall to OLE for accelerator keys
      until wParam != 9 || wb.document.activeElement != ""
   ; // Release the in place interface pointer to free memory
      ObjRelease(pipa)
      if r = 0 ;// S_OK: the message was translated to an accelerator.
         return 0
   }
}