📄 valuemsgview_2.cpp
字号:
/**************************************************
ValueMsgView_2.cpp : implementation file
**************************************************/
#include "stdafx.h"
#include "OpcClientSpy.h"
#include "ValueMsgView.h"
#include "AddItemDlg.h"
#include "ServerInfoView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
enum {COLUMN_NAME, COLUMN_VALUE, COLUMN_QUALITY,COLUMN_TIME};
void VariantToString(VARIANT value, CString& strText);
//增加一个ITEM
void CValueMsgView::OnAddItem()
{
ASSERT( m_pServerView->opcGroup.IsOk() );
AddItemDlg dlg( this, m_pServerView->opcServer );
dlg.DoModal();
}
void CValueMsgView::OnUpdateAddItem(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_pServerView->opcServer.IsOk() &&
m_pServerView->opcGroup.IsOk() );
}
//增加一个ITEM,被AddItemDlg调用
void CValueMsgView::AddItem(LPCTSTR itemID, LPCTSTR accessPath, VARTYPE type)
{
USES_CONVERSION;
CWaitCursor wait;
//get an interface pointer
OPCItemMgt itemMgt;
HRESULT hr = itemMgt.Attach( m_pServerView->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
{
MessageBox( _T("Addm_items: (AddItem)"));
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) )
{
MessageBox( _T("Addm_items:(AddItem") );
delete item;
return;
}
m_items.AddTail( item ); // store this item in the item list
// Read its initial value
OPCSyncIO opcSyncIO;
if( opcSyncIO.Attach( m_pServerView->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
{
MessageBox( _T("Sync Read: "));
return;
}
}
//添加条目到list
OnUpdate(NULL,0,NULL);
}
//将数据写到View中
void CValueMsgView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
m_value.SetRedraw( FALSE );
if( lHint==32 ) // update values only (a data advise)
{
CString number;
for( int index=0; index < m_value.GetItemCount(); index++ )
{
Item* pItem = (Item*)m_value.GetItemData( index );
VariantToString( pItem->value, number );
m_value.SetItem(index,COLUMN_VALUE,LVIF_TEXT,(LPTSTR)(LPCTSTR)number,0,0,0,0);
CString strQuality = "好";
if( (pItem->quality & OPC_QUALITY_MASK) != OPC_QUALITY_GOOD )
{
if( (pItem->quality & OPC_QUALITY_MASK) == OPC_QUALITY_UNCERTAIN )
strQuality = _T("不确定");
else if( (pItem->quality & OPC_QUALITY_MASK) == OPC_QUALITY_BAD )
strQuality = _T("损坏");
}
m_value.SetItem(index,COLUMN_QUALITY,LVIF_TEXT,strQuality,0,0,0,0);
#ifdef DATATIMEFORMAT
if( pItem->timestamp.dwHighDateTime != 0 )
{
CTime time( pItem->timestamp );
m_value.SetItem(index,COLUMN_TIME,LVIF_TEXT, time.Format(_T("%c")),0,0,0,0);
}
#endif // DATATIMEFORMAT
}
m_value.SetRedraw( TRUE );
return;
}
LV_ITEM lv_item;
lv_item.mask = LVIF_TEXT | LVIF_PARAM;
lv_item.iSubItem = COLUMN_NAME;
m_value.DeleteAllItems();
UpdateWindow();
m_value.SetItemCount( m_items.GetCount() );
POSITION pos = m_items.GetHeadPosition();
for( int index=0; pos!=NULL; index++)
{
Item* pItem = m_items.GetNext( pos );
lv_item.iItem = index;
lv_item.pszText = (LPTSTR)(LPCTSTR)pItem->name;
lv_item.lParam = (LPARAM)pItem;
int item = m_value.InsertItem(&lv_item);
CString number;
switch( pItem->value.vt )
{
case VT_BOOL:
number = pItem->value.boolVal ? _T("On") : _T("Off");
break;
case VT_UI1:
number.Format( _T("%hd"), pItem->value.bVal );
break;
case VT_I2:
number.Format( _T("%hd"), pItem->value.iVal );
break;
case VT_I4:
number.Format( _T("%d"), pItem->value.lVal );
break;
case VT_R8:
number.Format( _T("%g"), pItem->value.dblVal );
break;
case VT_BSTR:
number = pItem->value.bstrVal;
break;
default:
number = _T("?");
}
m_value.SetItem(item,COLUMN_VALUE,LVIF_TEXT,(LPTSTR)(LPCTSTR)number,0,0,0,0);
CString strQuality = "好";
if( (pItem->quality & OPC_QUALITY_MASK) != OPC_QUALITY_GOOD )
{
if( (pItem->quality & OPC_QUALITY_MASK) == OPC_QUALITY_UNCERTAIN )
strQuality = _T("不确定");
else if( (pItem->quality & OPC_QUALITY_MASK) == OPC_QUALITY_BAD )
strQuality = _T("损坏");
}
m_value.SetItem(index,COLUMN_QUALITY,LVIF_TEXT,strQuality,0,0,0,0);
}
m_value.SetItem(index, COLUMN_NAME, LVIF_STATE, NULL, 0, LVIS_SELECTED, 0, 0 );
m_value.SetRedraw( TRUE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -