Now into an unmanaged C++ DBX module… Here’s my C++ implementation of my custom AcDbHostApplicationServices object…
//////////////////////////////////////////////////////////////////////////
// by Fenton Webb, DevTech, Autodesk 30/04/2010
//-----------------------------------------------------------------------------
//----- HostApplicationServices.cpp
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "HostApplicationServices.h"
#include "Wininet.h"
#include "Shlwapi.h"
//////////////////////////////////////////////////////////////////////////
#pragma unmanaged
//////////////////////////////////////////////////////////////////////////////
HostApplication::HostApplication()
{
}
//////////////////////////////////////////////////////////////////////////////
HostApplication::~HostApplication()
{
CString local,url;
for (POSITION pos = m_localToUrl.GetStartPosition();pos!=NULL;)
{
m_localToUrl.GetNextAssoc(pos,local,url);
DeleteUrlCacheEntry(url);
}
}
//////////////////////////////////////////////////////////////////////////////
// Return the Install directory for customizable files
Acad::ErrorStatus HostApplication::getRoamableRootFolder(const ACHAR*& folder)
{
Acad::ErrorStatus ret = Acad::eOk;
static ACHAR buf[MAX_PATH] = _T("\0"); //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 HostApplication::getLocalRootFolder(const ACHAR*& folder)
{
Acad::ErrorStatus ret = Acad::eOk;
static ACHAR buf[MAX_PATH] = _T("\0"); //MDI SAFE
if (buf[0]==0)
if (GetModuleFileName(NULL, buf, MAX_PATH) != 0)
ret = Acad::eRegistryAccessError;
folder = buf;
return ret;
}
//////////////////////////////////////////////////////////////////////////////
Acad::ErrorStatus HostApplication::findFile(ACHAR* pcFullPathOut, int nBufferLength,
const ACHAR* pcFilename, AcDbDatabase* pDb,
AcDbHostApplicationServices::FindFileHint hint)
{
ACHAR pExtension[5];
switch (hint)
{
case kCompiledShapeFile:
_tcscpy(pExtension, _T(".shx"));
break;
case kTrueTypeFontFile:
_tcscpy(pExtension, _T(".ttf"));
break;
case kPatternFile:
_tcscpy(pExtension, _T(".pat"));
break;
case kARXApplication:
_tcscpy(pExtension, _T(".dbx"));
break;
case kFontMapFile:
_tcscpy(pExtension, _T(".fmp"));
break;
case kXRefDrawing:
_tcscpy(pExtension, _T(".dwg"));
break;
case kFontFile: // Fall through. These could have
case kEmbeddedImageFile: // various extensions
default:
pExtension[0] = _T('\0');
break;
}
ACHAR* filePart;
DWORD result;
ACHAR path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);
_tcscat(path, _T("\\AutoCADImages"));
result = SearchPath(path,
pcFilename, pExtension, nBufferLength, pcFullPathOut, &filePart);
if (result && result < (DWORD)nBufferLength)
return Acad::eOk;
else
return Acad::eFileNotFound;
}
//////////////////////////////////////////////////////////////////////////////
Adesk::Boolean HostApplication::isURL(const ACHAR* pszURL) const
{
return PathIsURL(pszURL);
}
//////////////////////////////////////////////////////////////////////////////
Adesk::Boolean HostApplication::isRemoteFile(const ACHAR* pszLocalFile, ACHAR* pszURL) const
{
CString value;
if (m_localToUrl.Lookup(pszLocalFile,value))
{
_tcscpy(pszURL,value);
return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////////////
Acad::ErrorStatus HostApplication::getRemoteFile(const ACHAR* pszURL, ACHAR* pszLocalFile, Adesk::Boolean bIgnoreCache) const
{
DWORD err = ERROR_FILE_NOT_FOUND;
if (!bIgnoreCache)
{
DWORD size = 0;
if (GetUrlCacheEntryInfo(pszURL,NULL,&size))
return Acad::eInetFileGenericError; //this shouldn't succeed
err = GetLastError();
if (err == ERROR_INSUFFICIENT_BUFFER)
{
INTERNET_CACHE_ENTRY_INFO* pCacheEntry = (INTERNET_CACHE_ENTRY_INFO*)malloc(size);
if (GetUrlCacheEntryInfo(pszURL,pCacheEntry,&size))
{
_tcscpy(pszLocalFile,pCacheEntry->lpszLocalFileName);
m_localToUrl.SetAt(pszLocalFile,pszURL);
free(pCacheEntry);
return Acad::eInetOk;
}
err = GetLastError();
}
}
if (err == ERROR_FILE_NOT_FOUND)
{
if (SUCCEEDED(URLDownloadToCacheFile(NULL,pszURL,pszLocalFile,_MAX_PATH,0,NULL)))
{
m_localToUrl.SetAt(pszLocalFile,pszURL);
return Acad::eInetOk;
}
}
return Acad::eInetFileGenericError;
}
//////////////////////////////////////////////////////////////////////////////
ACHAR * HostApplication::getAlternateFontName() const
{
return _T("txt.shx"); //findFile will be called again with this name
}
//////////////////////////////////////////////////////////////////////////////
void HostApplication::fatalError(const ACHAR *format, ...)
{
throw Acad::eFileInternalErr;
}
// Called when an unhandled exception occurs in an arx command or message.
// The EXCEPTION_POINTERS pointer is obtained from the win32 api:
// GetExceptionInformation().
//
//////////////////////////////////////////////////////////////////////////////
void HostApplication::reportUnhandledArxException(const _EXCEPTION_POINTERS *pExcPtrs,
const ACHAR *pAppName)
{
// might want to send your minidump file back to your company for processing
}
// The equivalent of ads_usrbrk()
//////////////////////////////////////////////////////////////////////////////
Adesk::Boolean HostApplication::userBreak(bool updCtrlsWhenEnteringIdle) const
{
throw Acad::eUserBreak;
}
//////////////////////////////////////////////////////////////////////////////
Recent Comments