Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipebase/shs_PipeBase.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

720 lines
19 KiB
C++

#include "StdAfx.h"
#include "StdArx.h"
#include "resource.h"
#include "TInterfaceModifyMsgContext.h"
PickSet g_ssLastSel(SS_FREE); // 上次选择集
CString g_csLastCmd; // 上次命令
AcGeTol g_globalTol; // 用于记录AcGePoint3d比较精度
void AddCommand(LPCTSTR cmdGroup, LPCTSTR cmdInt, LPCTSTR cmdLoc,
const int cmdFlags, const AcRxFunctionPtr cmdProc,
const int idLocal = -1);
// From TAuxTools.cpp
extern void GetTHvacParamFromDwg();
extern void SetTHvacParamToDwg(LPCTSTR pszKey = NULL);
DLLIMPEXP void SetSysPointEqual(double dDistance)
{
AcGeContext::gTol.setEqualPoint(dDistance);
}
DLLIMPEXP void SetSysVectorEqual(double dVector)
{
AcGeContext::gTol.setEqualVector(dVector);
}
// mcl add.获取风管是否加粗.用于非暖通环境时正确显示。临时方法,有待统一设置图纸相关参数
// delete by hh 2011-01-04 是否加粗保存在图纸中 见函数GetTHvacParamFromDwg
/*void SetDuctThickByDwg()
{
AcDbBlockTable* pBlockTable = NULL;
AcDbBlockTableRecord* pTableRecord = NULL;
if(acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead) != Acad::eOk)
return;
pBlockTable->close();
if(pBlockTable->getAt(ACDB_MODEL_SPACE, pTableRecord, AcDb::kForRead) != Acad::eOk)
return;
pTableRecord->close();
CString csIsThick = TAuxTools::ReadXdata(pTableRecord->id(), HVAC_SHOWWIDTH);
SetGlobalContext(HVAC_SHOWWIDTH, _ttoi(csIsThick));
PickSet ssObj(SS_FREE);
if (GetEntByDxf(ssObj, _T("ATS_DBHVACDUCT,ATS_DBHFITTING,ATS_DBHEQUIPMENT"), 1)==Acad::eOk)
UpdateGraphic(ssObj);
}*/
//{{AFX_ARX_MSG
void InitApplication();
void UnloadApplication();
void OnDwgLoaded();
//}}AFX_ARX_MSG
//{{AFX_ARX_ADDIN_FUNCS
void RegisterDbxApp();
//}}AFX_ARX_ADDIN_FUNCS
//MY_RES_HERE;
// mcl changed 2010.04.19.采用新建筑Ge库后,替换为下面方式
// static AFX_EXTENSION_MODULE TchPipeBaseDLL = { NULL, NULL };
// extern "C" {
// HINSTANCE _hdllInstance;
// }
// extern "C" BOOL APIENTRY //name modified
// extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
// {
// _hdllInstance = hInstance;
// return TRUE;
// }
//
// InitModule(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)//name modified
// {
// if (dwReason == DLL_PROCESS_ATTACH) {
// // Extension DLL one-time initialization
// if (!AfxInitExtensionModule(TchPipeBaseDLL, hInstance))
// return 0;
// CTemporaryResourceOverride::SetDefaultResource(_hdllInstance);
// // Insert this DLL into the resource chain
// new CDynLinkLibrary(TchPipeBaseDLL);
//
// }
// else if (dwReason == DLL_PROCESS_DETACH)
// {
// AfxTermExtensionModule(TchPipeBaseDLL);
// }
// return 1; // ok
// }
HINSTANCE _hdllInstance = NULL ;
AC_IMPLEMENT_EXTENSION_MODULE(PipeBaseDll);
extern void InitAol(const TCHAR *szAppName);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_hdllInstance = hInstance;
PipeBaseDll.AttachInstance(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
PipeBaseDll.DetachInstance();
}
return TRUE;
}
extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
// InitModule(_hdllInstance, DLL_PROCESS_ATTACH, NULL);
acrxDynamicLinker->unlockApplication(pkt);
acrxDynamicLinker->registerAppMDIAware(pkt);
InitApplication();
break;
case AcRx::kLoadDwgMsg: // mcl add 2010.08.02。处理与dwg自身有关参数
OnDwgLoaded();
break;
case AcRx::kUnloadAppMsg:
UnloadApplication();
// InitModule(_hdllInstance, DLL_PROCESS_DETACH, NULL);
break;
case AcRx::kSaveMsg: // add by hh 2011-01-05 保存动态扩展数据到图纸
// change by hh 图纸中已有动态数据时 不再保存,避免错误写入其他图纸设置到全局参数中的数据
BOOL bTemp = FALSE; // 使用“显示遮挡”参数进行判断
if(!TAuxTools::GetTHvacDataFromDwg(KEY_HIDEDRAW, bTemp))
SetTHvacParamToDwg();
break;
}
return AcRx::kRetOK;
}
//建立关系反应器
TDbMakeObjAssocReactor* g_pObjAssocReactor = NULL;
//关系维护反应器
TDbRelInterfaceReactor* g_pRelInterfaceReactor = NULL;
//全局datamap
TDbXDataMap g_mapClass2Cmd;
//全局消息
TInterfaceModifyMsgContext g_iMsgContext;
AcDbMatchProperties* g_pMatchPro = NULL;
void PBTest();
void ReSlectOrig();
void InitApplication()
{
//{{AFX_ARX_INIT
acrxRegisterService(TCHPIPEBASE_DBXSERVICE);
TDbInterfacesObj::rxInit();
TDbPipeBase::rxInit();
TDbPipeBase::InitMatchProtocol(TRUE);
TDbFittingBase::rxInit();
TDbPartBase::rxInit();
TDbEquipmentBase::rxInit();
TDbInterfaceRecord::rxInit();
TDbFittingCreatorService::rxInit();
TDbCableDim::rxInit();
TDbECabletry::rxInit();
TDbEFitting::rxInit();
TDbEEquipment::rxInit();
TDbEImpFittingCreatorService::rxInit();
TDbHvacDuct::rxInit();
TDbHvacFitting::rxInit();
TDbHvacEquipment::rxInit();
TDbHvacDimension::rxInit();
TDbHvacDimensionEx::rxInit();
TDbHImpFittingCreatorService::rxInit();
TDbEquRelativeDim::rxInit();
//}}AFX_ARX_INIT
//3.安装扩展协议
acrxBuildClassHierarchy();
//1.安装反应器
g_pObjAssocReactor = new TDbMakeObjAssocReactor;
g_pRelInterfaceReactor = new TDbRelInterfaceReactor;
acedEditor->addReactor(g_pRelInterfaceReactor);
AcDbDatabase* pDb = NULL;
#if ADS > 20
AcArray<AcDbDatabase*> pDbArray = acdbActiveDatabaseArray();
int iLen = pDbArray.length();
for (int i = 0; i < iLen; i++)
{
pDb = pDbArray.at(i);
if (NULL != pDb)
{
pDb->addReactor(g_pObjAssocReactor);
}
}
#else
AcDbVoidPtrArray* pDbArray = acdbActiveDatabaseArray();
if (pDbArray != NULL)
{
for (int i = 0; i < pDbArray->length(); i++)
{
pDb = (AcDbDatabase*)pDbArray->at(i);
if (pDb != NULL)
{
pDb->addReactor(g_pObjAssocReactor);
}
}
}
#endif
// modify by cq 2017-01-05 支持CAD2017
//2.安置桥架专业创建器
TDbEImpFittingCreatorService* pCurFittingCreator = new TDbEImpFittingCreatorService;
acrxDynamicLinker->registerService(KEY_FITCAB, pCurFittingCreator);
// 安装暖通专业创建器
TDbHImpFittingCreatorService* pHvacFittingCreator = new TDbHImpFittingCreatorService;
acrxDynamicLinker->registerService(KEY_FITHVAC, pHvacFittingCreator);
// modify begin
// SetSysPointEqual(1.e-3);
// SetSysVectorEqual(1.e-6);
g_globalTol.setEqualPoint(1.E-3);
g_globalTol.setEqualVector(1.E-6);
// modify end by cq 2017-10-31 暖通TFS30202、建筑TFS8208 在纯CAD中做过裁剪内部的块,用上华建筑打开,提示有图形错误。
// 修改方法:把目前isEqualTo函数 改成.distanceTo() < 1E-3 ;equalPoint()替换成 1E-3
//默认设置
SetGlobalContext(KEY_HIDEDRAW,1);
RegisterDbxApp();
AddCommand(_T("PipeBase"),_T("PBTest"),_T("PBTest"),ACRX_CMD_MODAL| ACRX_CMD_USEPICKSET,PBTest);
AddCommand(_T("PipeBase"),_T("ReSelOrig"),_T("ReSelOrig"),ACRX_CMD_USEPICKSET|ACRX_CMD_REDRAW,ReSlectOrig);
}
//add liaoy 170705 增加反应器的更新接口操作
void PipeBaseCommandEndedUser(const CString& sCmd)
{
if (g_pRelInterfaceReactor)
{
g_pRelInterfaceReactor->commandEndedUser(sCmd);
}
}
//add end
void PBTest()
{
// add by hh 2011-08-09 接口记录从字典移动到数据库中
TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB();
if(NULL != pIntfRec)
{
if(Acad::eOk == pIntfRec->upgradeOpen())
{
TInterface itf;
AcGePoint3d pt(22804.81,10126.16,3338.72);
AcGeVector3d vtDir(1,0,0);
BOOL bFind = pIntfRec->Find(pt,vtDir,itf);
pIntfRec->downgradeOpen();
}
pIntfRec->close();
return;
}
// add end
AcDbDictionary* pNamedDict = NULL;
if (Acad::eOk == acdbCurDwg()->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead))
{
AcDbDictionary* pDict = NULL;
if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead))
{
TDbInterfaceRecord* pInterfaceRec = NULL;
if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForWrite))
{
TInterface itf;
AcGePoint3d pt(22804.81,10126.16,3338.72);
AcGeVector3d vtDir(1,0,0);
BOOL bFind = pInterfaceRec->Find(pt,vtDir,itf);
pInterfaceRec->close();
}
pDict->close();
}
pNamedDict->close();
}
}
// mcl add 2011.2.12.重新选择用户最后选择的实体,解决选取实体时,按“P”,上次选择失效问题。
// 因为更新遮挡会创建新选择集,从而破坏上次选择集
void ReSlectOrig()
{
if (!g_csLastCmd.IsEmpty() && g_ssLastSel.Length() > 0)
{
ads_command(RTSTR, _T("select"), RTPICKS, (TLong_ptr*)g_ssLastSel, RTNONE);
acedPostCommand(_T(" "));
PostCommand(g_csLastCmd + _T("\n")); // 弥补由于运行本函数(命令)而中断用户上次命令问题
PostCommand(_T("\33"));
g_csLastCmd.Empty();
g_ssLastSel.Free();
}
}
void UnloadApplication()
{
//{{AFX_ARX_EXIT
deleteAcRxClass(TDbHvacDuct::desc());
deleteAcRxClass(TDbHvacFitting::desc());
deleteAcRxClass(TDbHvacEquipment::desc());
deleteAcRxClass(TDbHvacDimension::desc());
deleteAcRxClass(TDbHvacDimensionEx::desc());
deleteAcRxClass(TDbHImpFittingCreatorService::desc());
deleteAcRxClass(TDbCableDim::desc());
deleteAcRxClass(TDbECabletry::desc());
deleteAcRxClass(TDbEFitting::desc());
deleteAcRxClass(TDbEEquipment::desc());
deleteAcRxClass(TDbEImpFittingCreatorService::desc());
deleteAcRxClass(TDbPartBase::desc());
deleteAcRxClass(TDbPipeBase::desc());
TDbPipeBase::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbFittingBase::desc());
deleteAcRxClass(TDbEquipmentBase::desc());
deleteAcRxClass(TDbInterfacesObj::desc());
deleteAcRxClass(TDbInterfaceRecord::desc());
deleteAcRxClass(TDbFittingCreatorService::desc());
//}}AFX_ARX_EXIT
delete acrxServiceDictionary->remove(TCHPIPEBASE_DBXSERVICE);
//1.删除桥架专业创建器
delete acrxServiceDictionary->remove(KEY_FITCAB);
// 删除暖通专业创建器
delete acrxServiceDictionary->remove(KEY_FITHVAC);
//2.卸载掉所有数据库中的反应器
AcDbDatabase* pDb = NULL;
#if ADS > 20
AcArray<AcDbDatabase*> pDbArray = acdbActiveDatabaseArray();
int iLen = pDbArray.length();
for (int i = 0; i < iLen; ++i)
{
pDb = pDbArray.at(i);
if (pDb != NULL)
{
pDb->removeReactor(g_pObjAssocReactor);
}
}
#else
AcDbVoidPtrArray* pDbArray = acdbActiveDatabaseArray();
if (pDbArray != NULL)
{
for (int i = 0; i < pDbArray->length(); i++)
{
pDb = (AcDbDatabase*)pDbArray->at(i);
if (pDb != NULL)
{
pDb->removeReactor(g_pObjAssocReactor);
}
}
}
#endif
// modify by cq 2017-01-05 支持CAD2017
if (g_pObjAssocReactor != NULL)
{
delete g_pObjAssocReactor;
g_pObjAssocReactor = NULL;
}
acedEditor->removeReactor(g_pRelInterfaceReactor);
if (g_pRelInterfaceReactor != NULL)
{
delete g_pRelInterfaceReactor;
g_pRelInterfaceReactor = NULL;
}
acedRegCmds->removeGroup(_T("PipeBase"));
}
void OnDwgLoaded()
{
// change by hh 2011-01-04 读取暖通专业动态扩展数据
//if (g_nProductId != 6) // 暖通环境由 thvacCmd.arx中onDwgLoad()中处理
// SetDuctThickByDwg();
GetTHvacParamFromDwg();
}
void AddCommand(LPCTSTR cmdGroup, LPCTSTR cmdInt, LPCTSTR cmdLoc,
const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal)
{
TCHAR cmdLocRes[65];
if (idLocal != -1)
{
::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);
}
else
{
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
}
}
DLLIMPEXP void MakeSureDbHasAssocReactor(AcDbDatabase* pDb,TToolKitBase* pToolKit = NULL)
{
AcDbDictionary* pNamedDict = NULL;
// //add by sps 2013.1.15 是否显示遮挡延伸
// CRegProperty regProp(GetRegLocation(), _T("TCableTray"));
// regProp.SetTopRootKey(HKEY_CURRENT_USER);
// BOOL bShow = FALSE;
// if (!regProp.GetValue(KEY_SHOW_EXTEND, bShow))
// bShow = FALSE;
// SetLayerOnOff(LAY_CABLETRAY_HIDE, bShow);
if (Acad::eOk == pDb->getNamedObjectsDictionary(pNamedDict,AcDb::kForWrite))
{
AcDbDictionary* pDict = NULL;
if (Acad::eKeyNotFound == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForWrite))
{
AcDbObjectId idDict;
pDict = new AcDbDictionary;
pNamedDict->setAt(KEY_IRECORD,pDict,idDict);
}
pNamedDict->close();
if (!pDict->has(KEY_IRECORD))
{
TDbInterfaceRecord* pInterfaceRec = new TDbInterfaceRecord;
g_pRelInterfaceReactor->m_mapDbToIRecPtr.SetAt(pDb,pInterfaceRec);
pInterfaceRec = new TDbInterfaceRecord;
AcDbObjectId idT;
pDict->setAt(KEY_IRECORD,pInterfaceRec,idT);
pInterfaceRec->close();
}
pDict->close();
}
pDb->removeReactor(g_pObjAssocReactor);
pDb->addReactor(g_pObjAssocReactor);
if (g_pRelInterfaceReactor != NULL)
{
g_pRelInterfaceReactor->m_pToolKit = pToolKit;
g_pRelInterfaceReactor->AddToolKit(pToolKit);
}
}
void PickInterfaceModifyMsgs(TInterfaceModifyMsgs& msgs,AcDbDatabase* pDb)
{
if (pDb == NULL) pDb = acdbCurDwg();
CPtrArray* pArray = NULL;
if (g_iMsgContext.m_mapDb2TIMsgs.Lookup(pDb,(void*&)pArray))
{
TDbInterfaceMsgObj* pmsgObj = NULL;
TInterfaceModifyMsg msg;
for (int i = 0;i < pArray->GetSize();i++)
{
pmsgObj = (TDbInterfaceMsgObj* )pArray->GetAt(i);
if (pmsgObj != NULL)
{
pArray->SetAt(i,NULL);
pmsgObj->GetModifyMsg(msg);
msgs.append(msg);
delete pmsgObj;
}
}
pArray->RemoveAll();
}
}
//设置全局参数
void SetGlobalContext(LPCTSTR pszKey,LPCTSTR pszCmd)
{
if (pszKey != NULL && pszCmd != NULL)
{
g_mapClass2Cmd.SetAt(pszKey,pszCmd);
}
}
//设置全局参数
void SetGlobalContext(LPCTSTR pszKey,int nVal)
{
if (pszKey != NULL)
{
g_mapClass2Cmd.SetAt(pszKey,nVal);
}
}
BOOL GetGlobalContext(LPCTSTR pszKey,int& nVal)
{
if (pszKey != NULL)
{
return g_mapClass2Cmd.GetAt(pszKey,nVal);
}
return FALSE;
}
BOOL GetGlobalContext(LPCTSTR pszKey,CString& sCmd)
{
if (pszKey != NULL)
{
return g_mapClass2Cmd.GetAt(pszKey,sCmd);
}
return FALSE;
}
TDbXDataMap* GetGlobalContext()
{
return &g_mapClass2Cmd;
}
double _ttof(LPCTSTR pszString)
{
bool bSign = false;
bool bPowerSign = false;
bool bExponent = true;
bool bMantissa = false;
int nPower = 0;
double dExponent = 0.0;
double dMantissa = 0.0;
double dScale = 1.0;
TCHAR* pIn = (TCHAR*)pszString;
if (*pIn == _T('-'))
{
*pIn++;
bSign = true;
}
while (*pIn != 0)
{
// capture digits
if ((*pIn >= _T('0')) && (*pIn <= _T('9')))
{
if (bExponent)
{
dExponent *= 10.0;
dExponent += (*pIn - _T('0'));
}
else if (bMantissa)
{
dMantissa *= 10.0;
dMantissa += (*pIn - _T('0'));
dScale *= 10.0;
}
else
{
nPower *= 10;
nPower += (*pIn - _T('0'));
}
}
else if ((*pIn == _T('e')) || (*pIn == _T('E')))// power
{
// sign
if (*(++pIn) == _T('-'))
{
bPowerSign = true;
}
bMantissa = false;
}
else
{
// the first character that hasn't been accounted for already,
// is assumed to be the separator
// cross over
if (bExponent)
{
bExponent = false;
bMantissa = true;
}
// white space (including null) or bad char
// we're done either way
else
{
break;
}
}
pIn++;
}
double dVal = dExponent + (dMantissa / dScale);
if (nPower > 0)
{
for (; nPower > 0; nPower--)
{
if (bPowerSign)
{
dVal /= 10.0;
}
else
{
dVal *= 10.0;
}
}
}
if (bSign)
{
dVal *= -1.0;
}
return dVal;
}
void RegisterDbxApp()
{
int strLength;
HMODULE hModule = GetModuleHandle(_T("shs_PipeBase.arx"));
if (!hModule)
return;
//
// Register the application.
//
TCHAR ThisAppRegistryPath[] = { _T("Software\\Autodesk\\ObjectARX\\3.0\\SampleApps\\TDbECabletry\\") };
const TCHAR* dbxRegRoot = acrxObjectDBXRegistryKey();
TCHAR DbxAppRegistryPath[256];
_tcscpy(DbxAppRegistryPath, dbxRegRoot);
_tcscat(DbxAppRegistryPath, _T("\\Applications\\"));
_tcscat(DbxAppRegistryPath, _T("shs_PipeBase"));
//
// Create the registry key under the DBX path
// (use the variable DbxRegistryPath).
//
HKEY dbxKey;
DWORD result;
LONG status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
DbxAppRegistryPath,
0, _T(""),
REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &dbxKey, &result);
if (ERROR_SUCCESS != status)
return;
// Create the 'LOADCTRLS' value.
int loadReason = AcadApp::kOnProxyDetection |
AcadApp::kOnLoadRequest |
AcadApp::kTransparentlyLoadable;
status = RegSetValueEx(dbxKey, _T("LOADCTRLS"), 0, REG_DWORD,
(const BYTE*) &loadReason,
sizeof(loadReason));
if (ERROR_SUCCESS != status)
return;
// Create the 'REGPATH' value.
TCHAR regPath[256];
_tcscpy(regPath, _T("\\\\HKEY_LOCAL_MACHINE\\"));
_tcscat(regPath, ThisAppRegistryPath);
_tcscat(regPath, _T("shs_PipeBase"));
status = RegSetValueEx(dbxKey, _T("REGPATH"), 0, REG_SZ,
(const BYTE*) regPath, (DWORD)(_tcslen(regPath) + 1));
status = RegCloseKey(dbxKey);
if (ERROR_SUCCESS != status)
return;
//
// Create the registry key for this application
// (use the variable ThisAppRegistryPath).
//
HKEY appKey;
status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
ThisAppRegistryPath,
0, _T(""),
REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &appKey, &result);
if (ERROR_SUCCESS != status)
return;
HKEY prodKey;
status = RegCreateKeyEx(appKey, _T("shs_PipeBase"), 0, _T(""),
REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &prodKey, &result);
RegCloseKey(appKey);
if (ERROR_SUCCESS != status)
return;
// Create the 'Loader' key.
HKEY loaderKey;
status = RegCreateKeyEx(prodKey, _T("Loader"), 0, _T(""),
REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &loaderKey, &result);
if (ERROR_SUCCESS == status) {
TCHAR modulePath[512];
strLength = GetModuleFileName(hModule, modulePath, 512);
if (strLength)
RegSetValueEx(loaderKey, _T("MODULE"), 0, REG_SZ,
(const BYTE*)modulePath, strLength + 1);
RegCloseKey(loaderKey);
}
// Create the 'Name' key.
HKEY nameKey;
status = RegCreateKeyEx(prodKey, _T("Name"), 0, _T(""),
REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &nameKey, &result);
if (ERROR_SUCCESS == status) {
RegSetValueEx(nameKey, _T("shs_PipeBase"), 0, REG_SZ,
(const BYTE*) _T("shs_PipeBase"), 13);
RegCloseKey(nameKey);
}
RegCloseKey(prodKey);
}