[EVENTVWR] Improve behaviour on event item selection. (#4746)

CORE-18438

- Each event detail control stores its own "current" item index, so
  that there can be different event detail dialogs showing different
  events concurrently (half-plemented; this is a Win7-like feature).
  As such, give the index of the selected event item when sending
  the EVT_DISPLAY message, instead of having the details dialog
  retrieve everytime by itself the current selected item (that may
  change in-between calls, and can trigger the "No Items in ListView"
  error).

- When pressing "Prev"/"Next" buttons, detect whether we already are
  at the top/bottom of the event log, and if so, prompt the user to
  continue around.
  Clear up any selected event in the list, before selecting the new
  one. (Note: the event list supports multiple selection, for future
  functionality.)
This commit is contained in:
Hermès Bélusca-Maïto 2022-10-03 02:29:49 +02:00
parent 826bd41d88
commit ff3d1b7bb1
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 156 additions and 77 deletions

View file

@ -3362,16 +3362,44 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if ( (pnmv->uChanged & LVIF_STATE) && /* The state has changed */
(pnmv->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ )
{
if (hwndEventDetails)
SendMessageW(hwndEventDetails, EVT_DISPLAY, 0, 0);
if (!hwndEventDetails)
break;
/* Verify the index of selected item */
if (pnmv->iItem == -1)
{
MessageBoxW(hWnd,
L"No selected items!",
szTitle,
MB_OK | MB_ICONERROR);
break;
}
SendMessageW(hwndEventDetails, EVT_DISPLAY, 0, (LPARAM)pnmv->iItem);
}
break;
}
#ifdef LVN_ITEMACTIVATE
case LVN_ITEMACTIVATE:
{
/* Get the index of the single focused selected item */
LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
INT iItem = lpnmitem->iItem;
if (iItem != -1)
SendMessageW(hWnd, WM_COMMAND, IDM_EVENT_DETAILS, (LPARAM)iItem);
break;
}
#else // LVN_ITEMACTIVATE
case NM_DBLCLK:
case NM_RETURN:
SendMessageW(hWnd, WM_COMMAND, IDM_EVENT_DETAILS, 0);
{
/* Get the index of the single focused selected item */
INT iItem = ListView_GetNextItem(hwndListView, -1, LVNI_FOCUSED | LVNI_SELECTED);
if (iItem != -1)
SendMessageW(hWnd, WM_COMMAND, IDM_EVENT_DETAILS, (LPARAM)iItem);
break;
}
#endif // LVN_ITEMACTIVATE
}
}
else if (hdr->hwndFrom == hwndTreeView)
@ -3529,16 +3557,35 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case IDM_EVENT_DETAILS:
{
// LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
PEVENTLOGFILTER EventLogFilter = GetSelectedFilter(NULL);
if (/*lpnmitem->iItem != -1 &&*/ EventLogFilter)
INT iItem;
PEVENTLOGFILTER EventLogFilter;
/* Get the index of the single focused selected item */
iItem = ListView_GetNextItem(hwndListView, -1, LVNI_FOCUSED | LVNI_SELECTED);
if (iItem == -1)
{
/**
// FIXME: Reenable this check once menu items are
// correctly disabled when no event is selected, etc.
MessageBoxW(hWnd,
L"No selected items!",
szTitle,
MB_OK | MB_ICONERROR);
**/
break;
}
EventLogFilter = GetSelectedFilter(NULL);
if (EventLogFilter)
{
EVENTDETAIL_INFO DetailInfo = {EventLogFilter, iItem};
EventLogFilter_AddRef(EventLogFilter);
DialogBoxParamW(hInst,
MAKEINTRESOURCEW(IDD_EVENTDETAILS_DLG),
hWnd,
EventDetails,
(LPARAM)EventLogFilter);
(LPARAM)&DetailInfo);
EventLogFilter_Release(EventLogFilter);
}
break;
@ -4272,6 +4319,7 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG_PTR dwStyle;
RECT rcWnd, rect;
INT iEventItem;
hWndDetailsCtrl = CreateEventDetailsCtrl(hInst, hDlg, lParam);
if (!hWndDetailsCtrl)
@ -4333,8 +4381,9 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
cxOld = rcWnd.right - rcWnd.left;
cyOld = rcWnd.bottom - rcWnd.top;
/* Show event info on dialog control */
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, 0);
/* Show event info in dialog control */
iEventItem = (lParam != 0 ? ((PEVENTDETAIL_INFO)lParam)->iEventItem : 0);
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, (LPARAM)iEventItem);
// SetWindowPos(hWndDetailsCtrl, NULL,
// 0, 0,

View file

@ -14,6 +14,7 @@
// FIXME:
#define EVENT_MESSAGE_EVENTTEXT_BUFFER (1024*10)
extern WCHAR szTitle[];
extern HWND hwndListView;
extern BOOL
GetEventMessage(IN LPCWSTR KeyName,
@ -24,7 +25,9 @@ GetEventMessage(IN LPCWSTR KeyName,
typedef struct _DETAILDATA
{
/* Data initialized from EVENTDETAIL_INFO */
PEVENTLOGFILTER EventLogFilter;
INT iEventItem;
BOOL bDisplayWords;
HFONT hMonospaceFont;
@ -37,8 +40,16 @@ typedef struct _DETAILDATA
static
VOID
DisplayEvent(HWND hDlg, PEVENTLOGFILTER EventLogFilter)
DisplayEvent(
_In_ HWND hDlg,
_In_ PDETAILDATA pDetailData)
{
PEVENTLOGFILTER EventLogFilter = pDetailData->EventLogFilter;
INT iItem = pDetailData->iEventItem;
LVITEMW li;
PEVENTLOGRECORD pevlr;
BOOL bEventData;
WCHAR szEventType[MAX_PATH];
WCHAR szTime[MAX_PATH];
WCHAR szDate[MAX_PATH];
@ -48,38 +59,22 @@ DisplayEvent(HWND hDlg, PEVENTLOGFILTER EventLogFilter)
WCHAR szCategory[MAX_PATH];
WCHAR szEventID[MAX_PATH];
WCHAR szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER];
BOOL bEventData = FALSE;
LVITEMW li;
PEVENTLOGRECORD pevlr;
int iIndex;
/* Get index of selected item */
iIndex = ListView_GetNextItem(hwndListView, -1, LVNI_SELECTED | LVNI_FOCUSED);
if (iIndex == -1)
{
MessageBoxW(hDlg,
L"No Items in ListView",
L"Error",
MB_OK | MB_ICONINFORMATION);
return;
}
li.mask = LVIF_PARAM;
li.iItem = iIndex;
li.iItem = iItem;
li.iSubItem = 0;
ListView_GetItem(hwndListView, &li);
pevlr = (PEVENTLOGRECORD)li.lParam;
ListView_GetItemText(hwndListView, iIndex, 0, szEventType, ARRAYSIZE(szEventType));
ListView_GetItemText(hwndListView, iIndex, 1, szDate, ARRAYSIZE(szDate));
ListView_GetItemText(hwndListView, iIndex, 2, szTime, ARRAYSIZE(szTime));
ListView_GetItemText(hwndListView, iIndex, 3, szSource, ARRAYSIZE(szSource));
ListView_GetItemText(hwndListView, iIndex, 4, szCategory, ARRAYSIZE(szCategory));
ListView_GetItemText(hwndListView, iIndex, 5, szEventID, ARRAYSIZE(szEventID));
ListView_GetItemText(hwndListView, iIndex, 6, szUser, ARRAYSIZE(szUser));
ListView_GetItemText(hwndListView, iIndex, 7, szComputer, ARRAYSIZE(szComputer));
ListView_GetItemText(hwndListView, iItem, 0, szEventType, ARRAYSIZE(szEventType));
ListView_GetItemText(hwndListView, iItem, 1, szDate, ARRAYSIZE(szDate));
ListView_GetItemText(hwndListView, iItem, 2, szTime, ARRAYSIZE(szTime));
ListView_GetItemText(hwndListView, iItem, 3, szSource, ARRAYSIZE(szSource));
ListView_GetItemText(hwndListView, iItem, 4, szCategory, ARRAYSIZE(szCategory));
ListView_GetItemText(hwndListView, iItem, 5, szEventID, ARRAYSIZE(szEventID));
ListView_GetItemText(hwndListView, iItem, 6, szUser, ARRAYSIZE(szUser));
ListView_GetItemText(hwndListView, iItem, 7, szComputer, ARRAYSIZE(szComputer));
SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, szDate);
SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, szTime);
@ -180,32 +175,23 @@ PrintWordDataLine(PWCHAR pBuffer, UINT uOffset, PULONG pData, UINT uLength)
static
VOID
DisplayEventData(HWND hDlg, BOOL bDisplayWords)
DisplayEventData(
_In_ HWND hDlg,
_In_ PDETAILDATA pDetailData)
{
BOOL bDisplayWords = pDetailData->bDisplayWords;
INT iItem = pDetailData->iEventItem;
LVITEMW li;
PEVENTLOGRECORD pevlr;
int iIndex;
LPBYTE pData;
UINT i, uOffset;
UINT uBufferSize, uLineLength;
PWCHAR pTextBuffer, pLine;
/* Get index of selected item */
iIndex = ListView_GetNextItem(hwndListView, -1, LVNI_SELECTED | LVNI_FOCUSED);
if (iIndex == -1)
{
MessageBoxW(hDlg,
L"No Items in ListView",
L"Error",
MB_OK | MB_ICONINFORMATION);
return;
}
li.mask = LVIF_PARAM;
li.iItem = iIndex;
li.iItem = iItem;
li.iSubItem = 0;
ListView_GetItem(hwndListView, &li);
pevlr = (PEVENTLOGRECORD)li.lParam;
@ -800,7 +786,12 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)pData);
pData->EventLogFilter = (PEVENTLOGFILTER)lParam;
if (lParam != 0)
{
PEVENTDETAIL_INFO DetailInfo = (PEVENTDETAIL_INFO)lParam;
pData->EventLogFilter = DetailInfo->EventLogFilter;
pData->iEventItem = DetailInfo->iEventItem;
}
pData->bDisplayWords = FALSE;
pData->hMonospaceFont = CreateMonospaceFont();
@ -811,12 +802,6 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
InitDetailsDlgCtrl(hDlg, pData);
#if 0
/* Show event info on dialog box */
DisplayEvent(hDlg, pData->EventLogFilter);
DisplayEventData(hDlg, pData->bDisplayWords);
#endif
// OnSize(hDlg, pData, pData->cxOld, pData->cyOld);
return (INT_PTR)TRUE;
}
@ -835,39 +820,76 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
return (INT_PTR)TRUE;
case EVT_DISPLAY:
{
pData->iEventItem = (INT)lParam;
if (pData->EventLogFilter)
{
/* Show event info on dialog box */
DisplayEvent(hDlg, pData->EventLogFilter);
DisplayEventData(hDlg, pData->bDisplayWords);
/* Show event info in control */
DisplayEvent(hDlg, pData);
DisplayEventData(hDlg, pData);
}
return (INT_PTR)TRUE;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_PREVIOUS:
{
SendMessageW(hwndListView, WM_KEYDOWN, VK_UP, 0);
/* Show event info on dialog box */
if (pData->EventLogFilter)
{
DisplayEvent(hDlg, pData->EventLogFilter);
DisplayEventData(hDlg, pData->bDisplayWords);
}
return (INT_PTR)TRUE;
}
case IDC_NEXT:
{
SendMessageW(hwndListView, WM_KEYDOWN, VK_DOWN, 0);
BOOL bPrev = (LOWORD(wParam) == IDC_PREVIOUS);
INT iItem, iSel;
/* Show event info on dialog box */
/* Select the previous/next item from our current one */
iItem = ListView_GetNextItem(hwndListView,
pData->iEventItem,
bPrev ? LVNI_ABOVE : LVNI_BELOW);
if (iItem == -1)
{
// TODO: Localization.
if (MessageBoxW(hDlg,
bPrev
? L"You have reached the beginning of the event log. Do you want to continue from the end?"
: L"You have reached the end of the event log. Do you want to continue from the beginning?",
szTitle,
MB_YESNO | MB_ICONQUESTION)
== IDNO)
{
break;
}
/* Determine from where to restart */
if (bPrev)
iItem = ListView_GetItemCount(hwndListView) - 1;
else
iItem = 0;
}
/*
* Deselect the currently selected items in the list view.
* (They may be different from our current one, if multiple
* event details are being displayed concurrently!)
*/
iSel = -1;
while ((iSel = ListView_GetNextItem(hwndListView, iSel, LVNI_SELECTED)) != -1)
{
ListView_SetItemState(hwndListView, iSel,
0, LVIS_FOCUSED | LVIS_SELECTED);
}
/* Select the new item */
ListView_SetItemState(hwndListView, iItem,
LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
ListView_EnsureVisible(hwndListView, iItem, FALSE);
pData->iEventItem = iItem;
/* Show event info in control */
if (pData->EventLogFilter)
{
DisplayEvent(hDlg, pData->EventLogFilter);
DisplayEventData(hDlg, pData->bDisplayWords);
DisplayEvent(hDlg, pData);
DisplayEventData(hDlg, pData);
}
return (INT_PTR)TRUE;
}
@ -883,7 +905,7 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (pData->EventLogFilter)
{
pData->bDisplayWords = (LOWORD(wParam) == IDC_WORDRADIO);
DisplayEventData(hDlg, pData->bDisplayWords);
DisplayEventData(hDlg, pData);
}
return (INT_PTR)TRUE;
}

View file

@ -10,6 +10,14 @@
#ifndef _EVTDETCTL_H_
#define _EVTDETCTL_H_
/* Optional structure passed by pointer
* as LPARAM to CreateEventDetailsCtrl() */
typedef struct _EVENTDETAIL_INFO
{
PEVENTLOGFILTER EventLogFilter;
INT iEventItem;
} EVENTDETAIL_INFO, *PEVENTDETAIL_INFO;
#define EVT_SETFILTER (WM_APP + 2)
#define EVT_DISPLAY (WM_APP + 3)