I made some changes to the DLL API. I decided against having separate functions for Methods, Property Get, and Property Put, and combined them into one Invoke function with an added parameter. I updated the original post to reflect this, and added some additional details.
I realize however that people are probably more interested in the AHK wrapper functions API. So here it is (thrown together somewhat quickly, so there are probably errors):
Update: Removed InvokeN() and InvokeSN()
LoadEasyCOM / UnloadEasyCOM
LoadEasyCOM()
UnloadEasyCOM()
Remarks
Loads/unloads the EasyCOM.dll.
On error, a Msgbox will display any error description, and the application is terminated.
Example
LoadEasyCOM()
;; do some stuff...
UnloadEasyCOM()
CreateObject
CreateObject(ProgramId_or_ClassId)
Parameters
ProgramId_or_ClassId - A program identifier (e.g. "Excel.Application") or class identifier. (e.g. "{6D5140C1-7436-11CE-8034-00AA006009FA}")
Remarks
Use this function to create an instance of a COM object when the COM object doesn't already exist, or a new instance is desired.
On success, returns a handle (pointer) to the newly created COM object.
On error, a Msgbox will display any error description, and the thread is terminated.
Examples
objExcel := CreateObject("Excel.Application")
objSpeechAPI := CreateObject("{96749377-3391-11D2-9EE3-00C04F797396}")
GetObject
GetObject(ProgramId_or_ClassId)
Parameters
ProgramId_or_ClassId - A program identifier (e.g. "Excel.Application") or class identifier. (e.g. "{6D5140C1-7436-11CE-8034-00AA006009FA}")
Remarks
Use this function to get a handle (pointer) of a COM object that already exists.
On success, returns a handle (pointer) to the existing COM object.
On error, a Msgbox will display any error description, and the thread is terminated.
Example
objExcel := GetObject("Excel.Application")
ReleaseObject
ReleaseObject(ObjectHandle)
Parameters
ObjectHandle - Handle (pointer) to a COM object.
Remarks
Frees the COM object. All handles/pointers to this object become invalid.
On error, a Msgbox will display any error description, and the thread is terminated.
Note: Passing an invalid COM handle (pointer) to this function will crash your program!
Example
objExcel := CreateObject("Excel.Application")
;; do some stuff...
ReleaseObject(objExcel)
Invoke / InvokeEx
Invoke(ObjectHandle, MemberName [, arg1 [, arg2 [, arg3 [, ...]]]])
InvokeEx(ObjectHandle, MemberName [, type1, arg1 [, type2, arg2 [, ...]]])
Parameters
ObjectHandle - Handle (pointer) to a COM object.
MemberName - The name of a member of the COM object.[*:186okwox]If the member is a method, add "()" to the end of the name (e.g. "SomeMethod()").
[*:186okwox]If the member is a property whose value is being set, add "=" to the end of the name (e.g. "SomeProperty=").
[*:186okwox]If the member is a property whose value is being retrieved, just supply the property name without any suffix (e.g. "AnotherProperty").type1, type2, ... - One of the EasyCOM types (COM_SKIP, COM_INT, COM_FLT, COM_DBL, COM_STR, COM_OBJ, COM_OBJ_UNKN, COM_ARRAY) which may also have the COM_BYREF bit set.
arg1, arg2, ... - Data to be passed to the COM function.
Remarks
These 2 functions are useful in different situations:
Invoke() - If the member being invoked only takes COM_INT, COM_FLT, COM_DBL, or COM_STR types, then all the arguments can simply be passed as strings. Most COM objects will convert the strings to the data types it needs. This saves from having to explicitly list the parameter types. If the member requires parameters other than those listed, or it is unable to convert the passed strings to the necessary data type, then you should instead use Invoke().
InvokeEx() - This function requires explicit declarations of every argument type.
Up to 9 arguments may be passed (but that number is easily increased).
Invoke() uses "`b" (backspace character) as the default value for testing when the arguments end. If a "`b" string needs to be passed to a COM call, either change this default character in the Invoke() function, or use the InvokeEx() function.
If a COM object is returned, then ReleaseObject() should be called on it when the object is no longer needed.
On error, a Msgbox will display any error description, and the thread is terminated.
Note: Passing an invalid COM handle (pointer) to this function will crash your program!
Examples
objSpeech := CreateObject("SAPI.SpVoice")
;; These functions do the same thing
Invoke(objSpeech, "Speak()", "hello there", 0)
InvokeEx(objSpeech, "Speak()", COM_STR, "hello there", COM_INT, 0)
objFSO := CreateObject("Scripting.FileSystemObject")
;; All of these functions do the same thing
Invoke(objFSO, "OpenTextFile()"
, "file.txt"
, 2 ; Open for writing
, True ; Create file
, 0) ; non-unicode
Invoke(objFSO, "OpenTextFile()" ; Can skip optional parameters
, "file.txt")
InvokeEx(objFSO, "OpenTextFile()" ; Must declare each argument type
, COM_STR, "file.txt"
, COM_INT, 2
, COM_INT, True
, COM_INT, 0)
InvokeEx(objFSO, "OpenTextFile()" ; Can skip optional parameters
, COM_STR, "file.txt")
objXL := CreateObject("Excel.Application")
Invoke(objXL, "Visible=", True)
objWrkBks := Invoke(objXL, "Workbooks")
objWB := Invoke(objWrkBks, "Add()")
objWS := Invoke(objWB, "ActiveSheet")
;; Invoke() doesn't work with the 'Cells' property (exception 0x800A03EC)
;; because the second argument can either be column index (integer),
;; or column name (string, such as "A")
;; Therefore InvokeEx() must be used
objCell := InvokeEx(objWS, "Cells"
, COM_INT, A_Index
, COM_INT, 1)
Invoke(objCell, "Value=", "Happy!")
ReleaseObject(objCell)
objCell := InvokeEx(objWS, "Cells"
, COM_INT, A_Index
, COM_INT, 2)
Invoke(objCell, "Value=", 1000.34567)
ReleaseObject(objCell)
ReleaseObject(objWS)
ReleaseObject(objWB)
ReleaseObject(objWrkBks)
ReleaseObject(objXL)
Some things I still need to add:[*:186okwox]Wrapper functions for DLL GetArgument() for arguments passed by reference.
[*:186okwox]GetObject(), but from a file
[*:186okwox]Simplified SAFEARRAY creation and accessSome questions I have about this API:[*:186okwox]Currently, whenever there is a COM error, the thread is simply terminated. I imagine this won't be the desired behavior in many cases. So how would people want to handle errors?
[*:186okwox]About the MemberName parameter for the Invoke functions: Does the appended "=" and "()" make sense? Or would it just be better to keep such a thing in a separate parameter?
[*:186okwox]Do these different Invoke() functions help at all? Or do they instead just add confusion? Would be better to stick with one function?
[*:186okwox]Does anyone know of a COM object that requires some 'by reference' arguments? I need to test those related functions.
I suggest <!-- m -->https://ahknet.autohotkey.com/..<!-- m -->.
Thanks lexikos, I was considering using autohotkey.net. Seems like the best place.
1) Where is the DLL ?
2) Where is the example of use ?
1) The DLL is sitting on my computer(s) at the moment, alternating between a working and non-working state (it's still under development).
2) My
original post had a pretty good example of use--both using the raw DLL functions, and some nicer wrapper functions. However, there are some more up-to-date examples in the above API.