 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Thu Jan 10, 2008 9:47 am Post subject: DispatchObj (prototype) |
|
|
DispatchObj
Requirement: COM Standard Library
DispatchObj allows an AutoHotkey script to create an Invoke'able object. This object can then be passed to JavaScript, allowing it to call functions defined in AutoHotkey.
| Code: | obj := DispatchObj_Create("func")
MsgBox % COM_Invoke(obj, "func")
func() {
return 1337
}
| At the time I wrote it, I wasn't satisfied with how parameters are handled. It was not possible to call functions dynamically with string parameters (without extra coercion code in each function), so parameters must be extracted using DispatchObj_Param().
I'm still not satisfied with the script's current state, but it has been collecting dust for a while. Since it may be of some use in its current state, I thought I should release it.
Functions take the following style:
| Code: | func(this, params, result) ; all parameters are optional
{
; Get the value and type of the first parameter.
value := DispatchObj_Param(params, 1, type)
if type = 9 ; VT_DISPATCH (an object)
COM_Invoke(value, "someMethod")
; Return an integer (zero):
; optional since VT_I4 (int) is the default:
NumPut(3, result+0,0,"ushort") ; result.vt=VT_I4;
; method 1
NumPut(123, result+8,0,"int") ; result.lVal=123;
; method 2, overrides method 1 if non-zero. only works with int.
return 123
} | An advantage of the DispatchObj_Param method is that it allows the parameters to be validated, making the function more robust. For instance, if JavaScript passes an integer when an object is expected, the script can return an error code rather than crashing as a result of invoking on an invalid pointer.
| Code: | ; Builds an object from a list of methods. MethodList takes the following form:
; script_function_1,object_method_alias=script_function_2,...
DispatchObj_Create( MethodList )
{
id_count = 0
fail_count = 0
method_names =
Loop, Parse, MethodList, `,, %A_Space%%A_Tab%
{
; method: member name of method in object.
; function: name of actual script function.
if (pos := InStr(A_LoopField,"=")) {
method := SubStr(A_LoopField,1,pos-1)
function := SubStr(A_LoopField,pos+1)
} else
method := function := A_LoopField
; "CDecl" so we can pass more parameters than it expects.
if (method="") or !(cb := RegisterCallback(function,"CDecl"))
{
fail_count += 1
continue
}
id_count += 1
cb%id_count% := cb
; Store zero-based byte-offset from start of method_names.
method%id_count% := StrLen(method_names)
method_names .= method ","
}
if id_count = 0
return 0, ErrorLevel:="NO VALID METHODS"
; Memory organisation:
; *IDispatch ref_count reserved reserved
; id_count ( *name *callback )* ( name )*
; If a method is executing, cur_params is a pointer to a DISPPARAMS
; structure and cur_var_result is a pointer to a VARIANT structure
; where the result of the method call is stored.
pObj := COM_CoTaskMemAlloc(20+8*id_count+StrLen(method_names)+1)
pNames := pObj+20+8*id_count
NumPut(DispatchObj_CreateIDispatch(), pObj+0) ; &IDispatch
, NumPut(1, pObj+4) ; ref_count
, NumPut(0, pObj+8) ; reserved
, NumPut(0, pObj+12) ; reserved
, NumPut(id_count, pObj+16) ; id_count
DllCall("lstrcpy","uint",pNames,"str",method_names)
; null-terminate each name.
Loop, Parse, method_names
if (A_LoopField=",")
NumPut(0,pNames-1,A_Index,"char")
Loop %id_count%
NumPut(cb%A_Index%, NumPut(pNames+method%A_Index%, pObj+20, 8*(A_Index-1)))
return pObj
}
; Gets a parameter from a DISPPARAMS structure.
; params: Address of DISPPARAMS structure.
; index: ONE-based parameter index.
; type: [out] The *original* VARTYPE of the parameter VARIANT.
; returns: Parameter value, coerced to string where applicable.
DispatchObj_Param(params, index, ByRef type="")
{
if !params or index<1 or index>NumGet(params+8)
return
VarSetCapacity(var,16), DllCall("RtlMoveMemory","uint",&var
,"uint",NumGet(params+0)+(NumGet(params+8)-index)*16,"uint",16)
type := NumGet(var,0,"ushort")
if type in 0,4,5,6,7,14
DllCall("oleaut32\VariantChangeType","uint",&var,"uint",&var,"ushort",0,"ushort",8)
return NumGet(var,0,"ushort")=8 ? COM_Ansi4Unicode(NumGet(var,8)) : NumGet(var,8)
}
; Based on COM_DispInterface()
DispatchObj_IDispatch(this, prm1=0, prm2=0, prm3=0, prm4=0, prm5=0, prm6=0, prm7=0, prm8=0)
{
Critical
If A_EventInfo = 6
{
if ((prm4 & 1) && prm1>=1 && prm1<=NumGet(this+16)) {
NumPut(3,prm6+0,0,"ushort") ; default to Int return type.
NumPut(0,prm6+8,0,"int") ; default to 0 return value.
i:=DllCall(NumGet(this+24+8*(prm1-1)),"uint",this,"uint",prm5,"uint",prm6,"CDecl")
if i != 0 ; if non-zero, set new return value.
NumPut(i,prm6+8,0,"int")
hResult := 0
} else
hResult := 0x80020003
}
Else If A_EventInfo = 5
{
Loop, %prm3%
NumPut(-1, prm5+4*(A_Index-1))
name := COM_Ansi4Unicode(NumGet(prm2+0))
Loop % NumGet(this+16)
if !DllCall("lstrcmpi","str",name,"uint",NumGet(this+20+8*(A_Index-1)))
{
NumPut(A_Index, prm5+0)
break
}
hResult := (prm3>1 or -1=NumGet(prm5+0,0,"int")) ? 0x80020006 : 0
}
Else If A_EventInfo = 4
NumPut(0,prm3+0), hResult:=0x80004001
Else If A_EventInfo = 3
NumPut(0,prm1+0), hResult:=0
Else If A_EventInfo = 2
{
NumPut(hResult:=NumGet(this+4)-1,this+4)
if !hResult {
Loop % NumGet(this+16)
DllCall("GlobalFree","uint",NumGet(this+24+8*(A_Index-1)))
COM_CoTaskMemFree(this)
}
}
Else If A_EventInfo = 1
NumPut(hResult:=NumGet(this+4)+1,this+4)
Else If A_EventInfo = 0
InStr("{00020400-0000-0000-C000-000000000046}{00000000-0000-0000-C000-000000000046}",COM_String4GUID(prm1)) ? NumPut(this,prm2+0) . NumPut(NumGet(this+4)+1,this+4) . (hResult:=0) : NumPut(0,prm2+0) . (hResult:=0x80004002)
Return hResult
}
; Based on COM_CreateIDispatch()
DispatchObj_CreateIDispatch()
{
Static IDispatch
If !VarSetCapacity(IDispatch)
{
VarSetCapacity(IDispatch,28,0), nParams=3112469
Loop, Parse, nParams
NumPut(RegisterCallback("DispatchObj_IDispatch","",A_LoopField,A_Index-1),IDispatch,4*(A_Index-1))
}
Return &IDispatch
}
|
Planned Features ...for the distant future
- A better example script, demonstrating multiple methods, parameters, parameter/return types and interaction with JavaScript.
- Implement LowLevel to allow parameters to be passed directly to the script function as strings.
- Provide access to the parameter list (including parameter types) and return type for the current function.
- Provide an option to pass parameters as (type1, prm1, type2, prm2, etc.)
- Provide an option to keep the current style, which supports variable number of parameters.
(Thanks to majkinetor for the idea of "a flag to choose between different approaches.")
- Automatic ByRef support, if possible.
- Support for properties.
- Get/set accessor functions.
- Get/set an AutoHotkey variable.
- Get/set any value, possibly from either AutoHotkey or external code.
- Support for default property (which I think would allow array[index]-style syntax to be used.)
- Support for default method, so a DispatchObj can be used to handle an event. (This would make Handling Individual Events obsolete.)
Advanced Example
Requires ShowHTMLDialog.
| Code: | obj := DispatchObj_Create("getHtml, getDefaultText, okay=onOkay")
html =
(
<head><title>Example Dialog</title></head>
<body>
<input type=text id="textbox"><br>
<button id="okButton" onclick="dialogArguments.okay(window)">Okay</button>
<script for="window" event="onload">
textbox.value = dialogArguments.getDefaultText();
textbox.select();
</script>
</body>
)
text := ShowHTMLDialog("javascript:dialogArguments.getHtml()"
, "+" obj ; pass 'obj' as an object pointer
, "dialogWidth:155px;dialogHeight:50px")
if text !=
MsgBox %text%
getHtml(this, params, result)
{
global html
NumPut(8, result+0) ; VT_BSTR
return COM_SysAllocString(html)
}
getDefaultText(this, params, result)
{
NumPut(8, result+0) ; VT_BSTR
return COM_SysAllocString("default text!")
}
; This would be easier in JavaScript...
onOkay(this, params, result)
{
window := DispatchObj_Param(params, 1, type)
if type != 9 ; VT_DISPATCH
return
if textbox := COM_Invoke(window, "textbox")
{
returnValue := COM_Invoke(textbox, "value")
COM_Release(textbox)
}
COM_Invoke(window, "returnValue=", returnValue)
COM_Invoke(window, "close")
} |
Also note that given a pointer to a window object 'ieWin', the following can be used to pass a DispatchObj to JavaScript:
| Code: | ; Create 'ahk' variable. (var=''; also works)
COM_Invoke(ieWin,"execScript","var ahk;","JScript")
; Assign dispatch object to ahk variable.
COM_Invoke(ieWin,"ahk=","+" pObj)
|
Sean deserves much credit for demonstrating how to implement a COM interface in AutoHotkey. DispatchObj_IDispatch and DispatchObj_CreateIDispatch are based on COM_DispInterface and COM_CreateIDispatch, respectively.
All code in this post is covered by Lexikos' default copyright license.
Last edited by Lexikos on Tue Dec 30, 2008 12:41 am; edited 4 times in total |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4511 Location: Belgrade
|
Posted: Thu Jan 10, 2008 2:41 pm Post subject: |
|
|
Ok, so I will have object in ahk variable in jscode.
But how do I execute it from JS code and how do I pass it params ?
window.ahk(...) ?  _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Thu Jan 10, 2008 3:49 pm Post subject: |
|
|
See the new Advanced Example.
DispatchObj is usable like any other object on the JavaScript side. Until I implement LowLevel, the AutoHotkey side will require DispatchObj_Param() to retrieve parameters and NumPut & COM_SysAllocString to return strings.
Writing the example has shown me just how useful/convenient it would be for DispatchObj to support properties... |
|
| Back to top |
|
 |
COMTTS Guest
|
Posted: Fri Jan 11, 2008 12:28 am Post subject: |
|
|
Thanks for the script, Lexikos.
God, I cannot even understand what's going on in the code.
Maybe I have to dig into the showHtmlDialog, and then get back here.
And even though I didn't mention about your previous scripts,
they were really practical and useful. Thanks. |
|
| Back to top |
|
 |
paulwarr
Joined: 21 Sep 2006 Posts: 32
|
Posted: Sun Feb 17, 2008 12:12 am Post subject: |
|
|
@ lexikos:
I downloaded the advanced example above, together with ShowHTMLDialog and DispatchObj, and #include'd these in the advanced example.
On launching the advanced example, I get "Error" dialog box with the following text:
Line: 5
Error: Object doesn't support this property or method
When I dismiss the error message, I get the small Example Dialog window with a text box and an "Okay" button. But whether I type anything or not into the text box, when I click "Okay" I get another "Error" dialog box with the following text:
Line: 3
Error: Object doesn't support this property or method.
To be sure, I reinstalled the latest version of COM.ahk. Same errors.
Any suggestions on what to do next? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Sun Feb 17, 2008 1:59 am Post subject: |
|
|
| paulwarr wrote: | | I downloaded the advanced example above, together with ShowHTMLDialog and DispatchObj, and #include'd these in the advanced example. | Though it shouldn't matter, ShowHTMLDialog and DispatchObj are intended to be auto-included via the function library mechanism.
| Quote: | Line: 5
Error: Object doesn't support this property or method
| I suppose it doesn't say which object or which property/method? Lines 3 and 5 have no code on them... did you change the HTML at all?
| Quote: | | When I dismiss the error message, I get the small Example Dialog window with a text box and an "Okay" button. | Since the HTML for the dialog is retrieved via dialogArguments.getHtml(), DispatchObj must be working.
| Quote: | But whether I type anything or not into the text box, when I click "Okay" I get another "Error" dialog box with the following text:
Line: 3
Error: Object doesn't support this property or method.
| dialogArguments (the DispatchObj) is used on lines 4 and 6. Those errors make some sense if these are lines 3 and 5 on your system, but that would mean dialogArguments is not valid after loading the HTML.
Try saving the example HTML to a file and loading that. (Replace "javascript:dialogArguments.getHtml()" with the full path of the file.)
Which version of IE are you using? Have you tried on other computers?
I just tested on IE 6.0.2900.2180 (XP SP2 on Virtual PC), and it worked, except that the window was only large enough for the caption and scrollbar. MSDN explains why:
| Quote: | For Windows Internet Explorer 7, dialogHeight and dialogWidth return the height and width of the content area and no longer includes the height and width of the frame.
| (The example's dialogWidth/dialogHeight were based on IE7.) |
|
| Back to top |
|
 |
paulwarr
Joined: 21 Sep 2006 Posts: 32
|
Posted: Sun Feb 17, 2008 8:23 pm Post subject: |
|
|
Further experiments - still no joy:
My earlier tests were run on a machine with VStudio, hence popped up the debug window with the earlier unhelpful messages. So I switched to the following platform:
XP SP2, running in VMWare Workstation v6
Unmodified from original CD installation, save for all critical security updates and McAfee VirusScan 8.5i
Internet Explorer v. 6.0.2900.2180.xpsp_sp2_gdr.0702227-2254
AutoHotKey v
To avoid any unintended side-effects, I moved ShowHTMLDialog.ahk and DispatchObj.ahk to my /Lib folder and removed the #include lines.
Per your suggestions, I modified the "Advanced Example" in two ways:
1) changed the dialogWidth and dialogHeight parameters (so that I could actually see ShowHTMLDialog window).
2) Saved the html code to a separate file.
Both modifications were in the ShowHTMLDialog function call, like so:
text := ShowHTMLDialog("file:///" A_ScriptDir "\DispatchObj_Example2.htm"
, "+" obj ; pass 'obj' as an object pointer
, "dialogWidth:255px;dialogHeight:150px")
Now, on launch of the advanced example, I get the following:
Notice that the "Default Text!" entry is missing.
If I click "yes" on the script error window, then type something into the textbox and click the "Okay" button, I get the following:
I swear, I didn't touch anything else! |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Sun Feb 17, 2008 11:33 pm Post subject: |
|
|
Well, it seems I forgot to update the script when I updated the example. There was one important change:
| Code: | | Loop, Parse, MethodList, `,, %A_Space%%A_Tab% | The method list is: | Code: | | obj := DispatchObj_Create("getHtml, getDefaultText, okay=onOkay") | Notice the spaces...  |
|
| Back to top |
|
 |
paulwarr
Joined: 21 Sep 2006 Posts: 32
|
Posted: Thu Feb 21, 2008 12:10 am Post subject: |
|
|
Works! Thanks!
I note that DispatchObj's example requires ShowHTMLDialog, which passes the object as a parameter (to showhtmldialogex?). But I also note that there is no corresponding parameter-pass option in the Webbrowser or IE "Navigate" or "Navigate2" methods. So do you have any suggestions on how to create and pass a DispatchObj invoke-able object to a standard IE or Webbrowser control? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Thu Feb 21, 2008 3:25 am Post subject: |
|
|
| paulwarr wrote: | | So do you have any suggestions on how to create and pass a DispatchObj invoke-able object to a standard IE or Webbrowser control? |
| I wrote: | Also note that given a pointer to a window object 'ieWin', the following can be used to pass a DispatchObj to JavaScript:
| Code: | ; Create 'ahk' variable. (var=''; also works)
COM_Invoke(ieWin,"execScript","var ahk;","JScript")
; Assign dispatch object to ahk variable.
COM_Invoke(ieWin,"ahk=","+" pObj)
|
| To get a pointer to a window object ("ieWin"):
| Code: | ControlGet, hIESvr, Hwnd,, Internet Explorer_Server1, Google ; (WinTitle)
ACC_Init() ; Call this once only, or call ACC_Term() for each ACC_Init().
; Note ACC_Init also calls COM_Init(), so you don't need both.
ieAcc := ACC_AccessibleObjectFromWindow(hIESvr)
IID_IHTMLWindow2 := "{332C4427-26CB-11D0-B483-00C04FD90119}"
ieWin := COM_QueryService(ieAcc,IID_IHTMLWindow2,IID_IHTMLWindow2)
COM_Release(ieAcc) | Requires Accessibility Standard Library. |
|
| Back to top |
|
 |
tinku99
Joined: 03 Aug 2007 Posts: 513 Location: Houston, TX
|
Posted: Fri Jan 22, 2010 12:31 am Post subject: ahk plugin for ie |
|
|
Wow, I just found this.
Thanks, Lexikos. |
|
| Back to top |
|
 |
lexikos* Guest
|
Posted: Fri Jan 22, 2010 5:18 am Post subject: |
|
|
| I haven't used this script since writing it. If you find it useful, perhaps you'd like to try implementing some of the "Planned Features". LowLevel would not be necessary now that we have the built-in capability to dynamically call functions. Some of the other items overlap with capabilities now present in AutoHotkey_L/AutoHotkeyU objects, so writing an IDispatch wrapper for those could be useful. |
|
| Back to top |
|
 |
tinku99
Joined: 03 Aug 2007 Posts: 513 Location: Houston, TX
|
Posted: Tue Oct 05, 2010 3:16 am Post subject: invoking ahk function from javascript in IE browser |
|
|
I am able to replace javascript functions in a webpage loaded in IE through execscript. I am even able to put a dispatch obj into a variable on the webpage, and invoke it from ahk. Unfortunately, I can't figure out how to invoke an ahk function from the javascript / webpage side. (I know events can be connected, but can you connect a non event object / javascript function to an ahk function ? )
@Lexikos: could you provide an example using IE instead of showHTMLdialog ?
Edit:
Thanks Lexikos. I figured it out, see post below.
The following now works:
my ahk script: | Code: | onexit, cleanup
iewin := getiewin("ahk Plug-In")
obj := DispatchObj_Create("ahkMessage")
cobj := ComObjEnwrap(obj)
cobj.ahkMessage("cobj.ahkMessage works") ; works
ieWin.execScript("var ahk;","JScript")
ieWin.ahk := cobj
ieWin.ahk.ahkMessage("ieWin.ahk.ahkMessage now works")
script2 =
(
function testMessage()
{
alert("test message!" + window.status); // works
ahk.ahkMessage("from javascript ahk.ahkMessage"); //works too :)
}
)
ieWin.execScript(script2,"JScript")
return
;; testMessage(this, params, result) ; all parameters are optional
testMessage(this, params, result) ; all parameters are optional
{
; Get the value and type of the first parameter.
value := DispatchObj_Param(params, 1, type)
if type = 9 ; VT_DISPATCH (an object)
COM_Invoke(value, "someMethod")
; Return an integer (zero):
; optional since VT_I4 (int) is the default:
NumPut(3, result+0,0,"ushort") ; result.vt=VT_I4;
; method 1
NumPut(123, result+8,0,"int") ; result.lVal=123;
; method 2, overrides method 1 if non-zero. only works with int.
msgbox testmessage %value%
return 123
}
;; ahkMessage(this, params, result) ; all parameters are optional
ahkMessage(this, params, result) ; all parameters are optional
{
; Get the value and type of the first parameter.
value := DispatchObj_Param(params, 1, type)
if type = 9 ; VT_DISPATCH (an object)
COM_Invoke(value, "someMethod")
; Return an integer (zero):
; optional since VT_I4 (int) is the default:
NumPut(3, result+0,0,"ushort") ; result.vt=VT_I4;
; method 1
NumPut(123, result+8,0,"int") ; result.lVal=123;
; method 2, overrides method 1 if non-zero. only works with int.
msgbox ahkMessage %value%
return 123
}
;; cleanup:
cleanup:
ExitApp
;; includes
#include com.ahk
#include dispatchobj.ahk
#include acc.ahk
#include expando.ahk
;; ui
!r::reload
!q::exitapp
;; getiewin(title)
getiewin(title)
{
ControlGet, hIESvr, Hwnd,, Internet Explorer_Server1, %title%
ACC_Init() ; Call this once only, or call ACC_Term() for each ACC_Init().
; Note ACC_Init also calls COM_Init(), so you don't need both.
ieAcc := ACC_AccessibleObjectFromWindow(hIESvr)
IID_IHTMLWindow2 := "{332C4427-26CB-11D0-B483-00C04FD90119}"
ieWin := COM_QueryService2(ieAcc,IID_IHTMLWindow2,IID_IHTMLWindow2)
COM_Release(ieAcc)
return ieWin
}
COM_QueryService2(ppv, SID, IID = "")
{
If DllCall(NumGet(NumGet(1*ppv:=COM_Unwrap(ppv))), "Uint", ppv, "Uint", COM_GUID4String(IID_IServiceProvider,"{6D5140C1-7436-11CE-8034-00AA006009FA}"), "UintP", psp)=0
&& DllCall(NumGet(NumGet(1*psp)+12), "Uint", psp, "Uint", COM_GUID4String(SID,SID), "Uint", IID ? COM_GUID4String(IID,IID):&SID, "UintP", ppv:=0)+DllCall(NumGet(NumGet(1*psp)+8), "Uint", psp)*0=0
Return ComObjEnwrap(ppv)
}
| my webpage: | Code: | <!-- saved from url=(0013)about:internet -->
<HTML>
<HEAD>
<TITLE>ahk Plug-In</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<script type="text/javascript">
function testMessage()
{
alert("old message!");
}
</script>
</head>
<body>
<form>
<input type="button" value="testMessage" onclick="testMessage()" /> before launching ahk script, says "old Message", after says, "test mesaage" and calls an ahk message
</form><br>
<form>
<input type="button" name="ahkbutton" value="testahk" onclick="ahk.ahkMessage()" /> call ahk from javascript (after launching ahk script)
</form>
</body>
</HTML> |
Last edited by tinku99 on Tue Oct 05, 2010 3:42 pm; edited 2 times in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Tue Oct 05, 2010 7:50 am Post subject: Re: invoking ahk function from javascript in IE browser |
|
|
| tinku99 wrote: | obj := DispatchObj_Create("ahkMessage")
...
ieWin.ahk := obj | DispatchObj_Create() returns an integer/pointer, not an object. Use ComObjEnwrap(). |
|
| Back to top |
|
 |
tinku99
Joined: 03 Aug 2007 Posts: 513 Location: Houston, TX
|
Posted: Tue Oct 05, 2010 1:29 pm Post subject: Re: invoking ahk function from javascript in IE browser |
|
|
| Lexikos wrote: | | tinku99 wrote: | obj := DispatchObj_Create("ahkMessage")
...
ieWin.ahk := obj | DispatchObj_Create() returns an integer/pointer, not an object. Use ComObjEnwrap(). | Ok, I got it work. The problem was with iewin. COM_QueryService() uses COM_Enwrap instead of ComObjEnwrap. so | Code: | | iewin.ahk := ComObjEnwrap(DispatchObj_Create("ahkMessage")) ; was failing | I used a modified COM_QueryService2() | Code: | COM_QueryService2(ppv, SID, IID = "")
{
If DllCall(NumGet(NumGet(1*ppv:=COM_Unwrap(ppv))), "Uint", ppv, "Uint", COM_GUID4String(IID_IServiceProvider,"{6D5140C1-7436-11CE-8034-00AA006009FA}"), "UintP", psp)=0
&& DllCall(NumGet(NumGet(1*psp)+12), "Uint", psp, "Uint", COM_GUID4String(SID,SID), "Uint", IID ? COM_GUID4String(IID,IID):&SID, "UintP", ppv:=0)+DllCall(NumGet(NumGet(1*psp)+8), "Uint", psp)*0=0
Return ComObjEnwrap(ppv) ; was COM_Enwrap(ppv)
} | Now, I am able to call ahk function from javascript. I will update my post above with working code.
By the way, what's the difference between ComObjEnwrap() and COM_Enwrap() ? Why does com_L.ahk use the later in COM_queryservice() ? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|