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

📄 eventview.cpp

📁 KepWare的OPC Client 示例.面向C
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// Now allow view to redraw:
	SetRedraw (true);
	}

// **************************************************************************
// OnLogErrorsOnly ()
//
// Description:
//	ID_VIEW_ERRORONLY event handler.  Toggles the log errors only flag.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnLogErrorsOnly ()
	{
	// 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);

	// Toggle the log errors only flag:
	m_bLogErrorsOnly = m_bLogErrorsOnly ? false : true;
	}

// **************************************************************************
// OnRButtonDown ()
//
// Description:
//	Right mouse button down event handler.  Used to display context menu.
//
// Parameters:
//	UINT		nFlags		Flags
//	CPoint		point		Mouse cursor location.
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnRButtonDown (UINT nFlags, CPoint point) 
	{
	CMenu cMenu;

	// Convert point to screen coordinates:
	ClientToScreen (&point);	

	// Create a popup menu:
	if (cMenu.CreatePopupMenu ())
		{
		// Get pointer to our main menu.  We will use it to get text for 
		// the popup menu:
		CMenu *pMainMenu = AfxGetMainWnd ()->GetMenu ();

		// Declare a container for menu text:
		CString strMenuText;

		// Define flags to so that popup menu items will get text from pointer
		// to null terminated string.
		int nFlags = MF_ENABLED | MF_STRING;

		// If we have event, then add a "clear view" menu item:
		if (m_cnEvents)
			{
			pMainMenu->GetMenuString (ID_VIEW_CLEAR, strMenuText, MF_BYCOMMAND);
			cMenu.AppendMenu (nFlags, ID_VIEW_CLEAR, strMenuText);
			}

		// Add a "log errors only" menu item:
		pMainMenu->GetMenuString (ID_VIEW_ERRORONLY, strMenuText, MF_BYCOMMAND);
		cMenu.AppendMenu (nFlags, ID_VIEW_ERRORONLY, strMenuText);

		// Place the popup menu at the point of right mouse click, and route
		// all WM_COMMAND messages though the frame:
		cMenu.TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd ());
		}
	}


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

// **************************************************************************
// LogMsg ()
//
// Description:
//	Log a message to the event log.  Creates an CKEvent object and adds it to 
//	the pending event list.  Event will be taken from pending event list
//	and placed in list control in OnTimer().
//
// Parameters:
//  EVENTTYPE	eType			Event type (tEventError, tEventWarning, etc)
//	LPCTSTR		lpszMessage		Pointer to message string.
//
// Returns:
//  void
// **************************************************************************
void CKEventView::LogMsg (EVENTTYPE eType, LPCTSTR lpszMessage)
	{
	// 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);

	// No need to add the event if it is not an error and we are
	// logging errors only:
	if (m_bLogErrorsOnly && eType != tEventError)
		return;

	// Create an event and add to pending event list.  Wrap with exception
	// handler in case of memory allocation propbles (not too likely).
	try
		{
		// Instantiate a new CKEvent object to contain information about
		// this event:
		CKEvent *pEvent = new CKEvent (lpszMessage, eType);

		// Check for room in the pending events list.  If we are out of
		// room, allocate larger block of memory and transfer existing
		// events to it.
		if (m_cnPendingEvents == m_cnPendingAllocEvents)
			{
			// Create a pointer to a new pending events array:
			CKEvent **p;

			// Allocate memory for the new array/list large enough for 
			// existing events plus room for new ones. (This is an array
			// of pointers to CKEvent objects.)
			p = new CKEvent * [m_cnPendingAllocEvents + GROWEVENTS];

			// Transfer existing events to the new memory and free memory
			// used by old list:
			if (m_cnPendingEvents)
				{
				memcpy (p, m_pPendingEventList, m_cnPendingEvents * sizeof (m_pPendingEventList[0]));
				delete [] m_pPendingEventList;
				}

			// Reset pointer to pending event list to give new memory area:
			m_pPendingEventList = p;

			// Increment size of memory allocated for new pending event list:
			m_cnPendingAllocEvents += GROWEVENTS;
			}

		// Add the item to the event list and increment the pending events
		// counter:
		m_pPendingEventList [m_cnPendingEvents++] = pEvent;
		}

	catch (...)
		{
		TRACE (_T("OTC: Exception handler invoked adding an event to the log\n"));
		}
	}

// **************************************************************************
// AddEvent ()
//
// Description:
//	Places an event in list control
//
// Parameters:
//  CKEvent		*pEvent		Pointer to event object
//
// Returns:
//  bool - true if success.
// **************************************************************************
bool CKEventView::AddEvent (CKEvent *pEvent)
	{
	// Create a list view item structure:
	LV_ITEM lvi;

	// Get reference to list view's list control:
	CListCtrl &cList = GetListCtrl ();

	// Fill the list view item structure:

	// Item props we will fill (text, parameter, image):
	lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
	
	// No sub items:
	lvi.iSubItem = 0;

	// Defer to OnGetDispInfo () to get image:
	lvi.iImage = I_IMAGECALLBACK;

	// Defer to OnGetDispInfo () to get text:
	lvi.pszText = LPSTR_TEXTCALLBACK;

	// Set item number:
	lvi.iItem = cList.GetItemCount ();

	// We will use the list view item parameter to contain a pointer to
	// the associated CKEvent object.  The CKEvent object contains
	// contains information about the event.
	lvi.lParam = (LPARAM)pEvent;
	
	ASSERT (pEvent != NULL);

	// Insert the new item into list control:
	int nIndex = cList.InsertItem (&lvi);
	
	// If auto scroll flag is set, and new item's index is good, then force
	// list control to scroll if necessary to show new item:
	if (m_bAutoScroll && nIndex != -1)
		cList.EnsureVisible (nIndex, false);

	// If new item's index is -1 there was a problem, so return false
	// to indicate this.  Else return true to indicate success:
	return (nIndex != -1);
	}

// **************************************************************************
// OnTimer ()
//
// Description:
//	Timer event handler.  Do periodic maintenance of view.
//
// Parameters:
//	UINT		nIDEvent		Timer event type.
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnTimer (UINT nIDEvent) 
	{
	// Process according to timer event type:
	switch (nIDEvent)
		{
		// This is the view maitenance timer event type we defined:
		case UPDATE_EVENTPANE_EVENT:
			{
			// 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);

			// Get reference to list view's list control:
			CListCtrl &cList = GetListCtrl ();

			// Create a scratch pointer to event object:
			CKEvent *pEvent = NULL;
			int nIndex = 0;

			// If we have pending event we will be adding to view, postpone
			// redrawing until we are done.  This will make things go faster
			// and look smoother.
			if (m_cnPendingEvents)
				cList.SetRedraw (false);

			// Process all event in pending events list:
			while (nIndex < m_cnPendingEvents)
				{
				// Get next event in pending events list:
				pEvent = m_pPendingEventList [nIndex];
				ASSERT (pEvent != NULL);

				// Invalidate pending event:
				m_pPendingEventList [nIndex++] = NULL;

				// If we have reached the self-imposed limit of displayable
				// events then remove the first one in list control to make
				// room:
				if (m_cnEvents == MAXEVENTS)
					{
					// Delete first item in list (FIFO):
					cList.DeleteItem (0);

					// Delete the associated event object:
					delete m_pEventList [0];

					// Scroll events up one notch:
					memcpy (m_pEventList, &m_pEventList[1], (m_cnEvents - 1) * sizeof (m_pEventList[0]));
					
					// Decrement the number of events:
					--m_cnEvents;
					}

				// Check for room in the events list.  If we are out of
				// room, allocate larger block of memory and transfer
				// existing events to it.
				else if (m_cnEvents == m_cnAllocEvents)
					{
					// Create a pointer to new events array:
					CKEvent **p;

					// Allocate memory for the new array/list large enough
					// for existing events plus room for new ones. (This is
					// an array of pointers to CKEvent objects.)
					p = new CKEvent * [m_cnAllocEvents + GROWEVENTS];

					// Transfer existing events to the new memory and free
					// memory used by old list:
					if (m_cnEvents)
						{
						memcpy (p, m_pEventList, m_cnEvents * sizeof (m_pEventList[0]));
						delete [] m_pEventList;
						}
					
					// Reset pointer to event list to give new memory area:
					m_pEventList = p;

					// Increment size of memory allocated for new event list:
					m_cnAllocEvents += GROWEVENTS;
					}

				// Add the item to the event list and increment index for next
				// item in pending events list:
				m_pEventList[m_cnEvents++] = pEvent;

				// Add the item to the list control:
				AddEvent (pEvent);
				}

			// We should have processed all items in pending event list.
			// If there were pending items, we need to reset pending
			// event counter to zero, restore the list control redraw flag,
			// and invalidate the list control to force a redraw.
			if (m_cnPendingEvents)
				{
				m_cnPendingEvents = 0;
				cList.SetRedraw (true);
				cList.Invalidate ();
				}
			}
			break;

		// Perform default processing for all other timer event types:
		default:
			CListView::OnTimer (nIDEvent);
			break;
		}
	}

// **************************************************************************
// OnChar ()
//
// Description:
//	Handle keyboard input.  Switch view on tab, etc.
//
// Parameters:
//  UINT		nChar		Character code
//	UINT		nRepCnt		repeat count
//	UINT		nFlags		Flags
//
// Returns:
//  void
// **************************************************************************
void CKEventView::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) 
	{
	// Switch views on TAB:
	if (nChar == VK_TAB)
		{
		// Post a change view message to main window:
		AfxGetMainWnd ()->PostMessage (UM_CHANGEVIEW, 0, (LPARAM)this);

		// Return now so default processing does not occur:
		return;
		}
	
	// Show context menu on SPACEBAR:
	else if (nChar == VK_SPACE)
		{
		// Initialize item index to -1, to indicate no item selected:
		int nItem = -1;

		// Get reference to list control:
		CListCtrl &cList = GetListCtrl ();

		// Get the first selected item:
		nItem = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);

		// Get a sensible rectangular region to place the context menu in:
		CRect rc;

		// If there is a selected item, use its rectangle:
		if (nItem >= 0)
			{
			// Force the list control to scroll if necessary to show 
			// selected item:
			cList.EnsureVisible (nItem, false);

			// Get the item's rectangle:
			cList.GetItemRect (nItem, &rc, LVIR_LABEL);
			}

		// Otherwise use the window's rectangle:
		else
			{
			// Get the window's rectangle:
			GetWindowRect (&rc);

			// Must convert dimensions returned by GetWindowRect():
			ScreenToClient (&rc);
			}

		// Compute coordinates of the rectangle's center:
		rc.left = (rc.left + rc.right) / 2;
		rc.top = (rc.top + rc.bottom) / 2;

		// Display our context menu at rectangle's center.  No point in
		// reinventing the wheel, use the code already developed for right
		// mouse down events to do this:
		OnRButtonDown (0, CPoint (rc.left, rc.top));

		// Return now so default processing does not occur:
		return;
		}

	// Perform default processing for all other characters:
	CListView::OnChar (nChar, nRepCnt, nFlags);
	}

⌨️ 快捷键说明

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