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

📄 tyopcclientview.cpp

📁 OPC Client 源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 + -