Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[SOLVED]Insert JS into IE browser not owned by AHK using COM


  • Please log in to reply
35 replies to this topic
ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
While trying to help this post's creator, I have been able to load an url into the browser, but can not load js with the same code. Embedding the control into a gui allows it to work, but I want to do it with external browser window. Anyone tell me where it is wrong? or if there is a workaround?

Requires acc.ahk here:
<!-- m -->http://www.autohotke...pic.php?t=24234<!-- m -->
and
com.ahk here:
<!-- m -->http://www.autohotke...pic.php?t=19225<!-- m -->

EDIT:
-It Works! Script has been updated to use lexikos' method. THANKS
-Added check so that code is injected into correct tab on IE7.
-Removed unnecessary variable
-Added function
- Added functionality to return variables to script. (in function)
#Include acc.ahk
#Include com.ahk

^F12::

IE_MainWindow := WinExist("A")
WinGet, ActiveControlList, ControlListhWnd, ahk_id %IE_MainWindow%
Loop, Parse, ActiveControlList, `n
	{
	WinGetClass, ThisWinClass, ahk_id %A_LoopField%
	If (ThisWinClass = "Internet Explorer_Server") and (DllCall("IsWindowVisible", UInt, A_LoopField))
		hIESvr := A_LoopField
	}

If !hIESvr
	{
	MsgBox, Control "Internet Explorer_Server" not found.
	Return
	}

IID_IHTMLWindow2   := "{332C4427-26CB-11D0-B483-00C04FD90119}"

ACC_Init()
pacc := ACC_AccessibleObjectFromWindow(hIESvr)
pwin := COM_QueryService(pacc,IID_IHTMLWindow2,IID_IHTMLWindow2)
COM_Release(pacc)

;Load an URL
;COM_Invoke(pwin, "Navigate", "http://www.google.com")

;Load Javascript
JStoSend=javascript:alert('it works!');
COM_Invoke(pwin, "execscript", JStoSend)

COM_Release(pwin)
ACC_Term()
return

esc::exitapp

Function
Usage:
;WinExist("A") uses the active window
MsgBox % "AHKSCRIPT:" . IE_InjectJS(WinExist("A"), "javascript:ahkvar1='It really Does';ahkvar2='!!!';alert('JAVASCRIPT:Hey, it Works!');", "ahkvar1,ahkvar2")
; Function Name: IE_InjectJS
; Parameters:
; hWnd_MainWindow 	- REQUIRED	- the hWnd of the main window containing the "Internet Explorer_Server" control : EXAMPLE (using active window) - WinExist("A") 
; JS_to_Inject 			- REQUIRED	- Javascript to execute in the browser window : EXAMPLE - "javascript:ahkvar1='It really Does';ahkvar2='!!!';alert('Hey, it Works!');"
; VarNames_to_Return 	- OPTIONAL	- Comma delimited list of global javascript variables to return : EXAMPLE - "ahkvar1,ahkvar2"
;
; Return:
; Returns a comma delimited list of the variables contents (In the order passed to the function)
; Calling Example:
; IE_InjectJS(WinExist("A"), "javascript:ahkvar1='It really Does';ahkvar2='!!!';alert('Hey, it Works!');", "ahkvar1,ahkvar2")
;
IE_InjectJS(hWnd_MainWindow, JS_to_Inject, VarNames_to_Return="")
	{
	;Get a list of the hWnd's owned by the window specified
	WinGet, ActiveControlList, ControlListhWnd, ahk_id %hWnd_MainWindow%
	;Go throught the list 1 at a time to determine if it is the correct control
	;This will allow the script to find the current tab in IE7
	Loop, Parse, ActiveControlList, `n
		{
		;Get the classname of the current control
		WinGetClass, ThisWinClass, ahk_id %A_LoopField%
		;If the classname is correct and it is visible, it is the correct tab
		If (ThisWinClass = "Internet Explorer_Server") and (DllCall("IsWindowVisible", UInt, A_LoopField))
		 hIESvr := A_LoopField
		}
	;If a control was not found, give a message and return, doing nothing	
	If !hIESvr
		{
		MsgBox, Control "Internet Explorer_Server" not found.
		Return
		}
	;Initialize the COM interface. code modified from SEAN
	IID_IHTMLWindow2   := "{332C4427-26CB-11D0-B483-00C04FD90119}"
	ACC_Init()
	pacc := ACC_AccessibleObjectFromWindow(hIESvr)
	pwin := COM_QueryService(pacc,IID_IHTMLWindow2,IID_IHTMLWindow2)
	COM_Release(pacc)
	;Execute the Javascript (if there is any). Thanks LEXIKOS.
	If JS_to_Inject
		COM_Invoke(pwin, "execscript", JS_to_Inject)
	;Get the value of the variables, if any.
	If VarNames_to_Return {
		;Split the passed variable names into a psuedo array of ahk variables
		StringSplit, Vars_, VarNames_to_Return, `,
		;Get the value of each javascript variable in the order it was passed
		Loop, %Vars_0%
			Ret .= COM_Invoke(pwin,Vars_%A_Index%) . ","
		;Remove the trailing comma
		StringTrimRight, Ret, Ret, 1
		}
	; Cleanup
	COM_Release(pwin)
	ACC_Term()
	;Return a comma seperated list of variables in the order they were passed
	Return Ret
	}


Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ

BoBo¨
  • Guests
  • Last active:
  • Joined: --
That does work on IE6 SP2. But during the page is getting loaded, the triggered js-bookmarklet steals the focus, and therefore I'd to refocus manually to IE, just to trigger the expected pop up alert.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Perhaps this might work where Navigate fails:
execScript Method (window)

ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
That is SWEEEEET........

THANKS :!: :!: :D
Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ

ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
I tested on IE6 & IE7...It works on both. I used the JS Posted Image~dieom found to test with. It works on the IE7 popup windows that you can not input javascript into the address bar as well.
Thanks for the help lexikos. :D I'm sure Posted ImageTsurphr is glad, too! 8)
Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ

ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
It also works on the ahk html help and when using the IE Tab plugin for Firefox.
Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

IID_IHTMLWindow2   := "{332C4427-26CB-11D0-B483-00C04FD90119}"

ACC_Init()
pacc := ACC_AccessibleObjectFromWindow(hIESvr)
pwin := COM_QueryService(pacc,IID_IHTMLWindow2,IID_IHTMLWindow2)
COM_Release(pacc)

;COM_Invoke(pwin, "Navigate", "http://www.google.com")
JStoSend=javascript:alert('it works!');
COM_Invoke(pwin, "execscript", JStoSend)

COM_Release(pwin)
ACC_Term()


I now saw this post. And, I just found out that IHTMLWindow2 interface also has a function navigate. But, I don't think its functionality is the same as Navigate in IWebBrowser... interface. So, to use Navigate in this case, must use like this:

IID_IHTMLWindow2   := "{332C4427-26CB-11D0-B483-00C04FD90119}"
IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"

ACC_Init()
pacc := ACC_AccessibleObjectFromWindow(hIESvr)
pwin := COM_QueryService(pacc,IID_IHTMLWindow2,IID_IHTMLWindow2)
COM_Release(pacc)
pweb := COM_QueryService(pwin,IID_IWebBrowserApp,IID_IWebBrowserApp)
COM_Release(pwin)

JStoSend=javascript:alert('it works!');
COM_Invoke(pweb, "Navigate", JStoSend)
COM_Release(pweb)
ACC_Term()


Tsurphr
  • Members
  • 34 posts
  • Last active: Jun 08 2009 01:04 PM
  • Joined: 22 Oct 2007
It works flawlessly! This definately should get stickied, I'm sure many other headaches will be relieved by this as well. Not only does it solve my current problem, but will allow me to do a lot of cool new things too.

GG ahklerner and all who helped, thanks so much!
::Tsurphr::

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
If we stickied every cool/useful script, you would have to go to page 10 to read non-stickied posts.

Here we use search instead of stickies to find things in the future.

Tsurphr
  • Members
  • 34 posts
  • Last active: Jun 08 2009 01:04 PM
  • Joined: 22 Oct 2007
Note taken. Perhaps add it to the script catalogue or something, I don't know. Anyhow thanks eng for your help as well.
::Tsurphr::

nekko
  • Members
  • 65 posts
  • Last active: Oct 08 2008 11:40 PM
  • Joined: 25 Sep 2007
This is the single most amazing post I have seen. With this ability you are able to fully control IE and macro out commands via Javascript. Great job. Thanks so much!@#$

ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
Updated top post. Allows Javascript variables to be returned to script. See function.
Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ

Erittaf
  • Members
  • 192 posts
  • Last active: Feb 28 2013 11:49 PM
  • Joined: 02 Nov 2007
thanks for the added support ahklearner. I was wondering why I hadn't found variable return support from JS before! :lol:

nekko
  • Members
  • 65 posts
  • Last active: Oct 08 2008 11:40 PM
  • Joined: 25 Sep 2007
Here is another usage example that may help someone out

F4::
emailAddress:= IE_InjectJS(WinExist("A"),"javascript:var emailAddress = document.body.innerHTML.match(/\b[A-Z0-9._`%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i)[0];" , "emailAddress")

MsgBox, %emailAddress%

return


ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
An example of getting values of a control on a web page:
MsgBox % JSVAR := IE_InjectJS(WinExist("A"), "javascript:var ahkvar1 = parent.document.forms[1].elements[2].options[0].value;", "ahkvar1")
See this post for test page.
<!-- m -->http://www.autohotke...ic.php?p=163723<!-- m -->
Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ