Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
guides:machine_code:com [2025-03-26 17:49] – [Using COM with MCode] Link to COM APIs guide geek | guides:machine_code:com [2025-03-28 13:28] (current) – [Using COM with MCode] Link MCode guide geek | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Using COM with MCode ====== | ====== Using COM with MCode ====== | ||
- | Before continuing, consider | + | Please read the basic [[guides: |
+ | |||
+ | If you have not, consider | ||
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. | 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. | ||
Line 536: | Line 538: | ||
input := [1, 2, 3] | input := [1, 2, 3] | ||
MsgBox lib.SumValues(ObjPtr(input)) | MsgBox lib.SumValues(ObjPtr(input)) | ||
+ | </ | ||
+ | |||
+ | ==== Implementing QuickSort ==== | ||
+ | |||
+ | By invoking '' | ||
+ | |||
+ | <runner ahk2> | ||
+ | #Requires AutoHotkey v2.0 | ||
+ | #include <MCL> | ||
+ | |||
+ | lib := MCL.FromC(" | ||
+ | ( | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #define E_FAIL 0x80004005 | ||
+ | |||
+ | MCL_IMPORT(HRESULT, | ||
+ | MCL_IMPORT(HRESULT, | ||
+ | |||
+ | HRESULT GetItem(IDispatch* array, ULONG index, VARIANT* pvarResult) { | ||
+ | VARIANT vargGet = { .vt = VT_I4, .lVal = index }; | ||
+ | DISPPARAMS dpGet = { .cArgs = 1, .cNamedArgs = 0, .rgvarg = & | ||
+ | return array-> | ||
+ | array, DISPID_VALUE, | ||
+ | &dpGet, pvarResult, NULL, NULL); | ||
+ | } | ||
+ | |||
+ | HRESULT PutItem(IDispatch* array, ULONG index, VARIANT* pvarItem) { | ||
+ | VARIANT vargIndex = { .vt = VT_I4, .lVal = index }; | ||
+ | VARIANT rgvargArgs[] = { *pvarItem, vargIndex }; | ||
+ | DISPPARAMS dpPut = { .cArgs = 2, .cNamedArgs = 0, .rgvarg = rgvargArgs }; | ||
+ | return array-> | ||
+ | array, DISPID_VALUE, | ||
+ | &dpPut, NULL, NULL, NULL); | ||
+ | } | ||
+ | |||
+ | HRESULT partition(IDispatch *array, ULONG lo, ULONG hi, ULONG* newPartition) { | ||
+ | HRESULT result = E_FAIL; | ||
+ | |||
+ | VARIANT varHi = { .vt = VT_EMPTY }; | ||
+ | VARIANT varI = { .vt = VT_EMPTY }; | ||
+ | VARIANT varJ = { .vt = VT_EMPTY }; | ||
+ | |||
+ | // Use highest index value as pivot | ||
+ | if (S_OK != GetItem(array, | ||
+ | |||
+ | ULONG i = lo; | ||
+ | for (ULONG j = lo; j < hi; j++) { | ||
+ | if (S_OK != GetItem(array, | ||
+ | // lcid = LOCALE_INVARIANT, | ||
+ | if ( | ||
+ | (varJ.vt != varHi.vt) ? (varJ.vt <= varHi.vt) : | ||
+ | VarCmp(& | ||
+ | if (S_OK != GetItem(array, | ||
+ | if (S_OK != PutItem(array, | ||
+ | if (S_OK != PutItem(array, | ||
+ | i = i + 1; | ||
+ | VariantClear(& | ||
+ | } | ||
+ | VariantClear(& | ||
+ | } | ||
+ | |||
+ | // Center the pivot value | ||
+ | if (S_OK != GetItem(array, | ||
+ | if (S_OK != PutItem(array, | ||
+ | if (S_OK != PutItem(array, | ||
+ | |||
+ | *newPartition = i; | ||
+ | result = S_OK; | ||
+ | |||
+ | fail: | ||
+ | VariantClear(& | ||
+ | VariantClear(& | ||
+ | VariantClear(& | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | MCL_EXPORT(quicksort, | ||
+ | HRESULT quicksort(IDispatch *array, ULONG lo, ULONG hi) { | ||
+ | if (lo >= hi) return S_OK; | ||
+ | ULONG p = 0; | ||
+ | if (S_OK != partition(array, | ||
+ | if (S_OK != quicksort(array, | ||
+ | if (S_OK != quicksort(array, | ||
+ | return S_OK; | ||
+ | } | ||
+ | |||
+ | )") | ||
+ | |||
+ | x := [" | ||
+ | |||
+ | MsgBox " | ||
+ | |||
+ | lib.quicksort(ObjPtr(x), | ||
+ | |||
+ | MsgBox "After Sorting: " JSON.Dump(x) | ||
</ | </ | ||