www.pudn.com > OPC_VC++.rar > OPCSample_cpp.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; 
}