// DataNodeBase.h: interface for the CDataNodeBase class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_DATANODEBASE_H__B726FC8C_2E3D_4924_94DE_7BFA5677FD51__INCLUDED_) #define AFX_DATANODEBASE_H__B726FC8C_2E3D_4924_94DE_7BFA5677FD51__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include #include #define DATA_MANAGER_INCLUDED #define EXPORT_CLASS __declspec(dllexport) class EXPORT_CLASS CDataNodeBase; class EXPORT_CLASS CDataNodeBaseEx; class EXPORT_CLASS CMenuEx; class EXPORT_CLASS CLanguage; class EXPORT_CLASS CDataNodeList; class EXPORT_CLASS CDataNodeTree; class EXPORT_CLASS CImageListDyn; class EXPORT_CLASS CDataNodeListCtrl; class EXPORT_CLASS CDataNodeTreeCtrl; class EXPORT_CLASS CVariable; class EXPORT_CLASS CFilteredFolderDialog; class EXPORT_CLASS CFolderDialog; class EXPORT_CLASS CMyMapPtrToPtr; #define MAX_DEPTH 256 //此类禁止随意修改,任何修改将可能导致这个系统不可用。 //所以需要具备此类特性的类不能直接派生于此类,要派生可以派生于 //此类的派生类CDataNodeBaseExe;同时,也不能直接使用此类来实例化任何变量 //(上述限制该类库除外)。通常,操作变量时多用CDataNodeBase来定义变量。 // 2005年7月20日 // DXL Tech. Daiamao. // 版权所有,保留所有权利。 // 在动态库中,所有共享类的公共成员函数的首行必须是: // AFX_MANAGE_STATE(AfxGetStaticModuleState()); // 在应用程序中,所有共享类的公共成员函数的首行必须是: // AFX_MANAGE_STATE(theApp.GetModuleState()); // 其中GetModuleState()的内容是: // AFX_MODULE_STATE* CXXXApp::GetModuleState() // { // return m_pModuleState; // } // 否则,调用MFC函数时可能会出现问题. // 接口约定声明 typedef __declspec(dllexport) CDataNodeBase*Def_CreateObj(CString strClassName); typedef __declspec(dllexport) void Def_ReleaseObj(CDataNodeBase *pObj); //typedef __declspec(dllexport) void Def_SetMainProgObjInterface(LPVOID pfCreateObj, LPVOID pfReleaseObj); // 管理模块说明 typedef __declspec(dllexport) CString Def_GetMgrModuleFuncDesc(); //无参数函数声明 typedef void Def_NoParamsFunc(); // =================================================================== // 接口函数 // 创建一个指定类型的对象,每个动态库或应用程序必须实现以下两个函数 __declspec(dllexport) CDataNodeBase*CreateObj(CString strClassName); // 释放指定对象,此接口强烈建议实现,并且派生CDataNodeBaseEx类时,析构函数必须为虚函数 __declspec(dllexport) void ReleaseObj(CDataNodeBase *pObj); // 传递主程序的CreateObj和ReleaseObj接口 __declspec(dllexport) void SetMainProgObjInterface(LPVOID pfCreateObj, LPVOID pfReleaseObj); // 以上两个函数的实现方案实例: // __declspec(dllexport) CDataNodeBase*CreateObj(CString strClassName) // { // AFX_MANAGE_STATE(theApp.GetModuleState()); // if(strClassName == "CDataRoot") // return new CDataNodeBaseEx; // else //if(strClassName == "CDataNodeBase") // return new CDataNodeBase; // } // // __declspec(dllexport) void ReleaseObj(CDataNodeBase *pObj) // { // AFX_MANAGE_STATE(theApp.GetModuleState()); // delete pObj; // } //============================================================= // AFX_MODULE_STATE* CXXXApp::GetModuleState() // { // return m_pModuleState; // } // 通用函数: __declspec(dllexport) CString MyGetPrivateProfileString(CString strApp, CString strKey, CString strDefault, CString strIni); __declspec(dllexport) void MyWritePrivateProfileInt(CString strApp, CString strKey, int nVal, CString strIni); __declspec(dllexport) bool Encrypt(const char szFileOrig[], const char szFileNew[], const char szPwd[]); __declspec(dllexport) CString GetText(UINT uData);//数字转化为文本 //由数据精度获得浮点数的字符串值 __declspec(dllexport) CString GetDoubleText(double d); __declspec(dllexport) BOOL MyCreateDirectory(CString strPath);//创建任意深度的路径 __declspec(dllexport) BOOL MyCopyFiles(CString strSource, CString strDest);//复制文件夹 __declspec(dllexport) BOOL MyDeleteDirectory(CString strPath);//删除任意深度的路径 __declspec(dllexport) CString GetAppPath();//获取App的路径 __declspec(dllexport) CString SetPrjPath(CString strPrjPath);//设置工程的路径 __declspec(dllexport) CString GetPrjPath();//获取工程的路径 __declspec(dllexport) void SetPrjRoot(CDataNodeBase* pRoot);//设置工程的根节点,由主程序设置 __declspec(dllexport) CDataNodeBase* GetPrjRoot();//获取工程的根节点 __declspec(dllexport) void FreeObList(CObList &obList);//清除obList内的对象 __declspec(dllexport) CString EncodeString(CString strOld, BYTE cKey);//字符串加密 __declspec(dllexport) CString GetDllPath();//获取Dll的路径 __declspec(dllexport) BYTE TwoByteToByte(BYTE b1, BYTE b2);//两个字符转换为一个字符 __declspec(dllexport) void ByteToTwoByte(BYTE b, BYTE b2[]);//一个字符转换为两个字符 __declspec(dllexport) char TwoHexCharToChar(char ch1,char ch2); __declspec(dllexport) void Str2HexStr(char *szHexString,char *szString,int *iHexStringLen); __declspec(dllexport) void GetCRC(char *CRC_char1,char *CRC_char2,char *szString,int iStrLen); __declspec(dllexport) void AddCRC(char *szBuffer, int iLen); /* the szBuffer length, this means the szBuffer[iLen] is error data, perhaps szBuffer[iLen-1] != 0; also perhaps szBuffer[iLen] != 0; */ __declspec(dllexport) BOOL CheckCRC (char *szString,int iStrLen); __declspec(dllexport) int StrToInt(CString strTxt); //给采集点赋值,该函数负责产生各种可能的事件 __declspec(dllexport) void SetSpotTextValue(CDataNodeBase* pDevive, CDataNodeBase* pSpot, CString strTxtValue); #define SYSTEM_OK 0 #define COMMON_EVENT 1 #define ALARM_EVENT 2 //将路径加入到环境变量Path中 __declspec(dllexport) void AddPathToEnvirPath(CString strNewPath); //向文本文件中追加文本 __declspec(dllexport) BOOL AppendStringToFile(CString strMsg, CString strFile); //找到指定的字符串,但必须排除有控制符号'\'的情况 __declspec(dllexport) int MyStrFind(CString strSource, CString strSub, int nStartPos=0); //找到指定的字符,但必须排除有前导符号'\'的情况 __declspec(dllexport) int MyStrFind(CString strSource, char cSub, int nStartPos=0); //获取原始字符串,去除控制符号'\' __declspec(dllexport) CString GetOrigStr(CString strSaved); //获取保存字符串,对于需要添加控制符号的自动追加控制符号 __declspec(dllexport) CString GetSavedStr(CString strOrig); //汇报一个新的事件 __declspec(dllexport) void ReportNewEvent( CDataNodeBase* pNode, //事件的发出节点 CString strMsg, //事件内容 int nLevel, //事件级别1~10 int nStatus //状态:0:恢复正常,1:普通事件, 2:报警事件 ); //Power Function __declspec(dllexport) BOOL PowerFunc(CString strFunc, CString &strExchange); //自动化程序使用的帐号 __declspec(dllexport) BOOL GetAutoProcUser(CString &strUser, UINT &nFlag); __declspec(dllexport) void SetAutoProcUser(CString strUser); //获取字符串中用分号隔开的子字符串 __declspec(dllexport) CString GetSubString(CString strSource, CString strItem); //记载出错信息 __declspec(dllexport) void WriteErrorMsg(CString strErrorMsg); //调试输出窗体 void StartConsoleWin(); // Use wprintf like TRACE0, TRACE1, ... (The arguments are the same as printf) __declspec(dllexport) void MyDebugOutput(const char *fmt, ...); #define _MY_DEBUG #ifdef _MY_DEBUG #define MyTRACE MyDebugOutput #else #define MyTRACE TRACE #endif //获取对象的属性的C接口 __declspec(dllexport) int GetItemProperty(LPVOID pDataNodeBase, const char* szItem, char* szValue, int nLen); //设置对象的属性的C接口 __declspec(dllexport) BOOL SetItemProperty(LPVOID pDataNodeBase, const char* szItem, const char* szValue); //获取对象的属性的C接口 __declspec(dllexport) int V_GetItemProperty(LPVOID pDataNodeBase, const char* szItem, char* szValue, int nLen); //设置对象的属性的C接口 __declspec(dllexport) BOOL V_SetItemProperty(LPVOID pDataNodeBase, const char* szItem, const char* szValue); //返回DataManager.dll是否为Release版本 __declspec(dllexport) BOOL DataManagerIsReleaseVersion(); //设置数据精度 __declspec(dllexport) int SetPrecision(int p); //删除文件,支持通配符 __declspec(dllexport) void MyDeleteFile(CString strFiles); //获得用户临时目录 __declspec(dllexport) CString GetUserTempPath(); //子项排序 __declspec(dllexport) void SortSubs(CMapPtrToPtr &mapSubs, CPtrList &listSorted); //判断一个字符串是否为合法的文件名 __declspec(dllexport) BOOL IsLegalFileName(CString strFileName, BOOL bShowErr); //主程序注册主窗体句柄接口 __declspec(dllexport) void SetMainFramWnd(HWND hWnd); //获取主程序主窗体句柄 __declspec(dllexport) HWND GetMainFramWnd(); //exe程序必须调用的初始化接口 __declspec(dllexport) void InitCallForExe(const char* szParamsReserved); //exe程序必须调用的反初始化接口 __declspec(dllexport) void UinitCallForExe(const char* szParamsReserved); //设置全局临时值,在任意一个模块中设置,也可在任意模块中获取其值 __declspec(dllexport) void SetTempVar(const char* szName, const char* szValue); //获取全局临时值,在任意一个模块中设置,也可在任意模块中获取其值 __declspec(dllexport) BOOL GetTempVar(const char* szName, CString& strValue); //获取全局临时值C接口,在任意一个模块中设置,也可在任意模块中获取其值 __declspec(dllexport) int GetTempVarC(const char* szName, char* szValue, int nSize); //获取系统参数 __declspec(dllexport) BOOL GetSysParams(); //设置系统参数 __declspec(dllexport) BOOL SetSysParams(); //获取某节点的报警错误页面 __declspec(dllexport) BOOL GetRelatePage(CDataNodeBase* pNode, CString& strRelatePage, CString& strUidReq, CString& strIP); //获取某文件夹的父文件夹 __declspec(dllexport) CString GetParentDir(CString strDir); //通知主程序刷新树结构 __declspec(dllexport) void CallMainWndToRefreshNode(CDataNodeBase* pNode); //选择给定Uid的节点 __declspec(dllexport) BOOL SelectNode(CDataNodeTreeCtrl& tree, CString strUid); //获取与之关联的管理或页面分组的节点 __declspec(dllexport) CDataNodeBase* GetRelatePageGroupNode(CDataNodeBase* pNode); //事件联动触发动作 __declspec(dllexport) void EventRaiseAction(CDataNodeBase* pNode, int nStatus); //获取OEM产品的文件夹名字 __declspec(dllexport) CString GetMapDir(CString strDirDefault); // =================================================================== // 接口类 const CString LineEnd = "\r\n"; #define ATTR_SET_NULL NULL #define ATTR_NEET_SET_MODIFY_FLAG (1<<0) #define ATTR_MANUAL_SET_VALUE (1<<1) #define FLAG0_NODE_ON_GET_PROC (1<<0) //处于采集中 #define FLAG0_NODE_ON_LEFT_TREE_VISIBLE (1<<1) //节点在左侧设备树中可见 #define TEMP_VAR_ATTACH_LIMITE_SETTING "TVALS" enum ManagerNodeType { NOT_MANAGER_NODE = 0, //不是管理节点 COMM_MANAGER_NODE = 1, //普通管理接点 NET_LINK_MANAGER_NODE = 2, //网络客户端管理节点 NET_SERVER_MANAGER_NODE = 3, //网络服务端管理节点 CURVE_MANAGER_NODE = 4, //曲线服务节点 ALARM_MANAGER_NODE = 5, //报警服务节点 REPORT_MANAGER_NODE = 6, //报表服务节点 DEVICE_MANAGER_NODE = 7, //设备管理节点 }; #define EDIT_APPLY_TO_WHOLE_PROJECT (1<<0) #define EDIT_ADD_IF_IS_NEW_PROP (1<<1) #define TryDo(x) try{x;}catch(...){}; #define TRYDO(x) TRY{x;}CATCH(CDBException, E){}END_CATCH; class EXPORT_CLASS CMyMapPtrToPtr : public CMapPtrToPtr { friend CDataNodeBase; public: //ID递增方式管理的子项集合 CPtrList& GetPtrList(); protected: CMyMapPtrToPtr(); virtual ~CMyMapPtrToPtr(); void SetAt( LPVOID key, LPVOID newValue ); BOOL RemoveKey( LPVOID key ); void RemoveAll( ); CPtrList m_listSubs;//子项集,用列表方式管理 }; class EXPORT_CLASS CDataNodeBase : public CObject { DECLARE_SERIAL(CDataNodeBase) public: CDataNodeBase(); virtual ~CDataNodeBase(); // 获取节点的父结点 inline virtual CDataNodeBase *GetParent(); // 设置节点的父结点 inline virtual void SetParent(CDataNodeBase *pParent); // 获取子项列表 CMapPtrToPtr& GetSubs(); // 获取指定ID的直接子项 CDataNodeBase* GetSub(UINT uID); // 获取指定路径的任意深度的子项 CDataNodeBase* GetSub(CString strPath); // 获取名字 virtual CString GetName(); // 获取ID UINT GetID(); // 设置名字 virtual void SetName(CString strName); // 获取属性的字符串值 virtual BOOL V_GetPropertyTxtValue(CString strPropertyName, CString &strTxtValue); // 获取属性的原始值 virtual CVariable* GetProperty(CString strPropertyName); // 获取属性,支持无限深度子节点的属性获取 virtual BOOL GetProperty(CString strPropertyPath, CString &strTxtValue); //获取所有属性 virtual void GetPropertyNames(CMapStringToPtr &mapProperties); // 设置或增加属性的字符串值,名字以V_开头表示每个派生类强烈建议重载该函数. // uAttrFlag: ATTR_NEET_SET_MODIFY_FLAG, ATTR_MANUAL_SET_VALUE virtual BOOL V_SetPropertyTxtValue(CString strPropertyName, CString strTxtValue, BOOL bAddIfNotExist, UINT uAttrFlag); // 设置属性的值, 此函数必须重写. virtual BOOL SetProperty(CString strPropertyName, CVariable* pVar, UINT uAttrFlag); // 设置属性,支持无限深度子节点的属性设置 virtual BOOL SetProperty(CString strPropertyPath, CString &strTxtValue, BOOL bAddIfNotExist, UINT uAttrFlag); // 保存对象到文件 virtual CString V_GetSaveFileName(); // 保存对象到文件, 文件名由虚函数GetSaveFileName给定。 virtual BOOL SaveObj(); // 保存对象到文件 virtual BOOL SaveObj(CString strFileName); // 从文件中装载对象, 文件名由虚函数GetSaveFileName给定。 virtual BOOL LoadObj(); // 从文件中装载对象 virtual BOOL LoadObj(CString strFileName); // 添加对象为子项 virtual void AddSub(CDataNodeBase *pSub, BOOL bNotChangeID); // 移除子项 virtual void RemoveSub(CDataNodeBase* pSub); // 动态库的名字 //注意基类不能用AfxGetAppName(); 而其派生类,相反,必须用AfxGetAppName(); virtual CString PV_GetAppName(); // 获取类型名字, 名字以PV_开头表示每个派生类都必须重载该函数. //注意基类不能直接用类类型的名字,而用变量,而其派生类, 相反, 必须返回其类名的字符串 virtual CString PV_GetType(); // 任意函数调用,万能接口,调用通常是顶层调用底层的节点 virtual void AnyDownCall(int nCallStackDepth, CString strFuncName, CStringList &strParams, CStringList &strReturns); // 任意汇报接口,万能接口,与AnyDownCall的区别是,该接口是由底层节点往顶层调用 virtual void AnyUpCall( CString strPathInternal, //调用发出位置路径内部管理路径,用ID作为节点名的路径 CString strPathShow, //调用发出位置路径显示路径,用名字作为节点的路径 CString strFuncName, //函数名 CStringList &strParams, //函数的输入参数表 CStringList &strReturns //函数的输出参数表 ); // 获取ID方式表达的路径 virtual CString GetIdPath(); // 获取名字方式表达的路径 virtual CString GetNamePath(); // 将对象展现在树结构中 virtual HTREEITEM BuildTree(CDataNodeTree &treeCtrl, HTREEITEM hItemNow, int nBuildDepth = MAX_DEPTH, BOOL bBuildSubOnly = FALSE, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST); // 将对象展现在树结构中 virtual HTREEITEM BuildTree(CDataNodeTreeCtrl &treeCtrl, HTREEITEM hItemNow, int nBuildDepth = MAX_DEPTH, BOOL bBuildSubOnly = FALSE, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST); // 获取图标 virtual void GetImage(CImageListDyn &imageList, int &nImage, int &nSelectedImage); // 是否为管理类的节点 virtual BOOL PV_IsManagerNode(); // 对象配置接口 virtual BOOL DoConfig(CDataNodeBase* pPrjRoot, CString strPathCur); // 子对象配置接口 virtual BOOL DoConfigSub(CDataNodeBase* pPrjRoot, CDataNodeBase* pNodeSub, CString strPathCur); // 对象属性编辑接口,此接口只负责编辑内容,不负责将修改后的值应用到相应点。(因为要支持多点同时设置。) virtual BOOL EditProperty( CString strProp, CString& strValue, UINT& uOption, //EDIT_APPLY_TO_WHOLE_PROJECT, EDIT_ADD_IF_IS_NEW_PROP 取或 UINT& uResult //弹对话框时用户选择的IDOK、IDCANCEL等 ); // 获取修改标志 virtual BOOL GetModified(); // 设置修改标志 virtual void SetModified(BOOL bModified = TRUE); // 获取指定属性的特性 virtual CString GetAttributes(CString strPropertyName); // 根据对象的AppName属性,替换对象为对应App中定义的类, 替换后,原来对象将被删除 static CDataNodeBase* ReplaceObj(CDataNodeBase* pNodeOld, BOOL bAlsoSubs); // 工程装载后调用 virtual void DoAfterProjectLoaded(CString strProjectPath); // 工程关闭前调用 virtual void DoBeforeProjectClose(); // 从字符串中装载对象 virtual BOOL LoadObjFromString(CString strXmlTxt); // 保存对象到多行字符串 virtual BOOL SaveObjToString(CString &strXmlTxt); //代理的方式异步调用获取属性 virtual void AsyncDelegateGetProperty(CString strPropertyName); //代理的方式异步接收属性,该事件在调用AsyncDelegateGetProperty获取请求后对方回应后被调用, //调用发起者通常是重载了AsyncDelegateGetProperty函数的类的对象. virtual void OnAsyncDelegateReceiveProperty(CString strPropertyName, CString strTxtValue, BOOL bDataFromNet); //登记定制回调定制者 virtual void RegisterCustomCall(CDataNodeBase* pCustomer, BOOL bLowPriority); //取消登记定制回调定制者 virtual void UnRegisterCustomCall(CDataNodeBase* pCustomer); //删除属性 virtual void DeleteProperty(CString strPropertyName); //设置临时变量 BOOL SetTempItem(CString strItemName, CString strValue); //获取临时变量 BOOL GetTempItem(CString strItemName, CString &strValue); //一步获得属性的字符串值 CString GetProperty1(CString strPropertyName); //找出所有指定字母开头的项目 void GetItemsName(CStringList& strlistNames, char cHead); //保存修改 virtual void SaveChange(); //获取与之关联的管理节点 CDataNodeBase* GetRelateManagerNode(); UINT m_uFlags4[4]; protected: //判断一个属性是否为不可编辑 virtual BOOL IsUnEditableProperty(CString strPropertyName); // 更换属性 virtual void ReplaceProperty(CString strPropertyName, CVariable* pVar); // 更换子项 virtual void ReplaceSub(UINT uID, CDataNodeBase* pNodeNew); //文件保持加密种子, 为空表示文件不加密 virtual CString GetSaveEncryptSeed(); // 清除子项 void FreeSubs(); // 由全路径分离出路径和属性名称 void SeparatePathAndProperty(CString strFullName, CString &strPath, CString &strPropertyName); // 检查文件是否为正确的xml文件 BOOL CheckXMLFile(CStdioFile &file); // 保存对象到文件 virtual void SaveObj(CFile* pFile, CString strHeadSpace, CDataNodeBase* pNodeRoot, BOOL bIncludeMgrSub); // 字符串中提炼1个属性,并将提炼的属性从字符串中移出 virtual BOOL PickOneItem(CString &strLine, CString &strItem, CString &strValue); // 字符串中提炼1个属性,并将提炼的属性从字符串中移出 virtual BOOL PickItemType(CString &strLine, CString &strItemType); // 重置对象 virtual void Reset(); //从一行字符串中提取属性信息 virtual void PickItemsFromStrLine( CString strLine, CDataNodeBase* &pCurrentNode, CDataNodeBase* &pParent ); //将子项替换为制定App内的对象 virtual void ReplaceSubs(); //从多行字符串中读取一行字符串 virtual BOOL ReadStringLine(CString &strXmlTxt, CString &strLine); //检查多行字符串是否为合法的xml字符串 BOOL CheckXMLString(CString strXmlTxt); //定制回调 BOOL DoCustomCall( CString strPathInternalFromRoot, //调用发出位置路径内部管理路径,用ID作为节点名的路径 CString strPathShowFromRoot, //调用发出位置路径显示路径,用名字作为节点的路径 CString strFuncName, //函数名 CStringList &strParams, //函数的输入参数表 CStringList &strReturns //函数的输出参数表 ); //执行定制回调,处理完毕,无需后续处理时返回TRUE,否则返回FALSE virtual BOOL OnCustomCall( CString strPathInternalFromRoot, //调用发出位置路径内部管理路径,用ID作为节点名的路径 CString strPathShowFromRoot, //调用发出位置路径显示路径,用名字作为节点的路径 CString strFuncName, //函数名 CStringList &strParams, //函数的输入参数表 CStringList &strReturns //函数的输出参数表 ); CList m_customersCutomCall;//添加的定制回调定制者 CMutex m_mutexCustomCall; BOOL m_bModified;// 修改标志 CDataNodeBase *m_pParent; //父结点 CMyMapPtrToPtr m_mapSubs; //子项集 CMutex m_mutexMapSubs; //子项集同步锁 CMapStringToPtr m_mapExtProperties; //扩展字符串属性 CMutex m_mutexMapProperties; //子项集同步锁 CString m_strName; //节点的名字 UINT m_uID; //节点的ID BOOL __classCanUseDirectly; //此类禁止派生出除CDataNodeBaseEx以外的其它类,用此作为标记,不常用,不加m_前缀。 // HTREEITEM m_hItem; // 获取指定AppName的App的对象创建和释放函数 CString m_strAppName; //程序名字 CString m_strType; //类的名字 private: CMapStringToString m_mapTempItems; CMutex m_mutexTempItems; }; #endif // !defined(AFX_DATANODEBASE_H__B726FC8C_2E3D_4924_94DE_7BFA5677FD51__INCLUDED_)