📄 tyopcclientview.cpp
字号:
// TYOPCClientView.cpp : implementation of the CViewOPCItem class
//
#include "stdafx.h"
#include "TYOPCClient.h"
#include "TYOPCClientDoc.h"
#include "TYOPCClientView.h"
#include "DlgOPCItemWrite.h"
#include "DlgModifyName.h"
#include "DlgPropertyOPCItem.h"
#include "SafeLock.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Define some list control constants:
static UINT COLUMNWIDH[] =
{
100, //数据别名
160, //数据ID
80, //数据类型
120, //数据值
100, //邮戳
60, //品质
40, //ACTIVE
80 //更新记数
};
#define DEFAULTCOLUMNWIDTH 120
//Define Sort Order
#define ASCENDING 0 //升序
#define DESCENDING 1 //降序
// Define amount to grow item list by:
#define GROWLIST 1024
// Define column headers:
static LPCTSTR lpszRegSection = _T("Item View");
static LPCTSTR lpszSortColumn = _T("Sort Column");
static LPCTSTR lpszSortOrder = _T("Sort Order");
static LPCTSTR lpszUpdateInterval = _T("Update Interval");
// Item pane update timer evetn type:
#define UPDATE_ITEMPANE_EVENT 1
// Declare member statics:
WORD CViewOPCItem::sm_wSortOrder = ASCENDING;
WORD CViewOPCItem::sm_wSortColumn = 0;
DWORD* CViewOPCItem::sm_pSortedItems = NULL;
//数据更新速率
#define VIEW_DEFAULT_INTERVAL 250
/////////////////////////////////////////////////////////////////////////////
// CViewOPCItem
IMPLEMENT_DYNCREATE(CViewOPCItem, CListView)
BEGIN_MESSAGE_MAP(CViewOPCItem, CListView)
//{{AFX_MSG_MAP(CViewOPCItem)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
ON_WM_CREATE()
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetDispInfo)
ON_WM_TIMER()
ON_NOTIFY_REFLECT(HDN_ITEMCLICK, OnItemClick)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_OPCITEM_ASYNC20_WRITE, OnOPCItemAsync20Write)
ON_NOTIFY_REFLECT(NM_RCLICK, OnRClick)
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CViewOPCItem construction/destruction
CViewOPCItem::CViewOPCItem()
{
// TODO: add construction code here
m_nSortedItems=0; //已有数据量
m_nSortedListSize=0; //sm_pSortedItems能容纳数据总数
m_wUpdateInterval = VIEW_DEFAULT_INTERVAL;
}
CViewOPCItem::~CViewOPCItem()
{
if(sm_pSortedItems)
delete[] sm_pSortedItems;
}
/////////////////////////////////////////////////////////////////////////////
// CViewOPCItem drawing
void CViewOPCItem::OnDraw(CDC* pDC)
{
// CTYOPCClientDoc* pDoc = GetDocument();
CDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CViewOPCItem printing
BOOL CViewOPCItem::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CViewOPCItem::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CViewOPCItem::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CViewOPCItem diagnostics
#ifdef _DEBUG
void CViewOPCItem::AssertValid() const
{
CView::AssertValid();
}
void CViewOPCItem::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
//*
CTYOPCClientDoc* CViewOPCItem::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTYOPCClientDoc)));
return (CTYOPCClientDoc*)m_pDocument;
}
//*/
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CViewOPCItem message handlers
BOOL CViewOPCItem::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Add your specialized code here and/or call the base class
// Perform default processing. Return FALSE if failure:
if (!CListView::PreCreateWindow (cs))
return (FALSE);
// Modify window sytle:
// First clear icon view, small icon view, and list view bits.
// Then set report view and owner data bits.
// (Owner data transfers the responsibility of managing data from the
// list control to the application programmer. This allows very large
// data sets to be handled efficiently. See MSDN discussion of Virtual
// List-View Style.)
cs.style &= ~(LVS_ICON | LVS_SMALLICON | LVS_LIST);
cs.style |= (LVS_REPORT | LVS_OWNERDATA);
return TRUE;
}
int CViewOPCItem::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
//
// Initialize the image list for the items. The bitmap must use a
// purple background color, RGB (255, 0, 255), so that the CImageList
// object can construct a mask. The images are 14x14 pixels. Set the
// image list background color to CLR_NONE so masked pixels will be
// transparent.
// Image number Use
// 0 Active tag
// 1 Inactive tag
// 2 Invalid tag
// 3 not used
BOOL bCreate=m_cImageList.Create (IDB_ITEMIMAGES, 14, 2, RGB (255, 0, 255));
m_cImageList.SetBkColor (CLR_NONE);
GetListCtrl ().SetImageList (&m_cImageList, LVSIL_SMALL);
GetListCtrl ().ModifyStyle (NULL,CCS_TOP|LVS_SHOWSELALWAYS); //LVS_EDITLABELS|允许就地编辑
GetListCtrl ().SetExtendedStyle (LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
// Create a string to hold column tile:
CString strColumnTitle;
UINT unFlag=LVCFMT_CENTER;
// Define list control columns:
int nCols=sizeof(COLUMNWIDH)/sizeof(UINT);
for (int i = 0; i < nCols; 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 = AfxGetApp ()->GetProfileInt (lpszRegSection, szNum, DEFAULTCOLUMNWIDTH);
// Make sure it is valid:
if (nWidth < 0)
nWidth = DEFAULTCOLUMNWIDTH;
unFlag=LVCFMT_CENTER;
// Load the column title string resource:
switch (i)
{
case 0: // Item Alias
strColumnTitle.LoadString (IDS_ITEMALIAS);
unFlag=LVCFMT_LEFT;
break;
case 1: // Item ID
strColumnTitle.LoadString (IDS_ITEMID);
unFlag=LVCFMT_LEFT;
break;
case 2: // Data Type
strColumnTitle.LoadString (IDS_DATATYPE);
break;
case 3: // Value
strColumnTitle.LoadString (IDS_VALUE);
break;
case 4: // Timestamp
strColumnTitle.LoadString (IDS_TIMESTAMP);
break;
case 5: // Quality
strColumnTitle.LoadString (IDS_QUALITY);
break;
case 6: // Active
strColumnTitle.LoadString (IDS_ACTIVE);
break;
case 7: // Update Count
strColumnTitle.LoadString (IDS_UPDATE_COUNT);
break;
default: // Unexpected column index
ASSERT (FALSE);
break;
}
// Insert the column:
GetListCtrl ().InsertColumn (i, strColumnTitle, unFlag, COLUMNWIDH[i]);
}
// Load the sort settings from registry. (Settings saved at end of last session.)
sm_wSortColumn = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszSortColumn, sm_wSortColumn);
sm_wSortOrder = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszSortOrder, sm_wSortOrder);
// Load update interval setting from registry. (Setting saved at end of last session.)
m_wUpdateInterval = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszUpdateInterval, m_wUpdateInterval);
// Start update view timer. This will give us a chance to do periodic
// maintenance of the view.
SetTimer (UPDATE_ITEMPANE_EVENT, m_wUpdateInterval, 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);
return 0;
}
void CViewOPCItem::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: Add your specialized code here and/or call the base class
CWaitCursor wc;
// Process according to hint type:
switch (lHint)
{
// Need to update view due to added items:
case HINT_ITEM_ADD:
{
// pHint points to a CObArray containing a list of COPCItem
// objects to add.
// Check to see if pHint was set (debug only).
ASSERT (pHint != NULL);
// Get pointer to the item list:
CObArray *pAddItems = (CObArray *)pHint;
// Initialize some variables:
COPCItem *pItem = NULL;
DWORD dwIndex = 0;
// Postpone redrawing until we are done. This will make things
// go faster and look smoother.
SetRedraw (false);
for(int nIndex=0;nIndex<=pAddItems->GetUpperBound ();nIndex++)
{
pItem = (COPCItem *) pAddItems->GetAt (nIndex);
Insert (pItem);
}
// Update the item count. (This is one of the responsibilities
// we took on by using a virtual list view. See comments in
// PreCreateWindow().) Set flags to prevent the scroll position
// from changing and to prevent the list control from repainting
// unless affected items are in view.
GetListCtrl ().SetItemCountEx (m_nSortedItems, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);
// Sort the Items:
SortItems ();
// Now that we have added all of the items, we can let the
// view repaint itself:
SetRedraw (true);
}
break;
case HINT_GETSEL_ITEM:
{
// Check to see if pHint was set (debug only).
ASSERT (pHint != NULL);
// Get pointer to the item list:
CStringArray *pSelItems = (CStringArray *)pHint;
GetSelOPCItem(*pSelItems);
break;
}
/*/
// Need to update view due to re-added items:
case HINT_READD_ITEM:
{
// This will be accomplished by simply causing a repaint of the
// item icons currently in view.
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
int nTopIndex;
CRect rc;
CRect rcitem;
// Get view rectangle:
cList.GetClientRect (&rc);
// Get index of first visible item:
nTopIndex = cList.GetTopIndex ();
// Get rectangle bounding the first visible item's icon:
cList.GetItemRect (nTopIndex, &rcitem, LVIR_ICON);
// Adjust the view rectangle to invalidate all item icons areas:
rc.right = rcitem.right;
rc.left = rcitem.left;
// Invalidate the area to force a repaint of item icons:
cList.InvalidateRect (&rc);
}
break;
// Need to update view due to closed project or new server selection:
case HINT_CLOSE_PROJECT:
case HINT_SERVER_SELECT:
// pHint will be NULL if HINT_CLOSE_PROJECT and will contain a
// pointer to a CKServer object if HINT_SELECT_SERVER. (Not
// used in either case.)
// No items should be displayed after project is closed of if
// a server is selected. (Items are displayed only when a group
// is selected.) Delete any items in list control.
if (GetListCtrl ().GetItemCount () > 0)
DeleteAllItems ();
break;
//*/
// Need to update view due to new group selection:
case HINT_ITEM_REMOVE:
case HINT_GROUP_SELECT:
{
// pHint points to the newly selected CKGroup object.
// Hint pointer must have been set for us to proceed:
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
if (pHint == NULL)
{ //当前选择项---非组
m_nSortedItems=0;
cList.SetItemCountEx (m_nSortedItems, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);
cList.DeleteAllItems ();
break;
}
// Get pointer to newly selected COPCGroup:
COPCGroup *pGroup = (COPCGroup *) pHint;
// Postpone redrawing until we are done. This will make
// things go faster and look smoother.
SetRedraw (false);
// Delete any items that are currently in the list:
if (cList.GetItemCount () > 0)
cList.DeleteAllItems ();
m_nSortedItems=0;
// if (cList.GetItemCount () > 0)
// DeleteAllItems ();
// Insert all items that belong to the selected group:
// Start with head of linked list of items in group and
// work our way to the end.
CMapStringToOb* pMapItem = pGroup->GetItem();
// Add each item in linked list until we hit the end
// (indicated by a NULL pointer).
POSITION pos=pMapItem->GetStartPosition ();
COPCItem* pItem=NULL;
CString rKey;
while (pos)
{
pMapItem->GetNextAssoc (pos,rKey,(CObject*&)pItem);
ASSERT(pItem);
if(pItem)
Insert (pItem);
}
// Update the item count. (This is one of the responsibilities
// we took on by using a virtual list view. See comments in
// PreCreateWindow().) Set flags to prevent the scroll position
// from changing and to prevent the list control from repainting
// unless affected items are in view.
cList.SetItemCountEx (m_nSortedItems, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);
// Sort the list:
SortItems ();
// Now that we are done adding items, we can let the view
// repaint itself:
SetRedraw (true);
}
break;
/*/
// Need to update view due to refresh view request:
case HINT_REFRESH_ITEMVIEW:
// Force a repaint of whole view:
GetListCtrl ().Invalidate (false);
GetListCtrl ().UpdateWindow ();
break;
//*/
// Perform default processing:
case HINT_NEW_DOCUMENT:
case HINT_OPEN_DOCUMENT:
{
CListCtrl &cList = GetListCtrl ();
m_nSortedItems=0;
cList.SetItemCountEx (m_nSortedItems, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);
cList.DeleteAllItems ();
break;
}
default:
CView::OnUpdate (pSender, lHint, pHint);
break;
}
}
void CViewOPCItem::Insert(COPCItem *pItem,BOOL bSelItem/*=TRUE*/)
{
/*/
CListCtrl& cListCtrl=GetListCtrl();
// cListCtrl.InsertItem( 0,pItem->GetItemID (),0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -