www.pudn.com > SuperOPC-vc7.rar > HotOpcServer.h


#pragma once 
 
#include  
#include "comm\opcda.h" 
#include "comm\opccomn.h" 
#include  
#define _countof(array) (sizeof(array)/sizeof(array[0])) 
 
#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } } 
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } } 
#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } } 
#define VERSION_1		1 
#define CURRENT_VERSION VERSION_1 
// OPC_XX_DATAXX defines are based on an index in a listbox (do not modify)  
#define OPC_10_DATACHANGE			0	// OnDataChange 1.0 no timestamp request  
#define OPC_10_DATATIMECHANGE		1	// OnDataChange 1.0 with timestamp request  
#define OPC_20_DATACHANGE			2	// OnDataChange 2.0 (always a timestamp) request 
 
#define OPC_NO_QUALITY_NO_VALUE          0xFF 
#define OPC_QUALITY_BAD_NON_SPECIFIC     0x0 
#define OPC_QUALITY_BAD_CONFIG_ERR0R     0x04 
#define OPC_QUALITY_BAD_NOT_CONNECTED    0x08 
#define OPC_QUALITY_BAD_DEVICE_FAILURE   0x0C 
#define OPC_QUALITY_BAD_SENSOR_FAILURE   0x10 
#define OPC_QUALITY_BAD_LAST_KNOWN_VALUE 0x14 
#define OPC_QUALITY_BAD_COMM_FAILURE     0x18 
#define OPC_QUALITY_BAD_OUT_OF_SERVICE   0x1C 
 
#define OPC_QUALITY_UNCERTAIN_NON_SPECIFIC         0x40 
#define OPC_QUALITY_UNCERTAIN_LAST_USABLE_VALUE    0x44 
#define OPC_QUALITY_UNCERTAIN_SENSOR_NOT_ACCURATE  0x50 
#define OPC_QUALITY_UNCERTAIN_EU_UNITS_EXCEEDED    0x54 
#define OPC_QUALITY_UNCERTAIN_SUB_NORMAL           0x58 
 
#define OPC_QUALITY_GOOD_NON_SPECIFIC    0xC0 
#define OPC_QUALITY_GOOD_LOCAL_OVERRIDE  0xD8 
 
#define OPC_QUALITY_LIMITFIELD_NOT       0x0 
#define OPC_QUALITY_LIMITFIELD_LOW       0x1 
#define OPC_QUALITY_LIMITFIELD_HIGH      0x2 
#define OPC_QUALITY_LIMITFIELD_CONSTANT  0x3 
 
// group defaults 
#define GROUP_DEFAULT_ACTIVESTATE	TRUE 
#define GROUP_DEFAULT_LANGUAGEID	MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US) 
#define GROUP_DEFAULT_NAME			_T("") 
#define GROUP_DEFAULT_DEADBAND		0.0f 
#define GROUP_DEFAULT_TIMEBIAS		0 
#define GROUP_DEFAULT_UPDATERATE	100 
#define GROUP_DEFAULT_UPDATEMETHOD	OPC_20_DATACHANGE 
#define GROUP_DEFAULT_FORCEDELETE	FALSE 
#define GROUP_DEFAULT_REMOVEITEMSONDELETE	TRUE 
#define GROUP_DEFAULT_ACTIVATEITEMSONSELECT	TRUE	 
 
// item defaults 
#define ITEM_DEFAULT_ACCESSPATH		_T("") 
#define ITEM_DEFAULT_ITEMID			_T("") 
#define ITEM_DEFAULT_ACTIVESTATE	TRUE 
#define ITEM_DEFAULT_DATATYPE		VT_EMPTY 
 
#define MQI_IOPCSERVER		0 
#define MQI_IOPCCOMMON		1 
#define MQI_IOPCCONNPT		2 
#define MQI_IOPCITEMPROP	3 
#define MQI_IOPCBROWSE		4 
#define MQI_IOPCPUBLIC		5 
#define MQI_IOPCPERSIST		6 
 
 
/*// Clipboard formats for data access 1.0 streams: 
UINT CF_DATA_CHANGE = RegisterClipboardFormat (_T("OPCSTMFORMATDATA")); 
UINT CF_DATA_CHANGE_TIME	= RegisterClipboardFormat (_T("OPCSTMFORMATDATATIME")); 
UINT CF_WRITE_COMPLETE = RegisterClipboardFormat (_T("OPCSTMFORMATWRITECOMPLETE")); 
 
// Clipboard formats for cut/copy/paste: 
UINT CF_SERVER = RegisterClipboardFormat (_T("QCOpcClientServer")); 
UINT CF_GROUP = RegisterClipboardFormat (_T("QCOpcClientGroup")); 
UINT CF_ITEM = RegisterClipboardFormat (_T("QCOpcClientItem"));*/ 
VARTYPE VartypeFromString (LPCTSTR lpszType); 
void StringFromVartype (VARTYPE vtType, CString &strType); 
 
class IHotShutdown; 
class CHotOpcGroup; 
class CHotOpcItem; 
class CFixedSharedFile; 
// CHotOpcServer 命令目标 
/*--------------------------------------------- 
CHotOpcServer类 
 
desc:... 
 
----------------------------------------------*/ 
class CHotOpcServer : public CObject 
{ 
public: 
 
	CHotOpcServer(); 
	CHotOpcServer(CString &strSerName,CString strRemote); 
	virtual ~CHotOpcServer(); 
protected: 
	//声明OPC相应接口 
	IOPCServer					 *m_pIServer;		 
	IOPCCommon					 *m_pICommon; 
	IConnectionPointContainer	 *m_pIConnPtContainer; 
	IOPCItemProperties			 *m_pIItemProps; 
	IOPCBrowseServerAddressSpace *m_pIBrowse; 
	IOPCServerPublicGroups		 *m_pIPublicGroups; 
	IPersistFile				 *m_pIPersistFile; 
 
	IHotShutdown				 *m_pIShutdownSink; 
	DWORD						 m_dwCookieShutdown; 
	MULTI_QI m_arrMultiQI[7];	//接口数组,用于查询服务 
 
	typedef struct S_Flags 
	{ 
		DWORD bIsKepServerEx			: 1; 
		DWORD Reserved					: 31; 
	} FLAGS; 
 
	FLAGS m_bfFlags; 
 
	CStringList *m_pServerList; //服务器名列表 
	CString		m_strServerName; //服务器名称 
	CString     m_strRemoteMachine;//机器地址或名 
	bool		m_bConnected; 
	// 列表管理 
	CHotOpcServer *m_pPrev; 
	CHotOpcServer *m_pNext; 
 
	// 组管理 
	CHotOpcGroup *m_pGroupHead; 
	DWORD m_cdwGroups; 
 
	void InitInterface(void); 
	HRESULT GetCLSID (CLSID &clsid); 
public: 
	INT DisplayComponent(BOOL bOpc2 = TRUE); 
	INT GetServerCount(void); 
	CString  GetServerNameByIndex(int nIndex); 
	 
	void SetServerName (CString &strSerName); 
	LPCTSTR GetServerName() 
		{return (m_strServerName);} 
	void SetRemoteMachine (CString &strRemoteMachine); 
	LPCTSTR GetRemoteMachine ()  
	{ 
		if (m_strRemoteMachine.IsEmpty ()) 
			return (NULL); 
 
		return (m_strRemoteMachine); 
	} 
	void ShutdownRequest (LPCTSTR lpszReason); 
 
	bool Connect (CString &strSerName, CString &strRemoteMachine); 
	bool Connect(void); 
	void Disconnect(void); 
	 
 
	bool IsConnected () {return (m_bConnected);} 
	bool IsKepServerEx () {return (m_bfFlags.bIsKepServerEx);} 
	bool IsAlive (); 
 
	void Start (); 
	void Stop (); 
 
	// cut/copy/paste 
	void Copy (CFixedSharedFile &sf); 
	void Paste (CFixedSharedFile &sf); 
 
	// list management 
	void SetPrev (CHotOpcServer *pPrev) {m_pPrev = pPrev;} 
	CHotOpcServer* GetPrev () {return (m_pPrev);} 
 
	void SetNext (CHotOpcServer *pNext) {m_pNext = pNext;} 
	CHotOpcServer* GetNext () {return (m_pNext);} 
 
	// group management 
	void AddGroup (CHotOpcGroup *pGroup, bool bLoadingProject = false); 
	void AddClonedGroup (CHotOpcGroup *pClone); 
 
	void RemoveGroup (CHotOpcGroup *pGroup, bool bDelete = true); 
	void RemoveAllGroups (bool bDelete = true); 
 
	CHotOpcGroup* GetGroupHead () {return (m_pGroupHead);} 
 
	bool GenerateGroupName (CString &strName); 
	bool FindGroup (LPCTSTR lpszName); 
	CHotOpcGroup *GetGroup (LPCTSTR lpszName); 
 
	// 所支持的接口 
	bool IsIServerSupported () {return (m_pIServer != NULL);} 
	bool IsICommonSupported () {return (m_pICommon != NULL);} 
	bool IsIConnectionPointContainerSupported () {return (m_pIConnPtContainer != NULL);} 
	bool IsIItemPropertiesSupported () {return (m_pIItemProps != NULL);} 
	bool IsIBrowsingSupported () {return (m_pIBrowse != NULL);} 
	bool IsIServerPublicGroupsSupported () {return (m_pIPublicGroups != NULL);} 
	bool IsIPersistFileSupported () {return (m_pIPersistFile != NULL);} 
 
	IOPCServer* GetIServer () {return (m_pIServer);} 
	IOPCBrowseServerAddressSpace* GetIBrowse () {return (IsAlive () ? m_pIBrowse : NULL);} 
	IOPCItemProperties* GetIItemProps () {return (m_pIItemProps);} 
	virtual void Serialize(CArchive& ar); 
}; 
 
// ************************************************************************** 
class CSafeLock 
{ 
public: 
	CSafeLock (CSyncObject *pso) 
	{ 
		ASSERT (pso); 
		pso->Lock (); 
		m_pso = pso; 
	} 
	 
	~CSafeLock () 
	{ 
		m_pso->Unlock (); 
	} 
	 
private: 
	CSyncObject *m_pso; 
}; 
 
class CSafeArray : public SAFEARRAY 
{ 
public: 
	CSafeArray (const CSafeArray &cSrc); 
	CSafeArray (WORD wRows, WORD wCols, WORD wBytesPerElement, void *pData = NULL); 
	CSafeArray (DWORD cdwElements, WORD wBytesPerElement, void *pData = NULL); 
	~CSafeArray (); 
	 
	// Returns the length of the array in bytes 
	DWORD GetByteLength () const; 
	 
	// Returns the number of elements in the array 
	DWORD GetNumElements () const; 
	DWORD GetNumRows () const; 
	DWORD GetNumCols () const; 
	 
	// So we can send to a CF_TEXT client 
	void Format (CString &str, VARTYPE vt) const; 
	 
	// Assigment as a vector 
	void operator = (const SAFEARRAY &cSrc); 
	 
	// Overloaded operators to construct/destroy 
	void *operator new (size_t s); 
	void operator delete (void *p); 
	 
	// Comparison 
	bool operator == (const SAFEARRAY &cSrc) const; 
	bool operator != (const SAFEARRAY &cSrc) const {return !(*this == cSrc);} 
	 
protected: 
	void Alloc (DWORD dwBytes); 
}; 
//------------------------------------------------------ 
//继续IOPCShutdown接口 
/*--------------------------------------------- 
CHotOpcServer类 
 
desc:... 
 
----------------------------------------------*/ 
class IHotShutdown : public IOPCShutdown 
{ 
public: 
	IHotShutdown (CHotOpcServer *pServer); 
	~IHotShutdown (); 
 
	// 实现IUnknow接口方法 
	STDMETHODIMP         QueryInterface (REFIID iid, LPVOID *ppInterface); 
	STDMETHODIMP_(ULONG) AddRef (); 
	STDMETHODIMP_(ULONG) Release (); 
 
	// IOPCShutdown 接口方法  
	STDMETHODIMP ShutdownRequest (LPCWSTR lpwszReason); 
 
private: 
	DWORD		  m_cnRef; 
	CHotOpcServer *m_pServer; 
}; 
class IKDataSink20 : public IOPCDataCallback 
{ 
public: 
	IKDataSink20 (); 
	~IKDataSink20 (); 
 
	// IUnknown Methods 
	STDMETHODIMP         QueryInterface (REFIID iid, LPVOID *ppInterface); 
	STDMETHODIMP_(ULONG) AddRef (); 
	STDMETHODIMP_(ULONG) Release (); 
 
	// IOPCDataCallback Methods  
	STDMETHODIMP OnDataChange (		// OnDataChange notifications 
		DWORD dwTransID,			// 0 for normal OnDataChange events, non-zero for Refreshes 
		OPCHANDLE hGroup,			// client group handle 
		HRESULT hrMasterQuality,	// S_OK if all qualities are GOOD, otherwise S_FALSE 
		HRESULT hrMasterError,		// S_OK if all errors are S_OK, otherwise S_FALSE 
		DWORD dwCount,				// number of items in the lists that follow 
		OPCHANDLE *phClientItems,	// item client handles 
		VARIANT *pvValues,			// item data 
		WORD *pwQualities,			// item qualities 
		FILETIME *pftTimeStamps,	// item timestamps 
		HRESULT *pErrors);			// item errors	 
 
	STDMETHODIMP OnReadComplete (	// OnReadComplete notifications 
		DWORD dwTransID,			// Transaction ID returned by the server when the read was initiated 
		OPCHANDLE hGroup,			// client group handle 
		HRESULT hrMasterQuality,	// S_OK if all qualities are GOOD, otherwise S_FALSE 
		HRESULT hrMasterError,		// S_OK if all errors are S_OK, otherwise S_FALSE 
		DWORD dwCount,				// number of items in the lists that follow 
		OPCHANDLE *phClientItems,	// item client handles 
		VARIANT *pvValues,			// item data 
		WORD *pwQualities,			// item qualities 
		FILETIME *pftTimeStamps,	// item timestamps 
		HRESULT *pErrors);			// item errors	 
 
	STDMETHODIMP OnWriteComplete (	// OnWriteComplete notifications 
		DWORD dwTransID,			// Transaction ID returned by the server when the write was initiated 
		OPCHANDLE hGroup,			// client group handle 
		HRESULT hrMasterError,		// S_OK if all errors are S_OK, otherwise S_FALSE 
		DWORD dwCount,				// number of items in the lists that follow 
		OPCHANDLE *phClientItems,	// item client handles 
		HRESULT *pErrors);			// item errors	 
 
	STDMETHODIMP OnCancelComplete (	// OnCancelComplete notifications 
		DWORD dwTransID,			// Transaction ID provided by the client when the read/write/refresh was initiated 
		OPCHANDLE hGroup); 
 
private: 
	DWORD m_cnRef; 
}; 
 
// ************************************************************************** 
class CKAdviseSink : public IAdviseSink 
{ 
public: 
	CKAdviseSink (); 
 
	// IUnknown Methods 
	STDMETHODIMP QueryInterface (REFIID riid, LPVOID *ppInterface); 
	STDMETHODIMP_(ULONG) AddRef (); 
	STDMETHODIMP_(ULONG) Release (); 
 
	// IAdviseSink Methods 
	STDMETHODIMP_(void) OnDataChange (FORMATETC *pFormatEtc, STGMEDIUM *pMedium);  
	STDMETHODIMP_(void) OnViewChange (unsigned long dwAspect, long lindex) {/*Not implemented*/}; 
	STDMETHODIMP_(void) OnRename (LPMONIKER pmk) {/*Not implemented*/}; 
	STDMETHODIMP_(void) OnSave () {/*Not implemented*/}; 
	STDMETHODIMP_(void) OnClose () {/*Not implemented*/}; 
 
private:  
 
protected: 
	ULONG m_cRef;  
}; 
// ************************************************************************** 
// CHotOpcGroup 命令目标 
/*--------------------------------------------- 
CHotOpcGroup类 
 
desc:... 
 
----------------------------------------------*/ 
class CHotOpcGroup : public CObject   
{ 
public: 
	// construction/destruction 
	CHotOpcGroup (CHotOpcServer *pParent); 
	~CHotOpcGroup (); 
 
public: 
	// property accessor/manipulators 
	void SetName (CString &strName) {m_strName = strName;} 
	void SetName (LPCTSTR lpszName) {m_strName = lpszName;} 
	LPCTSTR GetName () {return (m_strName);} 
 
	void SetUpdateRate (DWORD dwRate) {m_dwUpdateRate = dwRate;} 
	DWORD GetUpdateRate () {return (m_dwUpdateRate);} 
 
	void SetLanguageID (LCID lcid) {m_dwLanguageID = lcid;} 
	LCID GetLanguageID () {return (m_dwLanguageID);} 
 
	void SetActive (BOOL bActive, BOOL bApply = FALSE)  
	{ 
		/*m_bActive = bActive; 
 
		// apply change to server now 
		if (bApply && m_pIGroupState) 
		{ 
			DWORD dwRevRate; // for [out] parm 
			m_pIGroupState->SetState (NULL, &dwRevRate, &m_bActive, NULL, NULL, NULL, NULL); 
 
			// select the activated group 
			CKMainWnd *pWnd = (CKMainWnd *) AfxGetMainWnd (); 
			if (pWnd) 
				pWnd->PostMessage (UM_SELECT_GROUP, 0, (LPARAM) this); 
 
			// log status 
			LogMsg (IDS_SET_GROUP_ACTIVE_STATE, bActive, GetName ()); 
		}*/ 
	} 
 
	BOOL IsActive () {return (m_bActive);} 
 
	void SetBias (long lBias) {m_lBias = lBias;} 
	long GetBias () {return (m_lBias);} 
 
	void SetDeadband (float fDeadband) {m_fDeadband = fDeadband;} 
	float GetDeadband () {return (m_fDeadband);} 
 
	void SetServerHandle (OPCHANDLE hServer) {m_hServer = hServer;} 
	OPCHANDLE GetServerHandle () {return (m_hServer);} 
 
	void SetValid (BOOL bValid) {m_bValid = bValid;} 
	BOOL IsValid () {return (m_bValid);} 
 
	void SetUpdateMethod (DWORD dwMethod) {m_dwUpdateMethod = dwMethod;} 
	DWORD GetUpdateMethod () {return (m_dwUpdateMethod);} 
 
	// flag accessor/manipulators 
	void ForceDeletion (BOOL bSet) {m_bfFlags.bOnDeleteForceDeletion = bSet;} 
	BOOL IsForceDeletion () {return (m_bfFlags.bOnDeleteForceDeletion);} 
 
	// OPC Specifics 
	void Initialize (LPUNKNOWN pUnk); 
	void Uninitialize (bool bDelete = true); 
 
	bool SetItemActiveState (CObArray &cItemList, DWORD cdwItems, bool bActive); 
 
	void ReadSync (CObArray &cItemList, DWORD cdwItems, bool bDeviceRead, bool bPostMsg = true); 
	void WriteSync (CObArray &cItemList, CStringArray &cValues, DWORD cdwItems); 
 
	void ReadAsync10 (CObArray &cItemList, DWORD cdwItems, bool bDeviceRead); 
	void RefreshAsync10 (bool bDeviceRead); 
	void WriteAsync10 (CObArray &cItemList, CStringArray &cValues, DWORD cdwItems); 
 
	void ReadAsync20 (CObArray &cItemList, DWORD cdwItems); 
	void RefreshAsync20 (bool bDeviceRead); 
	void WriteAsync20 (CObArray &cItemList, CStringArray &cValues, DWORD cdwItems); 
 
	CHotOpcGroup* Clone (); 
 
	 
	 
	void Start (); 
 
	void ExportCsv (CStdioFile &csv); 
	void ImportCsv (CStdioFile &csv, CObArray &cItemList, DWORD &cdwItems); 
 
	// cut/copy/paste 
	void Copy (CFixedSharedFile &sf); 
	void Paste (CFixedSharedFile &sf); 
 
	// parent server access 
	CHotOpcServer* GetParentServer () {return (m_pServer);} 
 
	// list management 
	void SetPrev (CHotOpcGroup *pPrev) {m_pPrev = pPrev;} 
	CHotOpcGroup* GetPrev () {return (m_pPrev);} 
 
	void SetNext (CHotOpcGroup *pNext) {m_pNext = pNext;} 
	CHotOpcGroup* GetNext () {return (m_pNext);} 
 
	// item management 
	void AddItems (CObArray &cItemList, DWORD dwCount, bool bLoadingProject = false); 
 
	void RemoveItems (CObArray &cItemList, DWORD dwCount, bool bDelete = true); 
	void RemoveAllItems (bool bDelete = true); 
 
	CHotOpcItem* GetItemHead () {return (m_pItemHead);} 
	DWORD GetItemCount () {return (m_cdwItems);} 
 
	bool IsIGroupStateMgtSupported () {return (m_pIGroupState != NULL);} 
	bool IsIPublicGroupStateMgtSupported () {return (m_pIPublicGroupState != NULL);} 
	bool IsIItemMgtSupported () {return (m_pIItemMgt != NULL);} 
	bool IsISyncIOSupported () {return (m_pISync != NULL);} 
	bool IsIAsyncIOSupported () {return (m_pIAsync != NULL);} 
	bool IsIDataObjectSupported () {return (m_pIDataObject != NULL);} 
	bool IsIAsyncIO2Supported () {return (m_pIAsync2 != NULL);} 
	bool IsIConnectionPointContainerSupported () {return (m_pIConnPtContainer != NULL);} 
 
	IOPCItemMgt* GetIItemMgt () {return (m_pIItemMgt);} 
	IOPCGroupStateMgt* GetIGroupStateMgt () {return (m_pIGroupState);} 
	IOPCSyncIO* GetISyncIO () {return (m_pISync);} 
 
private: 
	bool MapStringValToVariant (CString &strValue, VARIANT &vtVal, VARTYPE vtType); 
 
	typedef enum _tagGETARRELEMRET 
	{ 
		tElement = 0, 
		tEndRow, 
		tInvalid, 
		tOverflow, 
		tDone 
	} GETARRELEMRET; 
 
	GETARRELEMRET GetArrayElement (LPCTSTR szInBuff, int *pnStart, LPTSTR szOutBuff, int nBuffSize); 
	bool MapStringValToArrayVariant (CString &strValue, VARIANT *pvtSrc, VARIANT *pvtDst); 
 
	void AddItemToList (CHotOpcItem *pItem); 
	void RemoveItemFromList (CHotOpcItem *pItem); 
 
private: 
	// properties 
	CString m_strName;		// group name 
 
	DWORD m_dwUpdateRate;	// update rate in milliseconds 
	LCID m_dwLanguageID;	// language ID 
 
	BOOL m_bActive;			// active state 
	long m_lBias;			// time bias in minutes 
	float m_fDeadband;		// percent deadband 
 
	OPCHANDLE m_hServer;	// server handle for this group 
	BOOL m_bValid;			// TRUE if successfully added to the OPC server 
	DWORD m_dwUpdateMethod;	// update method used by this group (see globals.h) 
 
	typedef struct _flags 
	{ 
		DWORD bOnDeleteForceDeletion	: 1;	// TRUE if the server should force deletion of group even if references exists 
		//			DWORD bOnDeleteRemoveItems		: 1;	// TRUE if the client should remove items before remove group 
		DWORD Reserved					: 31; 
	} FLAGS; 
 
	FLAGS m_bfFlags; 
 
	// OPC specifics 
	IOPCGroupStateMgt *m_pIGroupState; 
	IOPCPublicGroupStateMgt *m_pIPublicGroupState; 
	IOPCItemMgt *m_pIItemMgt; 
	IOPCSyncIO *m_pISync; 
	IOPCAsyncIO *m_pIAsync; 
	IDataObject *m_pIDataObject; 
	IOPCAsyncIO2 *m_pIAsync2; 
	IConnectionPointContainer *m_pIConnPtContainer; 
 
	IKDataSink20 *m_pIDataSink20; 
	DWORD m_dwCookieDataSink20; 
 
	CKAdviseSink *m_pIAdviseSink; 
	DWORD m_dwCookieRead; 
	DWORD m_dwCookieWrite; 
 
	// parent server 
	CHotOpcServer *m_pServer; 
 
	// list management 
	CHotOpcGroup *m_pPrev; 
	CHotOpcGroup *m_pNext; 
 
	// item management 
	CHotOpcItem *m_pItemHead; 
	DWORD m_cdwItems; 
 
public: 
	virtual void Serialize(CArchive& ar); 
}; 
 
// ************************************************************************** 
// CHotOpcItem 命令目标 
/*--------------------------------------------- 
CHotOpcItem类 
 
desc:... 
 
----------------------------------------------*/ 
class CHotOpcItem : public CObject   
{ 
public: 
	// construction/destruction 
	CHotOpcItem (CHotOpcGroup *pParent); 
	~CHotOpcItem (); 
 
public: 
	// property accessor/manipulators 
	void SetAccessPath (LPCTSTR strAccessPath) {m_strAccessPath = strAccessPath;} 
	LPCTSTR GetAccessPath () {return (m_strAccessPath);} 
 
	void SetActive (BOOL bActive) {m_bActive = bActive;} 
	BOOL IsActive () {return (m_bActive);} 
 
	void SetDataType (VARTYPE vtType) {m_vtDataType = vtType;} 
	VARTYPE GetDataType ()  
	{ 
		if (m_vtValue.vt != VT_EMPTY) 
			return (m_vtValue.vt); 
 
		return (m_vtDataType); 
	} 
 
	void SetItemID (LPCTSTR strItemID) {m_strItemID = strItemID;} 
	LPCTSTR GetItemID () {return (m_strItemID);} 
 
	void SetServerHandle (OPCHANDLE hServer) {m_hServer = hServer;} 
	OPCHANDLE GetServerHandle () {return (m_hServer);} 
 
	void SetAccessRights (DWORD dwAccess) {m_dwAccessRights = dwAccess;} 
	DWORD GetAccessRights () {return (m_dwAccessRights);} 
 
	void SetValid (BOOL bValid)  
	{ 
		m_bValid = bValid; 
 
		if (!bValid) 
		{ 
			m_wQuality = OPC_QUALITY_BAD_OUT_OF_SERVICE; 
			m_cdwUpdates = 0; 
			m_bTimeStamped = FALSE; 
 
			VariantInit (&m_vtValue); 
		} 
	} 
 
	BOOL IsValid () {return (m_bValid);} 
 
	// data 
	void UpdateData (VARIANT &vtVal, WORD wQuality); 
	void UpdateData (VARIANT &vtVal, WORD wQuality, FILETIME &ftTimeStamp); 
 
	void GetValue (CString &strValue); 
	LPCTSTR GetQuality (); 
	void GetTimeStamp (CString &strTimeStamp); 
	DWORD GetUpdateCount (); 
 
	// This can be dangerous!! 
	VARIANT* GetValue () {return (&m_vtValue);} 
 
 
	// cut/copy/paste 
	void Copy (CFixedSharedFile &sf); 
	void Paste (CFixedSharedFile &sf); 
 
	// parent group access 
	CHotOpcGroup* GetParentGroup () {return (m_pGroup);} 
 
	// list management 
	void SetPrev (CHotOpcItem *pPrev) {m_pPrev = pPrev;} 
	CHotOpcItem* GetPrev () {return (m_pPrev);} 
 
	void SetNext (CHotOpcItem *pNext) {m_pNext = pNext;} 
	CHotOpcItem* GetNext () {return (m_pNext);} 
 
	// GUI management 
	void SetWParam (WPARAM wParam) {m_wParam = wParam;} 
	WPARAM GetWParam () {return (m_wParam);} 
 
private: 
	// properties 
	CString m_strAccessPath;	// access path 
	CString m_strItemID;		// fully qualified item ID 
	BOOL m_bActive;				// active state 
	VARTYPE m_vtDataType;		// server's canonical datatype 
	DWORD m_dwAccessRights;		// access rights 
	OPCHANDLE m_hServer;		// server handle for this item 
 
	typedef struct _flags 
	{ 
		DWORD Reserved					: 32; 
	} FLAGS; 
 
	FLAGS m_bfFlags; 
 
	BOOL m_bValid;				// TRUE if successfully added to an OPC server 
	BOOL m_bTimeStamped;		// TRUE if the last update included a timestamp 
 
	// data 
	FILETIME m_ftTimeStamp;		// timestamp attached to value 
	WORD m_wQuality;			// quality attached to value 
	VARIANT m_vtValue;			// current value 
 
	DWORD m_cdwUpdates; 
 
	// parent server 
	CHotOpcGroup *m_pGroup; 
 
	// list management 
	CHotOpcItem *m_pPrev; 
	CHotOpcItem *m_pNext; 
 
	// threading 
	CCriticalSection m_csDataLock; 
 
	// GUI management 
	WPARAM m_wParam; 
public: 
	virtual void Serialize(CArchive& ar); 
}; 
 
// ************************************************************************** 
// CFixedSharedFile 命令目标 
/*--------------------------------------------- 
CFixedSharedFile类 
 
desc:... 
 
----------------------------------------------*/ 
class CFixedSharedFile : public CSharedFile 
{ 
public: 
	CFixedSharedFile (int nGrowBy = 128) : CSharedFile (GMEM_DDESHARE | GMEM_MOVEABLE, nGrowBy) 
	{ 
	} 
 
	BYTE* GetBuffer ()	// Enhancement (must be used with care) 
	{ 
		ASSERT (m_lpBuffer); 
		return (m_lpBuffer); 
	} 
 
	HGLOBAL Detach () 
	{ 
		ASSERT (m_hGlobalMemory != NULL); 
		HGLOBAL hMem = m_hGlobalMemory; 
		m_hGlobalMemory = NULL; // detach from global handle 
 
		// This is the fix 
		::GlobalUnlock (hMem); 
 
		// re-initialize the CMemFile parts too 
		m_lpBuffer = NULL; 
		m_nBufferSize = 0; 
 
		return hMem; 
	} 
 
	// Enhancement to allow data to be transfered to the clipboard 
	BOOL CopyToClipboard (UINT uFmt) 
	{ 
		// Open the clipboard 
		if (!::OpenClipboard (NULL)) 
		{ 
			TRACE (_T("Shared Memory: Failed to open the clipboard\n")); 
			return (false); 
		} 
 
		TRACE (_T("Copying %u bytes to the clipboard (uFmt == %u)\n"), GetLength (), uFmt); 
		ASSERT (GetLength ()); 
 
		// Clear out current contents 
		::EmptyClipboard (); 
 
		// Stick the data in 
		HANDLE hData = ::SetClipboardData (uFmt, Detach ()); 
		::CloseClipboard (); 
 
		// Check for success 
		if (!hData) 
		{ 
			TRACE (_T("SetClipboardData () failed [OS Error == %u]\n"), GetLastError ()); 
			ASSERT (FALSE); 
		} 
 
		return (hData != NULL); 
	} 
 
protected: 
 
};