小飞的世界

°★·°∴☆°广阔的星空中有发生在你我身边的故事∴☆°★·,亦真亦幻。如若这漫长的月夜,无人与你同行,那就让我用微笑来伴你一程......欢迎来到小飞的幻想世界,留下那永恒的瞬间!
OPC客户端的原码工程实例!
作者:止一  发表时间:2004-10-27

在网上看到很多的朋友要OPC客户端的原码,我在网上找了一个C++类,包含了CHotOpcServer,CHotOpcGroup,CHotOpcItem三个主要类,对于实现OPC客户端起了很大的作用,简单不少.我最近做了一个,不过还不完善,仍有BUG,希望共同爱好的朋友共同完善了!
下面给出这三各类的部分原码!
//CHotOpcServer
// 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);
};

// **************************************************************************
//------------------------------------------------------
//继续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);
};

篇幅有限,不再多说了,通过连接服务器,填加组,在填加项,就可以看到OPC服务器的数据了.界面图如下:
感兴趣的朋友可以和我联系!

图片如下:

所属栏目:VC++天地  


 
评论内容(共有{Count}条)


{CommentAuthor}:
{{CommentContent}

--- {CommentTime} | {CommentEmail} {CommentUrl} {CommentIp}


 
 About ME

Name    : Xiaofei
Gender :  Male
Hobby   : Internet,chess,
       fishing,music,reading......
QQ     : 8201655
EMail : lizzie001@163.com


月夜思绪

在这月儿高挂的夜里

整理着散乱的

与感情有关的思绪

那些生活事业的前尘往事

飘然而至

原以为自己

可以做的云淡风轻

在飘渺的夜风里却发现

那些东西化做无边的落寂

在细柳轻舞的池塘边 舞蹈着

有谁 愿意让心辗转反侧

让影子相陪 举杯 饮尽

杯里 都是 星星的碎片

夜有月梦 心亦有梦

月儿皎洁的光辉 落在

苍白的脸庞 如水的目光

映耀 人世间的离合悲欢

一切的一切

在它的清光里

都不及鱼儿的悠闲 快乐



 友情链接




 最新评论




 访问统计



 日志搜索



 
Designed By xiaofei Powered by 5DBLog
版权所有 Copyright 2005-2008 小飞的世界