Skip to content

Commit a3ed8fc

Browse files
author
maul.esel
committed
improve error handling in ITL_InterfaceWrapper.__Call
1 parent 9fe7221 commit a3ed8fc

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

ITL_InterfaceWrapper.ahk

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ class ITL_InterfaceWrapper extends ITL.ITL_WrapperBaseClass
2020
{
2121
; code inspired by AutoHotkey_L source (script_com.cpp)
2222
static DISPATCH_METHOD := 0x1
23-
, DISPID_UNKNOWN := -1
24-
, sizeof_DISPPARAMS := 8 + 2 * A_PtrSize, sizeof_EXCEPINFO := 12 + 5 * A_PtrSize, sizeof_VARIANT := 8 + 2 * A_PtrSize, sizeof_ELEMDESC := 4 * A_PtrSize
25-
, DISP_E_MEMBERNOTFOUND := -2147352573, DISP_E_UNKNOWNNAME := -2147352570
26-
, INVOKEKIND_FUNC := 1
27-
, VT_USERDEFINED := 29, VT_RECORD := 36, VT_UNKNOWN := 13, VT_PTR := 26
28-
, TYPEKIND_RECORD := 1, TYPEKIND_INTERFACE := 3
29-
local paramCount, dispparams, rgvarg := 0, hr, info, dispid := DISPID_UNKNOWN, instance, excepInfo, err_index, result, variant, index := -1, funcdesc := 0, vt ;, fn
30-
, refHandle, refInfo := 0, refAttr := 0, refKind, tdesc, indirectionLevel
23+
, DISPID_UNKNOWN := -1
24+
, sizeof_DISPPARAMS := 8 + 2 * A_PtrSize, sizeof_EXCEPINFO := 12 + 5 * A_PtrSize, sizeof_VARIANT := 8 + 2 * A_PtrSize, sizeof_ELEMDESC := 4 * A_PtrSize
25+
, DISP_E_MEMBERNOTFOUND := -2147352573, DISP_E_UNKNOWNNAME := -2147352570, DISP_E_EXCEPTION := -2147352567, DISP_E_TYPEMISMATCH := -2147352571, DISP_E_PARAMNOTFOUND := -2147352572, DISP_E_BADVARTYPE := -2147352568
26+
, INVOKEKIND_FUNC := 1
27+
, VT_USERDEFINED := 29, VT_RECORD := 36, VT_UNKNOWN := 13, VT_PTR := 26
28+
, TYPEKIND_RECORD := 1, TYPEKIND_INTERFACE := 3
29+
local paramCount, dispparams, rgvarg := 0, hr, info, dispid := DISPID_UNKNOWN, instance, excepInfo, err_index := -1, result, variant, index := -1, funcdesc := 0, vt, fnFill ;, fn
30+
, refHandle, refInfo := 0, refAttr := 0, refKind, tdesc, indirectionLevel
3131

3232
paramCount := params.maxIndex() > 0 ? params.maxIndex() : 0 ; the ternary is necessary, otherwise it would hold an empty string, causing calculations to fail
3333
, info := this.base[ITL.Properties.TYPE_TYPEINFO]
@@ -174,9 +174,9 @@ class ITL_InterfaceWrapper extends ITL.ITL_WrapperBaseClass
174174
}
175175
; todo: handle arrays (native and safe)
176176
else
177-
ITL_VARIANT_Create(params[A_Index], variant) ; create VARIANT and put it in the array
177+
ITL_VARIANT_Create(params[A_Index], variant) ; create VARIANT
178178

179-
ITL_Mem_Copy(&variant, &rgvarg + (paramCount - A_Index) * sizeof_VARIANT, sizeof_VARIANT)
179+
ITL_Mem_Copy(&variant, &rgvarg + (paramCount - A_Index) * sizeof_VARIANT, sizeof_VARIANT) ; put the VARIANT structure into the array
180180
}
181181
NumPut(&rgvarg, dispparams, 00, "Ptr") ; DISPPARAMS::rgvarg - the pointer to the VARIANT array
182182
NumPut(paramCount, dispparams, 2 * A_PtrSize, "UInt") ; DISPPARAMS::cArgs - the number of arguments passed
@@ -185,8 +185,7 @@ class ITL_InterfaceWrapper extends ITL.ITL_WrapperBaseClass
185185
}
186186

187187
; invoke the function
188-
; currently, the excepinfo structure is not used; also, the last parameter (index of a bad argument if any) is not passed
189-
hr := DllCall(NumGet(NumGet(info+0), 11*A_PtrSize, "Ptr"), "Ptr", info, "Ptr", instance, "UInt", dispid, "UShort", DISPATCH_METHOD, "Ptr", &dispparams, "Ptr", &result, "Ptr", &excepInfo, "Ptr", 0, "Int") ; ITypeInfo::Invoke()
188+
hr := DllCall(NumGet(NumGet(info+0), 11*A_PtrSize, "Ptr"), "Ptr", info, "Ptr", instance, "UInt", dispid, "UShort", DISPATCH_METHOD, "Ptr", &dispparams, "Ptr", &result, "Ptr", &excepInfo, "UInt*", err_index, "Int") ; ITypeInfo::Invoke()
190189
if (ITL_FAILED(hr))
191190
{
192191
/*
@@ -202,11 +201,21 @@ class ITL_InterfaceWrapper extends ITL.ITL_WrapperBaseClass
202201
}
203202
}
204203
*/
205-
; use EXCEPINFO here!
204+
if (hr == DISP_E_EXCEPTION)
205+
{
206+
fnFill := NumGet(excepInfo, 08+4*A_PtrSize, "Ptr") ; EXCEPINFO::pfnDeferredFillIn
207+
if (fnFill)
208+
DllCall(fnFill, "Ptr", &excepInfo)
209+
hr := (hr := NumGet(excepInfo, 08+5*A_PtrSize, "Int")) ? hr : NumGet(excepInfo, 00, "UShort") ; get EXCEPINFO::scode or EXCEPINFO::wCode
210+
throw Exception(ITL_FormatException("Failed to call a method."
211+
, "The called method raised an exception: Source=""" StrGet(NumGet(excepInfo, 04, "Ptr")) """, Message=""" StrGet(NumGet(excepInfo, 04 + A_PtrSize, "Ptr")) """"
212+
, ErrorLevel, hr)*)
213+
}
206214
;throw Exception("""" method "()"" could not be called.", -1, ITL_FormatError(hr))
207215
throw Exception(ITL_FormatException("Failed to call a method."
208216
, "ITypeInfo::Invoke() failed for """ method """."
209-
, ErrorLevel, hr)*)
217+
, ErrorLevel, hr
218+
, (hr == DISP_E_TYPEMISMATCH || hr == DISP_E_PARAMNOTFOUND || hr == DISP_E_BADVARTYPE), "Invalid argument: #" err_index)*)
210219
}
211220
return ITL_VARIANT_GetValue(&result) ; return the result of the call
212221
}

0 commit comments

Comments
 (0)