Page 2 of 3

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 26 Apr 2017, 21:37
by lexikos
(Replying only because of a PM.)

Perhaps if you say what the problem is, or ask an actual question, I might be interested enough to answer it. As it is, I'm not nearly interested enough to figure out what the problem is, let alone the solution.

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 29 Apr 2017, 12:46
by F4Jonatas
:bravo:
Your kindness surprises me!

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 16 Sep 2017, 05:48
by icuurd12b42
anyone knows how to setup that dispatch table? I'm trying to expose more than on method of my object

Code: Select all

js.AddObject("myObj", ComDispatch(new MyClass, MyClass.DispTable))
js.Exec("myObj.Method(['first value', 'second value'])")

class MyClass
{
    Method1(x)
    {
        ; Just to show we can pass arrays from JScript to AHK:
        Debug.MsgBox("Method1: " . x)
    }
    Method2(x)
    {
        ; Just to show we can pass arrays from JScript to AHK:
        Debug.MsgBox("Method2: " . x)
    }
    static DispTable := [[MyClass.Method1], {Method1:1}
                               , [MyClass.Method2], {Method2:2}]
}
I assumed to add another entry... though I dont know what this :1 does either, there is no documentation on this dispatch table
I'm getting a Method is not supported exception calling myObj.Method2("text") from my code. Method1 works just fine

While typing this I had an idea of trying Comdispatch0, there has to be a reason for it's existance right? It works and seems to do the discovery of the object methods itself to define the interface, Yeah. the good news is I wont have to type all this dispatch information...
FIX:
js.AddObject("myObj", ComDispatch0(new MyClass))

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 17 Oct 2017, 00:53
by lexikos
icuurd12b42 wrote:While typing this I had an idea of trying Comdispatch0, there has to be a reason for it's existance right?
Yes. It removes the need to define the object's interface.

But they are both obsolete. Just pass the object directly to AddObject.
I wrote:ComObject := ComDispatch0(Object) - not needed in AutoHotkey v1.1.17+

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 19 Oct 2017, 03:46
by icuurd12b42
Your answer is a little short in context...

are you saying
his.m_Js := new ActiveScript("JScript")
;My Objects
this.m_Js.AddObject("HKS", ComDispatch0(HKS))

can be changed to
his.m_Js := new ActiveScript("JScript")
;My Objects
this.m_Js.AddObject(HKS)

HKS is an object.... with get properties that further adds more objects to the structure

Code: Select all

class HKS
{
    Debug {
        get {
            return Debug
        }
    }
    Resource {
        get {
            return Resource
        }
    }
    VoiceAgent {
        get {
            return VoiceAgent
        }
    }
    Recognition {
        get {
            return Recognition
        }
    }
}

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 19 Oct 2017, 08:40
by icuurd12b42
I just chased a bug where a AHK function returning a number called from the Jscript code has the number turned into a string on the JScript side... I solved it calling parseInt on the js side but it's really clumsy looking

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 19 Oct 2017, 21:15
by icuurd12b42
I would like to call this function
https://docs.microsoft.com/en-us/script ... riptthread
It does not look to be available, or if it is at what level it would be.

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 27 Oct 2017, 20:38
by lexikos
icuurd12b42 wrote:are you saying [...]
this.m_Js.AddObject("HKS", ComDispatch0(HKS))

can be changed to [...]
this.m_Js.AddObject(HKS)
No. I am saying you can replace ComDispatch0(HKS) with HKS. You still need to tell AddObject which name to bind in the JavaScript context.
I would like to call this function
If you want to call a function not supported by the wrapper, you will need to figure out its v-table offset and call it via DllCall. For instance, SetScriptSite uses 3*A_PtrSize because it is the fourth method in the plain C interface (search for "IActiveScriptVtbl" in the Windows SDK or on the web).

AutoHotkey v1 functions return strings in many cases, for backward-compatibility (i.e. 0x100 produces the string "0x100", not "256"). You can generally avoid it by adding an operation, such as return 0x100 + 0 instead of return 0x100.

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 30 Oct 2017, 06:09
by icuurd12b42
Thanks I looks into these

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 17 Nov 2017, 06:49
by Bunny the Dummy
does anyone know how to add an onclick even so if I click on the traytip i can open excel?

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 07 Jun 2018, 19:50
by FanaticGuru
lexikos wrote:I've added a method for enabling the use of WinRT (the framework used by Windows 10 apps) with JsRT.Edge, and an example for displaying a toast notification.

Image
How would you detect a click on the toast notification.

I want when I click on a toast notification, a function in my AHK script will be called.

I have went round and round with addEventListener("activated", onActivatedHandler, false); as well as every other thing I could google.

Here is what I got for displaying the toast notification:

Code: Select all

#NoEnv
#Include <ActiveScript>
#Include <JsRT>

; Get image file if needed
if !FileExist("sample.png")
    URLDownloadToFile https://autohotkey.com/boards/styles/simplicity/theme/images/announce_unread.png
        , % A_ScriptDir "\sample.png"

Toast_Notification(["Folder: " A_MyDocuments, "2 Files Saved"], A_ScriptDir "\sample.png")
return

Toast_Notification(toast_text := "", toast_image := "", toast_template := "toastImageAndText02" )
{
	static
	if !js
	{
		; This assumes AutoHotkey is installed in the default location:
		toast_appid := (A_Is64bitOS ? "{6D809377-6AF0-444b-8957-A3773F02200E}"
									: "{905e63b6-c1bf-494e-b29c-65b732d3d21a}")
			. "\AutoHotkey\AutoHotkey.exe"

		; Only the Edge version of JsRT supports WinRT.
		js := new JsRT.Edge

		; Enable use of WinRT.  "Windows.UI" or "Windows" would also work.
		js.ProjectWinRTNamespace("Windows.UI.Notifications")
		code =
		(
			function toast(template, image, text, app) {
				// Alias for convenience.
				var N = Windows.UI.Notifications;
				// Get the template XML as an XmlDocument.
				var toastXml = N.ToastNotificationManager.getTemplateContent(N.ToastTemplateType[template]);
				// Insert our content.
				var i = 0;
				for (let el of toastXml.getElementsByTagName("text")) {
					if (typeof text == 'string') {
						el.innerText = text;
						break;
					}
					el.innerText = text[++i];
				}
				toastXml.getElementsByTagName("image")[0].setAttribute("src", image);
				// Show the notification.
				var toastNotifier = N.ToastNotificationManager.createToastNotifier(app || "AutoHotkey");
				var notification = new N.ToastNotification(toastXml);
				toastNotifier.show(notification);
			}
		)
		try 
		{
			; Define the toast function.
			js.Exec(code)
		}
		catch ex 
		{
			try errmsg := ex.stack
			if !errmsg
				errmsg := "Error: " ex.message
			MsgBox % errmsg
		}
	}
	try 
	{
		; Show a toast notification.
		js.toast(toast_template, toast_image, toast_text, toast_appid)
	}
	catch ex 
	{
		try errmsg := ex.stack
		if !errmsg
			errmsg := "Error: " ex.message
		MsgBox % errmsg
	}
}

stuff(s)
{
	MsgBox % s
}
That part works fine but I cannot figure out what to put where to get the "stuff(s)" function at the end to run when the notification is clicked, preferably with the s containing the text of the notification.

I feel like it would only take a few lines in the JavaScript code. Any help would be very much appreciated.

FG

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 08 Jun 2018, 17:23
by FanaticGuru
After spending way too much time on unraveling this, I finally got it to work to handle clicks on a toast notification.

Code: Select all

#NoEnv
#Include <ActiveScript>
#Include <JsRT>

; get image
if !FileExist("sample.png")
    URLDownloadToFile https://autohotkey.com/boards/styles/simplicity/theme/images/announce_unread.png
        , % A_ScriptDir "\sample.png"

F1::Toast_Notification(["Folder: " A_MyDocuments, "2 Files Saved"], A_ScriptDir "\sample.png")
Esc::ExitApp

return

Toast_Notification(toast_text, toast_image , toast_template := "toastImageAndText02" )
{
	static
	if !js
	{
		; This assumes AutoHotkey is installed in the default location:
		toast_appid := (A_Is64bitOS ? "{6D809377-6AF0-444b-8957-A3773F02200E}"
									: "{905e63b6-c1bf-494e-b29c-65b732d3d21a}")
			. "\AutoHotkey\AutoHotkey.exe"

		; Only the Edge version of JsRT supports WinRT.
		js := new JsRT.Edge
		js.AddObject("JS_ToastActivated", Func("AHK_ToastActivated"))

		; Enable use of WinRT.  "Windows.UI" or "Windows" would also work.
		js.ProjectWinRTNamespace("Windows.UI.Notifications")
		code =
		(
			function toast(template, image, text, app) {
				// Alias for convenience.
				var N = Windows.UI.Notifications;
				// Get the template XML as an XmlDocument.
				var toastXml = N.ToastNotificationManager.getTemplateContent(N.ToastTemplateType[template]);
				// Create toastNode to launch on click
				var toastNode = toastXml.selectSingleNode('/toast');
				toastNode.setAttribute('launch', text[1]);
				// Insert our content.
				var i = 0;
				for (let el of toastXml.getElementsByTagName("text")) {
					if (typeof text == 'string') {
						el.innerText = text;
						break;
					}
					el.innerText = text[++i];
				}
				toastXml.getElementsByTagName("image")[0].setAttribute("src", image);
				// Show the notification.
				var toastNotifier = N.ToastNotificationManager.createToastNotifier(app || "AutoHotkey");
				var notification = new N.ToastNotification(toastXml);
				notification.addEventListener("activated", toastActivatedHandler);
				toastNotifier.show(notification);
			}
			function toastActivatedHandler(a) {
				JS_ToastActivated(a.arguments);
			}

		)
		try 
		{
			; Define the toast function.
			js.Exec(code)
		}
		catch ex 
		{
			try errmsg := ex.stack
			if !errmsg
				errmsg := "Error: " ex.message
			MsgBox % errmsg
		}
	}
	try 
	{
		; Show a toast notification.
		js.toast(toast_template, toast_image, toast_text, toast_appid)
	}
	catch ex 
	{
		try errmsg := ex.stack
		if !errmsg
			errmsg := "Error: " ex.message
		MsgBox % errmsg
	}
}

AHK_ToastActivated(a)
{
	MsgBox % a
}
This will create a toast notification and when clicked on the function AHK_ToastActivated(a) will be called which will display the first line of the toast notification.

It seems so simple now but getting all the parts right was a real challenge when starting with zero knowledge of JavaScript especially with the added layer of funneling it through AHK. On the plus side I did learn some basics of JavaScript.

FG

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 08 Jun 2018, 20:55
by joedf
Coolio! I haven't used this but it's good you provided this example!
Thanks FanaticGuru :)

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 25 Mar 2019, 13:17
by IMEime
works fine thanks..

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 04 Nov 2019, 20:47
by kczx3
A little fun with JsRT and JSON. I'm contemplating using something like this in AHKv2 (if I can convert ActiveScript and JsRT, of course).

Code: Select all

#include ActiveScript.ahk
#Include JsRT.ahk

JsRT := new JsRT.Edge
JSON := JsRT.JSON

obj := JSON.parse("{""stuff"": ""things"", ""manyThings"": [""my"", ""name"", ""is"", ""sparta""], ""myBool"": true}")

msgbox, % JSON.stringify(obj, , 4)

msgbox, % obj.manyThings.reduce(Func("totalCharacters"), 0)

obj.manyThings.forEach(Func("MsgBox"))

JsRT.Object.entries(obj).forEach(Func("MsgBox"))

MsgBox(str) {
    if (str is string) {
        msgbox, % str
        return
    }

    key := str[0], val := str[1]
    if (val is string) {
        MsgBox, % key " = " val
    }
    else {
        if (JsRT.Array.isArray(val)) {
            MsgBox, % key " = [" val.join(", ") "]"
        }
    }
}

totalCharacters(acc, next, index) {
    return acc + StrLen(next)
}

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 13 Jul 2021, 16:03
by joreli
Hi..

Having trouble with JSON and ActiveXObject. It seems by default they are not enabled with the latest IE11 runtime.

When I instantiate the class as

Code: Select all

js := new MyActiveScript("JScript9") ; I have added the registry setting 
or

Code: Select all

js := new MyActiveScript("{16d51579-a30b-4c8b-a276-0ff4dc41e755}")
ActiveXObject is working, but JSON is undefined (tested with typeof operator) and the version returns 11.0

With this

Code: Select all

js := new JsRT.IE
JSON is working, but ActiveXObject and GetObject are undefined. Version returns 11.0

Is it possible to support these functions using JScript9.dll version?

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 16 Jul 2021, 06:11
by lexikos
If you want an IE11-like environment, create a WebBrowser control or InternetExplorer.Application and inject script. ActiveScript only gives you the scripting engine, not the application model.

Alternatively, you can insert whatever functions you want into the ActiveScript instance by using AddObject or an assignment; e.g. js.AddObject("ComObjCreate", Func("ComObjCreate")).

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 17 Jul 2021, 00:33
by joreli
Thank you @lexikos.
Instead of WebBrowser control, "HtmlFile" object seems lightweight (less memory usage) and rather than hosting full WebBrowser control.

Code: Select all

oHtml := ComObjCreate("HtmlFile")
oHtml.write("<meta http-equiv='X-UA-Compatible' content='IE=edge'>")
oJs :=  oHtml.parentWindow

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 22 Oct 2021, 04:35
by lmstearn
Thanks for the script, how Coco Lexikos got to make _OnScriptError work is amazing. :) The version for V1.1 Luddites here.
Edit: Attempting to paste VBScript code in with object references to WScript won't work AFAIK unless there are tricks.

Re: ActiveScript - Host VBScript and JScript in-process

Posted: 12 Apr 2023, 13:56
by malcev
@lexikos, could You please tell why if We eval number > int32, then We get Double as result?

Code: Select all

js := new JsRT.Edge
msgbox % js.Eval("2147483648")
The same also is with v2:

Code: Select all

js := (JsRT.Edge)()
msgbox js.Eval("2147483648")