Jump to content


Photo

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


  • Please log in to reply
35 replies to this topic

#1 ahklerner

ahklerner
  • Members
  • 1382 posts

Posted 10 November 2007 - 06:45 PM

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
	}



#2 BoBo¨

BoBo¨
  • Guests

Posted 10 November 2007 - 07:14 PM

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.

#3 Lexikos

Lexikos
  • Administrators
  • 8832 posts

Posted 11 November 2007 - 01:28 AM

Perhaps this might work where Navigate fails:
execScript Method (window)

#4 ahklerner

ahklerner
  • Members
  • 1382 posts

Posted 11 November 2007 - 01:47 AM

That is SWEEEEET........

THANKS :!: :!: :D

#5 ahklerner

ahklerner
  • Members
  • 1382 posts

Posted 11 November 2007 - 04:32 AM

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)

#6 ahklerner

ahklerner
  • Members
  • 1382 posts

Posted 11 November 2007 - 05:26 AM

It also works on the ahk html help and when using the IE Tab plugin for Firefox.

#7 Sean

Sean
  • Members
  • 2462 posts

Posted 11 November 2007 - 12:44 PM

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()


#8 Tsurphr

Tsurphr
  • Members
  • 34 posts

Posted 12 November 2007 - 01:19 PM

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!

#9 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 12 November 2007 - 04:43 PM

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.

#10 Tsurphr

Tsurphr
  • Members
  • 34 posts

Posted 12 November 2007 - 05:27 PM

Note taken. Perhaps add it to the script catalogue or something, I don't know. Anyhow thanks eng for your help as well.

#11 nekko

nekko
  • Members
  • 65 posts

Posted 20 November 2007 - 06:26 PM

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!@#$

#12 ahklerner

ahklerner
  • Members
  • 1382 posts

Posted 01 December 2007 - 04:43 AM

Updated top post. Allows Javascript variables to be returned to script. See function.

#13 Erittaf

Erittaf
  • Members
  • 192 posts

Posted 01 December 2007 - 08:10 PM

thanks for the added support ahklearner. I was wondering why I hadn't found variable return support from JS before! :lol:

#14 nekko

nekko
  • Members
  • 65 posts

Posted 05 December 2007 - 06:42 AM

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


#15 ahklerner

ahklerner
  • Members
  • 1382 posts

Posted 06 December 2007 - 01:40 AM

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 -->