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

📄 valuemsgview.cpp

📁 Visual C++通信编程工程实例精解(附盘)
💻 CPP
字号:
// ValueMsgView.cpp : implementation file
//

#include "stdafx.h"
#include "OpcClientSpy.h"
#include "ValueMsgView.h"
#include "AddItemDlg.h"
#include "ServerInfoView.h"
#include "MainFrm.h"
#include "ItemParamsDlg.h"
#include "WriteItemDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CValueMsgView *theMsgValue=NULL;
/////////////////////////////////////////////////////////////////////////////
// CValueMsgView

IMPLEMENT_DYNCREATE(CValueMsgView, CFormView)

CValueMsgView::CValueMsgView()
	: CFormView(CValueMsgView::IDD)
{
	//{{AFX_DATA_INIT(CValueMsgView)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	pCurrentItem = NULL;
	transactionID = 0;
	theMsgValue = this;
}

CValueMsgView::~CValueMsgView()
{
   while( !m_items.IsEmpty() )
      delete m_items.RemoveTail();
}

void CValueMsgView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CValueMsgView)
	DDX_Control(pDX, IDC_LIST_INFO, m_value);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CValueMsgView, CFormView)
	//{{AFX_MSG_MAP(CValueMsgView)
	ON_MESSAGE(WM_OPCDATA, OnOPCDataChange)
	ON_MESSAGE(WM_OPCWRITE, OnOPCWriteError)
	ON_MESSAGE(WM_OPCSHUTDOWN, OnOPCShutdown)
	//ON_MESSAGE(WM_OPCWRITE, OnOPCWriteError)
	//ON_MESSAGE(WM_OPCSHUTDOWN, OnOPCShutdown)
	ON_WM_SIZE()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(IDT_ADD_ITEM, OnAddItem)
	ON_UPDATE_COMMAND_UI(IDT_ADD_ITEM, OnUpdateAddItem)
	ON_COMMAND(IDT_ITEM_PROPERTY, OnItemProperty)
	ON_UPDATE_COMMAND_UI(IDT_ITEM_PROPERTY, OnUpdateItemProperty)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_INFO, OnItemchangedListInfo)
	ON_COMMAND(IDT_WRITE_TOITEM, OnWriteToitem)
	ON_UPDATE_COMMAND_UI(IDT_WRITE_TOITEM, OnUpdateWriteToitem)
	ON_COMMAND(IDT_DELETE_ITEM, OnDeleteItem)
	ON_UPDATE_COMMAND_UI(IDT_DELETE_ITEM, OnUpdateDeleteItem)
	ON_COMMAND(IDT_REFRESH, OnRefresh)
	ON_UPDATE_COMMAND_UI(IDT_REFRESH, OnUpdateRefresh)
	ON_COMMAND(IDT_READ_VALUE, OnReadValue)
	ON_UPDATE_COMMAND_UI(IDT_READ_VALUE, OnUpdateReadValue)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CValueMsgView diagnostics

#ifdef _DEBUG
void CValueMsgView::AssertValid() const
{
	CFormView::AssertValid();
}

void CValueMsgView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CValueMsgView message handlers

//初始化列表的标题等。
void CValueMsgView::InitalListCtrl(void)
{
	CRect rect;
	m_value.DeleteAllItems();
	m_value.InsertColumn(0, "条目", LVCFMT_LEFT,150,0);
	m_value.InsertColumn(1, "值", LVCFMT_LEFT,100,1);
	m_value.InsertColumn(2, "数据质量", LVCFMT_LEFT,100,2);
	m_value.InsertColumn(3, "时间", LVCFMT_LEFT,100,3);
	m_value.InsertColumn(4, "OPC服务", LVCFMT_LEFT,100,4);
	m_value.InsertColumn(5, "描述信息", LVCFMT_LEFT,200,5);
}

void CValueMsgView::OnInitialUpdate() 
{
	CFormView::OnInitialUpdate();
	
	//并初始化列标题
	InitalListCtrl();
}

void CValueMsgView::OnSize(UINT nType, int cx, int cy) 
{
	CFormView::OnSize(nType, cx, cy);
	
	CFormView::ShowScrollBar(SB_VERT,FALSE);
	CFormView::ShowScrollBar(SB_HORZ,FALSE);

	if (GetSafeHwnd())
	{
		if (m_value.GetSafeHwnd())
		{
			CRect rect(0,0,cx,cy);
			m_value.MoveWindow(&rect);
		}
	}	
}


//弹出菜单
void CValueMsgView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
   CMenu popMenu;

   if( popMenu.LoadMenu(IDR_MENU_LIST) )
   {
      popMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
                                             point.x,point.y,
                                             AfxGetMainWnd());
   }	
}


//删除所有项
void  CValueMsgView::DeleteAllItem(void)
{
   while( !m_items.IsEmpty() )
      delete m_items.RemoveTail();
   pCurrentItem = NULL;
   //重新画list
   OnUpdate(NULL,0,NULL);
}

//ITEM参数对话框
void CValueMsgView::OnItemProperty() 
{
   // get an interface pointer
   OPCItemMgt itemMgt;
   HRESULT hr = itemMgt.Attach( m_pServerView->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) )
         MessageBox( _T("EnumOPCItemAttributes: "));
   }
	
}


void CValueMsgView::OnUpdateItemProperty(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( m_pServerView->opcServer.IsOk() && pCurrentItem );
}

void CValueMsgView::OnItemchangedListInfo(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	
	pCurrentItem = (Item*)pNMListView->lParam;
	
	*pResult = 0;
}

//写值到ITEM
void CValueMsgView::OnWriteToitem() 
{
	WriteItemDlg dlg;
	dlg.m_item = pCurrentItem->name;
	if( dlg.DoModal() != IDOK ) return;
	
	CWaitCursor wait;
	HRESULT *pErrors = NULL;
	if( dlg.m_async )
	{
		if( m_pServerView->usingCP )
		{
			OPCAsyncIO2 opcAsyncIO2;
			if( opcAsyncIO2.Attach( m_pServerView->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]) )
						MessageBox(_T("usingCP:pErrors[0]:ASync Write: "));
					CoTaskMemFree( pErrors );
				}
				else
					MessageBox(_T("usingCP:FAILED(hrt):ASync Write: "));
			}
		}
		else//usingCP=FALSE
		{
			 OPCAsyncIO opcAsyncIO;
			if( opcAsyncIO.Attach( m_pServerView->opcGroup ) == S_OK )
			{
				COleVariant vt( dlg.m_value );   // initialize as a string
				vt.ChangeType( pCurrentItem->value.vt );  // let COleVariant convert!
				HRESULT hr = opcAsyncIO.Write(m_pServerView->dwConnection2, 1, &pCurrentItem->hServerHandle,
                                          vt, &transactionID, &pErrors);
				if( SUCCEEDED(hr) )
				{
					if( FAILED(pErrors[0]) )
						MessageBox(_T("pErrors[0]:ASync Write: "));
					CoTaskMemFree( pErrors );
				}
				else
					MessageBox(_T("FAILED(hr):ASync Write: "));
			}
		}//end of "else
	}
	else//dlg.m_async=FALSE
	{
		OPCSyncIO opcSyncIO;
		if( opcSyncIO.Attach( m_pServerView->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]) )
				   MessageBox(_T("Sync Write: "));
			   CoTaskMemFree( pErrors );
			}
			else
				MessageBox( _T("FAILED(hrt):Sync Write: "));
		}
	}//end of "else...
	//强制显示新的数据
	OnUpdate(NULL,0,NULL);
}

//是否允许写值到ITEM
void CValueMsgView::OnUpdateWriteToitem(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( m_pServerView->opcServer.IsOk() && pCurrentItem );
}

//删除项目
void CValueMsgView::OnDeleteItem() 
{
   OPCItemMgt itemMgt;
   HRESULT hr = itemMgt.Attach( m_pServerView->opcGroup );
   if( SUCCEEDED(hr) )
   {
      HRESULT *pErrors=0;
      OPCHANDLE handle = pCurrentItem->hServerHandle;
      hr = itemMgt.RemoveItems( 1, &handle, &pErrors );
      if( SUCCEEDED(hr) )
         CoTaskMemFree( pErrors );
      POSITION pos = m_items.Find( pCurrentItem );
      m_items.RemoveAt( pos );
      delete pCurrentItem;
      pCurrentItem = NULL;
      OnUpdate(NULL,0,NULL);
   }
}

//是否允许删除项目
void CValueMsgView::OnUpdateDeleteItem(CCmdUI* pCmdUI) 
{
   pCmdUI->Enable( m_pServerView->opcServer.IsOk() && pCurrentItem );
}

// Refresh causes all items to be advised immediately.
void CValueMsgView::OnRefresh() 
{
   CWaitCursor wait;
   if( m_pServerView->usingCP )
   {
      OPCAsyncIO2 opcAsyncIO2;
      if( opcAsyncIO2.Attach( m_pServerView->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) )
         {
            MessageBox( _T("Refresh2:error"));
            return;
         }
      }
   }//end of "if(usingCP)...
   else
   {
      OPCAsyncIO opcAsyncIO;
      if( opcAsyncIO.Attach( m_pServerView->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(m_pServerView->dwConnection1, OPC_DS_DEVICE, &transactionID);
         if( FAILED(hr) )
         {
            MessageBox( _T("!usingCP:Refresh: "));
            return;
         }
      }
   }//end of "else...
   OnUpdate(NULL,0,NULL);
}

//是否允许刷新
void CValueMsgView::OnUpdateRefresh(CCmdUI* pCmdUI) 
{
   pCmdUI->Enable( m_pServerView->opcServer.IsOk() );
}

//Read value from OPC Server
void CValueMsgView::OnReadValue() 
{
	HRESULT *pErrors;
	CWaitCursor wait;
    // also test sync read since data is returned differently
    OPCSyncIO opcSyncIO;
    if( opcSyncIO.Attach( m_pServerView->opcGroup ) == S_OK )
    {
		OPCITEMSTATE* pItemState;
        HRESULT hr = opcSyncIO.Read(OPC_DS_DEVICE, 1, &pCurrentItem->hServerHandle, &pItemState, &pErrors);
        if( SUCCEEDED(hr) )
        {
            if( FAILED(pErrors[0]) )
				MessageBox("Sync Read is error!");
            else
            {
               pCurrentItem->quality = pItemState->wQuality;
               pCurrentItem->value = pItemState->vDataValue;
            }
            VariantClear( &pItemState->vDataValue );
            CoTaskMemFree( pItemState );
            CoTaskMemFree( pErrors );
         }
        else//FAILED(hr)
			MessageBox("Failed(hr),Sync Read.");
    }

   // Use AsyncIO2 here
   if( m_pServerView->usingCP )
   {
      OPCAsyncIO2 opcAsyncIO2;
      if( opcAsyncIO2.Attach( m_pServerView->opcGroup ) == S_OK )
      {
         transactionID = 3;
         HRESULT hr = opcAsyncIO2.Read(1, &pCurrentItem->hServerHandle, transactionID, &transactionID, &pErrors);
         if( SUCCEEDED(hr) )
         {
            if( FAILED(pErrors[0]) )
               MessageBox(_T("Async Read: "));
            CoTaskMemFree( pErrors );
         }
         else
            MessageBox( _T("Async Read: "));
      }
   }//end of "if (usingCP)...
   else
   {
      OPCAsyncIO opcAsyncIO;
      if( opcAsyncIO.Attach( m_pServerView->opcGroup ) == S_OK )
      {
         HRESULT hr = opcAsyncIO.Read(m_pServerView->dwConnection1, OPC_DS_CACHE, 1, &pCurrentItem->hServerHandle, &transactionID, &pErrors);
         if( SUCCEEDED(hr) )
         {
            if( FAILED(pErrors[0]) )
               MessageBox( _T("Async Read: "));
            CoTaskMemFree( pErrors );
         }
         else
            MessageBox(_T("Async Read: "));
      }
   }//end of "else...
   //重新显示新的数据
   OnUpdate(NULL,0,NULL);
}

//是否允许读值
void CValueMsgView::OnUpdateReadValue(CCmdUI* pCmdUI) 
{
   pCmdUI->Enable( m_pServerView->opcServer.IsOk() && pCurrentItem );
}


//**************************************************************************
// An asynchronous data change callback triggers this message to
// update the values in the display
//
LONG CValueMsgView::OnOPCDataChange(UINT wParam,LONG lParam)
{
   OnUpdate(NULL, 32, NULL);

   return 0L;
}


//**************************************************************************
// An asynchronous write complete callback triggers this message
// if there is a message to display
//
LONG CValueMsgView::OnOPCWriteError(UINT wParam,LONG lParam)
{
   MessageBox( _T("OPC Write错误信息:ASync Write error. "));

   return 0L;
}

//**************************************************************************
// An asynchronous shutdown callback triggers this message
//
LONG CValueMsgView::OnOPCShutdown(UINT wParam,LONG lParam)
{
	m_pServerView->DisconnectOPCServer(TRUE);
	CString msg;
	msg.Format(_T("Server shutting down."));
	CString appName((LPCSTR)AFX_IDS_APP_TITLE);
	MessageBox(msg, appName, MB_OK);

	return 0L;
}

⌨️ 快捷键说明

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