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

📄 main.~cpp

📁 OPC客户端程序
💻 ~CPP
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <assert.h>
#pragma hdrstop

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
#define MAX_KEYLEN 256

// Ole initializer/deinitializer
static struct SOLEINIT
{
   SOLEINIT()
   {
      CoInitialize(NULL);
   }
   ~SOLEINIT()
   {
      CoUninitialize();
   }
} oleinit__;

inline AnsiString Variant2Str(VARIANT& v)
{
   Variant var(v);
   return VarToStr(var);
}

#ifdef StrToInt
#undef StrToInt
#endif // StrToInt

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
   : TForm(Owner),
   m_vbActive(VARIANT_FALSE),
   m_hGroup(0),
   m_dwRate(100),
   m_fDeadBand(0.0f),
   m_hItem(0),
   m_dwID(0),
   m_dwCancelID(0)
{
   CoGetMalloc(MEMCTX_TASK, &m_ptrMalloc);
   assert(m_ptrMalloc != NULL);
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::CleanupItem()
{
   if (0 != m_hItem)
   {
      assert(m_ptrGroup != NULL);
      // Get the item management interface of the group
      CComPtr<IOPCItemMgt> ptrItMgm;
      OLECHECK(m_ptrGroup->QueryInterface(IID_IOPCItemMgt,
                              reinterpret_cast<LPVOID*>(&ptrItMgm)));
      assert(ptrItMgm != NULL);

      HRESULT* phResult = NULL;
      OLECHECK(ptrItMgm->RemoveItems(1, &m_hItem, &phResult));

      // Check the item result for errors
      assert(phResult != NULL);
      HRESULT hr = phResult[0];
      m_ptrMalloc->Free(phResult);
      OLECHECK((HRESULT)hr);

      // Final cleanup
      m_hItem = 0;
   }
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::Cleanup()
{
   // Free the current item
   CleanupItem();

   if (0 != m_hGroup)
   {
      // Disconnect group events
      m_DataCallbackSink.Disconnect();
      // Release the group
      m_ptrSyncIO.Release();
      m_ptrAsyncIO.Release();
      m_ptrGroup.Release();
      // Remove the group from the server itself
      OLECHECK(m_ptrServer->RemoveGroup(m_hGroup, FALSE));
      m_hGroup = 0;
   }
   assert(m_ptrSyncIO == NULL);
   assert(m_ptrAsyncIO == NULL);
   assert(m_ptrGroup == NULL);

   // Release the OPC server
   m_ptrServer.Release();

   // Set Deactivate Flag
   m_vbActive = VARIANT_FALSE;
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::ConnectToServer()
{
   assert(!m_vbActive);
   assert(m_bstrServer.Length() != 0);

   // INITIALIZATION:
   assert(m_ptrMalloc != NULL);

   // Create the OPC Server:
   CLSID clsid;
   OLECHECK(CLSIDFromProgID(m_bstrServer, &clsid));
   OLECHECK(CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IOPCServer,
                                     reinterpret_cast<LPVOID*>(&m_ptrServer)));

   OLECHECK(m_ptrServer->QueryInterface(IID_IOPCBrowseServerAddressSpace,
                                        reinterpret_cast<LPVOID*>(&m_ptrBrowse)));
   // Create a group with a unique name:
   LPOLESTR pszGRPID = NULL;
   try
   {
      GUID guidGroupName;
      OLECHECK(CoCreateGuid(&guidGroupName));
      OLECHECK(StringFromCLSID(clsid, &pszGRPID));
      assert(pszGRPID != NULL);
      DWORD dwRevisedRate = 0;
      OLECHECK(m_ptrServer->AddGroup(pszGRPID, TRUE, m_dwRate, 0, 0, &m_fDeadBand,
			      0, &m_hGroup, &dwRevisedRate, IID_IUnknown,
   			   reinterpret_cast<LPUNKNOWN*>(&m_ptrGroup)));
      m_dwRate = dwRevisedRate;
      assert(m_ptrGroup != NULL);
      CoTaskMemFree(pszGRPID);
   }
   catch(...)
   {
      if (pszGRPID != NULL)
      {
         CoTaskMemFree(pszGRPID);
      }
      throw;
   }

   // Get the sync IO interface of the group:
   OLECHECK(m_ptrGroup->QueryInterface(IID_IOPCSyncIO,
                           reinterpret_cast<LPVOID*>(&m_ptrSyncIO)));

   // Get the async IO interface of the group:
   OLECHECK(m_ptrGroup->QueryInterface(IID_IOPCAsyncIO2,
                           reinterpret_cast<LPVOID*>(&m_ptrAsyncIO)));

   // Connect the event handlers to those of this form:
   m_DataCallbackSink.EvDataChange = OnDataChange;
   m_DataCallbackSink.EvReadComplete = OnReadComplete;
   m_DataCallbackSink.EvWriteComplete = OnWriteComplete;
   m_DataCallbackSink.EvCancelComplete = OnCancelComplete;

   // Connect the IOPCDataCallback sink to the group
   OLECHECK(m_DataCallbackSink.Connect(m_ptrGroup));
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::ConnectToItem()
{
   assert(!m_vbActive);
   assert(m_ptrGroup != NULL);
   assert(m_bstrItem.Length() != 0);

   // Get the item management interface of the group
   CComPtr<IOPCItemMgt> ptrItMgm;
   OLECHECK(m_ptrGroup->QueryInterface(IID_IOPCItemMgt,
                           reinterpret_cast<LPVOID*>(&ptrItMgm)));

	OPCITEMDEF itemdef;
	HRESULT *phResult = NULL;
	OPCITEMRESULT *pItemState = NULL;

	// Define one item
	//
   USES_CONVERSION;
	itemdef.szItemID = m_bstrItem;
	itemdef.szAccessPath = T2OLE(_T(""));
	itemdef.bActive = TRUE;
	itemdef.hClient = reinterpret_cast<DWORD>(Handle);
	itemdef.dwBlobSize = 0;
	itemdef.pBlob = NULL;
	itemdef.vtRequestedDataType = 0;

	// Add then items and check the hresults
	//
	OLECHECK(ptrItMgm->AddItems(1, &itemdef, &pItemState, &phResult));

   // Check the item result for errors
   assert(phResult != NULL);

   if (SUCCEEDED(phResult[0]))
   {
      // Store item server handle for future use
      assert(pItemState != NULL);
      m_hItem = pItemState[0].hServer;

      if (pItemState[0].pBlob != NULL)
      {
         m_ptrMalloc->Free(pItemState[0].pBlob);
	   }

	   // Free the returned results
	   //
      m_ptrMalloc->Free(phResult);
	   m_ptrMalloc->Free(pItemState);

      // We always must call the SetEnabled of AsyncIO2:
      assert(m_ptrAsyncIO != NULL);
      OLECHECK(m_ptrAsyncIO->SetEnable(TRUE));

      // If it gets here, the server is active
      m_vbActive = VARIANT_TRUE;
   }
   else
   {
      HRESULT hr = phResult[0];

	   // Free the returned results
	   //
      m_ptrMalloc->Free(phResult);
	   m_ptrMalloc->Free(pItemState);

      OLECHECK((HRESULT)hr);// Always the exception is raised here
   }
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::EnableButtons(bool bEnabled)
{
   btnRead->Enabled = bEnabled;
   btnAsyncRead->Enabled = bEnabled;
   btnWrite->Enabled = bEnabled;
   btnAsyncWrite->Enabled = bEnabled;
   btnRefresh->Enabled = bEnabled;
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::DoLog(LPCTSTR pszMsg)
{
   memLog->Lines->Add(pszMsg);
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::OnDataChange(
      /* [in] */ DWORD dwTransid,
      /* [in] */ OPCHANDLE hGroup,
      /* [in] */ HRESULT hrMasterquality,
      /* [in] */ HRESULT hrMastererror,
      /* [in] */ DWORD dwCount,
      /* [size_is][in] */ OPCHANDLE __RPC_FAR *phClientItems,
      /* [size_is][in] */ VARIANT __RPC_FAR *pvValues,
      /* [size_is][in] */ WORD __RPC_FAR *pwQualities,
      /* [size_is][in] */ FILETIME __RPC_FAR *pftTimeStamps,
      /* [size_is][in] */ HRESULT __RPC_FAR *pErrors)
{
   DoLog(Format(_T("DataChange: Value = '%s'"),
               ARRAYOFCONST((Variant2Str(*pvValues)))).c_str());
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::OnReadComplete(
      /* [in] */ DWORD dwTransid,
      /* [in] */ OPCHANDLE hGroup,
      /* [in] */ HRESULT hrMasterquality,
      /* [in] */ HRESULT hrMastererror,
      /* [in] */ DWORD dwCount,
      /* [size_is][in] */ OPCHANDLE __RPC_FAR *phClientItems,
      /* [size_is][in] */ VARIANT __RPC_FAR *pvValues,
      /* [size_is][in] */ WORD __RPC_FAR *pwQualities,
      /* [size_is][in] */ FILETIME __RPC_FAR *pftTimeStamps,
      /* [size_is][in] */ HRESULT __RPC_FAR *pErrors)
{
   DoLog(Format(_T("ReadComplete: Value = '%s'"),
               ARRAYOFCONST((Variant2Str(*pvValues)))).c_str());
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::OnWriteComplete(
      /* [in] */ DWORD dwTransid,
      /* [in] */ OPCHANDLE hGroup,
      /* [in] */ HRESULT hrMastererr,
      /* [in] */ DWORD dwCount,
      /* [size_is][in] */ OPCHANDLE __RPC_FAR *pClienthandles,
      /* [size_is][in] */ HRESULT __RPC_FAR *pErrors)
{
   DoLog(_T("Async Write completed!"));
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::OnCancelComplete(
      /* [in] */ DWORD dwTransid,
      /* [in] */ OPCHANDLE hGroup)
{
}

//---------------------------------------------------------------------------

void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
   Cleanup();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::btnConnectClick(TObject *Sender)
{
   static const LPCTSTR szConnect = _T("&Connect");
   static const LPCTSTR szDisconnect = _T("Dis&connect");

   if (btnConnect->Tag == 0)
   {
      try
      {
         m_bstrServer.Empty();
         m_bstrServer = WideString(edServer->Text);

         ConnectToServer();
	 StatusBar1->SimpleText ="Connected to server: "+edServer->Text +" Select Item...";
         GetItems();

         btnConnect->Tag = 1;
         btnConnect->Caption = szDisconnect;

         EnableButtons(true);
      }
      catch(...)
      {
         Cleanup();
         throw;
      }
   }
   else
   {
      try
      {
         Cleanup();

         btnConnect->Tag = 0;
         btnConnect->Caption = szConnect;

	 StatusBar1->SimpleText ="Disonnected...";
         EnableButtons(false);
      }
      catch(...)
      {
         throw;
      }
   }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnWriteClick(TObject *Sender)
{
   // Only integers, by now:
   CComVariant vValue = Sysutils::StrToInt(edValue->Text);

   assert(m_ptrMalloc != NULL);
   assert(m_ptrSyncIO != NULL);

   HRESULT *phResult = NULL;
   OLECHECK(m_ptrSyncIO->Write(1, &m_hItem, &vValue, &phResult));

   // Check the item result for errors
   assert(phResult != NULL);
   HRESULT hr = phResult[0];
   m_ptrMalloc->Free(phResult);
   OLECHECK((HRESULT)hr);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnAsyncWriteClick(TObject *Sender)
{
   // Only integers, by now:
   CComVariant vValue = Sysutils::StrToInt(edValue->Text);

   assert(m_ptrMalloc != NULL);
   assert(m_ptrAsyncIO != NULL);

   HRESULT *phResult = NULL;
   OLECHECK(m_ptrAsyncIO->Write(1, &m_hItem, &vValue, m_dwID,
                          &m_dwCancelID, &phResult));

   // Check the item result for errors
   assert(phResult != NULL);
   HRESULT hr = phResult[0];
   m_ptrMalloc->Free(phResult);
   OLECHECK((HRESULT)hr);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnReadClick(TObject *Sender)
{
   try
   {
      assert(m_ptrMalloc != NULL);
      assert(m_ptrSyncIO != NULL);

      HRESULT *phResult = NULL;
      OPCITEMSTATE* pItemState;
      OLECHECK(m_ptrSyncIO->Read(OPC_DS_DEVICE, 1, &m_hItem, &pItemState, &phResult));

      assert(phResult != NULL);
      if (SUCCEEDED(phResult[0]))
      {
         assert(pItemState != NULL);

         DoLog(Format(_T("Synchronous Read: Value = '%s'"),
                     ARRAYOFCONST((Variant2Str(pItemState[0].vDataValue)))).c_str());

         // Free results
         m_ptrMalloc->Free(pItemState);
         m_ptrMalloc->Free(phResult);
      }
      else
      {
         HRESULT hr = phResult[0];

	      // Free the returned results
	      //
         m_ptrMalloc->Free(phResult);
	      m_ptrMalloc->Free(pItemState);

         OLECHECK(hr);// Always the exception is raised here
      }
   }
   catch(...)
   {
   }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnAsyncReadClick(TObject *Sender)
{
   // Only integers, by now:
   CComVariant vValue = Sysutils::StrToInt(edValue->Text);

   assert(m_ptrMalloc != NULL);
   assert(m_ptrAsyncIO != NULL);

   HRESULT *phResult = NULL;
   OLECHECK(m_ptrAsyncIO->Read(1, &m_hItem, m_dwID, &m_dwCancelID, &phResult));

   // Check the item result for errors
   assert(phResult != NULL);
   HRESULT hr = phResult[0];
   m_ptrMalloc->Free(phResult);
   OLECHECK((HRESULT)hr);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnRefreshClick(TObject *Sender)
{
   assert(m_ptrAsyncIO != NULL);
   OLECHECK(m_ptrAsyncIO->Refresh2(OPC_DS_DEVICE, m_dwID, &m_dwCancelID));
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnClearLogClick(TObject *Sender)
{
   memLog->Lines->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::GetServer()
{
//this code segment is take from SST_Client sample
// Copyright 

⌨️ 快捷键说明

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