[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,17 +3362,45 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if ( (pnmv->uChanged & LVIF_STATE) && /* The state has changed */ if ( (pnmv->uChanged & LVIF_STATE) && /* The state has changed */
(pnmv->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ ) (pnmv->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ )
{ {
if (hwndEventDetails) if (!hwndEventDetails)
SendMessageW(hwndEventDetails, EVT_DISPLAY, 0, 0); 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; 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_DBLCLK:
case NM_RETURN: 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; break;
} }
#endif // LVN_ITEMACTIVATE
}
} }
else if (hdr->hwndFrom == hwndTreeView) else if (hdr->hwndFrom == hwndTreeView)
{ {
@ -3529,16 +3557,35 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case IDM_EVENT_DETAILS: case IDM_EVENT_DETAILS:
{ {
// LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam; INT iItem;
PEVENTLOGFILTER EventLogFilter = GetSelectedFilter(NULL); PEVENTLOGFILTER EventLogFilter;
if (/*lpnmitem->iItem != -1 &&*/ 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); EventLogFilter_AddRef(EventLogFilter);
DialogBoxParamW(hInst, DialogBoxParamW(hInst,
MAKEINTRESOURCEW(IDD_EVENTDETAILS_DLG), MAKEINTRESOURCEW(IDD_EVENTDETAILS_DLG),
hWnd, hWnd,
EventDetails, EventDetails,
(LPARAM)EventLogFilter); (LPARAM)&DetailInfo);
EventLogFilter_Release(EventLogFilter); EventLogFilter_Release(EventLogFilter);
} }
break; break;
@ -4272,6 +4319,7 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
LONG_PTR dwStyle; LONG_PTR dwStyle;
RECT rcWnd, rect; RECT rcWnd, rect;
INT iEventItem;
hWndDetailsCtrl = CreateEventDetailsCtrl(hInst, hDlg, lParam); hWndDetailsCtrl = CreateEventDetailsCtrl(hInst, hDlg, lParam);
if (!hWndDetailsCtrl) if (!hWndDetailsCtrl)
@ -4333,8 +4381,9 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
cxOld = rcWnd.right - rcWnd.left; cxOld = rcWnd.right - rcWnd.left;
cyOld = rcWnd.bottom - rcWnd.top; cyOld = rcWnd.bottom - rcWnd.top;
/* Show event info on dialog control */ /* Show event info in dialog control */
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, 0); iEventItem = (lParam != 0 ? ((PEVENTDETAIL_INFO)lParam)->iEventItem : 0);
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, (LPARAM)iEventItem);
// SetWindowPos(hWndDetailsCtrl, NULL, // SetWindowPos(hWndDetailsCtrl, NULL,
// 0, 0, // 0, 0,

View file

@ -14,6 +14,7 @@
// FIXME: // FIXME:
#define EVENT_MESSAGE_EVENTTEXT_BUFFER (1024*10) #define EVENT_MESSAGE_EVENTTEXT_BUFFER (1024*10)
extern WCHAR szTitle[];
extern HWND hwndListView; extern HWND hwndListView;
extern BOOL extern BOOL
GetEventMessage(IN LPCWSTR KeyName, GetEventMessage(IN LPCWSTR KeyName,
@ -24,7 +25,9 @@ GetEventMessage(IN LPCWSTR KeyName,
typedef struct _DETAILDATA typedef struct _DETAILDATA
{ {
/* Data initialized from EVENTDETAIL_INFO */
PEVENTLOGFILTER EventLogFilter; PEVENTLOGFILTER EventLogFilter;
INT iEventItem;
BOOL bDisplayWords; BOOL bDisplayWords;
HFONT hMonospaceFont; HFONT hMonospaceFont;
@ -37,8 +40,16 @@ typedef struct _DETAILDATA
static static
VOID 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 szEventType[MAX_PATH];
WCHAR szTime[MAX_PATH]; WCHAR szTime[MAX_PATH];
WCHAR szDate[MAX_PATH]; WCHAR szDate[MAX_PATH];
@ -48,38 +59,22 @@ DisplayEvent(HWND hDlg, PEVENTLOGFILTER EventLogFilter)
WCHAR szCategory[MAX_PATH]; WCHAR szCategory[MAX_PATH];
WCHAR szEventID[MAX_PATH]; WCHAR szEventID[MAX_PATH];
WCHAR szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER]; 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.mask = LVIF_PARAM;
li.iItem = iIndex; li.iItem = iItem;
li.iSubItem = 0; li.iSubItem = 0;
ListView_GetItem(hwndListView, &li); ListView_GetItem(hwndListView, &li);
pevlr = (PEVENTLOGRECORD)li.lParam; pevlr = (PEVENTLOGRECORD)li.lParam;
ListView_GetItemText(hwndListView, iIndex, 0, szEventType, ARRAYSIZE(szEventType)); ListView_GetItemText(hwndListView, iItem, 0, szEventType, ARRAYSIZE(szEventType));
ListView_GetItemText(hwndListView, iIndex, 1, szDate, ARRAYSIZE(szDate)); ListView_GetItemText(hwndListView, iItem, 1, szDate, ARRAYSIZE(szDate));
ListView_GetItemText(hwndListView, iIndex, 2, szTime, ARRAYSIZE(szTime)); ListView_GetItemText(hwndListView, iItem, 2, szTime, ARRAYSIZE(szTime));
ListView_GetItemText(hwndListView, iIndex, 3, szSource, ARRAYSIZE(szSource)); ListView_GetItemText(hwndListView, iItem, 3, szSource, ARRAYSIZE(szSource));
ListView_GetItemText(hwndListView, iIndex, 4, szCategory, ARRAYSIZE(szCategory)); ListView_GetItemText(hwndListView, iItem, 4, szCategory, ARRAYSIZE(szCategory));
ListView_GetItemText(hwndListView, iIndex, 5, szEventID, ARRAYSIZE(szEventID)); ListView_GetItemText(hwndListView, iItem, 5, szEventID, ARRAYSIZE(szEventID));
ListView_GetItemText(hwndListView, iIndex, 6, szUser, ARRAYSIZE(szUser)); ListView_GetItemText(hwndListView, iItem, 6, szUser, ARRAYSIZE(szUser));
ListView_GetItemText(hwndListView, iIndex, 7, szComputer, ARRAYSIZE(szComputer)); ListView_GetItemText(hwndListView, iItem, 7, szComputer, ARRAYSIZE(szComputer));
SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, szDate); SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, szDate);
SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, szTime); SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, szTime);
@ -180,32 +175,23 @@ PrintWordDataLine(PWCHAR pBuffer, UINT uOffset, PULONG pData, UINT uLength)
static static
VOID VOID
DisplayEventData(HWND hDlg, BOOL bDisplayWords) DisplayEventData(
_In_ HWND hDlg,
_In_ PDETAILDATA pDetailData)
{ {
BOOL bDisplayWords = pDetailData->bDisplayWords;
INT iItem = pDetailData->iEventItem;
LVITEMW li; LVITEMW li;
PEVENTLOGRECORD pevlr; PEVENTLOGRECORD pevlr;
int iIndex;
LPBYTE pData; LPBYTE pData;
UINT i, uOffset; UINT i, uOffset;
UINT uBufferSize, uLineLength; UINT uBufferSize, uLineLength;
PWCHAR pTextBuffer, pLine; 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.mask = LVIF_PARAM;
li.iItem = iIndex; li.iItem = iItem;
li.iSubItem = 0; li.iSubItem = 0;
ListView_GetItem(hwndListView, &li); ListView_GetItem(hwndListView, &li);
pevlr = (PEVENTLOGRECORD)li.lParam; pevlr = (PEVENTLOGRECORD)li.lParam;
@ -800,7 +786,12 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
} }
SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)pData); 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->bDisplayWords = FALSE;
pData->hMonospaceFont = CreateMonospaceFont(); pData->hMonospaceFont = CreateMonospaceFont();
@ -811,12 +802,6 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
InitDetailsDlgCtrl(hDlg, pData); 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); // OnSize(hDlg, pData, pData->cxOld, pData->cyOld);
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
@ -835,39 +820,76 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
case EVT_DISPLAY: case EVT_DISPLAY:
{
pData->iEventItem = (INT)lParam;
if (pData->EventLogFilter) if (pData->EventLogFilter)
{ {
/* Show event info on dialog box */ /* Show event info in control */
DisplayEvent(hDlg, pData->EventLogFilter); DisplayEvent(hDlg, pData);
DisplayEventData(hDlg, pData->bDisplayWords); DisplayEventData(hDlg, pData);
} }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
}
case WM_COMMAND: case WM_COMMAND:
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDC_PREVIOUS: 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: 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) if (pData->EventLogFilter)
{ {
DisplayEvent(hDlg, pData->EventLogFilter); DisplayEvent(hDlg, pData);
DisplayEventData(hDlg, pData->bDisplayWords); DisplayEventData(hDlg, pData);
} }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
@ -883,7 +905,7 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (pData->EventLogFilter) if (pData->EventLogFilter)
{ {
pData->bDisplayWords = (LOWORD(wParam) == IDC_WORDRADIO); pData->bDisplayWords = (LOWORD(wParam) == IDC_WORDRADIO);
DisplayEventData(hDlg, pData->bDisplayWords); DisplayEventData(hDlg, pData);
} }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }

View file

@ -10,6 +10,14 @@
#ifndef _EVTDETCTL_H_ #ifndef _EVTDETCTL_H_
#define _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_SETFILTER (WM_APP + 2)
#define EVT_DISPLAY (WM_APP + 3) #define EVT_DISPLAY (WM_APP + 3)