⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opcsample_cpp.cpp

📁 用visual c++编写的OPC程序。
💻 CPP
字号:
// OPCSample_cpp.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "OPCSample_cppDlg.h"
#include "OPCSample_cpp.h"

#include "OPCServerDlg.h"   //dialog to connect to an OPC-Server

#define IID_DEFINED
#include "OPC_i.c"

// The OPC data formats
UINT OPCSTMFORMATDATA = RegisterClipboardFormat(_T("OPCSTMFORMATDATA"));
UINT OPCSTMFORMATDATATIME = RegisterClipboardFormat(_T("OPCSTMFORMATDATATIME"));
UINT OPCSTMFORMATWRITECOMPLETE = RegisterClipboardFormat(_T("OPCSTMFORMATWRITECOMPLETE"));

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COPCSample_cppApp

BEGIN_MESSAGE_MAP(COPCSample_cppApp, CWinApp)
	//{{AFX_MSG_MAP(COPCSample_cppApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COPCSample_cppApp construction

COPCSample_cppApp::COPCSample_cppApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
   groupHandle = 0;
   pCurrentItem = NULL;
   transactionID = 0;
   pcSink = new CAdviseSink;   // create the advise sink for notifications
   pcSink->AddRef();

   AfxOleLockApp();
}

COPCSample_cppApp::~COPCSample_cppApp()
{
  pcSink->Release(); // OLE should clean this up, but may not have time!
  AfxOleUnlockApp();
}
/////////////////////////////////////////////////////////////////////////////
// The one and only COPCSample_cppApp object

COPCSample_cppApp theApp;

/////////////////////////////////////////////////////////////////////////////
// COPCSample_cppApp initialization

BOOL COPCSample_cppApp::InitInstance()
{
  if (!AfxOleInit())
  {
    return FALSE;
  }
  // Standard initialization
  // If you are not using these features and wish to reduce the size
  //  of your final executable, you should remove from the following
  //  the specific initialization routines you do not need.
  // Initialize OLE libraries
  
#ifdef _AFXDLL
  Enable3dControls();     // Call this when using MFC in a shared DLL
#else
  Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
  
  
  //First call a dialog to connect to an OPC-server
  OPCServerDlg ConnectDlg;
  int nResponse = ConnectDlg.DoModal();
  if (nResponse == IDOK)
  {
    //the dialog only return the name of the selected server
    //now connect to it
    if (ConnectDlg.m_Server.GetLength())
    {
      HRESULT hr = S_OK;
      // Get the class ID of that server.
      CLSID clsid;
      hr = CLSIDFromProgID( ConnectDlg.m_Server.AllocSysString(), &clsid );
      if( FAILED(hr))
      {
        AfxMessageBox("Error during CLSIDFromProgID", MB_OK);
        return FALSE;
      }
      
      // Create a running object from that class ID
      // (CLSCTX_ALL will allow in-proc, local and remote)
      LPUNKNOWN pUnkn = NULL;
      hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID *)&pUnkn);
      if( FAILED(hr) || pUnkn == NULL)
      {
        AfxMessageBox("Error during CoCreateInstance", MB_OK);
        return FALSE;
      }
      
      // Get the IOPCServer interface.
      hr = pUnkn->QueryInterface( IID_IOPCServer, (LPVOID*)&pcServer);
      pUnkn->Release();  // Don't need this anymore.
      pUnkn = NULL;
      if( FAILED(hr) )
      {
        AfxMessageBox("You may not have registered the Proxy dll!\n", MB_OK);
        return FALSE;
      }
      if (!pcServer)
      {
        AfxMessageBox("Error during QueryInterface\n", MB_OK);
        return FALSE;
      } else
        pcServer->AddRef();
      // Create a single group that will contain all the items
      FLOAT deadband = 0.0;
      DWORD rate;
      hr = pcServer->AddGroup( L"",              // name of the group. If "" the server create one
        TRUE,             // active state of this group
        100,              // update rate of this group (in ms)
        MY_GROUPHANDLE,   // my handle
        NULL,             // bias
        &deadband,        //deadband
        0, 
        &groupHandle,     //handle of the server
        &rate,            //revised update rate  
        IID_IOPCGroupStateMgt,   // interface to return
        (LPUNKNOWN*)&pcGroup );              // this holds the group ptr
      if( FAILED(hr) )
      {
        AfxMessageBox("Error during AddGroup", MB_OK);
        return FALSE;
      }
      pcGroup->AddRef();
      
      //now add an advise to this group
      IAdviseSink *pAdviseSink = NULL;
      hr = pcSink->QueryInterface(IID_IAdviseSink, (LPVOID *)&pAdviseSink);
      pcSink->AddRef();
      if( FAILED(hr) )
      {
        pcGroup->Release();
        pcServer->Release();
        return FALSE;
      }
      pcGroup->QueryInterface(IID_IDataObject, (LPVOID*)&pcIData);
      // data advise format
      FORMATETC formatEtc ;
      #ifdef DATATIMEFORMAT
        formatEtc.cfFormat = OPCSTMFORMATDATATIME ;
      #else
        formatEtc.cfFormat = OPCSTMFORMATDATA ;
      #endif // DATATIMEFORMAT
      formatEtc.tymed =  TYMED_HGLOBAL;
      formatEtc.ptd = NULL;
      formatEtc.dwAspect = DVASPECT_CONTENT;
      formatEtc.lindex = -1;
      hr = pcIData->DAdvise(&formatEtc,
                               0,    // ADVF flag
                               pcSink, 
                               &dwConnection);
      pcSink->Release();
      //now I have a connection to the server and the group I need
      //next step is to browse the server and if there are Tags in a branch 
      //put them into the group
      //this is done by the next dialog 
    } else return FALSE;
  } else return FALSE;
  
  COPCSample_cppDlg dlg(this);
  m_pMainWnd = &dlg;
  nResponse = dlg.DoModal();
  if (nResponse == IDOK)
  {
    // TODO: Place code here to handle when the dialog is
    //  dismissed with OK
  }
  else if (nResponse == IDCANCEL)
  {
    // TODO: Place code here to handle when the dialog is
    //  dismissed with Cancel
  }
  
  // Since the dialog has been closed, return FALSE so that we exit the
  //  application, rather than start the application's message pump.
  return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -