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

📄 eventview.cpp

📁 KepWare的OPC Client 示例.面向C
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// **************************************************************************
// eventview.cpp
//
// Description:
//	Implements a CListView derived class.  This the bottom pane of our GUI 
//	which shows event messages.
//
// 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 "eventview.h"

#define NUMCOLUMNS			3
#define DEFAULTCOLUMNWIDTH	120
#define GROWEVENTS			1024
#define MAXEVENTS			GROWEVENTS

static LPCTSTR lpszRegSection = _T("Event View");
static LPCTSTR lpszLogErrorsOnly = _T("Log Errors Only");

// event pane update timer
#define UPDATE_EVENTPANE_EVENT	1


/////////////////////////////////////////////////////////////////////////////
// CKEventView
/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE (CKEventView, CListView)

// **************************************************************************
BEGIN_MESSAGE_MAP (CKEventView, CListView)
	//{{AFX_MSG_MAP(CKEventView)
	ON_WM_DESTROY ()
	ON_NOTIFY_REFLECT (LVN_GETDISPINFO, OnGetDispInfo)
	ON_COMMAND (ID_VIEW_CLEAR, OnClear)
	ON_WM_RBUTTONDOWN ()
	ON_WM_TIMER ()
	ON_WM_CHAR ()
	ON_COMMAND (ID_VIEW_ERRORONLY, OnLogErrorsOnly)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP ()


// **************************************************************************
// CKEventView ()
//
// Description:
//	Constructor.
//
// Parameters:
//  none
//
// Returns:
//  none
// **************************************************************************
CKEventView::CKEventView ()
	{
	// Initialize member variables:
	m_cnEvents = 0;
	m_cnAllocEvents = 0;
	m_pEventList = NULL;

	m_bAutoScroll = true;
	m_bLogErrorsOnly = false;

	m_cnPendingEvents = 0;
	m_cnPendingAllocEvents = 0;
	m_pPendingEventList = NULL;
	}

// **************************************************************************
// ~CKEventView ()
//
// Description:
//	Destructor.
//
// Parameters:
//  none
//
// Returns:
//  none
// **************************************************************************
CKEventView::~CKEventView ()
	{
	int i;

	// Free events:
	for (i = 0; i < m_cnEvents; i++)
		{
		delete m_pEventList [i];
		m_pEventList [i] = NULL;
		}

	// Free event list:
	if (m_pEventList)
		delete [] m_pEventList;	

	// Free pending events:
	for (i = 0; i < m_cnPendingEvents; i++)
		{
		delete m_pPendingEventList [i];
		m_pPendingEventList [i] = NULL;
		}

	// Free pending event list:
	if (m_pPendingEventList)
		delete [] m_pPendingEventList;
	}


/////////////////////////////////////////////////////////////////////////////
// CKEventView drawing
/////////////////////////////////////////////////////////////////////////////

// **************************************************************************
// OnDraw ()
//
// Description:
//	OnDraw event handler.  This function needs to be implemented since it is
//  declared as a pure virtual function in base class.  We don't need to do
//  anything with it in this case.
//
// Parameters:
//  CDC			*pDC		Pointer to view's device context.
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnDraw (CDC *pDC)
	{
	// This is how we get our document object in case we need to do something
	// with this function at some point:
	CDocument* pDoc = GetDocument ();
	}


/////////////////////////////////////////////////////////////////////////////
// CKEventView diagnostics
/////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
void CKEventView::AssertValid () const
	{
	CListView::AssertValid ();
	}

void CKEventView::Dump (CDumpContext &dc) const
	{
	CListView::Dump (dc);
	}
#endif //_DEBUG


/////////////////////////////////////////////////////////////////////////////
// CKEventView message handlers
/////////////////////////////////////////////////////////////////////////////

// **************************************************************************
// PreCreateWindow ()
//
// Description:
//	PreCreateWindow event handler.
//
// Parameters:
//  CREATESTRUCT	&cs		Defines the initialization parameters for window.
//
// Returns:
//  BOOL - TRUE if success.
// **************************************************************************
BOOL CKEventView::PreCreateWindow (CREATESTRUCT &cs) 
	{
	// Perform default processing.  Return FALSE if failure:
	if (!CListView::PreCreateWindow (cs))
		return (FALSE);

	// Modify the window style so that list view has report format and
	// column headers that do not sort rows:
	cs.style |= LVS_REPORT | LVS_NOSORTHEADER; 

	// Return TRUE to indicate success:
	return (TRUE);
	}

// **************************************************************************
// Create ()
//
// Description:
//	Creates the CKEventView window and attaches it to parent window.
//
// 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 CKEventView::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.  These are the images that
	// show up to the left of each item in list.  The bitmap must use a 
	// purple background color, RGB (255, 0, 255), so that the CImageList
	// object can construct a mask.  The images are 16x16 pixels.  Set the
	// image list background color to CLR_NONE so masked pixels will be
	// transparent. 
	//
	// Image number		Use
	//	0				Information event
	//	1				Error event
	m_cImageList.Create (IDB_EVENTIMAGES, 16, 4, RGB (255, 0, 255));
	m_cImageList.SetBkColor (CLR_NONE);
	GetListCtrl ().SetImageList (&m_cImageList, LVSIL_SMALL);

	// Create columns.  Column width used in last session were saved in
	// registry. Use these widths for the present session.
	CString strColumnTitle;
	for (int i = 0; i < NUMCOLUMNS; i++)
		{
		// Create a string that will identify the registry entry for each column:
		TCHAR szNum [8];
		wsprintf (szNum, _T("%d"), i);

		// Read the column width from the registry:
		int nWidth = AfxGetApp ()->GetProfileInt (lpszRegSection, szNum, DEFAULTCOLUMNWIDTH);

		// Make sure it is valid:
		if (nWidth < 0)
			nWidth = DEFAULTCOLUMNWIDTH;

		// Load the column title string resources:
		switch (i)
			{
			case 0: // Date
				strColumnTitle.LoadString (IDS_DATE);
				break;

			case 1: // Time
				strColumnTitle.LoadString (IDS_TIME);
				break;

			case 2:	// Event
				strColumnTitle.LoadString (IDS_EVENT);
				break;

			default:
				ASSERT (FALSE);
				break;
			}

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

	// Get the "log errors only" flag saved in registry last time:
	m_bLogErrorsOnly = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszLogErrorsOnly, FALSE) ? true : false;

	// Start update view timer:
	SetTimer (UPDATE_EVENTPANE_EVENT, 100, NULL);

	// Return TRUE to indicate success:
	return (TRUE);
	}

// **************************************************************************
// OnDestroy ()
//
// Description:
//	Called when window is destroyed.  Take opportunity to kill timer and save
//	view settings to registry.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnDestroy () 
	{
	CListView::OnDestroy ();

	// Stop update view timer:
	KillTimer (UPDATE_EVENTPANE_EVENT);
	
	// Save column widths in registry so we can use them next time:
	for (int i = 0; i < NUMCOLUMNS; i++)
		{
		// Create a string that will identify the registry entry for each
		// column:
		TCHAR szNum [8];
		wsprintf (szNum, _T("%d"), i);

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

	// Save "log errors only" flag in registry too:
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszLogErrorsOnly, m_bLogErrorsOnly);
	}

// **************************************************************************
// OnGetDispInfo ()
//
// Description:
//	Handle notification to fill item information for display.
//
// Parameters:
//  NMHDR		*pNMHDR			Contains information about a notification message.
//	LRESULT		*pResult		A 32-bit value returned from a window procedure 
//								  or callback function.	
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnGetDispInfo (NMHDR *pNMHDR, LRESULT *pResult) 
	{
	// Extract pointer to list view item and  associated CKEvent object
	// from pNMHDER.  The CKEvent object describes the event and is 
	// associated when a list view item is created through the item's lParam.
	LV_DISPINFO *plvdi = (LV_DISPINFO *)pNMHDR;
	LV_ITEM *pItem = &plvdi->item;
	CKEvent *pEvent = (CKEvent *)pItem->lParam;

	ASSERT (pEvent);

	// The item's mask text bit will be set if we are being asked to supply
	// the item's text.  The subitem will indicate what column the text is
	// needed for.
	if (pItem->mask & LVIF_TEXT)
		{
		switch (pItem->iSubItem)
			{
			case 0:	// Date
				pEvent->FormatDate (pItem->pszText, pItem->cchTextMax);
				break;

			case 1:	// Time
				pEvent->FormatTime (pItem->pszText, pItem->cchTextMax);
				break;

			case 2:	// Event
				lstrcpyn (pItem->pszText, pEvent->GetMessage (), pItem->cchTextMax);
				break;

			default:
				ASSERT (FALSE);
				break;
			}
		}

	// The item's mask image bit will be set if we are being asked to supply
	// the items image (index into image list.  It the event type is 
	// tEventInformation we will supply the first image in the image list,
	// else we will supply the second (error event).
	if (pItem->mask & LVIF_IMAGE)
		pItem->iImage = (pEvent->GetType () == tEventInformation) ? 0 : 1;
	}

// **************************************************************************
// OnClear ()
//
// Description:
//	ID_VIEW_CLEAR event handler.  Delete all items from list view and redraw.	
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnClear () 
	{
	// Create a CSafeLock to make this object thread safe.  Our critical
	// section gets locked here, and will automatically be unlocked when the
	// CSafeLock goes out of scope.
	CSafeLock sf (&m_csLog);

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

	// Delete all items in list control:
	GetListCtrl ().DeleteAllItems ();

	// Delete any CKEvent objects associated with deleted list control items:
	for (int i = 0; i < m_cnEvents; i++)
		{
		delete m_pEventList [i];
		m_pEventList [i] = NULL;
		}

	// Reset event count to zero:
	m_cnEvents = 0;

⌨️ 快捷键说明

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