📄 vcopcclientview.cpp
字号:
// VCOPCClientView.cpp : implementation of the CVCOPCClientView class
//
#include "stdafx.h"
#include "VCOPCClient.h"
#include "VCOPCClientDoc.h"
#include "VCOPCClientView.h"
#include "MainFrm.h"
#include "ConnSvrDlg.h"
#include "DisConnSvrDlg.h"
#include "GroupDlg.h"
#include "ItemDlg.h"
#include "PropDlg.h"
#include "WriteDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ID_MENU_ACTIVE 5001
#define ID_MENU_DEACTIVE 5002
#define ID_MENU_WRITEITEM 5003
#define ID_MENU_PROPERTY 5004
CString GetTypeStr(VARTYPE vt)
{
CString str;
switch(vt)
{
case VT_I1:
case VT_UI1: // BYTE
str = "BYTE";
break;
case VT_I2: // SHORT
str = "Short";
break;
case VT_UI2: // UNSIGNED SHORT / WORD
str = "Word";
break;
case VT_I4: // LONG
str = "Long";
break;
case VT_UI4: // UNSIGNED LONG
str = "DWord";
break;
case VT_INT: // INTEGER
str = "Int";
break;
case VT_UINT: // UNSIGNED INTEGER
str = "UINT";
break;
case VT_R4: // FLOAT
str = "Float";
break;
case VT_R8: // DOUBLE
str = "Double";
break;
case VT_BSTR: //BSTR
str = "String";
break;
case VT_BOOL:
str = "BOOL";
break;
default:
str = "Unknow";
break;
}
return str;
}
void GetVarStr(VARIANT* pValue, char* buf)
{
switch(pValue->vt)
{
case VT_I1:
case VT_UI1: // BYTE
sprintf (buf, "%d", pValue->bVal );
break;
case VT_I2: // SHORT
sprintf (buf, "%d", pValue->iVal );
break;
case VT_UI2: // UNSIGNED SHORT
sprintf (buf, "%d", pValue->uiVal );
break;
case VT_I4: // LONG
sprintf (buf, "%ld", pValue->lVal );
break;
case VT_UI4: // UNSIGNED LONG
sprintf (buf, "%ld", pValue->ulVal );
break;
case VT_INT: // INTEGER
sprintf (buf, "%ld", pValue->intVal );
break;
case VT_UINT: // UNSIGNED INTEGER
sprintf (buf, "%u", pValue->uintVal );
break;
case VT_R4: // FLOAT
sprintf (buf, "%5.2f", pValue->fltVal );
break;
case VT_R8: // DOUBLE
sprintf (buf, "%9.4f", pValue->dblVal );
break;
case VT_BSTR: //BSTR
sprintf (buf, "%ls", pValue->bstrVal );
break;
case VT_BOOL:
if (pValue->boolVal)
strcpy (buf, "TRUE");
else
strcpy (buf, "FALSE");
break;
default:
sprintf (buf, "unknown type:%d", pValue->vt );
break;
}
}
CString GetDateStr(FILETIME timestamp)
{
CTime ts = CTime::CTime(timestamp);
return ts.Format("%Y-%m-%d %H:%M:%S");
}
CString GetQualityStr(DWORD quality)
{
CString str;
switch (quality)
{
case OPC_QUALITY_UNCERTAIN:
str = "不确定";
break;
case OPC_QUALITY_BAD:
str = "无效";
break;
case OPC_QUALITY_GOOD:
str = "正常";
break;
default:
str = "未知";
break;
}
return str;
}
void CALLBACK DataChangeProc(HANDLE hServer,
HANDLE hGroup,
HANDLE hItem,
VARIANT *pVar,
FILETIME timestamp,
DWORD quality)
{
CMainFrame *pWnd;
pWnd = (CMainFrame *)AfxGetMainWnd();
CListCtrl& list = pWnd->m_pView->GetListCtrl();
int ItemCount = list.GetItemCount();
for( int i = 0; i < ItemCount; ++i)
{
GROUPITEM* pData = (GROUPITEM*)list.GetItemData(i);
if ( (pData->hServer == hServer) &&
(pData->hGroup == hGroup) &&
(pData->hItem == hItem) )
{
char buf[255] = { 0 };
GetVarStr(pVar, buf);
list.SetItemText(i, 1, buf);
list.SetItemText(i, 3, GetDateStr(timestamp));
list.SetItemText(i, 4, GetQualityStr(quality));
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CVCOPCClientView
IMPLEMENT_DYNCREATE(CVCOPCClientView, CListView)
BEGIN_MESSAGE_MAP(CVCOPCClientView, CListView)
//{{AFX_MSG_MAP(CVCOPCClientView)
ON_COMMAND(ID_FILE_CONNECT, OnFileConnect)
ON_COMMAND(ID_FILE_DISCONNECT, OnFileDisconnect)
ON_COMMAND(ID_FILE_MGROUP, OnFileMgroup)
ON_COMMAND(ID_FILE_MTAG, OnFileMtag)
ON_WM_CONTEXTMENU()
//}}AFX_MSG_MAP
ON_COMMAND(ID_MENU_ACTIVE, OnActive)
ON_COMMAND(ID_MENU_DEACTIVE, OnDeactive)
ON_COMMAND(ID_MENU_WRITEITEM, OnWriteItem)
ON_COMMAND(ID_MENU_PROPERTY, OnProperty)
ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_MGROUP, ID_FILE_DISCONNECT, OnUpdateUI)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVCOPCClientView construction/destruction
CVCOPCClientView::CVCOPCClientView()
{
// TODO: add construction code here
}
CVCOPCClientView::~CVCOPCClientView()
{
}
BOOL CVCOPCClientView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CListView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CVCOPCClientView drawing
void CVCOPCClientView::OnDraw(CDC* pDC)
{
CVCOPCClientDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
void CVCOPCClientView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CMainFrame *pWnd;
pWnd = (CMainFrame *)AfxGetMainWnd();
pWnd->m_pView = this;
CListCtrl& list = GetListCtrl();
list.ModifyStyle(NULL, LVS_REPORT | LVS_SORTASCENDING ,0);
list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
list.InsertColumn( 0, _T("标签"), LVCFMT_LEFT, 120, 0 );
list.InsertColumn( 1, _T("值"), LVCFMT_RIGHT, 90, 1 );
list.InsertColumn( 2, _T("数据类型"), LVCFMT_LEFT, 110, 1 );
list.InsertColumn( 3, _T("时间"), LVCFMT_LEFT, 120, 1 );
list.InsertColumn( 4, _T("质量"), LVCFMT_LEFT, 50, 1 );
list.InsertColumn( 5, _T("所属服务器"), LVCFMT_LEFT, 150, 1 );
list.InsertColumn( 6, _T("所属组"), LVCFMT_LEFT, 60, 1 );
}
/////////////////////////////////////////////////////////////////////////////
// CVCOPCClientView diagnostics
#ifdef _DEBUG
void CVCOPCClientView::AssertValid() const
{
CListView::AssertValid();
}
void CVCOPCClientView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
CVCOPCClientDoc* CVCOPCClientView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVCOPCClientDoc)));
return (CVCOPCClientDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CVCOPCClientView message handlers
CConnection* CVCOPCClientView::GetConnection(CString& strConn)
{
for( vector<CConnection*>::iterator iter = m_Connections.begin();
iter != m_Connections.end();
++iter)
{
if ( strcmp(strConn, (*iter)->m_ServerName) == 0 )
{
return *iter;
}
}
return NULL;
}
void CVCOPCClientView::AddTagtoList(CConnection* pConn, CGroup* pGroup, CString& strItemID)
{
HANDLE hItem = AddItem(pConn->m_hServer, pGroup->m_Handle, strItemID);
if ( hItem == INVALID_HANDLE_VALUE )
{
MessageBox("添加OPC标签失败!");
return;
}
GROUPITEM* pData = new GROUPITEM();
pData->hServer = pConn->m_hServer;
pData->hGroup = pGroup->m_Handle;
pData->hItem = hItem;
VARTYPE ItemType = 0;
DWORD right = 0;
if ( ValidateItem(pConn->m_hServer, pGroup->m_Handle, strItemID, &ItemType, &right) )
{
pData->right = right;
pData->vt = ItemType;
}
CListCtrl& list = GetListCtrl();
int nItem = list.InsertItem(0, strItemID);
list.SetItemText(nItem, 5, pConn->m_ServerName);
list.SetItemText(nItem, 6, pGroup->m_Name);
list.SetItemText(nItem, 2, GetTypeStr(pData->vt));
list.SetItemData(nItem, (DWORD)pData);
}
void CVCOPCClientView::OnFileConnect()
{
CConnSvrDlg dlg;
if(dlg.DoModal() != IDOK)
return;
HANDLE hConnect = Connect(dlg.m_strComputerName, dlg.m_ServerName);
if (hConnect==INVALID_HANDLE_VALUE)
{
AfxMessageBox("连接OPC服务器失败!");
return;
}
CConnection* pConn = new CConnection;
pConn->m_hServer = hConnect;
pConn->m_ServerName = dlg.m_ServerName;
m_Connections.push_back(pConn);
SetDataChangeProc(hConnect, &DataChangeProc);
}
void CVCOPCClientView::OnFileDisconnect()
{
CDisConnSvrDlg dlg;
dlg.m_pView = this;
dlg.DoModal();
}
void CVCOPCClientView::OnFileMgroup()
{
CGroupDlg dlg;
dlg.m_pView = this;
dlg.DoModal();
}
void CVCOPCClientView::OnFileMtag()
{
CItemDlg dlg;
dlg.m_pView = this;
dlg.DoModal();
}
void CVCOPCClientView::OnUpdateUI(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_Connections.size());
}
void CVCOPCClientView::OnContextMenu(CWnd* pWnd, CPoint point)
{
CListCtrl& list = GetListCtrl();
//当选择的项目不为1时不显示菜单
if ( list.GetSelectedCount() != 1 )
return;
GROUPITEM* pTag = NULL;
POSITION pos = list.GetFirstSelectedItemPosition();
if ( pos )
{
int nItem = list.GetNextSelectedItem(pos);
pTag = (GROUPITEM*)list.GetItemData(nItem);
}
CMenu menuPopup;
if(menuPopup.CreatePopupMenu())
{
menuPopup.AppendMenu(MF_STRING, ID_MENU_ACTIVE, "激活");
menuPopup.AppendMenu(MF_STRING, ID_MENU_DEACTIVE, "反激活");
menuPopup.AppendMenu(MF_SEPARATOR);
if (pTag->right & OPC_WRITEABLE)
menuPopup.AppendMenu(MF_STRING, ID_MENU_WRITEITEM, "写入");
else
menuPopup.AppendMenu(MF_STRING|MF_GRAYED, ID_MENU_WRITEITEM, "写入");
menuPopup.AppendMenu(MF_STRING, ID_MENU_PROPERTY, "属性");
}
menuPopup.TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
}
void CVCOPCClientView::OnActive()
{
CListCtrl& list = GetListCtrl();
//当选择的项目不为1时不显示菜单
if ( list.GetSelectedCount() != 1 )
return;
GROUPITEM* pTag = NULL;
POSITION pos = list.GetFirstSelectedItemPosition();
if ( pos )
{
int nItem = list.GetNextSelectedItem(pos);
pTag = (GROUPITEM*)list.GetItemData(nItem);
}
ActiveItem(pTag->hServer, pTag->hGroup, pTag->hItem, TRUE);
}
void CVCOPCClientView::OnDeactive()
{
CListCtrl& list = GetListCtrl();
//当选择的项目不为1时不显示菜单
if ( list.GetSelectedCount() != 1 )
return;
GROUPITEM* pTag = NULL;
POSITION pos = list.GetFirstSelectedItemPosition();
if ( pos )
{
int nItem = list.GetNextSelectedItem(pos);
pTag = (GROUPITEM*)list.GetItemData(nItem);
}
ActiveItem(pTag->hServer, pTag->hGroup, pTag->hItem, FALSE);
}
void CVCOPCClientView::OnWriteItem()
{
CListCtrl& list = GetListCtrl();
//当选择的项目不为1时不显示菜单
if ( list.GetSelectedCount() != 1 )
return;
GROUPITEM* pTag = NULL;
POSITION pos = list.GetFirstSelectedItemPosition();
if ( pos )
{
int nItem = list.GetNextSelectedItem(pos);
pTag = (GROUPITEM*)list.GetItemData(nItem);
}
CWriteDlg dlg;
if (dlg.DoModal() != IDOK)
return;
COleVariant varValue( dlg.m_strValue );
varValue.ChangeType(pTag->vt);
WriteItem(pTag->hServer, pTag->hGroup, pTag->hItem, varValue);
}
void CVCOPCClientView::OnProperty()
{
CPropDlg dlg;
dlg.m_pView = this;
dlg.DoModal();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -