This is an old revision of the document!
Using COM with MCode
When building integrations for AutoHotkey using MCode, it is often convenient to be able to work with COM objects. Either consuming COM objects in your MCode, or exporting COM objects from your MCode so they can be consumed by AHK.
Exporting IUnknown from MCode
The most basic COM object you can export from your MCode is an IUnknown object. To export an IUnknown object, you must implement the IUnknown interface's three methods: QueryInterface, AddRef, and Release.
IUnknown can't actually do anything worth demonstrating, so on top of those three methods we'll implement an additional three: SetFirstAddend, SetSecondAddend, and GetSum. Together, these will form our own custom interface, which we'll call IMyObj
.
#Requires AutoHotkey v2.0#include <MCL>lib := MCL.FromC("(#include <mcl.h>#include <stdlib.h>#include <oaidl.h>// --- Interface Identifiers ---------------------------------------------------// IID_IUnknown {00000000-0000-0000-C000-000000000046}GUID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };// IID_IMyObj (generated at random)GUID IID_IMyObj = { 0x2D055F08, 0xC092, 0x44D4, { 0x82, 0xA9, 0xF7, 0x57, 0x75, 0x1D, 0x0D, 0x80 } };// --- MyObj Structural Definition ---------------------------------------------// Forward declare the MyObj type so it can be referenced in MyObjVtbltypedef struct MyObj MyObj;// Define the virtual method table for objects of type MyObjtypedef struct MyObjVtbl {// Implements IUnknown__stdcall HRESULT(*QueryInterface) (MyObj *this, REFIID riid, void **ppvObject);__stdcall ULONG(*AddRef) (MyObj *this);__stdcall ULONG(*Release) (MyObj *this);
Exporting IDispatch from MCode
By implementing the IDispatch interface, your custom COM object can be wrapped by AHK. Once wrapped, users can interact with the object using native object syntax.
#Requires AutoHotkey v2.0#include <MCL>lib := MCL.FromC("(#include <mcl.h>#include <stdlib.h>#include <oaidl.h>#define DISP_E_TYPEMISMATCH 0x80020005MCL_IMPORT(int, msvcrt, _wcsicmp, (const short*, const short*));MCL_IMPORT(HRESULT, OleAut32, VariantChangeType, (VARIANT*, const VARIANT*, USHORT, VARTYPE));// --- Interface Identifiers ---------------------------------------------------// IID_IUnknown {00000000-0000-0000-C000-000000000046}GUID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };// IID_IDispatch {00020400-0000-0000-C000-000000000046}GUID IID_IDispatch = { 0x00020400, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };// --- MyObj Structural Definition ---------------------------------------------// Forward declare the MyObj type so it can be referenced in MyObjVtbltypedef struct MyObj MyObj;// Define the virtual method table for objects of type MyObjtypedef struct MyObjVtbl {// Implements IUnknown