Supporting AcDbOle2Frame objects in RealDWG

by Fenton Webb

Supporting AcDbOle2Frame objects inside of RealDWG unfortunately requires some extra work to make happen, I’ve pasted some sample code below which shows how to implement the code into your RealDWG C++ application.

The bad news is that if you are a .NET user of RealDWG then you will need to touch into unmanaged C++ via a Mixed Mode Dll in order to add support for your Ole2Frame class. That’s because, at the time of writing, the .NET version of the HostApplicationServices class does not export the functions you need.

Here’s how to create a Mixed Mode RealDWG app.

////////////////////////////////////////////    // RealDwg_App1Dlg.cpp : implementation file    #include "stdafx.h"    #include "RealDwg_App1.h"    #include "RealDwg_App1Dlg.h"    #include "AcIOxClientItemMgr.h"         #ifdef _DEBUG    #define new DEBUG_NEW    #endif         // CAboutDlg dialog used for App About    class CAboutDlg : public CDialog    {    public:      CAboutDlg();           // Dialog Data      enum { IDD = IDD_ABOUTBOX };         protected:      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support           // Implementation    protected:      DECLARE_MESSAGE_MAP()    };         CAboutDlg::CAboutDlg
() : CDialog(CAboutDlg::IDD)    {    }         void CAboutDlg::DoDataExchange(CDataExchange* pDX)    {      CDialog::DoDataExchange(pDX);    }         BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)    END_MESSAGE_MAP()         class CreatentHostApp : public AcDbHostApplicationServices    {      Acad::ErrorStatus findFile(TCHAR* pcFullPathOut, int nBufferLength,        const TCHAR* pcFilename, AcDbDatabase* pDb = NULL,        AcDbHostApplicationServices::FindFileHint = kDefault);           // These two functions return the full path to the root folder where roamable/local       // customizable files were installed. Note that the user may have reconfigured       // the location of some the customizable files using the Options Dialog       // therefore these functions should not be used to locate customizable files.       // To locate customizable files either use the findFile function or the       // appropriate system variable for the given file type.       //      Acad::ErrorStatus getRoamableRootFolder(const TCHAR*& folder);      Acad::ErrorStatus getLocalRootFolder(const TCHAR*& folder);      Acad::ErrorStatus getNewOleClientItem(COleClientItem*& pItem);      Acad::ErrorStatus serializeOleItem(COleClientItem* pItem, CArchive* pArchive);           // Support redo      virtual bool  supportsMultiRedo() const { return true; }      // make sure you implement getAlternateFontName. In case your findFile implementation      // fails to find a font you should return a font name here that is guaranteed to exist.      virtual TCHAR * getAlternateFontName() const      {        return _T("txt.shx"); //findFile will be called again with this name      }    };         // Return the Install directory for customizable files    Acad::ErrorStatus       CreatentHostApp::getRoamableRootFolder(const TCHAR*& folder)    {      Acad::ErrorStatus ret = Acad::eOk;      static TCHAR buf
[MAX_PATH] = _T(""); //MDI SAFE      if (buf[0]==0)        if (GetModuleFileName(NULL, buf, MAX_PATH) != 0)          ret = Acad::eRegistryAccessError;      folder = buf;      return ret;    }         // Return the Install directory for customizable files    Acad::ErrorStatus       CreatentHostApp::getLocalRootFolder(const TCHAR*& folder)    {      Acad::ErrorStatus ret = Acad::eOk;      static TCHAR buf[MAX_PATH] = _T(""); //MDI SAFE      if (buf[0]==0)        if (GetModuleFileName(NULL, buf, MAX_PATH) != 0)          ret = Acad::eRegistryAccessError;      folder = buf;      return ret;    }         Acad::ErrorStatus       CreatentHostApp::findFile(TCHAR* pcFullPathOut, int nBufferLength,      const TCHAR* pcFilename, AcDbDatabase* pDb,       AcDbHostApplicationServices::FindFileHint hint)    {      TCHAR pExtension[5];      switch (hint)      {      case kCompiledShapeFile:        _tcscpy_s(pExtension, _T(".shx"));        break;      case kTrueTypeFontFile:        _tcscpy_s(pExtension, _T(".ttf"));        break;      case kPatternFile:        _tcscpy_s(pExtension, _T(".pat"));        break;      case kARXApplication:        _tcscpy_s(pExtension, _T(".dbx"));        break;      case kFontMapFile
:        _tcscpy_s(pExtension, _T(".fmp"));        break;      case kXRefDrawing:        _tcscpy_s(pExtension, _T(".dwg"));        break;      case kFontFile:                // Fall through.  These could have      case kEmbeddedImageFile:       // various extensions      default:        pExtension[0] = _T('');        break;      }      TCHAR* filePart;      DWORD result;      result = SearchPath(NULL, pcFilename, pExtension, nBufferLength,         pcFullPathOut, &filePart);      if (result && result < (DWORD)nBufferLength)        return Acad::eOk;      else        return Acad::eFileNotFound;    }         Acad::ErrorStatus      CreatentHostApp::getNewOleClientItem(COleClientItem*& pItem)    {      AcDbDatabase* pClientItemOwner = 0;           pClientItemOwner = acdbHostApplicationServices()->workingDatabase();      if (pClientItemOwner) {        pItem = AcIOxClientItemMgr::GetNewOleClientItem(pClientItemOwner);        ASSERT(pItem != 0);      }           return Acad::eOk;    }         Acad::ErrorStatus      CreatentHostApp::serializeOleItem(COleClientItem* pItem, CArchive* pArchive)    {      TRY{             if ((*pArchive).IsStoring()){          ASSERT(pItem->m_lpObject != 0);        }             pItem->Serialize(*pArchive);             if ((*pArchive).IsStoring())          (*pArchive)

Comments

One response to “Supporting AcDbOle2Frame objects in RealDWG”

  1. And how can this be used to for example insert a bitmap or jpg inside of the active database?

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading