Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VB Code to C++ / COM

82 views
Skip to first unread message

Martin Schmid

unread,
Jun 4, 2004, 8:35:15 AM6/4/04
to
I have the following VBA example from an Automation Reference... can anyone
offer any insights on how I would convert this code to C++?

Dim object As AcadObject
Dim SchedApp As New AecScheduleApplication
Dim cPropSets As AecSchedulePropertySets
Dim PropSet As AecSchedulePropertySet
Dim cProps As AecScheduleProperties
Dim prop As AecScheduleProperty
Dim count As Integer

For Each object In ThisDrawing.ModelSpace
If TypeOf object Is AecDoor Then
count = count + 1
Set cPropSets = SchedApp.PropertySets(object)

If (cPropSets.count > 0) Then
Set PropSet = cPropSets.Item(0)
Set cProps = PropSet.Properties
Set prop = cProps.Item(0)
MsgBox "Door " & count & "'s Property Set 1 Property 1's
Value is: " & prop.Value, vbInformation, "Value Example"
Else
MsgBox "No Property Sets Attached to Door", vbInformation,
"Value Example"
End If
End If
Next

If (count = 0) Then
MsgBox "No Doors in Drawing", vbInformation, "Value Example"
End If


--
Thanks,
Martin Schmid, EIT, CCSA, MCDBA, MCSE


Martin Schmid

unread,
Jun 4, 2004, 8:45:45 AM6/4/04
to
I've gotten this far:
CAecScheduleApplication* sa=new CAecScheduleApplication;
CAecSchedulePropertySets sPropSets;
CAecSchedulePropertySet sPropSet;
CAecScheduleProperties sProps;
CAecScheduleProperty sProp;

sa->PropertySets(pObj);

delete sa;

But I get stuck.... the line sa->PropertySets(pObj); errors when
compiling:
error C2664: 'CAecScheduleApplication::PropertySets' : cannot convert
parameter 1 from 'AcDbObject *' to 'LPDISPATCH'
Which I expect... pObj is for type AcDbObject*... I guess my first question
is how to get an LPDISPATCH from an AcDbObject (what is an LPDISPATCH?)

--
Thanks,
Martin Schmid, EIT, CCSA, MCDBA, MCSE

"Martin Schmid" <mxrtxn...@sbcglxbxl.nxt> wrote in message
news:%23KZCpBj...@TK2MSFTNGP10.phx.gbl...

Martin Schmid

unread,
Jun 4, 2004, 9:10:55 AM6/4/04
to
I found this:

HRESULT hr;

hr=AcAxGetIUnknownOfObject(LPUNKNOWN* ppUnk, AcDbObjectId& objId,

LPDISPATCH pApp);

Is this on the right track.. I.e., how do I get the LPDISPATCH pApp, and is
LPUNKNOWN the same as an LPDISPATCH?


--
Thanks,
Martin Schmid, EIT, CCSA, MCDBA, MCSE
"Martin Schmid" <mxrtxn...@sbcglxbxl.nxt> wrote in message

news:OGKcgHjS...@tk2msftngp13.phx.gbl...

Simon Trew

unread,
Jun 4, 2004, 11:09:05 AM6/4/04
to
"Martin Schmid" <mxrtxn...@sbcglxbxl.nxt> wrote in message
news:ePKjkVjS...@TK2MSFTNGP09.phx.gbl...

> I found this:
>
> HRESULT hr;
>
> hr=AcAxGetIUnknownOfObject(LPUNKNOWN* ppUnk, AcDbObjectId& objId,
>
> LPDISPATCH pApp);
>
> Is this on the right track.. I.e., how do I get the LPDISPATCH pApp, and
is
> LPUNKNOWN the same as an LPDISPATCH?

LPUNKNOWN = IUnknown*
LPDISPATCH = IDispatch*

IDispatch is derived from IUnknown, as are all COM interfaces. To get one
interface from another, use QueryInterface defined by IUnknown:

LPDISPATCH pMyInterfaceDisp;
HRESULT hr = pMyInterface->QueryInterface(IID_IDispatch,
reinterpret_cast<void**>(&pDisp));
if (SUCCEEDED(hr))
{
// use pDisp in some way...
// remember to release the interface pointer
pDisp->Release();
}

IDispatch is the interface used for "late binding" in VBA, etc. It offers a
way to Invoke() methods on the object and find out what exists (via
GetTypeInfo() and GetIDsOfNames()) at run time. From C++, if you know the
specific interfaces you are dealing with, you are better off using those--
they are quicker, and you don't have to wrap up all your parameters into a
form that Invoke() can understand.

Consider using smart pointer types _com_ptr_t<IDispatch> (typedef'd as
IDispatchPtr) or ATL's CComPtr<IDispatch> which handle reference counting
(AddRef and Release) for you (most of the time).

S.


Simon Trew

unread,
Jun 4, 2004, 12:42:10 PM6/4/04
to
I should perhaps also have mentioned that _com_ptr_t and ATL's CComQIPtr
will wrap the calls to QueryInterface for you.

S.


Martin Schmid

unread,
Jun 5, 2004, 10:22:53 AM6/5/04
to
I appreciate you trying to help, but I am completely lost.

Can you take a step back, and see if you can follow the original VBA code
and offer any tips on how to write it as C++?

--
Thanks,
Martin Schmid, EIT, CCSA, MCDBA, MCSE

"Simon Trew" <noneo...@business.guv> wrote in message
news:efYFiXkS...@TK2MSFTNGP09.phx.gbl...

Simon Trew

unread,
Jun 7, 2004, 5:38:01 AM6/7/04
to
"Martin Schmid" <mxrtxn...@sbcglxbxl.nxt> wrote in message
news:uXzSeiw...@TK2MSFTNGP11.phx.gbl...

> I appreciate you trying to help, but I am completely lost.
>
> Can you take a step back, and see if you can follow the original VBA code
> and offer any tips on how to write it as C++?
>
> --
> Thanks,
> Martin Schmid, EIT, CCSA, MCDBA, MCSE

OK, something like this (not tested or compiled obviously)

// Import the ACAD DLL or tlb
#import "YourDLLNameHere.dll" no_namespace

// The declarations

IAcadObjectPtr object;
IAecScheduleApplicationPtr SchedApp;
IAecSchedulePropertySetsPtr cPropSets;
IAecSchedulePropertySetPtr PropSet;
IAecSchedulePropertiesPtr cProps;
IAcSchedulePropertyPtr prop;
long count;

// Create the app object
HRESULT hr = SchedApp.CreateInstance(CLSID_SchedApp);
if (FAILED(hr)) _com_issue_error(hr);

// Get the IEnumVariant on ModelSpace to do the "for each"
// presumable ThisDrawing is passed as a parameter to this code
// (otherwise I don't know where it might be got from)
VARIANT varEnum;
static DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
hr = ThisDrawing->ModelSpace->Invoke( DISPID_NEWENUM, IID_NULL,
LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, &varEnum, NULL,
NULL);
typedef _com_ptr_t<IEnumVARIANT> IEnumVariantPtr;
IEnumVariantPtr objectEnum;
hr = varEnum.punkVal->QueryInterface(__uuidof(IEnumVARIANT),
reinterpret_cast<void**>(&objectEnum));
if (FAILED(hr)) _com_issue_error(hr);

// Now loop...
for (_variant_t vObject; objectEnum->Next(1, &vObject, NULL) == S_OK; )
{
// typeof- first convert to an object
hr = ::VariantChangeType(&vObject, &vObject, 0, VT_UNKNOWN);
if (SUCCEEDED(hr))
{
// typeof-- now see if it supports door
IAecDoorPtr pDoor;
hr = vObject.punkVal->QueryInterace(__uuidof(IAecDoor),
reintrepret_cast<void**>(&pDoor));
if (SUCCEEDED(hr))
{
++count;
cPropSets = SchedApp->PropertySets(pDoor);
if (cPropSets->GetCount() > 0)
{
PropSet = cPropSets->GetItem(0);
cProps = PropSet->GetProperties();
prop = cProps.GetItem(0);
// message text creation omitted for brevity
}
else
{
::MessageBox(::GetActiveWindow(), _T("No property sets attached to
door"), _T("Value Example"), MB_ICONINFORMATION | MB_OK);
}
} // end if type is door
} // end if is an object
} // end for loop

if (count == 0)
{
::MessageBox(::GetActiveWindow(), _T("No Doors in Drawing"), _T("Value
Example"), MB_ICONINFORMATION | MB_OK);
}

Martin Schmid

unread,
Jun 7, 2004, 9:27:15 AM6/7/04
to
Thanks! I'll have to study it when I get a chance.

--
Thanks,
Martin Schmid, EIT, CCSA, MCDBA, MCSE

"Simon Trew" <noneo...@business.guv> wrote in message

news:uAjLfMHT...@TK2MSFTNGP10.phx.gbl...

0 new messages