Add code to support the new interface. First add an include for the dcapi.idl file to the AsdkDesignCenterSamp.idl. This include should be made after the two default imports:
import "oaidl.idl"; import "ocidl.idl"; #include "dcapi.idl"
Open the AsdkDcContent.h header file and change the derivation for the new class to include CWindowImplBase and IAcDcContentView as follows:
class ATL_NO_VTABLE CAsdkDcContent : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CAsdkDcContent, &CLSID_AsdkDcContent>, public ISupportErrorInfo, public IDispatchImpl<IAsdkDcContent, &IID_IAsdkDcContent, &LIBID_ASDKDESIGNCENTERSAMPLib>, public CWindowImplBase, public IAcDcContentView {
Enter the object's interfaces into the COM map using the COM_INTERFACE_ENTRY macro:
BEGIN_COM_MAP(CAsdkDcContent) COM_INTERFACE_ENTRY(IAsdkDcContent) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(IAcDcContentView) END_COM_MAP()
Add a message map to the class:
BEGIN_MSG_MAP(CAsdkDcContent) END_MSG_MAP()
Add the following declarations for the IAcDcContentView interface and some utility methods:
public: void OpenAndDisplayTextFile(); void OpenAndInsertTextFile(); CString OpenAndReadTextFile(DWORD& length); STDMETHOD(Initialize)( /*[in]*/ VARIANT varBrowser, /*[in]*/ VARIANT varReserved); STDMETHOD(SetImageLists)(); STDMETHOD(NavigatorNodeExpanding)( /*[in]*/ VARIANT varhNode , /*[in]*/ BSTR bstrFullPath); STDMETHOD(NavigatorNodeCollapsing)( /*[in]*/ VARIANT varhNode , /*[in]*/ BSTR bstrFullPath); STDMETHOD(NavigatorNodeClick)( /*[in]*/ VARIANT varhNode , /*[in, string]*/ BSTR bstrFullPath); STDMETHOD(NavigatorMouseUp)( /*[in]*/ VARIANT varhNode , /*[in, string]*/ BSTR bstrFullPath , /*[in]*/ VARIANT varX , /*[in]*/ VARIANT varY); STDMETHOD(PaletteItemClick)(/*[in]*/ BSTR bstrItemText); STDMETHOD(PaletteItemDblClick)(/*[in]*/ BSTR bstrItemText); STDMETHOD(PaletteColumnClick)(/*[in]*/ VARIANT varIndex); STDMETHOD(PaletteMouseUp)( /*[in]*/ VARIANT varButton , /*[in]*/ VARIANT varItemTexts , /*[in]*/ VARIANT varX , /*[in]*/ VARIANT varY); STDMETHOD(PaletteMouseDown)( /*[in]*/ VARIANT varButton , /*[in]*/ BSTR bstrFullText , /*[in]*/ VARIANT varX , /*[in]*/ VARIANT varY); STDMETHOD(RenderPreviewWindow)( /*[in]*/ BSTR bstrFullText , /*[in]*/ VARIANT varhPreviewWindow); STDMETHOD(PreviewMouseUp)( /*[in]*/ VARIANT varButton , /*[in]*/ VARIANT varX , /*[in]*/ VARIANT varY); STDMETHOD(Refresh)(); STDMETHOD(PaletteBeginDrag)( /*[in]*/ VARIANT varItemTexts , /*[in]*/ VARIANT varX , /*[in]*/VARIANT varY); STDMETHOD(ReleaseBrowser)(); STDMETHOD(QueryContextMenu)( /*[in]*/ VARIANT varhMenu , /*[in]*/ VARIANT varIndex , /*[in]*/ VARIANT varCmdFirst , /*[in]*/ VARIANT varCmdLast , /*[in]*/ VARIANT varItemTexts); STDMETHOD(InvokeCommand)(/*[in]*/ VARIANT varMenuID); STDMETHOD(IsExpandable)( /* [string][in] */ BSTR bstrItemText , /* [retval][out] */ VARIANT __RPC_FAR *pvarIsExpandable); STDMETHOD(GetLargeImage)( /* [in] */ BSTR bstrFileName , /* [out][in] */ VARIANT __RPC_FAR *pvarhLargeImage); STDMETHOD(GetSmallImageListForContent)( /*[in]*/ BSTR bstrFileName , /*[out]*/ VARIANT *pvarhImageList); STDMETHOD(GetLargeImageListForContent)( /*[in]*/ BSTR bstrFileName , /*[out]*/ VARIANT *pvarhImageList); STDMETHOD(GetCommandString)( /* [in] */ VARIANT varMenuID, /* [in] */ dcMenuInfoFlag __MIDL_0011, /* [out] */ VARIANT *pvarReserved, /* [out] */ BSTR *pbstrName); STDMETHOD(DeleteItemData)( /* [in] */ dcItemDataSource dcSrc, /* [in] */ VARIANT varItemDataArray); private: char * m_strSelectedItemText; IAcDcContentBrowser* m_pBrowser;
Add the code to implement the methods just added to the CPP file. Note that many of these methods do nothing but are necessary to complete the interface. The example makes use of the single-click (PaletteItemClick) and double-click (PaletteItemDblClick) events.
Adesk::Boolean append(AcDbEntity* pEntity) { AcDbBlockTable *pBlockTable; AcApDocument* pDoc = acDocManager->curDocument(); Acad::ErrorStatus es = acDocManager->lockDocument(pDoc); if (es != Acad::eOk) { acedAlert("Failed to lock the document!"); return Adesk::kFalse; } AcDbDatabase* pDb = pDoc->database(); es = pDb->getBlockTable(pBlockTable, AcDb::kForRead); if (es != Acad::eOk) { acedAlert("Failed to get block table!"); return Adesk::kFalse; } AcDbBlockTableRecord *pBlockRec; es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockRec, AcDb::kForWrite); if (es != Acad::eOk) { acedAlert("Failed to get block table record!"); pBlockTable->close(); return Adesk::kFalse; } es = pBlockRec->appendAcDbEntity(pEntity); if (es != Acad::eOk) { acedAlert("Failed to append entity!"); pBlockTable->close(); pBlockRec->close(); delete pEntity; return Adesk::kFalse; } pBlockRec->close(); pBlockTable->close(); acDocManager->unlockDocument(pDoc); return Adesk::kTrue; } STDMETHODIMP CAsdkDcContent::Initialize(VARIANT varBrowser, VARIANT) { m_pBrowser = (IAcDcContentBrowser*)varBrowser.punkVal; m_pBrowser->AddRef(); return S_OK; } STDMETHODIMP CAsdkDcContent::Initialize( VARIANT varBrowser, VARIANT varReserved) { return E_NOTIMPL; } STDMETHODIMP CAsdkDcContent::SetImageLists() { return S_OK; } STDMETHODIMP CAsdkDcContent::NavigatorNodeExpanding( VARIANT varhNode, BSTR bstrFullPath) { return S_OK; } STDMETHODIMP CAsdkDcContent::NavigatorNodeCollapsing( VARIANT varhNode, BSTR bstrFullPath) { return S_OK; } STDMETHODIMP CAsdkDcContent::NavigatorNodeClick( VARIANT varhNode, BSTR bstrFullPath) { return S_OK; } STDMETHODIMP CAsdkDcContent::NavigatorMouseUp( VARIANT varhNode, BSTR bstrFullPath, VARIANT varX, VARIANT varY) { return S_OK; } CString CAsdkDcContent::OpenAndReadTextFile(DWORD& length) { CFile fileText; fileText.Open(m_strSelectedItemText, CFile::modeRead); length = (DWORD)fileText.GetLength(); char *strBuff = new char[length]; fileText.Read(strBuff, length); fileText.Close(); CString cstrBuff(strBuff); delete strBuff; cstrBuff.SetAt(length, '\0'); cstrBuff.FreeExtra(); return cstrBuff; } void CAsdkDcContent::OpenAndDisplayTextFile() { DWORD length; CString cstrBuff = OpenAndReadTextFile(length); BSTR bstrBuf = cstrBuff.AllocSysString(); m_pBrowser->SetItemDescription(bstrBuf); ::SysFreeString(bstrBuf); } STDMETHODIMP CAsdkDcContent::PaletteItemClick(BSTR bstrItemText) { USES_CONVERSION; m_strSelectedItemText = OLE2T(bstrItemText); OpenAndDisplayTextFile(); return S_OK; } void CAsdkDcContent::OpenAndInsertTextFile() { DWORD length; CString cstrBuff = OpenAndReadTextFile(length); cstrBuff.Replace("\015\012", "\\P"); struct resbuf resbufViewCtr; resbufViewCtr.restype = RT3DPOINT; acedGetVar("VIEWCTR", &resbufViewCtr); AcGePoint3d pt(resbufViewCtr.resval.rpoint[X], resbufViewCtr.resval.rpoint[Y], resbufViewCtr.resval.rpoint[Z]); AcDbMText *pMText = new AcDbMText(); pMText->setLocation(pt); pMText->setContents(cstrBuff); append(pMText); pMText->downgradeOpen(); pMText->draw(); pMText->close(); } STDMETHODIMP CAsdkDcContent::PaletteItemDblClick( BSTR bstrItemText) { USES_CONVERSION; m_strSelectedItemText = OLE2T(bstrItemText); OpenAndInsertTextFile(); return S_OK; } STDMETHODIMP CAsdkDcContent::PaletteColumnClick( VARIANT varIndex) { return S_OK; } STDMETHODIMP CAsdkDcContent::PaletteMouseUp( VARIANT varButton, VARIANT varItemTexts, VARIANT varX, VARIANT varY) { return S_OK; } STDMETHODIMP CAsdkDcContent::PaletteMouseDown( VARIANT varButton, BSTR bstrFullText, VARIANT varX, VARIANT varY) { return S_OK; } STDMETHODIMP CAsdkDcContent::RenderPreviewWindow( BSTR bstrFullText, VARIANT varhPreviewWindow) { return S_OK; } STDMETHODIMP CAsdkDcContent::PreviewMouseUp( VARIANT varButton, VARIANT varX, VARIANT varY) { return S_OK; } STDMETHODIMP CAsdkDcContent::Refresh() { return S_OK; } STDMETHODIMP CAsdkDcContent::PaletteBeginDrag( VARIANT varItemTexts, VARIANT varX, VARIANT varY) { return S_OK; } STDMETHODIMP CAsdkDcContent::ReleaseBrowser() { return S_OK; } STDMETHODIMP CAsdkDcContent::QueryContextMenu( VARIANT varhMenu, VARIANT varIndex, VARIANT varCmdFirst, VARIANT varCmdLast, VARIANT varItemTexts) { return S_OK; } STDMETHODIMP CAsdkDcContent::InvokeCommand(VARIANT varMenuID) { return S_OK; } STDMETHODIMP CAsdkDcContent::IsExpandable( /* [string][in] */ BSTR bstrItemText, /* [retval][out] */ VARIANT __RPC_FAR *pvarIsExpandable) { pvarIsExpandable->iVal = TRUE; return S_OK; } STDMETHODIMP CAsdkDcContent::GetLargeImage( /* [in] */ BSTR bstrFileName, /* [out][in] */ VARIANT __RPC_FAR *pvarhLargeImage) { return E_NOTIMPL; } STDMETHODIMP CAsdkDcContent::GetSmallImageListForContent( BSTR bstrFileName, VARIANT *pvarhImageList) { return E_NOTIMPL; } STDMETHODIMP CAsdkDcContent::GetLargeImageListForContent( BSTR bstrFileName, VARIANT *pvarhImageList) { return E_NOTIMPL; } STDMETHODIMP CAsdkDcContent::GetCommandString( VARIANT varMenuID, dcMenuInfoFlag __MIDL_0011, VARIANT *pvarReserved, BSTR *pbstrName) { return E_NOTIMPL; } STDMETHODIMP CAsdkDcContent::DeleteItemData( dcItemDataSource dcSrc, VARIANT varItemDataArray) { return E_NOTIMPL; }
Include the appropriate header files in the sdtafx.h file. You will also need to add a definition to undefine _DEBUG, since the AutoCAD libraries are non-debug. Here is what the file should look like:
#if defined(_DEBUG) #undef _DEBUG #endif #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define STRICT #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif #define _ATL_APARTMENT_THREADED #include <afxwin.h> #include <afxdisp.h> #include <atlbase.h> // You may derive a class from CComModule and use // it if you want to override something, but do not // change the name of _Module. // extern CComModule _Module; #include <atlcom.h> #include <atlwin.h> #include <adslib.h> #include <dbmain.h> #include <dbsymtb.h> #include <dbmtext.h> #include <acdocman.h> #include <aced.h> #include <rxregsvc.h> #endif
In the project properties, remove the post-build step that calls regsvr32.exe.
Because this application depends on acad.exe, its registration is deferred until runtime.