Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Addin using Delphi

4 REPLIES 4
Reply
Message 1 of 5
Anonymous
926 Views, 4 Replies

Addin using Delphi

Has anyone implemented an addin using Delphi ?

Could anyone point me at some sample code ?

Thanks
Nick
4 REPLIES 4
Message 2 of 5
Anonymous
in reply to: Anonymous

Hi Nick,
I am now trying to create an addin since one week but its a hard job and I
have the feeling that I will give up soon and programm with VB6.

Here the points for Delphi 6 SP1 using IV 5.3 SP1 (all german versions, but
it schould work international):

- Create an ActiveX Library Projekt
- Import the "Autodesk Inventor Object Type Library"
and have the first problem: the import is not correct. Look for the
Interface:

ApplicationAddInSite = dispinterface
['{E3571299-DB40-11D2-B783-0060B0F159EF}']
property Type_: ObjectTypeEnum readonly dispid 0;
property Application: Application readonly dispid 50336769;
function CreateCommand(const CommandName: WideString; CommandID:
Integer;
InstallInTools: OleVariant):Command; dispid
1610678274;
end;

and add the missing line "function CreateCommand.....dispid 1610678274;"

I don't know if it is the only mistake, but it is an important.

- Now create a new Com-Object and choose in the dialog under "implementing
interface" the Interface

"_IRxApplicationAddInServer"


Here is the code you have to Add to the new Object:

//this is added by the com object wizard
type
TTAppAddInServ = class(TAutoObject, _IRxApplicationAddInServer)
protected
function Activate(const AddInSiteObject: ApplicationAddInSite;
FirstTime: WordBool): HResult; stdcall;
function Deactivate: HResult; stdcall;
function ExecuteCommand(CommandID: Integer): HResult; stdcall;
function Get_Automation(out AutomationPtr: AddInAutomation): HResult;
stdcall;
{ Protected-Deklarationen }
end;



var
oInventor : Inventor_TLB.Application;
oCmd1 : Inventor_TLB.Command;

implementation

uses ComServ;


function TTAppAddInServ.Activate(const AddInSiteObject:
ApplicationAddInSite; FirstTime: WordBool): HResult;
begin
//init
AppDefault := InitApplication;
//get the InventorObject
oInventor := AddInSiteObject.Application;

//Create commands
oCmd1 := AddInSiteObject.CreateCommand('My Add In Command',1,True);

Result := S_OK;
end;

function TTAppAddInServ.Deactivate: HResult;
begin
//CleanUp
oInventor := nil;
oCmd1 := nil;
Result := S_OK;
end;

function TTAppAddInServ.ExecuteCommand(CommandID: Integer): HResult;

begin
Case CommandID of
1: begin
//here your Code for your command
end;
end;
Result := S_OK;
end;

function TTAppAddInServ.Get_Automation(
out AutomationPtr: AddInAutomation): HResult;
begin
Result := E_NOINTERFACE;
end;

//this is added by the com object wizard
initialization
TAutoObjectFactory.Create(ComServer, TTAppAddInServ, Class_TAppAddInServ,
ciMultiInstance, tmApartment);
end.



That's the base for an addin. Registering the addin is the same as for VB,
shown in the SDK documentation. Use the GUID from the CoClass created by the
ActiveX Library Projekt Wizard.


All other stuff is "normal" COM-programming. To avoid trouble getting the
events done, you should use the Event Sink Importer from Binh Ly:
http://www.techvanguards.com/ There is also a "TypeExport" which creates a
more correct Version of "invetor_TLB.pas".

But, as i said, its hard to code. Till now, I don't get the interactive
selection part working. Also there is trouble with dynamic string arrays
getting via OLEVariant.

greetings from berlin, germany
Jörgen


"Nick Hall" schrieb im Newsbeitrag
news:Xns91E74087BFE4Bnickhallaltasystems@64.124.46.110...
> Has anyone implemented an addin using Delphi ?
>
> Could anyone point me at some sample code ?
>
> Thanks
> Nick
Message 3 of 5
Anonymous
in reply to: Anonymous

Hi Nick and Jörgen,

It *is* possible to create an add-in using Borland tools, but it isn't easy!
After fighting the MS Visual C++ compiler (not even close to ANSI compliant)
I finally went back to Borland C++ and figured out how to make it work.

The issues will be the same, but you will have to translate to Delphi
Pascal, I'm not familiar enough with it to tell you exactly how to do it.

Now here is the main problem:

You want to implement one of two interfaces which Inventor will attempt to
call on startup:
- "ApplicationAddInServer" (a dispatch interface, primarily for Visual
Basic) or
- "IRxApplicationAddInServer" (a custom interface).

Note that "_IRxApplicationAddInServer" is an internal interface which you
are not supposed to use, and it WILL NOT BE CALLED by Inventor on startup,
so your code will never run. (In general, you should not use any interfaces
that begin with an underscore, as Autodesk makes no commitment to their
continuity.)

Unfortunately, the Borland inport tool will not offer to let you implement
either of those interfaces! (IRxApplicationAddInServer is a custom
interface, so I don't know why it doesn't work, maybe because the
"OLEAutomation" flag isn't set.)

The work-around is to select "_IRxApplicationAddInServer" as the interface
you are implementing, and then manually patch up the code to implement
"IRxApplicationAddInServer" instead.

- Create an ActiveX Library Project
- Import the "Autodesk Inventor Object Type Library"
- Now create a new COM Object and choose in the dialog under "implementing
interface" the interface "_IRxApplicationAddInServer"

To patch up the code, you must do three things:

1) The implementation class must inherit from IRxApplicationAddInServer, not
_IRxApplicationAddInServer: I used a global search and replace in the
editor.

2) The interfaces of the methods Activate, Deactivate, ExecuteCommand, and
get_Automation must be changed to match the signatures for the
IRxApplicationAddInServer class instead of those for
_IRxApplicationAddInServer class. A file which defines the interfaces
should have been created during the import of the type library, in C++ it is
named "Inventor_TLB.h"

3) Add implementation code for the methods Activate, Deactivate,
ExecuteCommand, and get_Automation.

This is what it looks like in C++ before and after modification. I've
deleted blocks of code that are not changed. Also note that Borland C++
Builder renames some interfaces during the import to avoid conflicts with
Borland VCL classes, in particular the Application class is renamed to
"App".

Also note (to give credit where it's due) some of the code is copied from
the Inventor Application Wizard for Visual C++.



******************** LrTestAddInImpl.h -- Before Modification
**********************************************

// LRTESTADDINIMPL.H : Declaration of the TLrTestAddInImpl
. . . . . .

////////////////////////////////////////////////////////////////////////////
/
// TLrTestAddInImpl Implements _IRxApplicationAddInServer, default
interface of LrTestAddIn
// ThreadingModel : Apartment
// Dual Interface : FALSE
// Event Support : FALSE
// Default ProgID : TestInventorAddIn.LrTestAddIn
// Description : Example Code to make an Inventor Add In
////////////////////////////////////////////////////////////////////////////
/
class ATL_NO_VTABLE TLrTestAddInImpl :
public CComObjectRootEx,
public CComCoClass,
public _IRxApplicationAddInServer
{
public:
TLrTestAddInImpl() {}
. . . . . .

BEGIN_COM_MAP(TLrTestAddInImpl)
COM_INTERFACE_ENTRY(_IRxApplicationAddInServer)
END_COM_MAP()

// _IRxApplicationAddInServer
public:

STDMETHOD(Activate(ApplicationAddInSitePtr AddInSiteObject,
TOLEBOOL FirstTime));
STDMETHOD(Deactivate());
STDMETHOD(ExecuteCommand(long CommandID));
STDMETHOD(get_Automation(AddInAutomationPtr* AutomationPtr));
};

#endif //LrTestAddInImplH


******************** LrTestAddInImpl.cpp -- Before Modification
**********************************************

// LRTESTADDINIMPL : Implementation of TLrTestAddInImpl (CoClass:
LrTestAddIn, Interface: _IRxApplicationAddInServer)
. . . . . .

STDMETHODIMP TLrTestAddInImpl::Activate(
ApplicationAddInSitePtr AddInSiteObject, TOLEBOOL FirstTime)
{
try
{

}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
}
return S_OK;
};


STDMETHODIMP TLrTestAddInImpl::Deactivate()
{
try
{

}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
}
return S_OK;
};


STDMETHODIMP TLrTestAddInImpl::ExecuteCommand(long CommandID)
{
try
{

}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
}
return S_OK;
};


STDMETHODIMP TLrTestAddInImpl::get_Automation(
AddInAutomationPtr* AutomationPtr)
{
try
{

}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
}
return S_OK;
};




******************** LrTestAddInImpl.h -- After Modification
**********************************************

// LRTESTADDINIMPL.H : Declaration of the TLrTestAddInImpl
. . . . . .

////////////////////////////////////////////////////////////////////////////
/
// TLrTestAddInImpl Implements IRxApplicationAddInServer, default
interface of LrTestAddIn
// ThreadingModel : Apartment
// Dual Interface : FALSE
// Event Support : FALSE
// Default ProgID : TestInventorAddIn.LrTestAddIn
// Description : Example Code to make an Inventor Add In
////////////////////////////////////////////////////////////////////////////
/
class ATL_NO_VTABLE TLrTestAddInImpl :
public CComObjectRootEx,
public CComCoClass,
public IRxApplicationAddInServer
// ^^^^^^^^^^^^^^^^^^^^^^^^^ Inherit from IRxApplicationAddInServer,
not _IRxApplicationAddInServer
{
public:
TLrTestAddInImpl() {}
. . . . . .

BEGIN_COM_MAP(TLrTestAddInImpl)
COM_INTERFACE_ENTRY(IRxApplicationAddInServer)
END_COM_MAP()

private:
CComPtr m_pSite;
CComPtr m_pApplication;

// Definitions of commands here.
CComPtr m_pCmdTestCommand;

// IRxApplicationAddInServer
public:

// **** Note changed signature in Activate and get_Automation. Signature
copied from Inventor_TLB.h

STDMETHOD(Activate(Inventor_tlb::IRxApplicationAddInSitePtr pAddInSite,
Inventor_tlb::BooleanType FirstTime) );
STDMETHOD(Deactivate());
STDMETHOD(ExecuteCommand(long CommandID));
STDMETHOD(get_Automation(LPUNKNOWN* ppUnk));

// Return the Rubicon Add-In Site of this object's attachment. (Some useful
inline functions)
const CComPtr Site() const
{ return m_pSite; }

// Return the Rubicon Application.
const CComPtr & Application() const
{ return m_pApplication; }

};

#endif //LrTestAddInImplH




******************** LrTestAddInImpl.cpp -- After Modification
**********************************************

// LRTESTADDINIMPL : Implementation of TLrTestAddInImpl (CoClass:
LrTestAddIn, Interface: IRxApplicationAddInServer)
. . . . . .

STDMETHODIMP TLrTestAddInImpl::Activate(
Inventor_tlb::IRxApplicationAddInSitePtr pAddInSite,
Inventor_tlb::BooleanType FirstTime)
{
try
{
HRESULT Result=NOERROR;
CComPtr pAppUnk, pCmdUnk;
TVariant vInTools(true);

// Add display names of commands here.
WideString bstrTestCommand("Test Command");

// High-level interfaces supplied directly and implicitly by Inventor to
the
// AddIn. These may be held right up until the directive to shutdown
(Deactivate) is received.

m_pSite = pAddInSite;

Result = pAddInSite->get_Application(&pAppUnk);
if( FAILED( Result ) ) goto wrapup;

Result = pAppUnk->QueryInterface (DIID_App, (void **) &m_pApplication);
if( FAILED( Result ) ) goto wrapup;

// TODO:
// This is where you would place any additional startup code.


// Create commands here.
//
Result = pAddInSite->CreateCommand(bstrTestCommand, 0, vInTools,
&pCmdUnk);
if( FAILED( Result ) ) goto wrapup;

Result = pCmdUnk->QueryInterface (DIID_Command, (void **)
&m_pCmdTestCommand);
if( FAILED( Result ) ) goto wrapup;

MessageBox( 0, "Test Command Activated", "Test Add-In", MB_OK );
return Result;

wrapup:
MessageBox( 0, "LrTestAddIn Activated With Errors", "Test Add-In",
MB_OK );
return Result;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
}
};


STDMETHODIMP TLrTestAddInImpl::Deactivate()
{
try
{
// Addin wizard destroys commands here
if (m_pCmdTestCommand.p)
{
m_pCmdTestCommand->Delete();
m_pCmdTestCommand.Release();
}

// Cleanup up of interfaces supplied by Inventor and held on by this
AddIn
// at initialization or load.

m_pApplication.Release();
m_pSite.Release();

return NOERROR;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
}
return S_OK;
};


STDMETHODIMP TLrTestAddInImpl::ExecuteCommand(long CommandID)
{
try
{
MessageBox( 0, "LrTestAddIn Execute", "Test Add-In", MB_OK );
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
}
return S_OK;
};


STDMETHODIMP TLrTestAddInImpl::get_Automation(LPUNKNOWN* ppUnk)
{
try
{
if (!ppUnk)
return E_INVALIDARG;
*ppUnk = NULL;

return E_NOINTERFACE;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
}
};



I hope this is enough to get you going. Good Luck!



"jpisarz" wrote in message
news:F5733EC568C0924A777F92CF64F91B03@in.WebX.maYIadrTaRb...
> Hi Nick,
> I am now trying to create an addin since one week but its a hard job and I
> have the feeling that I will give up soon and programm with VB6.
>
> Here the points for Delphi 6 SP1 using IV 5.3 SP1 (all german versions,
but
> it schould work international):
>
> - Create an ActiveX Library Projekt
> - Import the "Autodesk Inventor Object Type Library"
> and have the first problem: the import is not correct. Look for the
> Interface:
>
> ApplicationAddInSite = dispinterface
> ['{E3571299-DB40-11D2-B783-0060B0F159EF}']
> property Type_: ObjectTypeEnum readonly dispid 0;
> property Application: Application readonly dispid 50336769;
> function CreateCommand(const CommandName: WideString; CommandID:
> Integer;
> InstallInTools: OleVariant):Command; dispid
> 1610678274;
> end;
>
> and add the missing line "function CreateCommand.....dispid 1610678274;"
>
> I don't know if it is the only mistake, but it is an important.
>
> - Now create a new Com-Object and choose in the dialog under "implementing
> interface" the Interface
>
> "_IRxApplicationAddInServer"
>
>
> Here is the code you have to Add to the new Object:
>
> //this is added by the com object wizard
> type
> TTAppAddInServ = class(TAutoObject, _IRxApplicationAddInServer)
> protected
> function Activate(const AddInSiteObject: ApplicationAddInSite;
> FirstTime: WordBool): HResult; stdcall;
> function Deactivate: HResult; stdcall;
> function ExecuteCommand(CommandID: Integer): HResult; stdcall;
> function Get_Automation(out AutomationPtr: AddInAutomation): HResult;
> stdcall;
> { Protected-Deklarationen }
> end;
>
>
>
> var
> oInventor : Inventor_TLB.Application;
> oCmd1 : Inventor_TLB.Command;
>
> implementation
>
> uses ComServ;
>
>
> function TTAppAddInServ.Activate(const AddInSiteObject:
> ApplicationAddInSite; FirstTime: WordBool): HResult;
> begin
> //init
> AppDefault := InitApplication;
> //get the InventorObject
> oInventor := AddInSiteObject.Application;
>
> //Create commands
> oCmd1 := AddInSiteObject.CreateCommand('My Add In Command',1,True);
>
> Result := S_OK;
> end;
>
> function TTAppAddInServ.Deactivate: HResult;
> begin
> //CleanUp
> oInventor := nil;
> oCmd1 := nil;
> Result := S_OK;
> end;
>
> function TTAppAddInServ.ExecuteCommand(CommandID: Integer): HResult;
>
> begin
> Case CommandID of
> 1: begin
> //here your Code for your command
> end;
> end;
> Result := S_OK;
> end;
>
> function TTAppAddInServ.Get_Automation(
> out AutomationPtr: AddInAutomation): HResult;
> begin
> Result := E_NOINTERFACE;
> end;
>
> //this is added by the com object wizard
> initialization
> TAutoObjectFactory.Create(ComServer, TTAppAddInServ,
Class_TAppAddInServ,
> ciMultiInstance, tmApartment);
> end.
>
>
>
> That's the base for an addin. Registering the addin is the same as for VB,
> shown in the SDK documentation. Use the GUID from the CoClass created by
the
> ActiveX Library Projekt Wizard.
>
>
> All other stuff is "normal" COM-programming. To avoid trouble getting the
> events done, you should use the Event Sink Importer from Binh Ly:
> http://www.techvanguards.com/ There is also a "TypeExport" which creates
a
> more correct Version of "invetor_TLB.pas".
>
> But, as i said, its hard to code. Till now, I don't get the interactive
> selection part working. Also there is trouble with dynamic string arrays
> getting via OLEVariant.
>
> greetings from berlin, germany
> Jörgen
>
>
> "Nick Hall" schrieb im Newsbeitrag
> news:Xns91E74087BFE4Bnickhallaltasystems@64.124.46.110...
> > Has anyone implemented an addin using Delphi ?
> >
> > Could anyone point me at some sample code ?
> >
> > Thanks
> > Nick
>
>
Message 4 of 5
Anonymous
in reply to: Anonymous

Hi Larry,

You are right, using the "_IRx" Interfaces is not recommend by autodesk, I
read this a few days ago.
But the interface IS CALLED on startup, the code I'm using works.

The Problem for Delphi is, that it is much easier to use the dispatch
interface instead the custom interface. And the "_IRxApplicationAddInServer"
delivers a dispinterface for the InSiteObject.

COM Programming under Delphi is tricky. There are a lot of good wizards
producing easy code and work in background so for normal OLE Automation it
is very simple (i.e. using the Apprentice Server is as easy as using a
visual component). Leaving this way (and this is what happend for producing
add-ins) will the delphi-programmer kick in the real COM-world. And this is
a very different world.

After working 2 weeks on a program in Delphi (still problems with
interactive selection) I realized the same program in Visual Basic in one
day (working).

Yes, it *is* possible to create an add-in using Delphi, but only for people
with (a lot) experience in COM-programming.

I will use VB in future for add-ins and Delphi for apprentice server
applications. This is my personal "best time and money" solution.

greetings Jörgen







"Larry Robinson" schrieb im Newsbeitrag
news:652094C5289EF4E966742A0E4B303B3B@in.WebX.maYIadrTaRb...
> Hi Nick and Jörgen,
>
> It *is* possible to create an add-in using Borland tools, but it isn't
easy!
> After fighting the MS Visual C++ compiler (not even close to ANSI
compliant)
> I finally went back to Borland C++ and figured out how to make it work.
>
> The issues will be the same, but you will have to translate to Delphi
> Pascal, I'm not familiar enough with it to tell you exactly how to do it.
>
> Now here is the main problem:
>
> You want to implement one of two interfaces which Inventor will attempt to
> call on startup:
> - "ApplicationAddInServer" (a dispatch interface, primarily for Visual
> Basic) or
> - "IRxApplicationAddInServer" (a custom interface).
>
> Note that "_IRxApplicationAddInServer" is an internal interface which you
> are not supposed to use, and it WILL NOT BE CALLED by Inventor on startup,
> so your code will never run. (In general, you should not use any
interfaces
> that begin with an underscore, as Autodesk makes no commitment to their
> continuity.)
>
> Unfortunately, the Borland inport tool will not offer to let you implement
> either of those interfaces! (IRxApplicationAddInServer is a custom
> interface, so I don't know why it doesn't work, maybe because the
> "OLEAutomation" flag isn't set.)
>
> The work-around is to select "_IRxApplicationAddInServer" as the interface
> you are implementing, and then manually patch up the code to implement
> "IRxApplicationAddInServer" instead.
>
> - Create an ActiveX Library Project
> - Import the "Autodesk Inventor Object Type Library"
> - Now create a new COM Object and choose in the dialog under "implementing
> interface" the interface "_IRxApplicationAddInServer"
>
> To patch up the code, you must do three things:
>
> 1) The implementation class must inherit from IRxApplicationAddInServer,
not
> _IRxApplicationAddInServer: I used a global search and replace in the
> editor.
>
> 2) The interfaces of the methods Activate, Deactivate, ExecuteCommand, and
> get_Automation must be changed to match the signatures for the
> IRxApplicationAddInServer class instead of those for
> _IRxApplicationAddInServer class. A file which defines the interfaces
> should have been created during the import of the type library, in C++ it
is
> named "Inventor_TLB.h"
>
> 3) Add implementation code for the methods Activate, Deactivate,
> ExecuteCommand, and get_Automation.
>
> This is what it looks like in C++ before and after modification. I've
> deleted blocks of code that are not changed. Also note that Borland C++
> Builder renames some interfaces during the import to avoid conflicts with
> Borland VCL classes, in particular the Application class is renamed to
> "App".
>
> Also note (to give credit where it's due) some of the code is copied from
> the Inventor Application Wizard for Visual C++.
>
>
>
> ******************** LrTestAddInImpl.h -- Before Modification
> **********************************************
>
> // LRTESTADDINIMPL.H : Declaration of the TLrTestAddInImpl
> . . . . . .
>
>
////////////////////////////////////////////////////////////////////////////
> /
> // TLrTestAddInImpl Implements _IRxApplicationAddInServer, default
> interface of LrTestAddIn
> // ThreadingModel : Apartment
> // Dual Interface : FALSE
> // Event Support : FALSE
> // Default ProgID : TestInventorAddIn.LrTestAddIn
> // Description : Example Code to make an Inventor Add In
>
////////////////////////////////////////////////////////////////////////////
> /
> class ATL_NO_VTABLE TLrTestAddInImpl :
> public CComObjectRootEx,
> public CComCoClass,
> public _IRxApplicationAddInServer
> {
> public:
> TLrTestAddInImpl() {}
> . . . . . .
>
> BEGIN_COM_MAP(TLrTestAddInImpl)
> COM_INTERFACE_ENTRY(_IRxApplicationAddInServer)
> END_COM_MAP()
>
> // _IRxApplicationAddInServer
> public:
>
> STDMETHOD(Activate(ApplicationAddInSitePtr AddInSiteObject,
> TOLEBOOL FirstTime));
> STDMETHOD(Deactivate());
> STDMETHOD(ExecuteCommand(long CommandID));
> STDMETHOD(get_Automation(AddInAutomationPtr* AutomationPtr));
> };
>
> #endif //LrTestAddInImplH
>
>
> ******************** LrTestAddInImpl.cpp -- Before Modification
> **********************************************
>
> // LRTESTADDINIMPL : Implementation of TLrTestAddInImpl (CoClass:
> LrTestAddIn, Interface: _IRxApplicationAddInServer)
> . . . . . .
>
> STDMETHODIMP TLrTestAddInImpl::Activate(
> ApplicationAddInSitePtr AddInSiteObject, TOLEBOOL FirstTime)
> {
> try
> {
>
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
> }
> return S_OK;
> };
>
>
> STDMETHODIMP TLrTestAddInImpl::Deactivate()
> {
> try
> {
>
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
> }
> return S_OK;
> };
>
>
> STDMETHODIMP TLrTestAddInImpl::ExecuteCommand(long CommandID)
> {
> try
> {
>
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
> }
> return S_OK;
> };
>
>
> STDMETHODIMP TLrTestAddInImpl::get_Automation(
> AddInAutomationPtr* AutomationPtr)
> {
> try
> {
>
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID__IRxApplicationAddInServer);
> }
> return S_OK;
> };
>
>
>
>
> ******************** LrTestAddInImpl.h -- After Modification
> **********************************************
>
> // LRTESTADDINIMPL.H : Declaration of the TLrTestAddInImpl
> . . . . . .
>
>
////////////////////////////////////////////////////////////////////////////
> /
> // TLrTestAddInImpl Implements IRxApplicationAddInServer, default
> interface of LrTestAddIn
> // ThreadingModel : Apartment
> // Dual Interface : FALSE
> // Event Support : FALSE
> // Default ProgID : TestInventorAddIn.LrTestAddIn
> // Description : Example Code to make an Inventor Add In
>
////////////////////////////////////////////////////////////////////////////
> /
> class ATL_NO_VTABLE TLrTestAddInImpl :
> public CComObjectRootEx,
> public CComCoClass,
> public IRxApplicationAddInServer
> // ^^^^^^^^^^^^^^^^^^^^^^^^^ Inherit from IRxApplicationAddInServer,
> not _IRxApplicationAddInServer
> {
> public:
> TLrTestAddInImpl() {}
> . . . . . .
>
> BEGIN_COM_MAP(TLrTestAddInImpl)
> COM_INTERFACE_ENTRY(IRxApplicationAddInServer)
> END_COM_MAP()
>
> private:
> CComPtr m_pSite;
> CComPtr m_pApplication;
>
> // Definitions of commands here.
> CComPtr m_pCmdTestCommand;
>
> // IRxApplicationAddInServer
> public:
>
> // **** Note changed signature in Activate and get_Automation. Signature
> copied from Inventor_TLB.h
>
> STDMETHOD(Activate(Inventor_tlb::IRxApplicationAddInSitePtr pAddInSite,
> Inventor_tlb::BooleanType FirstTime) );
> STDMETHOD(Deactivate());
> STDMETHOD(ExecuteCommand(long CommandID));
> STDMETHOD(get_Automation(LPUNKNOWN* ppUnk));
>
> // Return the Rubicon Add-In Site of this object's attachment. (Some
useful
> inline functions)
> const CComPtr Site() const
> { return m_pSite; }
>
> // Return the Rubicon Application.
> const CComPtr & Application() const
> { return m_pApplication; }
>
> };
>
> #endif //LrTestAddInImplH
>
>
>
>
> ******************** LrTestAddInImpl.cpp -- After Modification
> **********************************************
>
> // LRTESTADDINIMPL : Implementation of TLrTestAddInImpl (CoClass:
> LrTestAddIn, Interface: IRxApplicationAddInServer)
> . . . . . .
>
> STDMETHODIMP TLrTestAddInImpl::Activate(
> Inventor_tlb::IRxApplicationAddInSitePtr pAddInSite,
> Inventor_tlb::BooleanType FirstTime)
> {
> try
> {
> HRESULT Result=NOERROR;
> CComPtr pAppUnk, pCmdUnk;
> TVariant vInTools(true);
>
> // Add display names of commands here.
> WideString bstrTestCommand("Test Command");
>
> // High-level interfaces supplied directly and implicitly by Inventor to
> the
> // AddIn. These may be held right up until the directive to shutdown
> (Deactivate) is received.
>
> m_pSite = pAddInSite;
>
> Result = pAddInSite->get_Application(&pAppUnk);
> if( FAILED( Result ) ) goto wrapup;
>
> Result = pAppUnk->QueryInterface (DIID_App, (void **)
&m_pApplication);
> if( FAILED( Result ) ) goto wrapup;
>
> // TODO:
> // This is where you would place any additional startup code.
>
>
> // Create commands here.
> //
> Result = pAddInSite->CreateCommand(bstrTestCommand, 0, vInTools,
> &pCmdUnk);
> if( FAILED( Result ) ) goto wrapup;
>
> Result = pCmdUnk->QueryInterface (DIID_Command, (void **)
> &m_pCmdTestCommand);
> if( FAILED( Result ) ) goto wrapup;
>
> MessageBox( 0, "Test Command Activated", "Test Add-In", MB_OK );
> return Result;
>
> wrapup:
> MessageBox( 0, "LrTestAddIn Activated With Errors", "Test Add-In",
> MB_OK );
> return Result;
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
> }
> };
>
>
> STDMETHODIMP TLrTestAddInImpl::Deactivate()
> {
> try
> {
> // Addin wizard destroys commands here
> if (m_pCmdTestCommand.p)
> {
> m_pCmdTestCommand->Delete();
> m_pCmdTestCommand.Release();
> }
>
> // Cleanup up of interfaces supplied by Inventor and held on by this
> AddIn
> // at initialization or load.
>
> m_pApplication.Release();
> m_pSite.Release();
>
> return NOERROR;
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
> }
> return S_OK;
> };
>
>
> STDMETHODIMP TLrTestAddInImpl::ExecuteCommand(long CommandID)
> {
> try
> {
> MessageBox( 0, "LrTestAddIn Execute", "Test Add-In", MB_OK );
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
> }
> return S_OK;
> };
>
>
> STDMETHODIMP TLrTestAddInImpl::get_Automation(LPUNKNOWN* ppUnk)
> {
> try
> {
> if (!ppUnk)
> return E_INVALIDARG;
> *ppUnk = NULL;
>
> return E_NOINTERFACE;
> }
> catch(Exception &e)
> {
> return Error(e.Message.c_str(), IID_IRxApplicationAddInServer);
> }
> };
>
>
>
> I hope this is enough to get you going. Good Luck!
>
>
>
> "jpisarz" wrote in message
> news:F5733EC568C0924A777F92CF64F91B03@in.WebX.maYIadrTaRb...
> > Hi Nick,
> > I am now trying to create an addin since one week but its a hard job and
I
> > have the feeling that I will give up soon and programm with VB6.
> >
> > Here the points for Delphi 6 SP1 using IV 5.3 SP1 (all german versions,
> but
> > it schould work international):
> >
> > - Create an ActiveX Library Projekt
> > - Import the "Autodesk Inventor Object Type Library"
> > and have the first problem: the import is not correct. Look for the
> > Interface:
> >
> > ApplicationAddInSite = dispinterface
> > ['{E3571299-DB40-11D2-B783-0060B0F159EF}']
> > property Type_: ObjectTypeEnum readonly dispid 0;
> > property Application: Application readonly dispid 50336769;
> > function CreateCommand(const CommandName: WideString; CommandID:
> > Integer;
> > InstallInTools: OleVariant):Command; dispid
> > 1610678274;
> > end;
> >
> > and add the missing line "function CreateCommand.....dispid 1610678274;"
> >
> > I don't know if it is the only mistake, but it is an important.
> >
> > - Now create a new Com-Object and choose in the dialog under
"implementing
> > interface" the Interface
> >
> > "_IRxApplicationAddInServer"
> >
> >
> > Here is the code you have to Add to the new Object:
> >
> > //this is added by the com object wizard
> > type
> > TTAppAddInServ = class(TAutoObject, _IRxApplicationAddInServer)
> > protected
> > function Activate(const AddInSiteObject: ApplicationAddInSite;
> > FirstTime: WordBool): HResult; stdcall;
> > function Deactivate: HResult; stdcall;
> > function ExecuteCommand(CommandID: Integer): HResult; stdcall;
> > function Get_Automation(out AutomationPtr: AddInAutomation):
HResult;
> > stdcall;
> > { Protected-Deklarationen }
> > end;
> >
> >
> >
> > var
> > oInventor : Inventor_TLB.Application;
> > oCmd1 : Inventor_TLB.Command;
> >
> > implementation
> >
> > uses ComServ;
> >
> >
> > function TTAppAddInServ.Activate(const AddInSiteObject:
> > ApplicationAddInSite; FirstTime: WordBool): HResult;
> > begin
> > //init
> > AppDefault := InitApplication;
> > //get the InventorObject
> > oInventor := AddInSiteObject.Application;
> >
> > //Create commands
> > oCmd1 := AddInSiteObject.CreateCommand('My Add In Command',1,True);
> >
> > Result := S_OK;
> > end;
> >
> > function TTAppAddInServ.Deactivate: HResult;
> > begin
> > //CleanUp
> > oInventor := nil;
> > oCmd1 := nil;
> > Result := S_OK;
> > end;
> >
> > function TTAppAddInServ.ExecuteCommand(CommandID: Integer): HResult;
> >
> > begin
> > Case CommandID of
> > 1: begin
> > //here your Code for your command
> > end;
> > end;
> > Result := S_OK;
> > end;
> >
> > function TTAppAddInServ.Get_Automation(
> > out AutomationPtr: AddInAutomation): HResult;
> > begin
> > Result := E_NOINTERFACE;
> > end;
> >
> > //this is added by the com object wizard
> > initialization
> > TAutoObjectFactory.Create(ComServer, TTAppAddInServ,
> Class_TAppAddInServ,
> > ciMultiInstance, tmApartment);
> > end.
> >
> >
> >
> > That's the base for an addin. Registering the addin is the same as for
VB,
> > shown in the SDK documentation. Use the GUID from the CoClass created by
> the
> > ActiveX Library Projekt Wizard.
> >
> >
> > All other stuff is "normal" COM-programming. To avoid trouble getting
the
> > events done, you should use the Event Sink Importer from Binh Ly:
> > http://www.techvanguards.com/ There is also a "TypeExport" which
creates
> a
> > more correct Version of "invetor_TLB.pas".
> >
> > But, as i said, its hard to code. Till now, I don't get the interactive
> > selection part working. Also there is trouble with dynamic string arrays
> > getting via OLEVariant.
> >
> > greetings from berlin, germany
> > Jörgen
> >
> >
> > "Nick Hall" schrieb im Newsbeitrag
> > news:Xns91E74087BFE4Bnickhallaltasystems@64.124.46.110...
> > > Has anyone implemented an addin using Delphi ?
> > >
> > > Could anyone point me at some sample code ?
> > >
> > > Thanks
> > > Nick
> >
> >
>
>
Message 5 of 5
Anonymous
in reply to: Anonymous

I struggled to make it work for a while, and gave up.

I believe that Autodesk could (and should) create a simple Delphi component that works, and make it available for download. I don't think it would take more than a couple day's effort by some programmer from Autodesk.

I find Delphi superior to VB in many ways, and would really like to use it for Inventor programming. However, it seems that Autodesk is committed to Microsoft, so I doubt that they would put in the effort. Can you prove me wrong, Autodesk?

Murray

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report