📄 superopcview.cpp
字号:
// SuperOPCView.cpp : CSuperOPCView 类的实现
//
#include "stdafx.h"
#include "SuperOPC.h"
#include "SuperOPCDoc.h"
#include "SuperOPCView.h"
#include "HotOpcServer.h"
#include "ConnectDlg.h"
#include "addgroupdlg.h"
#include "additemdlg.h"
#include ".\superopcview.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSuperOPCView
IMPLEMENT_DYNCREATE(CSuperOPCView, CListView)
BEGIN_MESSAGE_MAP(CSuperOPCView, CListView)
ON_COMMAND(ID_CONN_SERVER, OnConnServer)
ON_WM_CLOSE()
ON_UPDATE_COMMAND_UI(ID_CONN_SERVER,OnUpdateCmdUI)
ON_UPDATE_COMMAND_UI(ID_RECONNECT,OnUpdateCmdUI)
ON_UPDATE_COMMAND_UI(ID_DISCONNECT,OnUpdateCmdUI)
ON_UPDATE_COMMAND_UI(ID_NEWGROUP,OnUpdateCmdUI)
ON_UPDATE_COMMAND_UI(ID_NEWITEM,OnUpdateCmdUI)
ON_COMMAND(ID_DISCONNECT, OnDisconnect)
ON_COMMAND(ID_RECONNECT, OnReconnect)
ON_COMMAND(ID_NEWGROUP, OnNewgroup)
ON_COMMAND(ID_TEST, OnTest)
ON_COMMAND(ID_NEWITEM, OnNewitem)
ON_WM_TIMER()
END_MESSAGE_MAP()
// CSuperOPCView 构造/析构
CSuperOPCView::CSuperOPCView()
: m_pServer(NULL),
m_pGroup(NULL),
m_pItem(NULL),
m_bCreateColumn(FALSE)
{
// TODO: 在此处添加构造代码
}
CSuperOPCView::~CSuperOPCView()
{
}
BOOL CSuperOPCView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
// 样式
return CListView::PreCreateWindow(cs);
}
void CSuperOPCView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
// TODO: 调用 GetListCtrl() 直接访问 ListView 的列表控件,
// 从而可以用项填充 ListView。
}
// CSuperOPCView 诊断
#ifdef _DEBUG
void CSuperOPCView::AssertValid() const
{
CListView::AssertValid();
}
void CSuperOPCView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
CSuperOPCDoc* CSuperOPCView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSuperOPCDoc)));
return (CSuperOPCDoc*)m_pDocument;
}
#endif //_DEBUG
// CSuperOPCView 消息处理程序
void CSuperOPCView::OnConnServer()
{
CConnectDlg ConnDlg;
if(ConnDlg.DoModal() != IDOK)
return;
if(m_pServer)
SAFE_DELETE(m_pServer);
m_pServer = new CHotOpcServer();
ASSERT(m_pServer);
if(!m_pServer->Connect(ConnDlg.m_strSerName,ConnDlg.m_strRemoteName))
{
AfxMessageBox(_T("无法连接OPC服务器"));
return;
}
}
void CSuperOPCView::OnClose()
{
KillTimer(1191);
SAFE_DELETE(m_pServer);
CListView::OnClose();
}
void CSuperOPCView::OnUpdateCmdUI(CCmdUI *pCmdUI)
{
switch(pCmdUI->m_nID)
{
case ID_CONN_SERVER:
{
if(m_pServer)
pCmdUI->Enable(!m_pServer->IsConnected());
else
pCmdUI->Enable();
break;
}
case ID_RECONNECT:
case ID_DISCONNECT:
case ID_NEWGROUP:
{
if(m_pServer)
pCmdUI->Enable(m_pServer->IsConnected());
else
pCmdUI->Enable(FALSE);
break;
}
case ID_NEWITEM:
{
pCmdUI->Enable((m_pGroup != NULL));
break;
}
}
}
void CSuperOPCView::OnDisconnect()
{
ASSERT(m_pServer);
m_pServer->Stop();
GetListCtrl().DeleteAllItems();
KillTimer(1191);
}
void CSuperOPCView::OnReconnect()
{
ASSERT(m_pServer);
CWaitCursor cs;
m_pServer->Stop();
GetListCtrl().DeleteAllItems();
::Sleep(1000);
m_pServer->Start();
}
void CSuperOPCView::OnNewgroup()
{
if (m_pGroup != NULL)
{
AfxMessageBox("组已经建立");
return;
}
CAddGroupDlg groupDlg;
if(groupDlg.DoModal() != IDOK)
return;
if (m_pGroup == NULL)
{
ASSERT (m_pServer != NULL);
try
{
// Instantiate a new CKGroup:
m_pGroup = new CHotOpcGroup(m_pServer);
}
catch (...)
{
// If problem, delete the group and return with IDCANCEL code:
ASSERT (FALSE);
m_pGroup = NULL;
return;
}
}
// Create name if currently undefined:
if (groupDlg.m_strName.IsEmpty ())
{
if (!m_pServer || !m_pServer->IsAlive ())
{
groupDlg.m_strName = DEFAULTGROUPNAME;
m_pServer->GenerateGroupName (groupDlg.m_strName);
}
}
m_pGroup->SetName (groupDlg.m_strName);
m_pGroup->SetActive (TRUE);
m_pGroup->SetLanguageID (groupDlg.m_dwLanguageID);
m_pGroup->SetDeadband (groupDlg.m_fDeadband);
m_pGroup->SetBias (groupDlg.m_lBais);
m_pGroup->SetUpdateRate (groupDlg.m_dwUpdateRate);
m_pGroup->SetUpdateMethod (OPC_20_DATACHANGE);
// If this is a new group (indicated by non-NULL m_pServer),
// add it to the server:
if (m_pServer)
m_pServer->AddGroup (m_pGroup);
}
void CSuperOPCView::OnTest()
{
}
void CSuperOPCView::OnNewitem()
{
if(m_pServer == NULL || m_pGroup == NULL )
ASSERT(FALSE);
CAddItemDlg dlg (m_pGroup, m_pServer->GetIBrowse ());
// Show as modal dialog. If user hits "OK", we need to add items to
// project:
if (dlg.DoModal () != IDOK)
return;
// Get the number of items to add specified in dialog:
int cnItems = dlg.GetItemCount ();
// If number of items is non-zero, then add them to project:
if (cnItems > 0)
{
// Get an object array containing the list of items to be added:
CObArray &cList = dlg.GetItemList ();
// If the number of items is large, then use a worker thread
// to add them:
if (cnItems > 64)
{
// Get pointer to first item from list. We will use it to
// get the group object these items will be added to:
CHotOpcItem *pItem = (CHotOpcItem *)cList.GetAt (0);
ASSERT (pItem);
// Add the items to this group:
m_pGroup->AddItems (cList, cnItems);
}
// Else if number of items is small, add them directly:
else
m_pGroup->AddItems (cList, cnItems);
}
if(!m_bCreateColumn)
{
GetListCtrl().ModifyStyle(NULL, LVS_REPORT | LVS_SORTASCENDING ,0);
GetListCtrl().SetExtendedStyle(LVS_EX_FULLROWSELECT);
CString strColumnTitle;
// Define list control columns:
for (int i = 0; i < 6; i++)
{
// Create a string to contain column width registry entry:
TCHAR szNum [8];
wsprintf (szNum, _T("%d"), i);
// Read the column width from the registry. This is the width of the column
// saved at the end of the last session.
int nWidth = 120 ;
// Load the column title string resource:
switch (i)
{
case 0: // Item ID
strColumnTitle = ("项名称");
break;
case 1: // Data Type
strColumnTitle = ("数据类型");
break;
case 2: // Value
strColumnTitle = ("值");
break;
case 3: // Timestamp
strColumnTitle = ("时间标记");
break;
case 4: // Quality
strColumnTitle = ("状态");
break;
case 5: // Update Count
strColumnTitle = ("列新次数");
break;
default: // Unexpected column index
ASSERT (FALSE);
break;
}
// Insert the column:
GetListCtrl ().InsertColumn (i, strColumnTitle, LVCFMT_LEFT, nWidth);
}
m_bCreateColumn = TRUE;
}
//--插入到ListView
CString strText;
int nColumnCount = GetListCtrl ().GetHeaderCtrl()->GetItemCount();
m_pItem = m_pGroup->GetItemHead();
ASSERT(m_pItem);
strText = m_pItem->GetItemID();
for (int i=0;i < m_pGroup->GetItemCount();i++)
{
// Insert the item, select every other item.
GetListCtrl ().InsertItem(
LVIF_TEXT|LVIF_STATE, i, strText,
0 , LVIS_SELECTED,
0, 0);
if(!GetListCtrl().SetItemData(i,(DWORD_PTR)m_pItem))
AfxMessageBox("SetItemData Error");
// Initialize the text of the subitems.
for (int j=1;j < nColumnCount;j++)
{
switch(j)
{
case 1:
StringFromVartype(m_pItem->GetDataType(),strText);
break;
case 2:
m_pItem->GetValue(strText);
break;
case 3:
m_pItem->GetTimeStamp(strText);
break;
case 4:
strText = m_pItem->GetQuality();
case 5:
strText.Format("%d",m_pItem->GetUpdateCount());
break;
}
GetListCtrl ().SetItemText(i, j, strText);
}
m_pItem = m_pItem->GetNext();
if(m_pItem == NULL)
break;
strText = m_pItem->GetItemID();
}
::SetTimer(m_hWnd,1191,250,NULL);
// Add the extended full row selection style (This causes all subitems
// to be selected at once - i.e. full row is selected.)
//SendMessage (LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
}
void CSuperOPCView::OnTimer(UINT nIDEvent)
{
if(nIDEvent == 1191)
{
CString tmpStr;
CHotOpcItem *pOpcItem = NULL;
int i=0;
CListCtrl& pList = GetListCtrl();
while ( (i<pList.GetItemCount()) )
{
pOpcItem = (CHotOpcItem *)pList.GetItemData(i);
if(!pOpcItem)
continue;
pOpcItem->GetValue(tmpStr);
pList.SetItemText(i,2,tmpStr);
pOpcItem->GetTimeStamp(tmpStr);
pList.SetItemText(i,3,tmpStr);
pList.SetItemText(i,4,pOpcItem->GetQuality());
tmpStr.Format("%d",pOpcItem ->GetUpdateCount());
pList.SetItemText(i,5,tmpStr);
i++;
}
}
else
CListView::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -