📄 opc clientdoc.cpp
字号:
// 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 OPCClientDoc::OnUpdateOpcDisconnect(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcServer.IsOk() );
}
//*******************************************************************
void OPCClientDoc::OnOpcServerstatus()
{
ASSERT( opcServer.IsOk() );
//CServerStatus dlg(opcServer);
//dlg.DoModal();
}
void OPCClientDoc::OnUpdateOpcServerstatus(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcServer.IsOk() );
}
//*******************************************************************
void OPCClientDoc::OnOpcGroupparameters()
{
//GroupParamsDlg dlg( opcGroup );
//dlg.DoModal();
}
void OPCClientDoc::OnUpdateOpcGroupparameters(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcGroup.IsOk() );
}
//*******************************************************************
void OPCClientDoc::OnOpcAdditem()
{
ASSERT( opcGroup.IsOk() );
}
void OPCClientDoc::OnUpdateOpcAdditem(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcServer.IsOk() && opcGroup.IsOk() );
}
//*******************************************************************
void OPCClientDoc::AddItem(LPCTSTR itemID, LPCTSTR accessPath, VARTYPE type)
{
USES_CONVERSION;
//CWaitCursor wait;
// get an interface pointer
OPCItemMgt itemMgt;
HRESULT hr = itemMgt.Attach( opcGroup );
if( FAILED(hr) )
return;
// Add a new item
Item* item = new Item;
item->quality = OPC_QUALITY_GOOD;
item->name = itemID;
// fill out its definition
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;
// add the item
OPCITEMRESULT * pResults;
HRESULT *pErrors;
hr = itemMgt.AddItems(1, &idef, &pResults, &pErrors);
if( FAILED( hr ) ) // if the call failed, get out
{
ReportError( _T("AddItems: "), hr );
delete item;
return;
}
// If the call was successful, memory must be cleaned up
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 );
delete item;
return;
}
items.AddTail( item ); // store this item in the item list
// Read its initial value
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 );
return;
}
}
// test some more interfaces
#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);
}
//*******************************************************************
// This is the 2.0 Item Properties interface
void OPCClientDoc::OnOpcItemProperties()
{
}
void OPCClientDoc::OnUpdateOpcItemProperties(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcServer.IsOk() && pCurrentItem );
}
//*******************************************************************
void OPCClientDoc::OnOpcItemattributes()
{
// get an interface pointer
OPCItemMgt itemMgt;
HRESULT hr = itemMgt.Attach( opcGroup );
if( FAILED(hr) )
return;
// test the item attributes enumerator
EnumOPCItemAttributes enumerator;
hr = itemMgt.CreateEnumerator( IID_IEnumOPCItemAttributes, enumerator );
while( hr==S_OK && enumerator.IsOk() )
{
OPCITEMATTRIBUTES* pAttributes = NULL;
ULONG count=0;
hr = enumerator.Next( 1, &pAttributes, &count );
if( hr == S_OK )
{
if( pAttributes->hClient == (OPCHANDLE)pCurrentItem )
{
// found the matching attributes for this item
/*ItemParamsDlg dlg;
dlg.pItemAttr = pAttributes;
if( dlg.DoModal() == IDOK )
{
HRESULT *pErrors;
hr = itemMgt.SetActiveState( 1, &pCurrentItem->hServerHandle, dlg.m_active, &pErrors);
if( SUCCEEDED(hr) )
CoTaskMemFree( pErrors );
}*/
}
VariantClear( &pAttributes->vEUInfo );
CoTaskMemFree( pAttributes->szAccessPath );
CoTaskMemFree( pAttributes->szItemID );
if( pAttributes->pBlob )
CoTaskMemFree( pAttributes->pBlob );
CoTaskMemFree( pAttributes );
}
else if( FAILED(hr) )
ReportError( _T("EnumOPCItemAttributes: "), hr );
}
}
//*******************************************************************
void OPCClientDoc::OnUpdateOpcItemattributes(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcServer.IsOk() && pCurrentItem );
}
//*******************************************************************
// the user enters something to write to the item in the dialog.
// COleVariant's ChangeType converts the string into the proper format
// or else puts up a dialog that it couldn't convert.
// Write can be sync or async
void OPCClientDoc::OnOpcWritevaluetoitem()
{
WriteItemDlg dlg;
dlg.m_item = pCurrentItem->name;
if( dlg.DoModal() == IDOK )
{
CWaitCursor wait;
HRESULT *pErrors = NULL;
if( dlg.m_async )
{
if( usingCP )
{
OPCAsyncIO2 opcAsyncIO2;
if( opcAsyncIO2.Attach( opcGroup ) == S_OK )
{
transactionID = 2; // any number the client wants
COleVariant vt( dlg.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] );
}
CoTaskMemFree( pErrors );
}
else
{
ReportError( _T("ASync Write: "), hr );
}
}
}
else
{
OPCAsyncIO opcAsyncIO;
if( opcAsyncIO.Attach( opcGroup ) == S_OK )
{
COleVariant vt( dlg.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] );
}
CoTaskMemFree( pErrors );
}
else
{
ReportError( _T("ASync Write: "), hr );
}
}
}
}
else
{
OPCSyncIO opcSyncIO;
if( opcSyncIO.Attach( opcGroup ) == S_OK )
{
COleVariant vt( dlg.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] );
}
CoTaskMemFree( pErrors );
}
else
{
ReportError( _T("Sync Write: "), hr );
}
}
}
}
}
void OPCClientDoc::OnUpdateOpcWritevaluetoitem(CCmdUI* pCmdUI)
{
pCmdUI->Enable( opcServer.IsOk() && pCurrentItem );
}
//*******************************************************************
// Test async reading by calling 4 times (server will queue them up)
void OPCClientDoc::OnOpcReaditem()
{
HRESULT *pErrors;
CWaitCursor wait;
{ // also test sync read since data is returned differently
OPCSyncIO opcSyncIO;
if( opcSyncIO.Attach( opcGroup ) == S_OK )
{
OPCITEMSTATE* pItemState;
HRESULT hr = opcSyncIO.Read(OPC_DS_DEVICE, 1, &pCurrentItem->hServerHandle, &pItemState, &pErrors);
if( SUCCEEDED(hr) )
{
if( FAILED(pErrors[0]) )
{
ReportError( _T("Sync Read: "), pErrors[0] );
}
else
{
pCurrentItem->quality = pItemState->wQuality;
pCurrentItem->value = pItemState->vDataValue;
}
VariantClear( &pItemState->vDataValue );
CoTaskMemFree( pItemState );
CoTaskMemFree( pErrors );
}
else
{
ReportError( _T("Sync Read: "), hr );
}
}
}
// Use AsyncIO2 here
if( usingCP )
{
OPCAsyncIO2 opcAsyncIO2;
if( opcAsyncIO2.Attach( opcGroup ) == S_OK )
{
transactionID = 3;
HRESULT hr = opcAsyncIO2.Read(1, &pCurrentItem->hServerHandle, transactionID, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
if( FAILED(pErrors[0]) )
{
ReportError( _T("Async Read: "), pErrors[0] );
}
CoTaskMemFree( pErrors );
}
else
{
ReportError( _T("Async Read: "), hr );
}
#ifdef FULL_TEST
transactionID = 3;
hr = opcAsyncIO2.Read(1, &pCurrentItem->hServerHandle, transactionID, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
CoTaskMemFree( pErrors );
}
transactionID = 3;
hr = opcAsyncIO2.Read(1, &pCurrentItem->hServerHandle, transactionID, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
{
CoTaskMemFree( pErrors );
}
// ask for a few this time (it doesn't matter that its the same one)
transactionID = 3;
OPCHANDLE serverHandles[3];
for( int i=0; i<3; i++ )
serverHandles[i] = pCurrentItem->hServerHandle;
hr = opcAsyncIO2.Read(3, serverHandles, transactionID, &transactionID, &pErrors);
if( SUCCEEDED(hr) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -