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

📄 itemview.cpp

📁 KepWare的OPC Client 示例.面向C
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// **************************************************************************
// itemview.cpp
//
// Description:
//	Implements a CListView derived class.  This the top right pane of our GUI
//	which shows the OPC items.
//
// DISCLAIMER:
//	This programming example is provided "AS IS".  As such Kepware, Inc.
//	makes no claims to the worthiness of the code and does not warranty
//	the code to be error free.  It is provided freely and can be used in
//	your own projects.  If you do find this code useful, place a little
//	marketing plug for Kepware in your code.  While we would love to help
//	every one who is trying to write a great OPC client application, the 
//	uniqueness of every project and the limited number of hours in a day 
//	simply prevents us from doing so.  If you really find yourself in a
//	bind, please contact Kepware's technical support.  We will not be able
//	to assist you with server related problems unless you are using KepServer
//	or KepServerEx.
// **************************************************************************


#include "stdafx.h"
#include "opctestclient.h"
#include "itemview.h"
#include "document.h"
#include "item.h"
#include "group.h"
#include "server.h"
#include "itempropertiesdlg.h"
#include "itemwritedlg.h"
#include "updateintervaldlg.h"

// Define some list control constants:
#define NUMCOLUMNS			6
#define DEFAULTCOLUMNWIDTH	120
#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 CKItemView::sm_wSortOrder = ASCENDING;
WORD CKItemView::sm_wSortColumn = 0;
DWORD* CKItemView::sm_pSortedItemList = NULL;


/////////////////////////////////////////////////////////////////////////////
// CKItemView
/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE (CKItemView, CListView)

// **************************************************************************
BEGIN_MESSAGE_MAP (CKItemView, CListView)
	//{{AFX_MSG_MAP(CKItemView)
	ON_WM_DESTROY ()
	ON_COMMAND (ID_EDIT_NEWITEM, OnNewItem)
	ON_NOTIFY_REFLECT (LVN_GETDISPINFO, OnGetDispInfo)
	ON_COMMAND (ID_EDIT_PROPERTIES, OnProperties)
	ON_NOTIFY_REFLECT (LVN_COLUMNCLICK, OnColumnClick)
	ON_WM_TIMER ()
	ON_COMMAND (ID_EDIT_DELETE, OnDelete)
	ON_WM_RBUTTONDOWN ()
	ON_COMMAND (ID_VIEW_UPDATETIMER, OnUpdateTimer)
	ON_COMMAND (ID_TOOLS_SYNC_WRITE, OnSyncWrite)
	ON_COMMAND (ID_TOOLS_ASYNC10_WRITE, OnAsync10Write)
	ON_COMMAND (ID_TOOLS_ASYNC20_WRITE, OnAsync20Write)
	ON_COMMAND (ID_TOOLS_SET_ACTIVE, OnSetActive)
	ON_COMMAND (ID_TOOLS_SET_INACTIVE, OnSetInactive)
	ON_COMMAND (ID_TOOLS_SYNC_READ_CACHE, OnSyncReadCache)
	ON_COMMAND (ID_TOOLS_SYNC_READ_DEVICE, OnSyncReadDevice)
	ON_COMMAND (ID_TOOLS_ASYNC10_READ_CACHE, OnAsync10ReadCache)
	ON_COMMAND (ID_TOOLS_ASYNC10_READ_DEVICE, OnAsync10ReadDevice)
	ON_COMMAND (ID_TOOLS_ASYNC20_READ_DEVICE, OnAsync20ReadDevice)
	ON_COMMAND (ID_TOOLS_ASYNC10_REFRESH_CACHE, OnAsync10RefreshCache)
	ON_COMMAND (ID_TOOLS_ASYNC10_REFRESH_DEVICE, OnAsync10RefreshDevice)
	ON_COMMAND (ID_TOOLS_ASYNC20_REFRESH_CACHE, OnAsync20RefreshCache)
	ON_COMMAND (ID_TOOLS_ASYNC20_REFRESH_DEVICE, OnAsync20RefreshDevice)
	ON_COMMAND (ID_EDIT_COPY, OnCopy)
	ON_COMMAND (ID_EDIT_CUT, OnCut)
	ON_COMMAND (ID_EDIT_PASTE, OnPaste)
	ON_NOTIFY_REFLECT (NM_DBLCLK, OnDblclk)
	ON_WM_CHAR ()
	//}}AFX_MSG_MAP
	ON_NOTIFY_EX_RANGE (TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
	ON_NOTIFY_EX_RANGE (TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP ()


// **************************************************************************
// CKItemView ()
//
// Description:
//	Constructor.
//
// Parameters:
//  none
//
// Returns:
//  none
// **************************************************************************
CKItemView::CKItemView ()
	{
	// Initialize member variables:
	sm_wSortOrder = ASCENDING;
	sm_wSortColumn = 0;
	m_wUpdateInterval = VIEW_DEFAULT_INTERVAL;

	m_cnSortedItems = 0;
	m_nSortedListSize = 0;
	sm_pSortedItemList = NULL;
	}

// **************************************************************************
// ~CKItemView ()
//
// Description:
//	Destructor.
//
// Parameters:
//  none
//
// Returns:
//  none
// **************************************************************************
CKItemView::~CKItemView ()
	{
	// Free any memory used for sorted item list:
	if (sm_pSortedItemList)
		delete [] sm_pSortedItemList;
	}


/////////////////////////////////////////////////////////////////////////////
// CKItemView creation/drawing
/////////////////////////////////////////////////////////////////////////////

// **************************************************************************
// PreCreateWindow ()
//
// Description:
//	Called by framework before the creation of this window.  Use opportunity
//	to modify style of window.
//
// Parameters:
//	CREATESTRUCT	&cs		Defines the window initialization parameters. 
//
// Returns:
//  BOOL - TRUE if success.
// **************************************************************************
BOOL CKItemView::PreCreateWindow (CREATESTRUCT &cs) 
	{
	// 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 to indicate success:
	return (TRUE);	
	}

// **************************************************************************
// PreSubclassWindow ()
//
// Description:
//	This method is called by the framework to allow other necessary 
//	subclassing to occur before the window is subclassed. 
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemView::PreSubclassWindow () 
	{
	// Perform default processing:
	CListView::PreSubclassWindow ();

	// Enable tooltips:
	EnableToolTips (TRUE);
	}

// **************************************************************************
// Create
//
// Description:
//	Creates the CKItemView window and attaches it to parent window.  Use
//	opportunity to set list control's column properties from data saved
//	in registry and to start an update timer.
//
// Parameters:
//  LPCTSTR			lpszClassName	Names the Windows class.
//	LPCTSTR			lpszWindowName	Window name.
//	DWORD			dwStyle			Window stype.
//	const RECT		&rect			The size and position of the window.
//	CWnd			*pParentWnd		Parent window.
//	UINT			nID				The ID of the child window.
//	CCreateContext	*pContext		The create context of window.
//
// Returns:
//  BOOL - TRUE if success.
// **************************************************************************
BOOL CKItemView::Create (LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, UINT nID, CCreateContext *pContext) 
	{
	// Perform default processing.  Return FALSE if failure:
	if (!CWnd::Create (lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext))
		return (FALSE);

	// 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
	m_cImageList.Create (IDB_ITEMIMAGES, 14, 2, RGB (255, 0, 255));
	m_cImageList.SetBkColor (CLR_NONE);
	GetListCtrl ().SetImageList (&m_cImageList, LVSIL_SMALL);

	// Create a string to hold column tile:
	CString strColumnTitle;

	// Define list control columns:
	for (int i = 0; i < NUMCOLUMNS; 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;

		// Load the column title string resource:
		switch (i)
			{
			case 0:	// Item ID
				strColumnTitle.LoadString (IDS_ITEMID);
				break;

			case 1: // Data Type
				strColumnTitle.LoadString (IDS_DATATYPE);
				break;

			case 2: // Value
				strColumnTitle.LoadString (IDS_VALUE);
				break;

			case 3:	// Timestamp
				strColumnTitle.LoadString (IDS_TIMESTAMP);
				break;

			case 4: // Quality
				strColumnTitle.LoadString (IDS_QUALITY);
				break;

			case 5:	// Update Count
				strColumnTitle.LoadString (IDS_UPDATE_COUNT);
				break;

			default: // Unexpected column index
				ASSERT (FALSE);
				break;
			}

		// Insert the column:
		GetListCtrl ().InsertColumn (i, strColumnTitle, LVCFMT_LEFT, nWidth);
		}

	// 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 TRUE to inicate success:
	return (TRUE);
	}

// **************************************************************************
// OnDestroy ()
//
// Description:
//	Called by framework just before window is destroyed.  Use opportunity to
//	save list control's column settings to registry and kill update timer.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemView::OnDestroy () 
	{
	// Perform default processing:
	CListView::OnDestroy ();
	
	// Save current column information to registry so we can use the same
	// settings next time:
	for (int i = 0; i < NUMCOLUMNS; i++)
		{
		// Create a string to identify column width registry entry:
		TCHAR szNum [8];
		wsprintf (szNum, _T("%d"), i);

		// Save width:
		AfxGetApp ()->WriteProfileInt (lpszRegSection, szNum, GetListCtrl ().GetColumnWidth (i));
		}

	// Save sorting preferences to registry:
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszSortColumn, sm_wSortColumn);
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszSortOrder, sm_wSortOrder);

	// Save update interval to registry:
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszUpdateInterval, m_wUpdateInterval);

	// Stop update view timer:
	KillTimer (UPDATE_ITEMPANE_EVENT);
	}

// **************************************************************************
// OnUpdate ()
//
// Description:
//	Called when we the document has changed and we should update our view.
//
// Parameters:
//  CView		*pSender	Points to the view that modified the document, 
//							  or NULL if all views are to be updated.
//	LPARAM		lHint		Contains information about the modifications.
//							  Hints used here are defined in globals.h.
//	CObject		*pHint		Points to an object storing information about the 
//							  modifications.
//
// Returns:
//  void
// **************************************************************************
void CKItemView::OnUpdate (CView *pSender, LPARAM lHint, CObject *pHint) 
	{
	// Create a wait cursor object.  This will cause the wait cursor, 
	// usually an hourglass, to be displayed.  When this object goes
	// out of scope, its destructor will restore the previous cursor
	// type.
	CWaitCursor wc;

	// Process according to hint type:
	switch (lHint)
		{
		// Need to update view due to added items:
		case HINT_ADD_ITEM:	
			{
			// pHint points to a CObArray containing a list of CKItem 
			// objects to add.  
			
			// Check to see if pHint was set (debug only).
			ASSERT (pHint != NULL);
			
			// Get pointer to the item list:
			CObArray *pList = (CObArray *)pHint;

			// Initialize some variables:
			CKItem *pItem = NULL;
			DWORD dwIndex = 0;

			// Postpone redrawing until we are done.  This will make things
			// go faster and look smoother.
			SetRedraw (false);

			// Insert all the items in array in.  Get pointer to next item
			// in object array, increment array index, and cast item pointer
			// to CKItem pointer.  A null pointer will have been placed in
			// array after last item to mark end of data.  This will cause
			// the loop to terminate.
			while (pItem = (CKItem *) pList->GetAt (dwIndex++))
				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_cnSortedItems, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);

⌨️ 快捷键说明

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