OnExecute Event C++ (no ATL, the simpliest way)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello last week, I take some time to optimize and understand Addins for Inventor. After I realize that it's just a simple DLL with a DllGetClassObject entry and some query interface. I decide to flush the entire actual ATL template, IDL, DEF and re-begin on a new form, for my part, are really more understandable and clear. For the moment I'm not sure for the IClassFactory base class and I know it's can be again more trimmed, but anyway working fine in this way. There is the code.
#include "pch.h"
extern "C" __declspec(selectany) const _GUID CLSID_InventorAddInLite = { 0x0B047779, 0x4EFD, 0x4ADF, {0x99, 0x24, 0x76, 0x8B, 0xF9, 0x76, 0xA6, 0x48}};
//extern "C" __declspec(selectany) const _GUID CLSID_InventorAddInServer = { 0xE3571292, 0xDB40, 0x11D2, {0xB7, 0x83, 0x00, 0x60, 0xB0, 0xF1, 0x59, 0xEF }};
unsigned long g_lockCount;
unsigned long g_objCount;
class CInventorLite : public IRxApplicationAddInServer
{
public :
CInventorLite()
{
m_cRef = 0;
g_objCount++;
}
~CInventorLite()
{
g_objCount--;
}
virtual _declspec(nothrow) long _stdcall Activate(IRxApplicationAddInSite* pAddInSite, char FirstTime)
{
if (pAddInSite == NULL)
return E_INVALIDARG;
m_pAddInSite = pAddInSite;
CComPtr<IUnknown> pAppUnk;
long hr;
if (FAILED(hr = m_pAddInSite->get_Application(&pAppUnk)))
return hr;
if (FAILED(hr = pAppUnk->QueryInterface(&m_pApplication)))
return hr;
/* Ribbon */
CComPtr<UserInterfaceManager> pUserInterfaceMgr;
hr = m_pApplication->get_UserInterfaceManager(&pUserInterfaceMgr);
if (FAILED(hr)) return hr;
CComPtr<Ribbons> pRibbons;
hr = pUserInterfaceMgr->get_Ribbons(&pRibbons);
if (FAILED(hr)) return hr;
CComPtr<Ribbon> pPartRibbon;
hr = pRibbons->get_Item(CComVariant(_T("Assembly")), &pPartRibbon);
if (FAILED(hr)) return hr;
//get the tabs associated with part ribbon
CComPtr<RibbonTabs> pRibbonTabs;
hr = pPartRibbon->get_RibbonTabs(&pRibbonTabs);
if (FAILED(hr)) return hr;
CComPtr<RibbonTab> pRibbonTab;
hr = pRibbonTabs->Add(CComBSTR("My Ribbon"), CComBSTR("id_Tab_MyRibbon"), CComBSTR("MyID"), CComBSTR(""), false, false, &pRibbonTab);
if (FAILED(hr)) return hr;
CComPtr<RibbonPanel> pCustomPanel;
pRibbonTab->GetRibbonPanels()->Add(CComBSTR("Sample"), CComBSTR("MYSample"), CComBSTR(""), CComBSTR(""), false, &pCustomPanel);
if (FAILED(hr)) return hr;
/* Combo */
CComPtr<CommandManager> pCommandManager;
hr = m_pApplication->get_CommandManager(&pCommandManager);
if (FAILED(hr)) return hr;
CComPtr<ControlDefinitions> pControlDefinitions;
hr = pCommandManager->get_ControlDefinitions(&pControlDefinitions);
if (FAILED(hr)) return hr;
CComPtr<ComboBoxDefinitionObject> m_pSlotWidthComboBoxDef;
hr = pControlDefinitions->AddComboBoxDefinition(CComBSTR(_T("Slot Width")),
CComBSTR(_T("Autodesk:SimpleAddIn:SlotWidthCboBox")),
kShapeEditCmdType,
50,
CComVariant(_T("{DB59D9A7-EE4C-434A-BB5A-F93E8866E872}")),
CComBSTR(_T("Specifies slot width")),
CComBSTR(_T("Slot width")),
vtMissing,
vtMissing,
kAlwaysDisplayText,
&m_pSlotWidthComboBoxDef);
CComPtr<ButtonDefinitionObject> pAddSlotOptionCmdBtnDef;
hr = pControlDefinitions->AddButtonDefinition(CComBSTR(_T("Add Slot")),
CComBSTR(_T("Autodesk:SimpleAddIn:AddSlotOptionCmd")),
kShapeEditCmdType,
CComVariant(_T("{DB59D9A7-EE4C-434A-BB5A-F93E8866E872}")),
CComBSTR(_T("Adds option for slot width/height")),
CComBSTR(_T("Add slot option")),
vtMissing,
vtMissing,
kDisplayTextInLearningMode,
&pAddSlotOptionCmdBtnDef);
if (FAILED(hr)) return hr;
CComPtr<CommandControls> pCommandControls;
hr = pCustomPanel->get_CommandControls(&pCommandControls);
if (FAILED(hr)) return hr;
CComPtr<CommandControl> pSlotWidthCmdCboBoxCmdCtrl;
hr = pCommandControls->AddComboBox(m_pSlotWidthComboBoxDef, CComBSTR(""), true, &pSlotWidthCmdCboBoxCmdCtrl);
if (FAILED(hr)) return hr;
CComPtr<CommandControl> pSlotWidthCmdButtonCmdCtrl;
hr = pCommandControls->AddButton(pAddSlotOptionCmdBtnDef,false, true, CComBSTR(_T("")), false, &pSlotWidthCmdButtonCmdCtrl);
if (FAILED(hr)) return hr;
/* End Combo*/
MessageBox(NULL, L"Activate", L"Inventor Addins - C++ Native", MB_OK);
return S_OK;
}
virtual _declspec(nothrow) long _stdcall Deactivate()
{
MessageBox(NULL, L"Desactivate", L"Inventor Addins - C++ Native", MB_OK);
return S_OK;
}
virtual _declspec(nothrow) long _stdcall ExecuteCommand(LONG CommandID)
{
MessageBox(NULL, L"ExecuteCommand", L"Inventor Addins - C++ Native", MB_OK);
return S_OK;
}
virtual _declspec(nothrow) long _stdcall get_Automation(IUnknown** ppResult)
{
return S_OK;
}
virtual _declspec(nothrow) long _stdcall QueryInterface(const _GUID& riid, void** ppv)
{
*ppv = NULL;
long Result = E_NOINTERFACE;
MessageBox(NULL, L"Querry Interface", L"Inventor Addins - C++ Native", MB_OK);
//if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, CLSID_InventorAddInServer))
//{
*ppv = (IUnknown*)this;
if (*ppv)
{
AddRef();
Result = NOERROR;
}
//}
return Result;
}
virtual _declspec(nothrow) unsigned long _stdcall AddRef()
{
return ++m_cRef;
}
virtual _declspec(nothrow) unsigned long _stdcall Release()
{
if (--m_cRef == 0)
{
delete this;
return 0;
}
return m_cRef;
}
private:
unsigned long m_cRef;
CComPtr<Application> m_pApplication;
CComPtr<IRxApplicationAddInSite> m_pAddInSite;
};
class CInventorLiteFactory : public IClassFactory
{
public:
CInventorLiteFactory()
{
m_cRef = 0;
g_objCount++;
}
~CInventorLiteFactory()
{
g_objCount--;
}
virtual _declspec(nothrow) long _stdcall QueryInterface(const _GUID& riid, void** ppv)
{
long Result = E_NOINTERFACE;
*ppv = NULL;
MessageBox(NULL, L"Querry Interface Class Factory", L"Inventor Addins - C++ Native", MB_OK);
if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IClassFactory))
{
*ppv = (IUnknown*)this;
AddRef();
Result = NOERROR;
}
return Result;
}
virtual _declspec(nothrow) unsigned long _stdcall AddRef()
{
return ++m_cRef;
}
virtual _declspec(nothrow) unsigned long _stdcall Release()
{
if (--m_cRef == 0)
{
delete this;
return 0;
}
return m_cRef;
}
virtual _declspec(nothrow) long _stdcall CreateInstance(IUnknown* pUnkOuter, const _GUID &riid, void** ppvObject)
{
long hr;
CInventorLite* pInvLite = new CInventorLite();
if (FAILED(hr = pInvLite->QueryInterface(riid, ppvObject)))
delete pInvLite;
return hr;
}
virtual _declspec(nothrow) long _stdcall LockServer(int fLock)
{
fLock ? g_lockCount++ : g_lockCount--;
return S_OK;
}
private:
unsigned long m_cRef;
};
extern "C" long _stdcall DllGetClassObject(const _GUID & rclsid, const _GUID & riid, void** ppv)
{
long Result = NOERROR;
*ppv = NULL;
if (!IsEqualGUID(riid, IID_IUnknown) && !IsEqualGUID(riid, IID_IClassFactory))
Result = E_NOINTERFACE;
else if (IsEqualGUID(rclsid, CLSID_InventorAddInLite))
{
if (*ppv = new CInventorLiteFactory())
((IUnknown*)*ppv)->AddRef();
else
return E_OUTOFMEMORY;
}
else
Result = E_FAIL;
return Result;
}
extern "C" long _stdcall DllCanUnloadNow()
{
return g_lockCount == 0 && g_objCount == 0 ? S_OK : S_FALSE;
}
#pragma comment(linker, "/EXPORT:DllCanUnloadNow=DllCanUnloadNow,PRIVATE")
#pragma comment(linker, "/EXPORT:DllGetClassObject=DllGetClassObject,PRIVATE")
Now the question.
In C# we use m_SampleButton.OnExecute += SampleButton_OnExecute; (//oki simple ptr Function)
In VB we use AddHandler m_SampleButton.OnExecute, AddressOf m_SampleButton_OnExecute (//oki another kind)
but in C++ ATL is
SINK_ENTRY_EX (1, DIID_UserInterfaceEventsSink, UserInterfaceEventsSink_OnResetCommandBarsMeth, OnResetCommandBars)
Because I've no ATL, how to manage ButtonDefinitionHandler or ButtonDefinitionHandlerEventsSink.
Thanks.