📄 opcclient.cpp
字号:
if( opcAsyncIO.Attach( opcGroup ) == S_OK )
{
HRESULT hr = opcAsyncIO.Read(dwConnection1, OPC_DS_CACHE, 1, &pCurrentItem->hServerHandle, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
if( FAILED(pErrors[0]) )
{
//ReportError( _T("Async Read: "), pErrors[0] );
AfxMessageBox("Sync Read failed");
}
CoTaskMemFree( pErrors );
}
else
{
//ReportError( _T("Async Read: "), hr );
AfxMessageBox("Sync Read failed");
}
#ifdef FULL_TEST
hr = opcAsyncIO.Read(dwConnection1, OPC_DS_DEVICE, 1, &pCurrentItem->hServerHandle, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
CoTaskMemFree( pErrors );
}
hr = opcAsyncIO.Read(dwConnection1, OPC_DS_CACHE, 1, &pCurrentItem->hServerHandle, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
CoTaskMemFree( pErrors );
}
// ask for a few this time (it doesn't matter that its the same one)
OPCHANDLE serverHandles[3];
for( int i=0; i<3; i++ )
serverHandles[i] = pCurrentItem->hServerHandle;
hr = opcAsyncIO.Read(dwConnection1, OPC_DS_DEVICE, 3, serverHandles, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
CoTaskMemFree( pErrors );
}
#endif // FULL_TEST
}
}
UpdateAllViews(NULL);
return 1;
}
BOOL COPCClient::HandWrite()
{
HRESULT* pErrors = NULL;
CWaitCursor wait;
CString m_name;
//这里还应该进行手动写数据和自动写数据两种方式
//手动
/*CWRITEITEM dlg;
dlg.DoModal();
m_async = dlg.m_async;
m_value = dlg.m_value;
m_name = dlg.m_name;*/
POSITION pos = items.GetHeadPosition();
for( int index=0; pos; index++ )
{
Item* pItem = items.GetNext( pos );
if(pItem->name.Compare(m_name)==0)
pCurrentItem = pItem;
}
if( m_async )//改正
{
if( usingCP )
{
OPCAsyncIO2 opcAsyncIO2;
if( opcAsyncIO2.Attach( opcGroup ) == S_OK )
{
transactionID = 2; // any number the client wants
COleVariant vt( m_value ); // initialize as a string
vt.ChangeType( pCurrentItem->value.vt ); // let COleVariant convert!
HRESULT hr = opcAsyncIO2.Write(1, &pCurrentItem->hServerHandle,
vt, transactionID, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
if( FAILED(pErrors[0]) )
{
//ReportError( _T("ASync Write: "), pErrors[0] );
AfxMessageBox("ASync Write failed");
}
CoTaskMemFree( pErrors );
}
else
{
//ReportError( _T("ASync Write: "), hr );
AfxMessageBox("ASync Write failed");
}
}
}
else
{
OPCAsyncIO opcAsyncIO;
if( opcAsyncIO.Attach( opcGroup ) == S_OK )
{
COleVariant vt( m_value ); // initialize as a string
vt.ChangeType( pCurrentItem->value.vt ); // let COleVariant convert!
HRESULT hr = opcAsyncIO.Write(dwConnection2, 1, &pCurrentItem->hServerHandle,
vt, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
if( FAILED(pErrors[0]) )
{
//ReportError( _T("ASync Write: "), pErrors[0] );
AfxMessageBox("ASync Write failed");
}
CoTaskMemFree( pErrors );
}
else
{
//ReportError( _T("ASync Write: "), hr );
AfxMessageBox("ASync Write failed");
}
}
}
}
else
{
OPCSyncIO opcSyncIO;
if( opcSyncIO.Attach( opcGroup ) == S_OK )
{
COleVariant vt( m_value ); // initialize as a string
vt.ChangeType( pCurrentItem->value.vt ); // let COleVariant convert!
HRESULT hr = opcSyncIO.Write( 1, &pCurrentItem->hServerHandle, vt, &pErrors);
if( SUCCEEDED(hr) )
{
if( FAILED(pErrors[0]) )
{
//ReportError( _T("Sync Write: "), pErrors[0] );
AfxMessageBox("ASync Write failed");
}
CoTaskMemFree( pErrors );
}
else
{
//ReportError( _T("Sync Write: "), hr );
AfxMessageBox("ASync Write failed");
}
}
}
return 1;
}
void COPCClient::Additem(LPCTSTR itemID, LPCTSTR accessPath, VARTYPE type)
{
USES_CONVERSION;
CWaitCursor wait;
OPCItemMgt itemMgt;
HRESULT hr = itemMgt.Attach( opcGroup);
if( FAILED(hr) )
return;
Item * item =new Item;
item->quality = OPC_QUALITY_GOOD;
item->name = itemID;
OPCITEMDEF idef;
idef.szItemID = T2OLE((LPTSTR)itemID);
idef.dwBlobSize = 0;
idef.pBlob = NULL;
idef.bActive = TRUE;
idef.hClient = (OPCHANDLE)item; // pointer to item is its "handle"
idef.szAccessPath = T2OLE((LPTSTR)accessPath);
idef.vtRequestedDataType = type;
OPCITEMRESULT * pResults;
HRESULT *pErrors;
hr = itemMgt.AddItems(1, &idef, &pResults, &pErrors);
if( FAILED( hr ) ) // if the call failed, get out
{
//ReportError( _T("AddItems: "), hr );
AfxMessageBox(_T("AddItems failed"));
delete item;
return;
}
item->hServerHandle = pResults->hServer; // save the server handle
type = pResults->vtCanonicalDataType;
// Save the result in pErrors before freeing
HRESULT itemResult = pErrors[0]; // and the item's result
if( pResults->pBlob != NULL )
CoTaskMemFree( pResults->pBlob );
CoTaskMemFree( pResults );
CoTaskMemFree( pErrors );
// It this item failed, don't keep it (the server didn't)
if( FAILED(itemResult) )
{
//ReportError( _T("AddItems: "), itemResult );
AfxMessageBox("AddItems:failed");
delete item;
return;
}
items.AddTail( item );
OPCSyncIO opcSyncIO;
if(opcSyncIO.Attach(opcGroup) == S_OK )
{
OPCITEMSTATE* pItemState;
hr = opcSyncIO.Read(OPC_DS_CACHE, 1, &item->hServerHandle, &pItemState, &pErrors);
if( SUCCEEDED(hr) )
{
ASSERT( pItemState->hClient == (OPCHANDLE)item );
item->quality = pItemState->wQuality;
item->value = pItemState->vDataValue;
VariantClear( &pItemState->vDataValue );
CoTaskMemFree( pItemState );
CoTaskMemFree( pErrors );
}
else
{
//ReportError( _T("Sync Read: "), hr );
AfxMessageBox(" sync Read failled");
return;
}
}
#ifdef FULL_TEST
if( itemMgt.IsOk() )
{
hr = itemMgt.SetActiveState( 1, &item->hServerHandle, FALSE, &pErrors);
if( SUCCEEDED(hr) )
CoTaskMemFree( pErrors );
hr = itemMgt.SetActiveState( 1, &item->hServerHandle, TRUE, &pErrors);
if( SUCCEEDED(hr) )
CoTaskMemFree( pErrors );
hr = itemMgt.SetClientHandles( 1, &item->hServerHandle, (OPCHANDLE*)&item, &pErrors);
if( SUCCEEDED(hr) )
CoTaskMemFree( pErrors );
}
#endif // FULL_TEST
UpdateAllViews(NULL);
}
void COPCClient::DisConnect()
{
CWaitCursor wait;
HRESULT hr = S_OK;
if( opcServer.IsOk() && opcGroup.IsOk() )
{
if( dwShutdownConnection )
{
IConnectionPointContainer *pCPC = 0;
hr = opcServer.QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if( SUCCEEDED(hr) )
{
IConnectionPoint *pCallbackCP = 0;
hr = pCPC->FindConnectionPoint(IID_IOPCShutdown, &pCallbackCP);
if( SUCCEEDED(hr) )
{
hr = pCallbackCP->Unadvise(dwShutdownConnection);
pCallbackCP->Release();
}
pCPC->Release();
}
}
if( usingCP )
{
// OPC 2.0 ConnectionPoints
IConnectionPointContainer *pCPC = 0;
hr = opcGroup.QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if( SUCCEEDED(hr) && dwConnection1 ) // This server supports 2.0
{
IConnectionPoint *pCallbackCP = 0;
hr = pCPC->FindConnectionPoint(IID_IOPCDataCallback, &pCallbackCP);
if( SUCCEEDED(hr) )
{
hr = pCallbackCP->Unadvise(dwConnection1);
pCallbackCP->Release();
}
pCPC->Release();
}
}
else
// call IDataObject::DUnadvise to turn off data notification
{
DataObject dataObject;
HRESULT hr = dataObject.Attach( opcGroup );
if( SUCCEEDED(hr) )
{
if( dwConnection1 )
hr = dataObject.DUnadvise(dwConnection1);
if( dwConnection2 )
hr = dataObject.DUnadvise(dwConnection2);
dataObject.Detach();
}
}
// test RemoveItems (RemoveGroup cleans up anyway.)
#ifdef FULL_TEST
OPCItemMgt itemMgt;
hr = itemMgt.Attach( opcGroup );
if( SUCCEEDED(hr) && items.GetCount()>0 )
{
HRESULT *pErrors=0;
OPCHANDLE* handles = new OPCHANDLE[items.GetCount()];
POSITION pos = items.GetHeadPosition();
for( int index=0; pos; index++ )
{
Item* pItem = items.GetNext( pos );
handles[index] = pItem->hServerHandle;
}
hr = itemMgt.RemoveItems( items.GetCount(), handles, &pErrors );
if( SUCCEEDED(hr) )
CoTaskMemFree( pErrors );
delete [] handles;
}
#endif // FULL_TEST
opcServer.RemoveGroup(groupHandle, FALSE);
}
opcGroup.Detach();
opcServer.Detach();
Sleep( 100 );
// now that the group is released and unadvised, no more data will
// be sent from the server. It is safe to delete the items
while( !items.IsEmpty() )
delete items.RemoveTail();
pCurrentItem = NULL;
UpdateAllViews(NULL);
SetTitle( _T("Unconnected ") );
}
void COPCClient::OpcAdditem()
{
ASSERT( opcGroup.IsOk() );
}
void COPCClient::AutoAdditem(CString m_itemID)
{
ASSERT( opcGroup.IsOk() );
}
void COPCClient::refresh()
{
CWaitCursor wait;
if( usingCP )
{
OPCAsyncIO2 opcAsyncIO2;
if( opcAsyncIO2.Attach( opcGroup ) == S_OK )
{
// test both Device and Cache data sources
// This should cause the server to queue a refresh while one is going on.
transactionID = 2; // any number the client wants
HRESULT hr = opcAsyncIO2.Refresh2(OPC_DS_DEVICE, transactionID, &transactionID);
if( FAILED(hr) )
{
//ReportError( _T("Refresh2: "), hr );
AfxMessageBox("Refresh failed");
return;
}
#ifdef FULL_TEST
transactionID = 3; // any number the client wants
hr = opcAsyncIO2.Refresh2(OPC_DS_DEVICE, transactionID, &transactionID);
if( FAILED(hr) )
{
//ReportError( _T("Refresh: "), hr );
AfxMessageBox("Refresh failed");
return;
}
#endif // FULL_TEST
}
}
else
{
OPCAsyncIO opcAsyncIO;
if( opcAsyncIO.Attach( opcGroup ) == S_OK )
{
// test both Device and Cache data sources
// This should cause the server to queue a refresh while one is going on.
HRESULT hr = opcAsyncIO.Refresh(dwConnection1, OPC_DS_DEVICE, &transactionID);
if( FAILED(hr) )
{
//ReportError( _T("Refresh: "), hr );
AfxMessageBox("Refresh failed");
return;
}
#ifdef FULL_TEST
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -