📄 eventview.cpp
字号:
// EventView.cpp : implementation file
//
#include "stdafx.h"
#include "xxxOPCSRV.h"
#include "EventView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define NUMCOLUMNS 3
#define DEFAULTCOLUMNWIDTH 120
#define GROWEVENTS 1024
#define MAXEVENTS GROWEVENTS
static LPCTSTR lpszMenuViewClear = _T("Clear Messages");
static LPCTSTR lpszMenuOnlyErrorMsg = _T("Log Errors only");
static LPCTSTR lpszTitleDate = _T("Date");
static LPCTSTR lpszTitleTime = _T("Time");
static LPCTSTR lpszTitleEvent = _T("Event");
static LPCTSTR lpszRegSection = _T("Event View");
static LPCTSTR lpszLogErrorsOnly = _T("Log Errors Only");
// event pane update timer
#define UPDATE_EVENTPANE_EVENT 1
/////////////////////////////////////////////////////////////////////////////
// CEventView
IMPLEMENT_DYNCREATE(CEventView, CListView)
CEventView::CEventView()
{
// 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;
}
CEventView::~CEventView()
{
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;
OnDestroy();
}
BEGIN_MESSAGE_MAP(CEventView, CListView)
//{{AFX_MSG_MAP(CEventView)
ON_WM_DESTROY()
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
ON_WM_RBUTTONDOWN()
ON_WM_TIMER()
ON_WM_CHAR()
ON_COMMAND(ID_VIEW_CLEAR, OnViewClear)
ON_COMMAND(ID_VIEW_ERRORONLY, OnViewErroronly)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEventView drawing
void CEventView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CEventView diagnostics
#ifdef _DEBUG
void CEventView::AssertValid() const
{
CListView::AssertValid();
}
void CEventView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CEventView message handlers
BOOL CEventView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
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 = lpszTitleDate;
break;
case 1: // Time
strColumnTitle = lpszTitleTime;
break;
case 2: // Event
strColumnTitle = lpszTitleEvent;
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);
}
BOOL CEventView::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);
}
void CEventView::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);
// TODO: Add your message handler code here
}
void CEventView::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;
}
void CEventView::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);
strMenuText = lpszMenuViewClear;
cMenu.AppendMenu (nFlags, ID_VIEW_CLEAR, strMenuText);
}
// Add a "log errors only" menu item:
//pMainMenu->GetMenuString (ID_VIEW_ERRORONLY, strMenuText, MF_BYCOMMAND);
strMenuText = lpszMenuOnlyErrorMsg;
cMenu.AppendMenu (nFlags, ID_VIEW_ERRORONLY, strMenuText);
cMenu.CheckMenuItem( ID_VIEW_ERRORONLY, m_bLogErrorsOnly ? MF_CHECKED : MF_UNCHECKED );
// 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 ());
}
}
void CEventView::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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -