**Using a122
I've had a similar issue recently with byref outputs and scintilla messages, and I'm sure it's because I don't totally grasp the memory operations taking place.
I'm using COM to interact with AutoCAD, and I've been able to send values through COM to CAD no problem. Output from CAD->AHK has been another story. I need to use the following method to retrieve an entity's XData (VBA signature shown):
;;Note: VT Defined Externally as an Enum Class and included in script (e.g. VT_R8->VT.R8)
#include %A_ScriptDir%\lib\VT.ahk
;;AutoCAD Enum Classes---------------------------------------------------
;;These values were found by evaluating the constants in autoLISP -> '!acSelectionSetWindow', etc.
;;For use with <AcadSelectionSet>.Select()
class acSelectionSet {
static Window[] => 0
static Crossing[] => 1
static Previous[] => 3
static Last[] => 4
static All[] => 5
}
;;-----------------------------------------------------------------------
;;Get a reference to the active CAD instance using the appropriate version
ACAD_VERSION := 23
ACAD := ComObjActive("AutoCAD.Application." . ACAD_VERSION)
try {
;;Delete the selection set named 'ALL' if it exists
;;If it doesn't exist, fail quietly (dangerous game, I know) and continue
ACAD.ActiveDocument.SelectionSets("ALL").Delete()
}
;;Now create the set named 'ALL' and select all entities
allEnts := ACAD.ActiveDocument.SelectionSets.Add("ALL")
allEnts.Select(acSelectionSet.All)
;;Loop through the ents
for e in allEnts {
;;If the entity is a line, take a look at its xdata
if(COMObjType(e,"class")="AcadLine"){
;;Number of xdata items to return - I won't typically know this ahead of time
xCount := 6
;;xTypes will be an array of shorts
xTypes := ComObjArray(VT.I2, xCount)
wxTypes := COMObject(VT.BYREF|VT.ARRAY|VT.I2,xTypes.ptr)
;;xData will be an array of variants
xData := ComObjArray(VT.VARIANT, xCount)
wxData := COMObject(VT.BYREF|VT.ARRAY|VT.VARIANT,xData.ptr)
;;Wrapped the pointers as byref, typed COMObjects to pass to AcadEntity.getXData
e.getXData("TEST_APP", wxTypes, wxData)
;;Take a peek to see if we got valid results
typesStr:="Types Results:"
for val in xTypes {
typesStr.=" " . val
}
msgbox(typesStr)
dataStr:="Data Results:"
for val in xData {
dataStr.=" " . val
}
msgbox(dataStr)
}
}
More generally, here's where I could use guidance:
I need a safearray of a given type of data (e.g. VT_VARIANT or VT_I2).
This has to be passed to a COM object's method byref to be used as an output -> I need a pointer (in a COM acceptable form) to the safearray.
I've seen the examples that call BufferAlloc() to create a buffer of appropriate size, then wrap the buffer.ptr in a ComObject(VT_BYREF|etc.) call before passing it to the method.
My data type or buffer size is probably incorrect, so I'm not having any luck.
In short:
1. How much memory do I buffer for an array? Perhaps (# of entries)*(bytes per entry)?
2. Would COMObject(VT_BYREF|VT_ARRAY|VT_VARIANT, buff.ptr) denote a reference to an array of variants? If not, what is the appropriate type here?