472 lines
11 KiB
C++
472 lines
11 KiB
C++
#include "StdAfx.h"
|
|
#include "StdArx.h"
|
|
#include "resource.h"
|
|
#include <afxdllx.h>
|
|
#include "AecDbCurveBase.h"
|
|
#include "AecDbEntityBase.h"
|
|
#include "AecDbXDraw.h"
|
|
#include "AecDbObjXDataMapObj.h"
|
|
#include "atlbase.h"
|
|
#include "aecdbobjxdatamap.h"
|
|
#include "acdblclkedit.h"
|
|
#include "AecBaseDoubleClickEdit.h"
|
|
|
|
HINSTANCE _hdllInstance =NULL ;
|
|
|
|
#ifndef _ttof
|
|
#define _ttof(pszVal) _tcstod((pszVal), NULL)
|
|
#endif
|
|
|
|
|
|
#ifndef AECRXBASE_MODULE
|
|
#define AECRXBASE_MODULE _T("AECRXBASE_MODULE")
|
|
#endif
|
|
|
|
#if ARX <= 18
|
|
ACRX_DEFINE_MEMBERS(AcDbDoubleClickEdit);
|
|
#endif
|
|
|
|
namespace
|
|
{
|
|
CString GetArxDir()
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
::GetModuleFileName(_hdllInstance, szPath, MAX_PATH);
|
|
CString sPath(szPath);
|
|
sPath = sPath.Left(sPath.ReverseFind(_T('\\')));
|
|
return sPath;
|
|
}
|
|
|
|
CString GetRootDir()
|
|
{
|
|
CString arx = GetArxDir();
|
|
CString root = arx.Left(arx.ReverseFind(_T('\\')));
|
|
return root;
|
|
}
|
|
int initAdeskHlrDbx()
|
|
{
|
|
CString sDbx;
|
|
#ifdef ZWCAD
|
|
return 0;
|
|
#else
|
|
struct resbuf rb;
|
|
acedGetVar(_T("ACADVER"), &rb);//Acadver = 18.2s (LMS Tech)
|
|
double dVer = _ttof(rb.resval.rstring);
|
|
int nVer = (int)(dVer + 0.2);
|
|
|
|
#if ARX < 24
|
|
sDbx.Format(_T("%s\\AsdkHlrDbx\\sys%.1fx64\\AsdkHlrApi%d.dbx")
|
|
, GetRootDir(), dVer, nVer);
|
|
#else
|
|
sDbx.Format(_T("AsdkHlrApi%d.dbx"), nVer);
|
|
#endif
|
|
|
|
if (!acrxServiceIsRegistered(_T("ASDK_HLR_API_SERVICES")))
|
|
{
|
|
acrxLoadModule(sDbx, false, true);
|
|
}
|
|
acrxLoadModule(sDbx, false, false);
|
|
|
|
if (acrxServiceIsRegistered(_T("ASDK_HLR_API_SERVICES")))
|
|
acutPrintf(_T("\n ASDK_HLR_API_SERVICES has been loaded."));
|
|
else
|
|
acutPrintf(_T("\n ASDK_HLR_API_SERVICES failed to load."));
|
|
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
// cad版本,"R18" "R19.1" etc
|
|
CString getACADVer()
|
|
{
|
|
#ifndef ZWCAD
|
|
CString str(_T(""));
|
|
resbuf *pRes = acutNewRb(RTSTR);
|
|
int iRel = acedGetVar(_T("ACADVER"), pRes);
|
|
if (iRel == RTNORM)
|
|
{
|
|
str = pRes->resval.rstring;
|
|
str = str.Left(4);
|
|
}
|
|
acutRelRb(pRes);
|
|
return str;
|
|
#else
|
|
#ifndef CMAKE
|
|
#if defined(R24)
|
|
return _T("2004");
|
|
#elif defined(R25)
|
|
return _T("2005");
|
|
#elif defined(R26)
|
|
return _T("2006");
|
|
#endif
|
|
#else
|
|
#if ARX == 23
|
|
return _T("2023");
|
|
#elif ARX == 24
|
|
return _T("2024");
|
|
#elif ARX == 25
|
|
return _T("2025");
|
|
#elif ARX == 26
|
|
return _T("2026");
|
|
#endif
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
// cad打版本下的子版本 "ACAD-D001" "ACAD-D001:804" etc
|
|
CString getCurrentSubVer()
|
|
{
|
|
CString subVer(_T(""));
|
|
|
|
CString strVer(getACADVer()), strReg(_T(""));
|
|
if (strVer.IsEmpty()) return subVer;
|
|
#ifndef ZWCAD
|
|
strReg.Format(_T("Software\\Autodesk\\AutoCAD\\R%s"), strVer);
|
|
#else
|
|
strReg.Format(_T("Software\\ZWSOFT\\ZWCAD\\%s"), strVer);
|
|
#endif
|
|
|
|
CRegKey keyVer;
|
|
long rel = keyVer.Open(HKEY_CURRENT_USER, strReg);
|
|
if (rel == ERROR_SUCCESS)
|
|
{
|
|
ULONG sz(MAX_PATH);
|
|
TCHAR *chSubKey = new TCHAR[sz];
|
|
::memset(chSubKey, 0, sizeof(TCHAR) * sz);
|
|
if (keyVer.QueryStringValue(_T("CurVer"), chSubKey, &sz) == ERROR_SUCCESS)
|
|
{
|
|
subVer = chSubKey;
|
|
}
|
|
delete[] chSubKey;
|
|
keyVer.Close();
|
|
}
|
|
|
|
return subVer;
|
|
}
|
|
|
|
// getACADVer() 函数在程序退出时有时会崩溃,
|
|
// 在这里用全局变量保存,供程序关闭时使用
|
|
const CString g_cadMainVer = getACADVer();
|
|
const CString g_cadSubVer = getCurrentSubVer();
|
|
|
|
bool openProfilesKey(CRegKey &keyProfiles, const DWORD &access = KEY_READ)
|
|
{
|
|
CString mVer(g_cadMainVer);
|
|
CString sVer(g_cadSubVer);
|
|
CString strReg(_T(""));
|
|
#ifndef ZWCAD
|
|
strReg.Format(_T("Software\\Autodesk\\AutoCAD\\R%s\\%s\\Profiles"), mVer, sVer);
|
|
long rel = keyProfiles.Open(HKEY_CURRENT_USER, strReg, access);
|
|
return rel == ERROR_SUCCESS;
|
|
#else
|
|
strReg.Format(_T("Software\\ZWSOFT\\ZWCAD\\%s\\%s\\Profiles"), mVer, sVer);
|
|
long rel = keyProfiles.Open(HKEY_CURRENT_USER, strReg, access);
|
|
return rel == ERROR_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
CString getDefaultProfile(CRegKey &keyProfiles)
|
|
{
|
|
DWORD sz(MAX_PATH);
|
|
CString sDef(_T("<<Unnamed Profile>>"));
|
|
if (keyProfiles.QueryStringValue(_T(""), NULL, &sz) == ERROR_SUCCESS)
|
|
{
|
|
keyProfiles.QueryStringValue(_T(""), sDef.GetBuffer(sz), &sz);
|
|
sDef.ReleaseBuffer();
|
|
}
|
|
return sDef;
|
|
}
|
|
|
|
// 得到第一个不是上华的profile(不含SHS开头的)
|
|
CString getFirstProfiles_NoSHS(CRegKey &keyProfiles)
|
|
{
|
|
CString sProfile(_T("<<Unnamed Profile>>"));
|
|
|
|
DWORD sz(MAX_PATH);
|
|
TCHAR *chSubKey = new TCHAR[sz];
|
|
::memset(chSubKey, 0, sizeof(TCHAR) * sz);
|
|
|
|
for (DWORD i = 0
|
|
; keyProfiles.EnumKey(i, chSubKey, &sz) != ERROR_NO_MORE_ITEMS
|
|
; sz = MAX_PATH, ++i)
|
|
{
|
|
sProfile = chSubKey;
|
|
if (sProfile.Find(_T("SHS-")) != -1) continue;
|
|
break;
|
|
}
|
|
delete[] chSubKey;
|
|
|
|
if (sProfile.Find(_T("SHS-")) != -1)
|
|
sProfile = _T("<<Unnamed Profile>>");
|
|
|
|
return sProfile;
|
|
}
|
|
|
|
void RebackReg()
|
|
{
|
|
CRegKey keyProfiles;
|
|
if (openProfilesKey(keyProfiles, KEY_ALL_ACCESS))
|
|
{
|
|
CString sProfile = getDefaultProfile(keyProfiles);
|
|
if (sProfile.Find(_T("SHS-")) != -1)
|
|
sProfile = getFirstProfiles_NoSHS(keyProfiles);
|
|
|
|
keyProfiles.SetValue(sProfile);
|
|
keyProfiles.Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
void AddCommand(const TCHAR* cmdGroup, const TCHAR* cmdInt, const TCHAR* cmdLoc,
|
|
const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal = -1);
|
|
|
|
//{{AFX_ARX_MSG
|
|
void InitApplication();
|
|
void UnloadApplication();
|
|
//}}AFX_ARX_MSG
|
|
|
|
//{{AFX_ARX_ADDIN_FUNCS
|
|
//}}AFX_ARX_ADDIN_FUNCS
|
|
|
|
// Define the sole extension module object.
|
|
AC_IMPLEMENT_EXTENSION_MODULE(AecRxBase);
|
|
|
|
extern "C"
|
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
{
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
{
|
|
_hdllInstance = hInstance;
|
|
AecRxBase.AttachInstance(hInstance);
|
|
}
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
AecRxBase.DetachInstance();
|
|
// 双保险,关闭后也清空cad配置
|
|
RebackReg();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// ObjectARX EntryPoint
|
|
extern "C" AcRx::AppRetCode
|
|
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case AcRx::kInitAppMsg:
|
|
// Comment out the following line if your
|
|
// application should be locked into memory
|
|
acrxDynamicLinker->unlockApplication(pkt);
|
|
acrxDynamicLinker->registerAppMDIAware(pkt);
|
|
InitApplication();
|
|
// 启动后立即清空cad配置
|
|
RebackReg();
|
|
|
|
initAdeskHlrDbx();
|
|
|
|
#ifndef NDEBUG
|
|
struct resbuf rb;
|
|
rb.restype = RTSHORT;
|
|
rb.resval.rint = 1;
|
|
acedSetVar(_T("recoverymode"), &rb);
|
|
acedPostCommand(_T("drawingrecoveryhide "));
|
|
#endif
|
|
#ifdef TRIAL_YEAR
|
|
{
|
|
CTime tCur = CTime::GetCurrentTime();
|
|
int year(tCur.GetYear());
|
|
if (year != TRIAL_YEAR)
|
|
{
|
|
CString str(_T(""));
|
|
str.Format(_T("%d试用版验证到期!"), TRIAL_YEAR);
|
|
AfxMessageBox(str);
|
|
return AcRx::kRetError;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
break;
|
|
case AcRx::kUnloadAppMsg:
|
|
UnloadApplication();
|
|
break;
|
|
}
|
|
return AcRx::kRetOK;
|
|
}
|
|
|
|
AecBaseDoubleClickEdit* g_pDblBaseEdit(NULL);
|
|
void InitApplication()
|
|
{
|
|
//{{AFX_ARX_INIT
|
|
AecDbEntityBase::rxInit();
|
|
AecDbCurveBase::rxInit();
|
|
AecDbObjXDataMapObj::rxInit();
|
|
AecDbXDraw::rxInit();
|
|
//}}AFX_ARX_INIT
|
|
|
|
acrxBuildClassHierarchy();
|
|
acrxRegisterService(AECRXBASE_MODULE);
|
|
|
|
//基础实体双击修改
|
|
g_pDblBaseEdit = new AecBaseDoubleClickEdit;
|
|
AecDbEntityBase::desc()->addX(AcDbDoubleClickEdit::desc(),g_pDblBaseEdit);
|
|
AecDbCurveBase::desc()->addX(AcDbDoubleClickEdit::desc(),g_pDblBaseEdit);
|
|
}
|
|
|
|
void UnloadApplication()
|
|
{
|
|
//{{AFX_ARX_EXIT
|
|
AecDbEntityBase::desc()->delX(AcDbDoubleClickEdit::desc());
|
|
AecDbCurveBase::desc()->delX(AcDbDoubleClickEdit::desc());
|
|
|
|
deleteAcRxClass(AecDbCurveBase::desc());
|
|
deleteAcRxClass(AecDbEntityBase::desc());
|
|
deleteAcRxClass(AecDbObjXDataMapObj::desc());
|
|
deleteAcRxClass(AecDbXDraw::desc());
|
|
delete acrxServiceDictionary->remove(AECRXBASE_MODULE);
|
|
|
|
//}}AFX_ARX_EXIT
|
|
delete g_pDblBaseEdit;
|
|
}
|
|
|
|
void AddCommand(const TCHAR* cmdGroup, const TCHAR* cmdInt, const TCHAR* cmdLoc,
|
|
const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal)
|
|
{
|
|
TCHAR cmdLocRes[65];
|
|
|
|
// If idLocal is not -1, it's treated as an ID for
|
|
// a string stored in the resources.
|
|
if (idLocal != -1)
|
|
{
|
|
::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
|
|
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);
|
|
}
|
|
else
|
|
{
|
|
// idLocal is -1, so the 'hard coded'
|
|
// localized function name is used.
|
|
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
|
|
}
|
|
}
|
|
|
|
CString IDCreate()
|
|
{
|
|
CString sID = _T("");
|
|
|
|
GUID Guid;
|
|
static TCHAR szGuid[39];
|
|
RPC_WSTR pszGuid = NULL;
|
|
|
|
UuidCreate( &Guid );
|
|
|
|
if (RPC_S_OK != UuidToString( &Guid, &pszGuid ))
|
|
{
|
|
return _T("");
|
|
}
|
|
|
|
lstrcpyn(szGuid, (TCHAR *)pszGuid, sizeof(szGuid) );
|
|
RpcStringFree( &pszGuid );
|
|
|
|
szGuid[38] = _T('\0');
|
|
sID = szGuid;
|
|
sID.MakeUpper();
|
|
return sID;
|
|
}
|
|
|
|
BOOL ReadModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb)
|
|
{
|
|
AcDbDictionary *pNamedobj = NULL;
|
|
if (pDb == NULL)
|
|
{
|
|
acdbHostApplicationServices()->workingDatabase()->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
|
|
}
|
|
else
|
|
{
|
|
pDb->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
|
|
}
|
|
|
|
BOOL bSuccess = FALSE;
|
|
if (pNamedobj != NULL)
|
|
{
|
|
AcDbObject* pObj = NULL;
|
|
pNamedobj->getAt(_T("ACAD_LAYOUT"), pObj, AcDb::kForRead);
|
|
|
|
if (pObj != NULL)
|
|
{
|
|
AcDbDictionary* pDic = AcDbDictionary::cast(pObj);
|
|
if (pDic != NULL)
|
|
{
|
|
AcDbObject* pModel = NULL;
|
|
pDic->getAt(_T("Model"), pModel, AcDb::kForRead);
|
|
|
|
if (pModel != NULL)
|
|
{
|
|
bSuccess = xDataMap.Read(pModel, pszKey);
|
|
pModel->close();
|
|
}
|
|
}
|
|
pObj->close();
|
|
}
|
|
pNamedobj->close();
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
BOOL WriteModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb)
|
|
{
|
|
AcDbDictionary *pNamedobj = NULL;
|
|
if (pDb == NULL)
|
|
{
|
|
acdbHostApplicationServices()->workingDatabase()->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
|
|
}
|
|
else
|
|
{
|
|
//if (pDb != NULL)
|
|
{
|
|
AcDbRegAppTable* pTbl = NULL;
|
|
if (Acad::eOk == pDb->getRegAppTable(pTbl, AcDb::kForWrite))
|
|
{
|
|
AcDbObjectId idRec;
|
|
if (Acad::eOk != pTbl->getAt(pszKey, idRec))
|
|
{
|
|
AcDbRegAppTableRecord* pRec = new AcDbRegAppTableRecord;
|
|
pRec->setName(pszKey);
|
|
|
|
pTbl->add(idRec, pRec);
|
|
pRec->close();
|
|
}
|
|
pTbl->close();
|
|
}
|
|
}
|
|
pDb->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
|
|
}
|
|
|
|
BOOL bSuccess = FALSE;
|
|
if (pNamedobj != NULL)
|
|
{
|
|
AcDbObject* pObj = NULL;
|
|
pNamedobj->getAt(_T("ACAD_LAYOUT"), pObj, AcDb::kForRead);
|
|
|
|
if (pObj != NULL)
|
|
{
|
|
AcDbDictionary* pDic = AcDbDictionary::cast(pObj);
|
|
if (pDic != NULL)
|
|
{
|
|
AcDbObject* pModel = NULL;
|
|
pDic->getAt(_T("Model"), pModel, AcDb::kForWrite);
|
|
|
|
if (pModel != NULL)
|
|
{
|
|
bSuccess = xDataMap.Write(pModel, pszKey);
|
|
pModel->close();
|
|
}
|
|
}
|
|
pObj->close();
|
|
}
|
|
pNamedobj->close();
|
|
}
|
|
return bSuccess;
|
|
}
|