c++ Addin attempt

Valued Contributor
Valued Contributor

 

I'm trying to get the document type in the BeforeDocumentSave event.  Could anyone give me a clue?

theDocument is defined in the event procedure as type LPDISPATCH.  What does that mean?  I'm a VB guy (sometimes).  c++ is new to me. 

 

Thanks,

Mike

HRESULT CEventManager::XApplicationEvents::raw_BeforeDocumentSave( LPDISPATCH theDocument )

{

    switch (theDocument->Type)

    {

        case SolidEdgeConstants::igPartDocument:

            //Do something

            break;

        case SolidEdgeConstants::igDraftDocument:

            //Do something else

            break;

 

    }

 

 

    return E_NOTIMPL;

}

 

Posted by: Michael Frayser
Post date: 9/10/2008 10:06:25 AM

8 REPLIES

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

 

Hi Mike,

 

LPDISPATCH is the same as IDispatch* or IDispatchPtr. They are all pointers to a dispatch (late-binding) interface - hence Long Pointer to DISPATCH.

To get a pointer to a SolidEdgeDocument interface you need to do something like this:

 SolidEdgeDocumentPtr doc = NULL; /* Or SolidEdgeDocument* but then you're responsible for releasing the pointer */

HRESULT hr = theDocument->QueryInterface(&doc);

if (FAILED(hr)) return hr;

 

switch (doc->Type)

{

case igPartDocument:

/* Do Something, but don't forget the 'break' below */

break;

case ig...

break;

default:

break;

}

Hope this helps Calum

 

Posted by: Calum McLellan
Post date: 9/10/2008 10:30:15 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

 

Thanks for the (super) quick reply!  I'll give it a shot!

 

 

Posted by: Michael Frayser
Post date: 9/10/2008 10:46:31 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

 

I tried using this code:

HRESULT CEventManager::XApplicationEvents::raw_BeforeDocumentSave( LPDISPATCH theDocument )

{

    SolidEdgeDocumentPtr doc = NULL;

    HRESULT hr = theDocument->QueryInterface(&doc);

    if (FAILED(hr)) return hr;

 

    switch (doc->Type)

    {

        case igPartDocument:

            //Do something

            break;

        case igDraftDocument:

            //Do something else

            break;

        default:

            //Do something else

            break;

    }

 

    return E_NOTIMPL;

}

 

If I set breakpoints at the case statements (& default), it doesn't appear that they ever get hit.  If I set a breakpoint at the switch statement, I can step thru some code until I get into a framework.tli, then the debugger tells me there is no more code to step into.  Did I mess up some syntax somewhere?

 

 

Posted by: Michael Frayser
Post date: 9/10/2008 11:21:42 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

Hi Mike,

 

Sorry for the late reply.

If you fill out the case blocks with code then you should be able to set breakpoints there, otherwise the debugger just jumps over them. If you want to avoid stepping into other files or methods (eg framewrk.tli) then use the 'Step Over' command (the middle of the three step buttons in the Visual Studio IDE).

 

Try adding this to 'case igPartDocument' and let me know if the debugger breaks on the line:

 

doc->Application->PutCaption(_bstr_t(L"Test"));

 

Cheers

Calum

 

Posted by: Calum McLellan
Post date: 9/13/2008 9:18:21 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

You can save a bit of code using the "smart pointer". Try this:

 

SolidEdgeDocumentPtr doc = theDocument; // this should always work as it is independent of the exact doc type

DocumentTypeConstants nType = doc->Type;

 

If you want a document specific interface you can also simply use the typed interfaces (the smart pointer sees the "=" and does the query for you) for a particular doc interface.

 

PartDocumentPtr pPart = theDocument;

AssemblyDocumentPtr pAsm = theDocument;

 

if( NULL != pPart )

{

// I have a part doc

}

else if( NULL != pAsm )

{

// I have an asm doc

}

 

 

Of you might find this useful although is precedes smart pointers so it is a bit archaic.

 

// This routine returns the document type given the dispatch of a Solid Edge document.

// Returns E_INVALIDARG if pDocDispatch is NULL. Otherwise, returns the result from the Invoke

// method on that dispatch.

HRESULT GetDocType( LPDISPATCH pDocDispatch,

DocumentTypeConstants& nDocType )

{

HRESULT hr = NOERROR;

 

nDocType = igUnknownDocument;

 

try

{

if( NULL != pDocDispatch )

{

DISPID rgDispId = 0;

 

OLECHAR *Names[1] = {L"Type"};

 

hr = pDocDispatch->GetIDsOfNames( IID_NULL,

Names,

1,

LOCALE_USER_DEFAULT,

&rgDispId );

 

if( SUCCEEDED(hr) )

{

VARIANT varResult;

VariantInit(&varResult);

V_VT(&varResult) = VT_I4;

 

DISPPARAMS disp = { NULL, NULL, 0, 0 };

 

// Get the document type property.

hr = pDocDispatch->Invoke( rgDispId,

IID_NULL,

LOCALE_USER_DEFAULT,

DISPATCH_PROPERTYGET,

&disp,

&varResult,

NULL,

NULL );

if( SUCCEEDED(hr) )

{

nDocType = (DocumentTypeConstants)(V_I4(&varResult));

}

else

{

_com_issue_errorex(hr, pDocDispatch, __uuidof(pDocDispatch));

}

}

 

}

else

{

hr = E_INVALIDARG;

}

}

catch(_com_error &e)

{

hr = e.Error();

}

 

return hr;

}

 

Posted by: R.D. Holland
Post date: 9/18/2008 10:14:53 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

Thanks RD - I didn't know that the smart pointer interfaces did an implicit query. I'm not sure if I'll make use of it though (I kind of like to see where I'm doing a cast).

 

Cheers

Calum

 

Posted by: Calum McLellan
Post date: 9/18/2008 10:56:59 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

 

I don't think I would call what you are doing a cast (not in the c++ sense). The smart pointer assignment is more analagous to a true c++ dynamic_cast.

That is, if a dynamic_cast in c++ fails you end up with a null pointer (if casting a class pointer) and a smart pointer assignment will result in a null (interface) pointer if the underlying query fails.

In c++ a "static" cast of a pointer assignment never fails. But you never know what you really have!

 

Posted by: R.D. Holland
Post date: 9/18/2008 11:49:24 AM

RE: c++ Addin attempt

Valued Contributor
Valued Contributor

Hi RD,

I sort of classify everything that changes a variables type as a cast. In this case its just like 'as' in c# and TryCast in VB. The only reason I wouldn't do it is because that line of code would be easy to overlook when searching for a bug - it isn't immediately obvious that a null-check should follow. For the same reason I litter my code with static_cast(var) instead of (wchar_t*)var.

 

Posted by: Calum McLellan
Post date: 9/18/2008 8:04:08 PM