DataNodeBase.Cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973
  1. // DataRoot.cpp: implementation of the CDataRoot class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "DataManager.h"
  6. #include "DataNodeBase.h"
  7. #include "DataNodeBaseEx.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. Def_CreateObj* g_pfCreateObj = NULL;
  14. Def_ReleaseObj* g_pfReleaseObj = NULL;
  15. __declspec(dllexport) CDataNodeBase*CreateObj(CString strClassName)
  16. {
  17. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  18. if(strClassName == "CDataNodeBaseEx")
  19. return new CDataNodeBaseEx;
  20. else //if(strClassName == "CDataNodeBase")
  21. return new CDataNodeBaseEx;//CDataNodeBase
  22. }
  23. __declspec(dllexport) void ReleaseObj(CDataNodeBase *pObj)
  24. {
  25. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  26. delete pObj;
  27. }
  28. // 传递主程序的CreateObj和ReleaseObj接口
  29. __declspec(dllexport) void SetMainProgObjInterface(LPVOID pfCreateObj, LPVOID pfReleaseObj)
  30. {
  31. g_pfCreateObj = (Def_CreateObj*)pfCreateObj;
  32. g_pfReleaseObj = (Def_ReleaseObj*)pfReleaseObj;
  33. }
  34. //////////////////////////////////////////////////////////////////////////
  35. //////////////////////////////////////////////////////////////////////
  36. // Construction/Destruction
  37. //////////////////////////////////////////////////////////////////////
  38. IMPLEMENT_SERIAL(CDataNodeBase, CObject, 1)
  39. CDataNodeBase::CDataNodeBase()
  40. {
  41. m_strAppName = "DataManager";//AfxGetAppName();
  42. __classCanUseDirectly = FALSE;
  43. m_pParent = NULL;
  44. m_uID = 0;
  45. m_strName = "NoName";
  46. m_bModified = FALSE;
  47. memset(m_uFlags4, 0, sizeof(m_uFlags4));
  48. }
  49. CDataNodeBase::~CDataNodeBase()
  50. {
  51. Reset();
  52. if(!__classCanUseDirectly)
  53. {
  54. //TRACE("\n\n\n严重编码错误,禁止直接使用CDataNode类或直接派生于此类!这里会制造一些内存泄露来提醒处理.\n\n\n");
  55. //ASSERT(FALSE);
  56. //AfxMessageBox("严重编码错误,禁止直接使用CDataNode类或直接派生于此类!");
  57. }
  58. }
  59. void CDataNodeBase::Reset()
  60. {
  61. FreeSubs();
  62. m_mutexMapProperties.Lock();
  63. CString strItem;
  64. CVariable* pVar = NULL;
  65. POSITION pos = m_mapExtProperties.GetStartPosition();
  66. while (pos)
  67. {
  68. m_mapExtProperties.GetNextAssoc(pos, strItem, (void*&)pVar);
  69. delete pVar;
  70. }
  71. m_mapExtProperties.RemoveAll();
  72. m_mutexMapProperties.Unlock();
  73. // m_mutexTempItems.Lock();中间临时变量不能删除,例如在树中的位置的参数。2006-06-19
  74. // m_mapTempItems.RemoveAll();
  75. // m_mutexTempItems.Unlock();
  76. m_bModified = FALSE;
  77. }
  78. // 获取节点的父结点
  79. inline CDataNodeBase *CDataNodeBase::GetParent()
  80. {
  81. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  82. return m_pParent;
  83. }
  84. // 设置节点的父结点
  85. inline void CDataNodeBase::SetParent(CDataNodeBase *pParent)
  86. {
  87. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  88. m_pParent = pParent;
  89. // SetModified();
  90. }
  91. // 获取子项列表
  92. CMapPtrToPtr& CDataNodeBase::GetSubs()
  93. {
  94. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  95. return m_mapSubs;
  96. }
  97. // 获取指定ID的直接子项
  98. CDataNodeBase* CDataNodeBase::GetSub(UINT uID)
  99. {
  100. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  101. CDataNodeBase* pNode = NULL;
  102. m_mapSubs.Lookup((LPVOID)uID, (void*&)pNode);
  103. return pNode;
  104. }
  105. // 获取指定路径的任意深度的子项
  106. CDataNodeBase* CDataNodeBase::GetSub(CString strPath)
  107. {
  108. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  109. CDataNodeBase* pNode = this;
  110. if (strPath != "")
  111. {
  112. int nPos = strPath.Find('.');
  113. while (nPos > -1 && pNode)
  114. {
  115. CString strID = strPath.Left(nPos);
  116. UINT uID = (UINT)atoi(strID);
  117. strPath = strPath.Mid(nPos+1);
  118. nPos = strPath.Find('.');
  119. pNode = pNode->GetSub(uID);
  120. }
  121. if(pNode && strPath.GetLength()>0)
  122. pNode = pNode->GetSub((UINT)atoi(strPath));
  123. }
  124. return pNode;
  125. }
  126. // 获取名字
  127. CString CDataNodeBase::GetName()
  128. {
  129. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  130. return m_strName;
  131. }
  132. // 设置名字
  133. void CDataNodeBase::SetName(CString strName)
  134. {
  135. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  136. m_strName = strName;
  137. SetModified();
  138. }
  139. // 获取属性的字符串值
  140. BOOL CDataNodeBase::V_GetPropertyTxtValue(CString strPropertyName, CString &strTxtValue)
  141. {
  142. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  143. BOOL bRtn = TRUE;
  144. m_mutexMapProperties.Lock();
  145. CVariable* pVar = NULL;
  146. if((strPropertyName == "V" || strPropertyName == "Value" || strPropertyName == "")
  147. && m_mapExtProperties.Lookup("Value", (void*&)pVar))
  148. {//Value的处理频度最大,故最先处理这个属性值
  149. strTxtValue = pVar->GetTextValue();
  150. if(theApp.m_bJtToFj && strTxtValue.GetLength()>1 && strTxtValue.GetAt(0)&(1<<7))
  151. strTxtValue = CLanguage::GetCurLanguage(strTxtValue);
  152. }
  153. else if((strPropertyName == "S" || strPropertyName == "Status")
  154. && m_mapExtProperties.Lookup("Status", (void*&)pVar))
  155. {//Status的处理频度最大,故最先处理这个属性值
  156. strTxtValue = pVar->GetTextValue();
  157. }
  158. else if(strPropertyName == "Name")
  159. {
  160. strTxtValue = GetName();
  161. if(theApp.m_bJtToFj)
  162. strTxtValue = CLanguage::GetCurLanguage(strTxtValue);
  163. }
  164. else if(strPropertyName == "AppName")
  165. {
  166. strTxtValue = PV_GetAppName();
  167. }
  168. else if(strPropertyName == "Type")
  169. {
  170. strTxtValue = PV_GetType();
  171. }
  172. else if(strPropertyName == "ID")
  173. {
  174. strTxtValue = GetText(m_uID);
  175. }
  176. else if(strPropertyName == "SubsStatus" && theApp.m_bLoadedByMainProg)
  177. {
  178. BOOL bAlarm = FALSE;
  179. CPtrList listNode, listPos;
  180. CDataNodeBase* pNodeA = this;
  181. POSITION pos;
  182. BEGIN:
  183. do
  184. {
  185. if(pNodeA->PV_IsManagerNode())
  186. {//是设备
  187. CString strStatus;
  188. CString strErrorCount;
  189. pNodeA->V_GetPropertyTxtValue("S", strStatus);
  190. pNodeA->V_GetPropertyTxtValue("SpotErrorCount", strErrorCount);
  191. if(atoi(strStatus) > 0 || atoi(strErrorCount) > 0)
  192. bAlarm = TRUE;
  193. }
  194. else if(pNodeA->m_mapSubs.GetCount() > 0)
  195. {//是分类节点
  196. pos = pNodeA->m_mapSubs.GetPtrList().GetHeadPosition();
  197. GO_ON:
  198. while (pos && !bAlarm)
  199. {
  200. CDataNodeBase* pNode = (CDataNodeBase*)pNodeA->m_mapSubs.GetPtrList().GetNext(pos);
  201. if(pos)
  202. {
  203. listNode.AddTail(pNodeA);
  204. listPos.AddTail(pos);
  205. }
  206. pNodeA = pNode;
  207. goto BEGIN;
  208. }
  209. }
  210. if(listNode.GetCount() > 0 && !bAlarm)
  211. {
  212. pNodeA = (CDataNodeBase*)listNode.RemoveTail();
  213. pos = (POSITION)listPos.RemoveTail();
  214. goto GO_ON;
  215. }
  216. else
  217. break;
  218. } while(!bAlarm);
  219. strTxtValue = bAlarm?"2":"0";
  220. }
  221. else if(strPropertyName == "XML")
  222. {
  223. this->SaveObjToString(strTxtValue);
  224. }
  225. else if(strPropertyName == "UidPath")
  226. {
  227. strTxtValue = GetIdPath();
  228. }
  229. else if(strPropertyName == "NamePath")
  230. {
  231. strTxtValue = GetNamePath();
  232. }
  233. else if(strPropertyName == "NamePath2")
  234. {
  235. CString strPath = GetName();
  236. CString strNAMN;
  237. if(m_pParent != NULL
  238. && (!(m_pParent->V_GetPropertyTxtValue("NAMN", strNAMN)) || atoi(strNAMN)==0)
  239. )
  240. {
  241. strPath = m_pParent->GetName() + "." + strPath;
  242. }
  243. strTxtValue = strPath;
  244. }
  245. else if(strPropertyName == "SubsID")
  246. {
  247. // 添加子项
  248. // CPtrList listSort;
  249. // SortSubs(m_mapSubs, listSort);
  250. if(m_mapSubs.GetCount() > 0)
  251. {
  252. POSITION pos = m_mapSubs.GetPtrList().GetHeadPosition();
  253. while (pos)
  254. {
  255. CDataNodeBase* pNode = (CDataNodeBase*)m_mapSubs.GetPtrList().GetNext(pos);
  256. strTxtValue += GetText(pNode->m_uID) + ";";
  257. }
  258. }
  259. // elser
  260. // {
  261. // m_mutexMapProperties.Lock();
  262. // CString strKey;
  263. // CVariable* pVar = NULL;
  264. // int i = 0;
  265. // POSITION pos = m_mapExtProperties.GetStartPosition();
  266. // while(pos)
  267. // {
  268. // m_mapExtProperties.GetNextAssoc(pos, strKey, (void*&)pVar);
  269. // if(strKey.GetLength() < 3 || strKey.GetAt(2) != '_')
  270. // {
  271. // i++;
  272. // strTxtValue += GetText(i) + ";";
  273. // }
  274. // }
  275. // m_mutexMapProperties.Unlock();
  276. // }
  277. if(strTxtValue == "")
  278. strTxtValue = "<null>";
  279. }
  280. else if(strPropertyName == "Properties")
  281. {
  282. strTxtValue = "Name;";
  283. m_mutexMapProperties.Lock();
  284. POSITION pos = m_mapExtProperties.GetStartPosition();
  285. while (pos)
  286. {
  287. CString strKey;
  288. CVariable* pVar = NULL;
  289. m_mapExtProperties.GetNextAssoc(pos, strKey, (void*&)pVar);
  290. strTxtValue += strKey + ";";
  291. }
  292. m_mutexMapProperties.Unlock();
  293. if(strTxtValue == "")
  294. strTxtValue = "<null>";
  295. }
  296. else if(m_mapExtProperties.Lookup(strPropertyName, (void*&)pVar))
  297. {
  298. strTxtValue = pVar->GetTextValue();
  299. }
  300. else
  301. {
  302. bRtn = FALSE;
  303. }
  304. m_mutexMapProperties.Unlock();
  305. return bRtn;
  306. }
  307. // 获取属性的原始值
  308. CVariable* CDataNodeBase::GetProperty(CString strPropertyName)
  309. {
  310. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  311. ASSERT(FALSE);
  312. // AfxMessageBox(strPropertyName + ":获取属性,此函数停止使用!");
  313. CVariable *p = NULL;
  314. m_mutexMapProperties.Lock();
  315. m_mapExtProperties.Lookup(strPropertyName, (void*&)p);
  316. m_mutexMapProperties.Unlock();
  317. return p;
  318. }
  319. // 获取属性,支持无限深度子节点的属性获取
  320. BOOL CDataNodeBase::GetProperty(CString strPropertyPath, CString &strTxtValue)
  321. {
  322. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  323. BOOL bOK = FALSE;
  324. CString strPath;
  325. CString strPropertyName;
  326. SeparatePathAndProperty(strPropertyPath, strPath, strPropertyName);
  327. CDataNodeBase* pNode = this;
  328. if (strPath != "")
  329. {
  330. int nPos = strPath.Find('.');
  331. while (nPos > -1 && pNode)
  332. {
  333. CString strID = strPath.Left(nPos);
  334. UINT uID = (UINT)atoi(strID);
  335. strPath = strPath.Mid(nPos+1);
  336. nPos = strPath.Find('.');
  337. pNode = pNode->GetSub(uID);
  338. if(pNode && pNode->PV_IsManagerNode() == NET_LINK_MANAGER_NODE)
  339. {//作为站点连接管理节点,需要触发向远程获取数据的请求,需要调用重载的该函数。
  340. return pNode->GetProperty(strPath + strPropertyName, strTxtValue);
  341. }
  342. }
  343. }
  344. if(pNode)
  345. {
  346. bOK = pNode->V_GetPropertyTxtValue(strPropertyName, strTxtValue);
  347. }
  348. // else if(strPropertyName == "V" || strPropertyName == "Name")
  349. // {//增加功能:属性也可以用ID的方式来访问。
  350. // int nDotPos = strPropertyPath.ReverseFind('.');
  351. // if(nDotPos != -1)
  352. // {
  353. // CString strPropID = strPropertyPath.Left(nDotPos);
  354. // strPath = "";
  355. // int nDotPos2 = strPropID.ReverseFind('.');
  356. // if(nDotPos2 != -1)
  357. // {
  358. // strPath = strPropID.Left(nDotPos2);
  359. // strPropID = strPropID.Mid(nDotPos2+1);
  360. // }
  361. // int nPropID = atoi(strPropID);
  362. // pNode = GetSub(strPath);
  363. // if(pNode)
  364. // {
  365. // pNode->m_mutexMapProperties.Lock();
  366. // if(nPropID > 0 && nPropID <= pNode->m_mapExtProperties.GetCount() &&
  367. // pNode->m_mapSubs.GetCount() == 0)
  368. // {
  369. // CString strKey;
  370. // CVariable* pVar = NULL;
  371. // POSITION pos = pNode->m_mapExtProperties.GetStartPosition();
  372. // for(int i = 0; i < nPropID; )
  373. // {
  374. // pVar = NULL;
  375. // if(pos)
  376. // {
  377. // pNode->m_mapExtProperties.GetNextAssoc(pos, strKey, (void*&)pVar);
  378. // if(strKey.GetLength() < 3 || strKey.GetAt(2) != '_')
  379. // i++;
  380. // }
  381. // else
  382. // break;
  383. // }
  384. // if(i == nPropID)
  385. // {
  386. // bOK = TRUE;
  387. // if(strPropertyName == "V")
  388. // {
  389. // if(pVar)
  390. // strTxtValue = pVar->GetTextValue();
  391. // }
  392. // else
  393. // strTxtValue = CLanguage::GetCurLanguage(strKey);
  394. // }
  395. // }
  396. // pNode->m_mutexMapProperties.Unlock();
  397. // }
  398. // }
  399. // }
  400. return bOK;
  401. }
  402. //获取所有属性
  403. void CDataNodeBase::GetPropertyNames(CMapStringToPtr &mapProperties)
  404. {
  405. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  406. // ASSERT(FALSE);
  407. // AfxMessageBox(strPropertyName + ":获取属性,此函数停止使用!");
  408. m_mutexMapProperties.Lock();
  409. POSITION pos = m_mapExtProperties.GetStartPosition();
  410. while (pos)
  411. {
  412. CString strKey;
  413. CVariable* pVar = NULL;
  414. m_mapExtProperties.GetNextAssoc(pos, strKey, (void*&)pVar);
  415. mapProperties.SetAt(strKey, (LPVOID)pVar);
  416. }
  417. m_mutexMapProperties.Unlock();
  418. }
  419. // 更换属性
  420. void CDataNodeBase::ReplaceProperty(CString strPropertyName, CVariable* pVar)
  421. {
  422. m_mutexMapProperties.Lock();
  423. CVariable* pVarOld = NULL;
  424. if(m_mapExtProperties.Lookup(strPropertyName, (void*&)pVarOld))
  425. {
  426. try
  427. {
  428. delete pVarOld;
  429. }
  430. catch(...)
  431. {
  432. }
  433. if(pVar == NULL)
  434. m_mapExtProperties.RemoveKey(strPropertyName);
  435. }
  436. if(pVar)
  437. m_mapExtProperties.SetAt(strPropertyName, pVar);
  438. SetModified(TRUE);
  439. m_mutexMapProperties.Unlock();
  440. }
  441. // 设置或增加属性的字符串值,名字以V_开头表示每个派生类强烈建议重载该函数.
  442. BOOL CDataNodeBase::V_SetPropertyTxtValue(CString strPropertyName, CString strTxtValue, BOOL bAddIfNotExist, UINT uAttrFlag)
  443. {
  444. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  445. m_mutexMapProperties.Lock();
  446. BOOL bOK = FALSE;
  447. if(!IsUnEditableProperty(strPropertyName))
  448. {
  449. CVariable* pVar = NULL;
  450. if((strPropertyName == "V" || strPropertyName == "Value")
  451. && m_mapExtProperties.Lookup("Value", (void*&)pVar))
  452. {//Value的处理频度最大,故最先处理这个属性值
  453. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  454. TRACE("");
  455. pVar->SetTextValue(strTxtValue, pVar->GetVarType());
  456. bOK = TRUE;
  457. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  458. SetModified();
  459. }
  460. else if((strPropertyName == "S" || strPropertyName == "Status")
  461. && m_mapExtProperties.Lookup("Status", (void*&)pVar))
  462. {//Value的处理频度最大,故最先处理这个属性值
  463. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  464. TRACE("");
  465. pVar->SetTextValue(strTxtValue, pVar->GetVarType());
  466. bOK = TRUE;
  467. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  468. SetModified();
  469. }
  470. else if(strPropertyName == "Name")
  471. {
  472. m_strName = strTxtValue;
  473. bOK = TRUE;
  474. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  475. SetModified();
  476. }
  477. else if(strPropertyName == "XML")
  478. {
  479. this->Reset();
  480. this->LoadObjFromString(strTxtValue);
  481. //this->SetModified();
  482. this->SaveObj();
  483. }
  484. else if(strPropertyName == "RaiseEvent")
  485. {
  486. CString strLevel;
  487. V_GetPropertyTxtValue("Level", strLevel);
  488. ReportNewEvent(this, strTxtValue, atoi(strLevel), 1);
  489. }
  490. // else if(strPropertyName == "UidPath")
  491. // {
  492. // }
  493. else if(strPropertyName == "NamePath")
  494. {
  495. }
  496. else if(strPropertyName == "SubsID")
  497. {
  498. }
  499. else if(strPropertyName == "Properties")
  500. {
  501. }
  502. else if(strPropertyName == "ID")
  503. {
  504. if(m_pParent == NULL && atoi(strTxtValue) > 0)
  505. m_uID = atoi(strTxtValue);
  506. }
  507. else if(m_mapExtProperties.Lookup(strPropertyName, (void*&)pVar))
  508. {
  509. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  510. TRACE("");
  511. //////////////////////////////////////////////////////////////////////////
  512. if(strPropertyName == "PauseTimeRelease" && strTxtValue.GetLength() > 0)
  513. {//暂停时间设置时,如果给定的是数字,要自动转换为时间
  514. COleDateTime timeRelease;
  515. BOOL bValidTime = TRUE;
  516. if(strTxtValue.Find('-') == -1)
  517. {
  518. bValidTime = FALSE;
  519. }
  520. else
  521. {
  522. try
  523. {
  524. timeRelease.ParseDateTime(strTxtValue);
  525. }
  526. catch (...)
  527. {
  528. bValidTime = FALSE;
  529. }
  530. }
  531. if(!bValidTime)
  532. {
  533. COleDateTimeSpan span;
  534. span.SetDateTimeSpan(0, 0, atoi(strTxtValue), 0);
  535. timeRelease = COleDateTime::GetCurrentTime() + span;
  536. strTxtValue = timeRelease.Format("%Y-%m-%d %H:%M:%S");
  537. }
  538. }
  539. //////////////////////////////////////////////////////////////////////////
  540. pVar->SetTextValue(strTxtValue, pVar->GetVarType());
  541. bOK = TRUE;
  542. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  543. SetModified();
  544. }
  545. else if(bAddIfNotExist)
  546. {
  547. pVar = new CVariable;
  548. //pVar->SetAttributes(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG, TRUE, TRUE, VT_BSTR);
  549. pVar->SetTextValue(strTxtValue, VT_EMPTY);
  550. ReplaceProperty(strPropertyName, pVar);
  551. bOK = TRUE;
  552. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  553. SetModified();
  554. }
  555. if(uAttrFlag & ATTR_MANUAL_SET_VALUE)
  556. {
  557. CStringList strParams, strReturns;
  558. strParams.AddTail(strPropertyName);
  559. strParams.AddTail(strTxtValue);
  560. //???? don't delete thease lines:
  561. #ifndef DEMO_VERSION
  562. if(!Loadlmage(NULL))
  563. {
  564. static int nIncrease = 0;
  565. WORD wStop = *(&nIncrease);
  566. wStop++;
  567. wStop = (WORD)(DWORD)&theApp;
  568. wStop = wStop + (BYTE)(DWORD)(LPVOID)(&nIncrease);
  569. }
  570. else
  571. #endif
  572. AnyUpCall("", "", "ManualSet", strParams, strReturns);//控制性的操作改变某个属性,此时需要激发上层节点响应设置操作
  573. }
  574. }
  575. m_mutexMapProperties.Unlock();
  576. return bOK;
  577. }
  578. // 设置属性,支持无限深度子节点的属性设置
  579. BOOL CDataNodeBase::SetProperty(CString strPropertyPath, CString &strTxtValue, BOOL bAddIfNotExist, UINT uAttrFlag)
  580. {
  581. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  582. BOOL bOK = FALSE;
  583. CString strPath;
  584. CString strPropertyName;
  585. SeparatePathAndProperty(strPropertyPath, strPath, strPropertyName);
  586. CDataNodeBase* pNode = this;
  587. if (strPath != "")
  588. {
  589. int nPos = strPath.Find('.');
  590. while (nPos > -1 && pNode)
  591. {
  592. CString strID = strPath.Left(nPos);
  593. UINT uID = (UINT)atoi(strID);
  594. strPath = strPath.Mid(nPos+1);
  595. nPos = strPath.Find('.');
  596. pNode = pNode->GetSub(uID);
  597. if(pNode && pNode->PV_IsManagerNode() == NET_LINK_MANAGER_NODE)
  598. {//作为站点连接管理节点,需要触发向远程获取数据的请求,需要调用重载的该函数。
  599. return pNode->SetProperty(strPath + strPropertyName, strTxtValue, bAddIfNotExist, uAttrFlag);
  600. }
  601. }
  602. }
  603. if(pNode)
  604. {
  605. bOK = pNode->V_SetPropertyTxtValue(strPropertyName, strTxtValue, bAddIfNotExist, uAttrFlag);
  606. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  607. SetModified();
  608. }
  609. return bOK;
  610. }
  611. // 设置属性的值, 此函数必须重写.
  612. BOOL CDataNodeBase::SetProperty(CString strPropertyName, CVariable* pVar, UINT uAttrFlag)
  613. {
  614. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  615. BOOL bOK = FALSE;
  616. m_mutexMapProperties.Lock();
  617. if(strPropertyName != "ID" && strPropertyName != "AppName" && strPropertyName != "Type")
  618. {
  619. CVariable* pVarOld = NULL;
  620. if(m_mapExtProperties.Lookup(strPropertyName, (void*&)pVarOld))
  621. {
  622. delete pVarOld;
  623. ReplaceProperty(strPropertyName, pVar);
  624. bOK = TRUE;
  625. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  626. SetModified();
  627. }
  628. else
  629. {
  630. ReplaceProperty(strPropertyName, pVar);
  631. bOK = TRUE;
  632. if(uAttrFlag & ATTR_NEET_SET_MODIFY_FLAG)
  633. SetModified();
  634. }
  635. }
  636. m_mutexMapProperties.Unlock();
  637. return bOK;
  638. }
  639. // 保存对象到文件
  640. CString CDataNodeBase::V_GetSaveFileName()
  641. {
  642. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  643. return "";
  644. }
  645. // 保存对象到文件, 文件名由虚函数GetSaveFileName给定。
  646. BOOL CDataNodeBase::SaveObj()
  647. {
  648. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  649. BOOL bOK = FALSE;
  650. CString strFileName = V_GetSaveFileName();
  651. if(strFileName != "")
  652. bOK = SaveObj(strFileName);
  653. return bOK;
  654. }
  655. // 从文件中装载对象, 文件名由虚函数GetSaveFileName给定。
  656. BOOL CDataNodeBase::LoadObj()
  657. {
  658. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  659. BOOL bOK = FALSE;
  660. CString strFileName = V_GetSaveFileName();
  661. if(strFileName != "")
  662. bOK = LoadObj(strFileName);
  663. return bOK;
  664. }
  665. // 保存对象到文件
  666. BOOL CDataNodeBase::SaveObj(CString strFileName)
  667. {
  668. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  669. BOOL bOK = FALSE;
  670. CStdioFile file;
  671. CString strEncryptSeed = GetSaveEncryptSeed();
  672. CString strFileNameTemp = strFileName;
  673. try
  674. {
  675. if(strEncryptSeed != "")
  676. {
  677. strFileNameTemp += "T";
  678. }
  679. if(file.Open(strFileNameTemp, CFile::modeCreate|CFile::modeWrite))
  680. {
  681. //file.WriteString("<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + LineEnd);
  682. SaveObj(&file, "", this, FALSE);
  683. file.Close();
  684. bOK = TRUE;
  685. m_bModified = FALSE;
  686. }
  687. if(strEncryptSeed != "")
  688. {
  689. Encrypt(strFileNameTemp, strFileName, strEncryptSeed);
  690. }
  691. }
  692. catch (...)
  693. {
  694. TRACE("\n保存对象%s到文件%s时出现异常。", m_strName, strFileName);
  695. bOK = FALSE;
  696. }
  697. if(strEncryptSeed != "")
  698. {
  699. DeleteFile(strFileNameTemp);
  700. }
  701. return bOK;
  702. }
  703. // 保存对象到多行字符串
  704. BOOL CDataNodeBase::SaveObjToString(CString &strXmlTxt)
  705. {
  706. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  707. BOOL bOK = FALSE;
  708. CMemFile memFile;
  709. SaveObj(&memFile, "", this, TRUE);
  710. int nLen = memFile.GetLength();
  711. memFile.SeekToBegin();
  712. char* pBuf = new char[nLen+1];
  713. pBuf[nLen] = 0;
  714. memFile.Read(pBuf, nLen);
  715. strXmlTxt = pBuf;
  716. delete []pBuf;
  717. bOK = TRUE;
  718. // m_bModified = FALSE;
  719. return bOK;
  720. }
  721. //从一行字符串中提取属性信息
  722. void CDataNodeBase::PickItemsFromStrLine(
  723. CString strLine,
  724. CDataNodeBase* &pCurrentNode,
  725. CDataNodeBase* &pParent
  726. )
  727. {
  728. while(strLine.GetLength() > 0)
  729. {
  730. strLine.TrimLeft();
  731. if(strLine.Find("</") == 0)
  732. {
  733. int nPosEnd = strLine.Find('>');
  734. ASSERT(nPosEnd > -1);
  735. if(nPosEnd > -1)
  736. strLine = strLine.Mid(nPosEnd+1);
  737. else
  738. strLine = "";
  739. pCurrentNode = pParent;
  740. if(pParent)
  741. pParent = pParent->m_pParent;
  742. continue;
  743. }
  744. int nPos = strLine.Find('<');
  745. if(nPos == 0)
  746. {
  747. pParent = pCurrentNode;
  748. if(pCurrentNode == NULL)
  749. {
  750. pCurrentNode = this;
  751. pParent = this->m_pParent;
  752. }
  753. else
  754. {
  755. pCurrentNode = new CDataNodeBase;//CDataNodeBaseEx;
  756. //pCurrentNode->__classCanUseDirectly = TRUE;//需要临时指定为可用.
  757. }
  758. pCurrentNode->m_pParent = pParent;
  759. strLine = strLine.Mid(1);
  760. CString strItemType;
  761. if(PickItemType(strLine, strItemType))
  762. {
  763. pCurrentNode->m_strType = strItemType;
  764. }
  765. }
  766. else if(pCurrentNode != NULL)
  767. {
  768. // 获取属性
  769. CString strItem, strValue;
  770. while (PickOneItem(strLine, strItem, strValue))
  771. {
  772. if(strItem == "ID")
  773. {
  774. if(pCurrentNode != this)
  775. {//当前装载操作对象的ID不能被修改!
  776. pCurrentNode->m_uID = atoi(strValue);
  777. if(pParent != NULL)
  778. pParent->AddSub(pCurrentNode, TRUE);
  779. }
  780. pCurrentNode->V_SetPropertyTxtValue("UidPath", GetIdPath(), TRUE, NULL);
  781. }
  782. else if(strItem == "UidPath")
  783. { ;}//do nothing
  784. else if(strItem == "AppName")
  785. pCurrentNode->m_strAppName = strValue;
  786. else if(strItem == "Name")
  787. pCurrentNode->SetName(strValue);
  788. // else if(strItem == "DeviceType")
  789. // {
  790. // if(pCurrentNode != this)
  791. // {//当前装载操作对象的ID不能被修改!
  792. // pCurrentNode->V_SetPropertyTxtValue(strItem, strValue, TRUE, ATTR_NEET_SET_MODIFY_FLAG);
  793. // }
  794. // }
  795. else
  796. pCurrentNode->V_SetPropertyTxtValue(strItem, strValue, TRUE, ATTR_NEET_SET_MODIFY_FLAG);
  797. }
  798. }
  799. else
  800. {
  801. //文件头信息,不做处理.
  802. strLine = "";
  803. break;
  804. }
  805. }
  806. }
  807. //将子项替换为制定App内的对象
  808. void CDataNodeBase::ReplaceSubs()
  809. {
  810. POSITION pos = m_mapSubs.GetStartPosition();
  811. while(pos)
  812. {
  813. UINT uID = 0;
  814. CDataNodeBase *pNode = NULL;
  815. m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  816. CDataNodeBase* pNodeNew = ReplaceObj(pNode, TRUE);
  817. if(pNodeNew)
  818. {
  819. m_mapSubs.SetAt((LPVOID)uID, (LPVOID)pNodeNew);
  820. }
  821. }
  822. }
  823. // 从文件中装载对象
  824. BOOL CDataNodeBase::LoadObj(CString strFileName)
  825. {
  826. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  827. BOOL bOK = FALSE;
  828. CStdioFile file;
  829. CString strEncryptSeed = GetSaveEncryptSeed();
  830. try
  831. {
  832. if(strEncryptSeed != "")
  833. {
  834. Encrypt(strFileName, strFileName+"T", strEncryptSeed);
  835. strFileName += "T";
  836. }
  837. if(file.Open(strFileName, CFile::modeRead))
  838. {
  839. if(CheckXMLFile(file))
  840. {
  841. CDataNodeBase *pCurrentNode = NULL;
  842. CDataNodeBase *pParent = NULL;
  843. CString strLine;
  844. while (file.ReadString(strLine))
  845. {
  846. PickItemsFromStrLine(strLine, pCurrentNode, pParent);
  847. strLine = "";
  848. }
  849. }
  850. file.Close();
  851. m_bModified = FALSE;
  852. CString strFileTemp;
  853. strFileTemp.Format("%s\\DataCenterTemp", GetUserTempPath());
  854. if(strFileName.Find(strFileTemp) != 0)//如果是从临时文件中读取的,则不替换子项
  855. ReplaceSubs();
  856. bOK = TRUE;
  857. }
  858. }
  859. catch (...)
  860. {
  861. TRACE("\n从文件%s装载对象%s时出现异常。", m_strName, strFileName);
  862. }
  863. if(strEncryptSeed != "")
  864. {
  865. DeleteFile(strFileName);//删除解密时生成的临时文件
  866. }
  867. return bOK;
  868. }
  869. //从多行字符串中读取一行字符串
  870. BOOL CDataNodeBase::ReadStringLine(CString &strXmlTxt, CString &strLine)
  871. {
  872. BOOL bOK = FALSE;
  873. strLine = "";
  874. if(strXmlTxt.GetLength() > 0)
  875. {
  876. int nPos = strXmlTxt.Find(LineEnd);
  877. if(nPos > -1)
  878. {
  879. strLine = strXmlTxt.Left(nPos);
  880. strXmlTxt = strXmlTxt.Mid(nPos + LineEnd.GetLength());
  881. }
  882. else
  883. {
  884. strLine = strXmlTxt;
  885. strXmlTxt = "";
  886. }
  887. bOK = TRUE;
  888. }
  889. return bOK;
  890. }
  891. // 从字符串中装载对象
  892. BOOL CDataNodeBase::LoadObjFromString(CString strXmlTxt)
  893. {
  894. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  895. BOOL bOK = FALSE;
  896. for(int n = 0; n < 2; n++)
  897. {//若字符串过长将尝试采用先存到文件的方式处理,所有这里要进行两次处理。
  898. if(strXmlTxt.GetLength() < 500 || n == 1)
  899. {
  900. if(CheckXMLString(strXmlTxt))
  901. {
  902. CDataNodeBase *pCurrentNode = NULL;
  903. CDataNodeBase *pParent = NULL;
  904. CString strLine;
  905. while (ReadStringLine(strXmlTxt, strLine))
  906. {
  907. PickItemsFromStrLine(strLine, pCurrentNode, pParent);
  908. strLine = "";
  909. }
  910. }
  911. break;
  912. }
  913. else
  914. {
  915. CString strFileTemp;
  916. strFileTemp.Format("%s\\DataCenterTemp%d.xml", GetUserTempPath(), rand());
  917. CStdioFile fileTemp;
  918. CFileException e;
  919. try
  920. {
  921. if(fileTemp.Open(strFileTemp, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary, &e))
  922. {
  923. fileTemp.WriteString(strXmlTxt);
  924. fileTemp.Close();
  925. if(LoadObj(strFileTemp))
  926. bOK = TRUE;
  927. }
  928. }
  929. catch (...)
  930. {
  931. }
  932. DeleteFile(strFileTemp);
  933. if(bOK)
  934. break;
  935. }
  936. }
  937. // m_bModified = FALSE;
  938. // ReplaceSubs();从字符串装载时不替换内容,因为这种情况发生在网络浏览端,
  939. bOK = TRUE;
  940. return bOK;
  941. }
  942. // 更换子项
  943. void CDataNodeBase::ReplaceSub(UINT uID, CDataNodeBase* pNodeNew)
  944. {
  945. //删除原来的ID相同的数据
  946. this->m_mutexMapSubs.Lock();
  947. CDataNodeBase* pNodeOld = NULL;
  948. if(m_mapSubs.Lookup((LPVOID)uID, (void*&)pNodeOld))
  949. {
  950. delete pNodeOld;
  951. }
  952. m_mapSubs.SetAt((LPVOID)uID, (LPVOID)pNodeNew);
  953. this->m_mutexMapSubs.Unlock();
  954. }
  955. // 添加对象为子项
  956. void CDataNodeBase::AddSub(CDataNodeBase *pSub, BOOL bNotChangeID)
  957. {
  958. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  959. m_mutexMapSubs.Lock();
  960. if(!bNotChangeID)
  961. {
  962. if(pSub->m_uID == 0)
  963. pSub->m_uID = m_mapSubs.GetCount() + 1;
  964. int nCount = m_mapSubs.GetCount();
  965. if(nCount > 0)
  966. {
  967. BOOL *pUint = new BOOL[nCount];
  968. memset(pUint, FALSE, sizeof(BOOL)*nCount);
  969. POSITION pos = m_mapSubs.GetStartPosition();
  970. while(pos)
  971. {
  972. UINT uID = 0;
  973. CDataNodeBase *pNode = NULL;
  974. m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  975. if(uID <= (UINT)nCount && uID > 0)
  976. pUint[uID-1] = TRUE;
  977. }
  978. for(int i = 0; i < nCount; i++)
  979. {
  980. if(pUint[i] == FALSE)
  981. {
  982. pSub->m_uID = i+1;
  983. break;
  984. }
  985. }
  986. delete []pUint;
  987. }
  988. }
  989. ReplaceSub(pSub->m_uID, pSub);
  990. pSub->SetParent(this);
  991. m_mutexMapSubs.Unlock();
  992. SetModified();
  993. }
  994. // 移除子项
  995. void CDataNodeBase::RemoveSub(CDataNodeBase* pSub)
  996. {
  997. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  998. CDataNodeBase* pSubFind = NULL;
  999. if(m_mapSubs.Lookup((LPVOID)pSub->m_uID, (void*&)pSubFind) && pSub == pSubFind)
  1000. {
  1001. m_mapSubs.RemoveKey((LPVOID)pSub->m_uID);
  1002. SetModified();
  1003. }
  1004. // 删除工作不在此处进行!
  1005. TRACE("\n进行移除子项操作RemoveSub时,子项不会被删除,请在此过程外进行手动删除!");
  1006. }
  1007. // 动态库的名字
  1008. //注意基类不能用AfxGetAppName(); 而其派生类,相反,必须用AfxGetAppName();
  1009. CString CDataNodeBase::PV_GetAppName()
  1010. {
  1011. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1012. return m_strAppName;
  1013. }
  1014. // 获取类型名字, 名字以PV_开头表示每个派生类都必须重载该函数.
  1015. //注意基类不能直接用类类型的名字,而用变量,而其派生类, 相反, 必须返回其类名的字符串
  1016. CString CDataNodeBase::PV_GetType()
  1017. {
  1018. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1019. if(m_strType == "")
  1020. return "CDataNodeBase";
  1021. return m_strType;
  1022. }
  1023. // 任意函数调用,万能接口,调用通常是顶层调用底层的节点
  1024. void CDataNodeBase::AnyDownCall(
  1025. int nCallStackDepth,
  1026. CString strFuncName,
  1027. CStringList &strParams,
  1028. CStringList &strReturns
  1029. )
  1030. {
  1031. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1032. if(nCallStackDepth < MAX_DEPTH)
  1033. {//最多往下递归256层,防止连环连接出现死递归
  1034. if(strFuncName == "SetModified")
  1035. SetModified(strParams.GetCount()?atoi(strParams.GetHead()):TRUE);
  1036. POSITION pos = m_mapSubs.GetStartPosition();
  1037. while (pos)
  1038. {
  1039. UINT uID;
  1040. CDataNodeBase* pNode = NULL;
  1041. m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  1042. pNode->AnyDownCall(nCallStackDepth+1, strFuncName, strParams, strReturns);
  1043. }
  1044. }
  1045. }
  1046. // 任意汇报接口,万能接口,与AnyDownCall的区别是,该接口是由底层节点往顶层调用
  1047. void CDataNodeBase::AnyUpCall(
  1048. CString strPathInternal, //调用发出位置路径内部管理路径,用ID作为节点名的路径
  1049. CString strPathShow, //调用发出位置路径显示路径,用名字作为节点的路径
  1050. CString strFuncName, //函数名
  1051. CStringList &strParams, //函数的输入参数表
  1052. CStringList &strReturns //函数的输出参数表
  1053. )
  1054. {
  1055. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1056. if(m_pParent && strPathInternal.GetLength()<=255)//防止连环连接而出现死递归,限制最深路径不超过255个字符
  1057. {
  1058. CString strPathShow2;
  1059. CString strNotAppendMyName;
  1060. if(strPathShow != "" && V_GetPropertyTxtValue("NAMN", strNotAppendMyName) && atoi(strNotAppendMyName) != 0)
  1061. strPathShow2 = strPathShow;
  1062. else
  1063. strPathShow2 = GetName()+"."+strPathShow;
  1064. m_pParent->AnyUpCall(GetText(m_uID)+"."+strPathInternal,
  1065. strPathShow2,
  1066. strFuncName,
  1067. strParams,
  1068. strReturns);
  1069. }
  1070. }
  1071. void CDataNodeBase::FreeSubs()
  1072. {
  1073. POSITION pos = m_mapSubs.GetStartPosition();
  1074. while (pos)
  1075. {
  1076. CDataNodeBase *pSub = NULL;
  1077. UINT uID = -1;
  1078. m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pSub);
  1079. delete pSub;
  1080. }
  1081. m_mapSubs.RemoveAll();
  1082. }
  1083. // 检查文件是否为正确的xml文件
  1084. BOOL CDataNodeBase::CheckXMLFile(CStdioFile &file)
  1085. {
  1086. BOOL bXMLOK = TRUE;
  1087. int nBracket = 0;
  1088. int nFlash = 0;//反斜杠统计
  1089. CString strLine;
  1090. while(file.ReadString(strLine))
  1091. {
  1092. int nPos = MyStrFind(strLine, "</");//strLine.Find("</");
  1093. if(nPos >= 0)
  1094. nFlash--;
  1095. else if(MyStrFind(strLine, '<') >= 0)//strLine.Find('<') >= 0)
  1096. nFlash++;
  1097. if(nFlash < 0)
  1098. {
  1099. bXMLOK = FALSE;
  1100. goto EXIT;
  1101. }
  1102. char cPrev = '?';
  1103. for(int i=0; i<strLine.GetLength(); i++)
  1104. {
  1105. char c = strLine.GetAt(i);
  1106. if(c == '<' && cPrev != '\\')
  1107. nBracket++;
  1108. else if(c == '>' && cPrev != '\\')
  1109. nBracket--;
  1110. if(nBracket < 0)
  1111. {
  1112. bXMLOK = FALSE;
  1113. goto EXIT;
  1114. }
  1115. if((c == '=' && cPrev != '\\') &&
  1116. (
  1117. strLine.GetLength()<=i+2 || strLine.GetAt(i+1) != '"' ||
  1118. strLine.Find('"', i+2) == -1))
  1119. {
  1120. bXMLOK = FALSE;
  1121. goto EXIT;
  1122. }
  1123. cPrev = c;
  1124. }
  1125. }
  1126. if(nBracket != 0 || nFlash != 0)
  1127. bXMLOK = FALSE;
  1128. EXIT:
  1129. file.SeekToBegin();
  1130. return bXMLOK;
  1131. }
  1132. //检查多行字符串是否为合法的xml字符串
  1133. BOOL CDataNodeBase::CheckXMLString(CString strXmlTxt)
  1134. {
  1135. BOOL bXMLOK = TRUE;
  1136. int nBracket = 0;
  1137. int nFlash = 0;//反斜杠统计
  1138. CString strLine;
  1139. while(ReadStringLine(strXmlTxt, strLine))
  1140. {
  1141. int nPos = MyStrFind(strLine, "</");//strLine.Find("</");
  1142. if(nPos >= 0)
  1143. nFlash--;
  1144. else if(MyStrFind(strLine, '<') >= 0)//strLine.Find('<') >= 0)
  1145. nFlash++;
  1146. if(nFlash < 0)
  1147. {
  1148. bXMLOK = FALSE;
  1149. goto EXIT;
  1150. }
  1151. char cPrev = '?';
  1152. for(int i=0; i<strLine.GetLength(); i++)
  1153. {
  1154. char c = strLine.GetAt(i);
  1155. if(c == '<' && cPrev != '\\')
  1156. nBracket++;
  1157. else if(c == '>' && cPrev != '\\')
  1158. nBracket--;
  1159. if(nBracket < 0)
  1160. {
  1161. bXMLOK = FALSE;
  1162. goto EXIT;
  1163. }
  1164. if((c == '=' && cPrev != '\\') &&
  1165. (
  1166. strLine.GetLength()<=i+2 || strLine.GetAt(i+1) != '"' ||
  1167. strLine.Find('"', i+2) == -1))
  1168. {
  1169. bXMLOK = FALSE;
  1170. goto EXIT;
  1171. }
  1172. cPrev = c;
  1173. }
  1174. strLine = "";
  1175. }
  1176. if(nBracket != 0 || nFlash != 0)
  1177. bXMLOK = FALSE;
  1178. EXIT:
  1179. return bXMLOK;
  1180. }
  1181. // 保存对象到文件
  1182. void CDataNodeBase::SaveObj(CFile* pFile, CString strHeadSpace, CDataNodeBase* pNodeRoot, BOOL bIncludeMgrSub)
  1183. {
  1184. if(pFile == NULL)
  1185. return;
  1186. CString strLine;
  1187. // 节点:类名为节点名
  1188. strLine = strHeadSpace + "<" + PV_GetType() + " ";
  1189. pFile->Write(strLine, strLine.GetLength());
  1190. //AppName:动态库名字
  1191. strLine = "AppName=\"" + PV_GetAppName() + "\" ";
  1192. pFile->Write(strLine, strLine.GetLength());
  1193. //Name:动态库名字
  1194. strLine = "Name=\"" + GetSavedStr(GetName()) + "\" ";
  1195. pFile->Write(strLine, strLine.GetLength());
  1196. //ID:
  1197. CString strTemp;
  1198. strTemp.Format("ID=\"%d\" ", m_uID);
  1199. strLine = strTemp;
  1200. pFile->Write(strLine, strLine.GetLength());
  1201. // 其他动态属性
  1202. CMapStringToPtr mapProperties;
  1203. GetPropertyNames(mapProperties);
  1204. POSITION pos = mapProperties.GetStartPosition();
  1205. while (pos)
  1206. {
  1207. CString strKey;
  1208. CVariable* pVar = NULL;
  1209. mapProperties.GetNextAssoc(pos, strKey, (void*&)pVar);
  1210. //if(pVar->m_bIsDesignTimeVar)
  1211. {
  1212. CString strSaveFmtTxt = pVar->GetSaveFmtTxt();
  1213. if(strSaveFmtTxt.Find("DTV:-1,") == -1)
  1214. {
  1215. strSaveFmtTxt = GetSavedStr(strSaveFmtTxt);
  1216. strLine = LineEnd + strHeadSpace + "\t" + strKey + "\t=\"" + strSaveFmtTxt + "\"";
  1217. pFile->Write(strLine, strLine.GetLength());
  1218. }
  1219. }
  1220. }
  1221. strLine = " >" + LineEnd;
  1222. pFile->Write(strLine, strLine.GetLength());
  1223. if(PV_IsManagerNode() && this != pNodeRoot && !bIncludeMgrSub)
  1224. {// 是管理类节点,并且该节点不是当前保存操作的根,并且当前不是保存到字符串中,则子项不在这里保存,而是在该节点自己的保存函数中保存
  1225. // Do nothing else.
  1226. }
  1227. else
  1228. {//
  1229. // 子项:
  1230. // CPtrList listSort;
  1231. // SortSubs(m_mapSubs, listSort);
  1232. POSITION pos = m_mapSubs.GetPtrList().GetHeadPosition();
  1233. while (pos)
  1234. {
  1235. UINT uID = 0;
  1236. CDataNodeBase* pNode = (CDataNodeBase*)m_mapSubs.GetPtrList().GetNext(pos);
  1237. pNode->SaveObj(pFile, strHeadSpace + "\t", pNodeRoot, bIncludeMgrSub);
  1238. }
  1239. }
  1240. strLine = strHeadSpace + "</" + PV_GetType() + ">" + LineEnd;
  1241. pFile->Write(strLine, strLine.GetLength());
  1242. }
  1243. // 字符串中提炼1个属性,并将提炼的属性从字符串中移出
  1244. BOOL CDataNodeBase::PickItemType(CString &strLine, CString &strItemType)
  1245. {
  1246. strLine.TrimLeft();
  1247. strLine.TrimLeft('>');
  1248. strLine.TrimLeft('\r');
  1249. // 优先找类名字(类名字是出现等号之前出现空格时之前的字符串)
  1250. for(int i = 0; i < strLine.GetLength(); i++)
  1251. {
  1252. char c = strLine.GetAt(i);
  1253. if(c == ' ')
  1254. {
  1255. strItemType = strLine.Left(i);
  1256. strLine = strLine.Mid(i + 1);
  1257. break;
  1258. }
  1259. }
  1260. //
  1261. if(strItemType == "")
  1262. {
  1263. strItemType = strLine;
  1264. strLine = "";
  1265. }
  1266. return strItemType.GetLength()>0;
  1267. }
  1268. // 字符串中提炼1个属性,并将提炼的属性从字符串中移出
  1269. BOOL CDataNodeBase::PickOneItem(CString &strLine, CString &strItem, CString &strValue)
  1270. {
  1271. strItem = "";
  1272. strValue = "";
  1273. strLine.TrimLeft();
  1274. strLine.TrimLeft('>');
  1275. strLine.TrimLeft('\r');
  1276. //找属性
  1277. int nPos = strLine.Find('=');
  1278. if(nPos > -1)
  1279. {
  1280. strItem = strLine.Left(nPos);
  1281. strItem.TrimRight();
  1282. strLine = strLine.Mid(nPos + 1);
  1283. strLine.TrimLeft();
  1284. // if(strLine.GetLength() > 0 &&
  1285. // strLine.GetAt(0) == '"' &&
  1286. // strLine.Find('"', 1) > 0 )
  1287. if(strLine.GetLength() > 0 &&
  1288. strLine.GetAt(0) == '"' &&
  1289. MyStrFind(strLine, '"', 1) > 0 )
  1290. {
  1291. nPos = MyStrFind(strLine, '"', 1);//strLine.Find('"', 1);
  1292. ASSERT(nPos > 0);
  1293. strValue = strLine.Left(nPos);
  1294. strValue = strValue.Mid(1);
  1295. strValue = GetOrigStr(strValue);
  1296. strLine = strLine.Mid(nPos + 1);
  1297. }
  1298. else
  1299. ASSERT(FALSE);
  1300. }
  1301. if(strItem == "")
  1302. {
  1303. strItem = strLine;
  1304. strLine = "";
  1305. }
  1306. return strItem.GetLength()>0;
  1307. }
  1308. CDataNodeBase* CDataNodeBase::ReplaceObj(CDataNodeBase* pNodeOld, BOOL bAlsoSubs)
  1309. {
  1310. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1311. CDataNodeBase* pNodeNew = NULL;
  1312. Def_CreateObj* fpCreateObj = NULL;
  1313. Def_ReleaseObj* fpReleaseObj = NULL;
  1314. if(theApp.GetObjFuncs(pNodeOld->PV_GetAppName(), fpCreateObj, fpReleaseObj))
  1315. {
  1316. try
  1317. {
  1318. pNodeNew = fpCreateObj(pNodeOld->PV_GetType());
  1319. pNodeNew->m_uID = pNodeOld->m_uID;
  1320. pNodeNew->SetName(pNodeOld->GetName());
  1321. // 拷贝属性
  1322. pNodeOld->m_mutexMapProperties.Lock();
  1323. //CMapStringToPtr mapProperties;
  1324. //pNodeOld->V_GetPropertyNames(mapProperties);
  1325. POSITION pos = pNodeOld->m_mapExtProperties.GetStartPosition();
  1326. while (pos)
  1327. {
  1328. CString strItem;
  1329. CVariable* pVar = NULL;
  1330. pNodeOld->m_mapExtProperties.GetNextAssoc(pos, strItem, (void*&)pVar);
  1331. pNodeNew->ReplaceProperty(strItem, pVar);
  1332. }
  1333. pNodeOld->m_mapExtProperties.RemoveAll();// 清除但不能删除关联的对象!
  1334. pNodeOld->m_mutexMapProperties.Unlock();
  1335. // 拷贝子项:
  1336. pNodeOld->m_mutexMapSubs.Lock();
  1337. pos = pNodeOld->m_mapSubs.GetStartPosition();
  1338. while(pos)
  1339. {
  1340. UINT uID = 0;
  1341. CDataNodeBase *pNode = NULL;
  1342. pNodeOld->m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  1343. pNode->m_pParent = pNodeNew;
  1344. pNodeNew->ReplaceSub(pNode->m_uID, pNode);
  1345. }
  1346. pNodeOld->m_mapSubs.RemoveAll();// 清除但不能删除关联的对象!
  1347. pNodeOld->m_mutexMapSubs.Unlock();
  1348. pNodeNew->m_bModified = FALSE;
  1349. // 父项的更新
  1350. if(pNodeOld->m_pParent != NULL)
  1351. {
  1352. pNodeNew->m_pParent = pNodeOld->m_pParent;
  1353. pNodeOld->m_pParent->m_mapSubs.SetAt((LPVOID)pNodeOld->m_uID, pNodeNew);
  1354. }
  1355. delete pNodeOld;// 析构函数为虚函数,删除可不需要通过接口ReleaseObj.
  1356. //pNodeOld = pNodeNew;
  1357. if(bAlsoSubs)
  1358. {
  1359. pos = pNodeNew->m_mapSubs.GetStartPosition();
  1360. while(pos)
  1361. {
  1362. UINT uID = 0;
  1363. CDataNodeBase *pNode = NULL;
  1364. pNodeNew->m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  1365. CDataNodeBase* pNodeNewSub = ReplaceObj(pNode, TRUE);
  1366. if(pNodeNewSub)
  1367. {
  1368. pNodeNew->m_mapSubs.SetAt((LPVOID)uID, (LPVOID)pNodeNewSub);
  1369. }
  1370. }
  1371. }
  1372. }
  1373. catch (...)
  1374. {
  1375. }
  1376. }
  1377. return pNodeNew;
  1378. }
  1379. // 由全路径分离出路径和属性名称
  1380. void CDataNodeBase::SeparatePathAndProperty(CString strFullName, CString &strPath, CString &strPropertyName)
  1381. {
  1382. int nPos = strFullName.ReverseFind('.');
  1383. if(nPos > -1)
  1384. {
  1385. strPath = strFullName.Left(nPos+1);
  1386. strPropertyName = strFullName.Mid(nPos+1);
  1387. }
  1388. else
  1389. strPropertyName = strFullName;
  1390. }
  1391. // 获取名字方式表达的路径
  1392. CString CDataNodeBase::GetNamePath()
  1393. {
  1394. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1395. CString strPath;
  1396. CDataNodeBase* pNode = this;
  1397. while (pNode->m_pParent != NULL)
  1398. {
  1399. strPath = pNode->GetName() + "." + strPath;
  1400. pNode = pNode->m_pParent;
  1401. }
  1402. return strPath;
  1403. }
  1404. // 获取ID方式表达的路径
  1405. CString CDataNodeBase::GetIdPath()
  1406. {
  1407. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1408. CString strPath;
  1409. CDataNodeBase* pNode = this;
  1410. while (pNode->m_pParent != NULL)
  1411. {
  1412. CString strID;
  1413. strID.Format("%u", pNode->m_uID);
  1414. strPath = strID + "." + strPath;
  1415. pNode = pNode->m_pParent;
  1416. }
  1417. return strPath;
  1418. }
  1419. // 将对象展现在树结构中
  1420. HTREEITEM CDataNodeBase::BuildTree(CDataNodeTree &treeCtrl,
  1421. HTREEITEM hItemNow,
  1422. int nBuildDepth,
  1423. BOOL bBuildSubOnly,
  1424. HTREEITEM hParent,
  1425. HTREEITEM hInsertAfter)
  1426. {
  1427. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1428. ASSERT(FALSE);//已经停止使用此函数!
  1429. ASSERT(treeCtrl.m_hWnd);
  1430. return BuildTree(treeCtrl.GetTreeCtrl(), hItemNow, nBuildDepth, bBuildSubOnly, hParent, hInsertAfter);
  1431. // // 删除原有子项
  1432. // if(hItemNow != TVI_ROOT && hItemNow != NULL)
  1433. // {
  1434. // HTREEITEM hSub = treeCtrl.GetTreeCtrl().GetChildItem(hItemNow);
  1435. // while (hSub)
  1436. // {
  1437. // HTREEITEM hNext = treeCtrl.GetTreeCtrl().GetNextSiblingItem(hSub);
  1438. // treeCtrl.GetTreeCtrl().DeleteItem(hSub);
  1439. // hSub = hNext;
  1440. // }
  1441. // }
  1442. // // 创建自己的节点
  1443. // HTREEITEM hItemNew = hItemNow;
  1444. // if(!bBuildSubOnly)
  1445. // {// 创建自己在树中的节点
  1446. // int nImage, nSelectedImage;
  1447. // GetImage(treeCtrl.m_imageList, nImage, nSelectedImage);
  1448. // hItemNew = treeCtrl.GetTreeCtrl().InsertItem(GetName(), nImage, nSelectedImage, hParent, hInsertAfter);
  1449. // treeCtrl.GetTreeCtrl().SetItemData(hItemNew, (DWORD)this);
  1450. // }
  1451. //
  1452. // if(nBuildDepth > 0)
  1453. // {
  1454. // // 添加子项
  1455. //// CPtrList listSort;
  1456. //// SortSubs(m_mapSubs, listSort);
  1457. // POSITION pos = m_mapSubs.GetPtrList().GetHeadPosition();
  1458. // while (pos)
  1459. // {
  1460. // UINT uID = 0;
  1461. // CDataNodeBase* pNode = (CDataNodeBase*)m_mapSubs.GetPtrList().GetNext(pos);
  1462. // pNode->BuildTree(treeCtrl, TVI_ROOT, nBuildDepth-1, FALSE, hItemNew);
  1463. // }
  1464. // }
  1465. // return hItemNew;
  1466. }
  1467. // 将对象展现在树结构中
  1468. HTREEITEM CDataNodeBase::BuildTree(CDataNodeTreeCtrl &treeCtrl,
  1469. HTREEITEM hItemNow,
  1470. int nBuildDepth,
  1471. BOOL bBuildSubOnly,
  1472. HTREEITEM hParent,
  1473. HTREEITEM hInsertAfter)
  1474. {
  1475. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1476. ASSERT(treeCtrl.m_hWnd);
  1477. // 删除原有子项
  1478. if(hItemNow != TVI_ROOT && hItemNow != NULL)
  1479. {
  1480. HTREEITEM hSub = treeCtrl.GetTreeCtrl().GetChildItem(hItemNow);
  1481. while (hSub)
  1482. {
  1483. HTREEITEM hNext = treeCtrl.GetTreeCtrl().GetNextSiblingItem(hSub);
  1484. treeCtrl.GetTreeCtrl().DeleteItem(hSub);
  1485. hSub = hNext;
  1486. }
  1487. }
  1488. // 创建自己的节点
  1489. HTREEITEM hItemNew = hItemNow;
  1490. if(!bBuildSubOnly)
  1491. {// 创建自己在树中的节点
  1492. if(hItemNow != TVI_ROOT && hItemNow != NULL)
  1493. {
  1494. treeCtrl.GetTreeCtrl().DeleteItem(hItemNow);
  1495. }
  1496. int nImage, nSelectedImage;
  1497. GetImage(treeCtrl.m_imageList, nImage, nSelectedImage);
  1498. hItemNew = treeCtrl.GetTreeCtrl().InsertItem(GetName(), nImage, nSelectedImage, hParent, hInsertAfter);
  1499. treeCtrl.GetTreeCtrl().SetItemData(hItemNew, (DWORD)this);
  1500. treeCtrl.GetTreeCtrl().m_mapNodeTohItem.SetAt(this, hItemNew);
  1501. CString strPause;
  1502. BOOL bPause = FALSE;
  1503. if(V_GetPropertyTxtValue("Pause", strPause) && (strPause == "1" || strPause.Find('T') == 0))
  1504. bPause = TRUE;
  1505. treeCtrl.ChangePauseDeviceIco(hItemNew, bPause);
  1506. }
  1507. if(nBuildDepth > 0)
  1508. {
  1509. // 添加子项
  1510. // CPtrList listSort;
  1511. // SortSubs(m_mapSubs, listSort);
  1512. POSITION pos = m_mapSubs.GetPtrList().GetHeadPosition();
  1513. while (pos)
  1514. {
  1515. UINT uID = 0;
  1516. CDataNodeBase* pNode = (CDataNodeBase*)m_mapSubs.GetPtrList().GetNext(pos);
  1517. pNode->BuildTree(treeCtrl, TVI_ROOT, nBuildDepth-1, FALSE, hItemNew);
  1518. }
  1519. }
  1520. return hItemNew;
  1521. }
  1522. // 获取图标
  1523. void CDataNodeBase::GetImage(CImageListDyn &imageList, int &nImage, int &nSelectedImage)
  1524. {
  1525. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1526. CString strProptery;
  1527. this->V_GetPropertyTxtValue("Image", strProptery);
  1528. nImage = imageList.GetImage(strProptery);
  1529. this->V_GetPropertyTxtValue("SelectedImage", strProptery);
  1530. nSelectedImage = imageList.GetImage(strProptery);
  1531. if(nImage == -1)
  1532. nImage = 0;
  1533. if(nSelectedImage == -1)
  1534. nSelectedImage = 1;
  1535. }
  1536. UINT CDataNodeBase::GetID()
  1537. {
  1538. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1539. return m_uID;
  1540. }
  1541. // 是否为管理类的节点
  1542. BOOL CDataNodeBase::PV_IsManagerNode()
  1543. {
  1544. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1545. return FALSE;
  1546. }
  1547. // 对象配置接口
  1548. BOOL CDataNodeBase::DoConfig(CDataNodeBase* pPrjRoot, CString strPathCur)
  1549. {
  1550. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1551. CDataNodeBase* pMgr = this;
  1552. CString strPathCurNew;
  1553. while(pMgr->m_pParent)
  1554. {
  1555. CString strID;
  1556. strID.Format("%u", pMgr->m_uID);
  1557. strPathCurNew = strID + "." + strPathCurNew;
  1558. pMgr = pMgr->m_pParent;
  1559. if(pMgr->PV_IsManagerNode())
  1560. {
  1561. return pMgr->DoConfigSub(pPrjRoot, this, strPathCurNew);
  1562. }
  1563. }
  1564. return FALSE;
  1565. }
  1566. // 子对象配置接口
  1567. BOOL CDataNodeBase::DoConfigSub(CDataNodeBase* pPrjRoot, CDataNodeBase* pNodeSub, CString strPathCur)
  1568. {
  1569. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1570. return FALSE;
  1571. }
  1572. // 对象属性编辑接口,此接口只负责编辑内容,不负责将修改后的值应用到相应点。(因为要支持多点同时设置。)
  1573. BOOL CDataNodeBase::EditProperty(CString strProp, CString& strValue, UINT& uOption, UINT& uResult)
  1574. {
  1575. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1576. BOOL bRtn = FALSE;
  1577. if(m_pParent && m_pParent->EditProperty(strProp, strValue, uOption, uResult))
  1578. bRtn = TRUE;
  1579. return bRtn;
  1580. }
  1581. // 获取修改标志
  1582. BOOL CDataNodeBase::GetModified()
  1583. {
  1584. return m_bModified;
  1585. }
  1586. // 设置修改标志
  1587. void CDataNodeBase::SetModified(BOOL bModified)
  1588. {
  1589. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1590. m_bModified = bModified;
  1591. if(bModified)
  1592. {// 如果是将修改标志置位TRUE,则同时修改所在的管理类的对象的修改标志也修改为修改标志,以便保存。
  1593. CDataNodeBase *pNode = m_pParent;
  1594. while (pNode)
  1595. {
  1596. if(pNode->PV_IsManagerNode())
  1597. {
  1598. pNode->m_bModified = bModified;
  1599. break;
  1600. }
  1601. pNode = pNode->m_pParent;
  1602. }
  1603. }
  1604. }
  1605. // 获取指定属性的特性
  1606. CString CDataNodeBase::GetAttributes(CString strPropertyName)
  1607. {
  1608. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1609. m_mutexMapProperties.Lock();
  1610. CString strAttr;
  1611. CVariable var;
  1612. if(strPropertyName == "Name")
  1613. {
  1614. var.SetAttributes(TRUE, TRUE, TRUE, VT_BSTR);
  1615. }
  1616. else if(strPropertyName == "ID")
  1617. {
  1618. var.SetAttributes(TRUE, TRUE, FALSE, VT_UINT);
  1619. }
  1620. else if(strPropertyName == "AppName")
  1621. {
  1622. var.SetAttributes(TRUE, TRUE, FALSE, VT_BSTR);
  1623. }
  1624. else if(strPropertyName == "Type")
  1625. {
  1626. var.SetAttributes(TRUE, TRUE, FALSE, VT_BSTR);
  1627. }
  1628. else
  1629. {
  1630. CVariable* pVar = GetProperty(strPropertyName);
  1631. if(pVar)
  1632. strAttr = pVar->GetAttributesMsg();
  1633. }
  1634. m_mutexMapProperties.Unlock();
  1635. if(strAttr == "")
  1636. strAttr = var.GetAttributesMsg();
  1637. return strAttr;
  1638. }
  1639. // 工程装载后调用
  1640. void CDataNodeBase::DoAfterProjectLoaded(CString strProjectPath)
  1641. {
  1642. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1643. POSITION pos = m_mapSubs.GetStartPosition();
  1644. while (pos)
  1645. {
  1646. UINT uID;
  1647. CDataNodeBase* pNode = NULL;
  1648. m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  1649. pNode->DoAfterProjectLoaded(strProjectPath);
  1650. }
  1651. }
  1652. // 工程关闭前调用
  1653. void CDataNodeBase::DoBeforeProjectClose()
  1654. {
  1655. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1656. POSITION pos = m_mapSubs.GetStartPosition();
  1657. while (pos)
  1658. {
  1659. UINT uID;
  1660. CDataNodeBase* pNode = NULL;
  1661. m_mapSubs.GetNextAssoc(pos, (void*&)uID, (void*&)pNode);
  1662. pNode->DoBeforeProjectClose();
  1663. }
  1664. }
  1665. //代理的方式异步调用获取属性
  1666. void CDataNodeBase::AsyncDelegateGetProperty(CString strPropertyName)
  1667. {
  1668. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1669. if(m_pParent && strPropertyName.GetLength()<=255)//防止连环连接而出现死递归,限制最深路径不超过255个字符
  1670. {
  1671. m_pParent->AsyncDelegateGetProperty(GetText(m_uID)+"."+strPropertyName);
  1672. }
  1673. }
  1674. //代理的方式异步接收属性,该事件在调用AsyncDelegateGetProperty获取请求后对方回应后被调用,
  1675. //调用发起者通常是重载了AsyncDelegateGetProperty函数的类的对象.
  1676. void CDataNodeBase::OnAsyncDelegateReceiveProperty(CString strPropertyName, CString strTxtValue, BOOL bDataFromNet)
  1677. {
  1678. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1679. if(bDataFromNet)
  1680. this->V_SetPropertyTxtValue(strPropertyName, strTxtValue, FALSE, 0);
  1681. }
  1682. //登记定制回调定制者
  1683. void CDataNodeBase::RegisterCustomCall(CDataNodeBase* pCustomer, BOOL bLowPriority)
  1684. {
  1685. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1686. m_mutexCustomCall.Lock();
  1687. POSITION pos = m_customersCutomCall.Find(pCustomer);
  1688. if(pos == NULL)
  1689. {
  1690. if(bLowPriority)
  1691. m_customersCutomCall.AddTail(pCustomer);
  1692. else
  1693. m_customersCutomCall.AddHead(pCustomer);
  1694. }
  1695. m_mutexCustomCall.Unlock();
  1696. }
  1697. //取消登记定制回调定制者
  1698. void CDataNodeBase::UnRegisterCustomCall(CDataNodeBase* pCustomer)
  1699. {
  1700. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1701. m_mutexCustomCall.Lock();
  1702. POSITION pos = m_customersCutomCall.Find(pCustomer);
  1703. if(pos != NULL)
  1704. {
  1705. m_customersCutomCall.RemoveAt(pos);
  1706. }
  1707. m_mutexCustomCall.Unlock();
  1708. }
  1709. //定制回调
  1710. BOOL CDataNodeBase::DoCustomCall(
  1711. CString strPathInternalFromRoot, //调用发出位置路径内部管理路径,用ID作为节点名的路径
  1712. CString strPathShowFromRoot, //调用发出位置路径显示路径,用名字作为节点的路径
  1713. CString strFuncName, //函数名
  1714. CStringList &strParams, //函数的输入参数表
  1715. CStringList &strReturns //函数的输出参数表
  1716. )
  1717. {
  1718. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1719. BOOL bDealed = FALSE;
  1720. if(m_customersCutomCall.GetCount() > 0)
  1721. {
  1722. m_mutexCustomCall.Lock();
  1723. POSITION pos = m_customersCutomCall.GetHeadPosition();
  1724. while (pos != NULL)
  1725. {
  1726. POSITION posLast = pos;
  1727. CDataNodeBase* pCustomer = m_customersCutomCall.GetNext(pos);
  1728. try
  1729. {
  1730. if(pCustomer->OnCustomCall(
  1731. strPathInternalFromRoot,
  1732. strPathShowFromRoot,
  1733. strFuncName,
  1734. strParams,
  1735. strReturns
  1736. ))//处理后返回TRUE,表示不需要再作处理
  1737. {
  1738. bDealed = TRUE;
  1739. break;
  1740. }
  1741. }
  1742. catch(...)
  1743. {
  1744. m_customersCutomCall.RemoveAt(posLast);//出现异常时立即清除此定制者
  1745. }
  1746. }
  1747. m_mutexCustomCall.Unlock();
  1748. }
  1749. return bDealed;
  1750. }
  1751. //执行定制回调,处理完毕,无需后续处理时返回TRUE,否则返回FALSE
  1752. BOOL CDataNodeBase::OnCustomCall(
  1753. CString strPathInternalFromRoot, //调用发出位置路径内部管理路径,用ID作为节点名的路径
  1754. CString strPathShowFromRoot, //调用发出位置路径显示路径,用名字作为节点的路径
  1755. CString strFuncName, //函数名
  1756. CStringList &strParams, //函数的输入参数表
  1757. CStringList &strReturns //函数的输出参数表
  1758. )
  1759. {
  1760. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1761. try
  1762. {
  1763. //.... do some thing.
  1764. }
  1765. catch (...)
  1766. {
  1767. }
  1768. return FALSE;
  1769. }
  1770. //删除属性
  1771. void CDataNodeBase::DeleteProperty(CString strPropertyName)
  1772. {
  1773. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1774. if(!IsUnEditableProperty(strPropertyName))
  1775. ReplaceProperty(strPropertyName, NULL);
  1776. }
  1777. //判断一个属性是否为不可编辑
  1778. BOOL CDataNodeBase::IsUnEditableProperty(CString strPropertyName)
  1779. {
  1780. return (strPropertyName == "ID" && m_pParent != NULL) ||
  1781. strPropertyName == "AppName" ||
  1782. strPropertyName == "Type";
  1783. }
  1784. //设置临时变量
  1785. BOOL CDataNodeBase::SetTempItem(CString strItemName, CString strValue)
  1786. {
  1787. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1788. if(m_mutexTempItems.Lock(10000))
  1789. {
  1790. if(strValue == "")
  1791. m_mapTempItems.RemoveKey(strItemName);
  1792. else
  1793. m_mapTempItems.SetAt(strItemName, strValue);
  1794. m_mutexTempItems.Unlock();
  1795. return TRUE;
  1796. }
  1797. return FALSE;
  1798. }
  1799. //获取临时变量
  1800. BOOL CDataNodeBase::GetTempItem(CString strItemName, CString &strValue)
  1801. {
  1802. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1803. BOOL bOK = FALSE;
  1804. if(m_mutexTempItems.Lock(10000))
  1805. {
  1806. bOK = m_mapTempItems.Lookup(strItemName, strValue);
  1807. m_mutexTempItems.Unlock();
  1808. }
  1809. return bOK;
  1810. }
  1811. //一步获得属性的字符串值
  1812. CString CDataNodeBase::GetProperty1(CString strPropertyName)
  1813. {
  1814. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1815. CString strTxtValue;
  1816. GetProperty(strPropertyName, strTxtValue);
  1817. return strTxtValue;
  1818. }
  1819. //文件保持加密种子, 为空表示文件不加密
  1820. CString CDataNodeBase::GetSaveEncryptSeed()
  1821. {
  1822. return "";
  1823. }
  1824. //找出所有指定字母开头的项目
  1825. void CDataNodeBase::GetItemsName(CStringList& strlistNames, char cHead)
  1826. {
  1827. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1828. POSITION pos = m_mapExtProperties.GetStartPosition();
  1829. while (pos)
  1830. {
  1831. CString strItem;
  1832. LPVOID p;
  1833. m_mapExtProperties.GetNextAssoc(pos, strItem, (void*&)p);
  1834. if(strItem.GetLength() >= 1 && strItem.GetAt(0) == cHead)
  1835. strlistNames.AddTail(strItem);
  1836. }
  1837. }
  1838. //保存修改
  1839. void CDataNodeBase::SaveChange()
  1840. {
  1841. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1842. if(this->GetModified())
  1843. {
  1844. this->SaveObj();
  1845. }
  1846. }
  1847. //获取与之关联的管理节点
  1848. CDataNodeBase* CDataNodeBase::GetRelateManagerNode()
  1849. {
  1850. CDataNodeBase* pRtn = this;
  1851. while(pRtn)
  1852. {
  1853. CString strDeviceType;//有设备类型属性即认为是设备
  1854. if(pRtn->PV_IsManagerNode() || pRtn->V_GetPropertyTxtValue("DeviceType", strDeviceType))
  1855. break;
  1856. pRtn = pRtn->m_pParent;
  1857. }
  1858. return pRtn;
  1859. }