Skip to content

Commit ff3d1b7

Browse files
committed
[EVENTVWR] Improve behaviour on event item selection. (reactos#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.)
1 parent 826bd41 commit ff3d1b7

File tree

3 files changed

+153
-74
lines changed

3 files changed

+153
-74
lines changed

base/applications/mscutils/eventvwr/eventvwr.c

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,16 +3362,44 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
33623362
if ( (pnmv->uChanged & LVIF_STATE) && /* The state has changed */
33633363
(pnmv->uNewState & LVIS_SELECTED) /* The item has been (de)selected */ )
33643364
{
3365-
if (hwndEventDetails)
3366-
SendMessageW(hwndEventDetails, EVT_DISPLAY, 0, 0);
3365+
if (!hwndEventDetails)
3366+
break;
3367+
3368+
/* Verify the index of selected item */
3369+
if (pnmv->iItem == -1)
3370+
{
3371+
MessageBoxW(hWnd,
3372+
L"No selected items!",
3373+
szTitle,
3374+
MB_OK | MB_ICONERROR);
3375+
break;
3376+
}
3377+
SendMessageW(hwndEventDetails, EVT_DISPLAY, 0, (LPARAM)pnmv->iItem);
33673378
}
33683379
break;
33693380
}
33703381

3382+
#ifdef LVN_ITEMACTIVATE
3383+
case LVN_ITEMACTIVATE:
3384+
{
3385+
/* Get the index of the single focused selected item */
3386+
LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
3387+
INT iItem = lpnmitem->iItem;
3388+
if (iItem != -1)
3389+
SendMessageW(hWnd, WM_COMMAND, IDM_EVENT_DETAILS, (LPARAM)iItem);
3390+
break;
3391+
}
3392+
#else // LVN_ITEMACTIVATE
33713393
case NM_DBLCLK:
33723394
case NM_RETURN:
3373-
SendMessageW(hWnd, WM_COMMAND, IDM_EVENT_DETAILS, 0);
3395+
{
3396+
/* Get the index of the single focused selected item */
3397+
INT iItem = ListView_GetNextItem(hwndListView, -1, LVNI_FOCUSED | LVNI_SELECTED);
3398+
if (iItem != -1)
3399+
SendMessageW(hWnd, WM_COMMAND, IDM_EVENT_DETAILS, (LPARAM)iItem);
33743400
break;
3401+
}
3402+
#endif // LVN_ITEMACTIVATE
33753403
}
33763404
}
33773405
else if (hdr->hwndFrom == hwndTreeView)
@@ -3529,16 +3557,35 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
35293557

35303558
case IDM_EVENT_DETAILS:
35313559
{
3532-
// LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
3533-
PEVENTLOGFILTER EventLogFilter = GetSelectedFilter(NULL);
3534-
if (/*lpnmitem->iItem != -1 &&*/ EventLogFilter)
3560+
INT iItem;
3561+
PEVENTLOGFILTER EventLogFilter;
3562+
3563+
/* Get the index of the single focused selected item */
3564+
iItem = ListView_GetNextItem(hwndListView, -1, LVNI_FOCUSED | LVNI_SELECTED);
3565+
if (iItem == -1)
35353566
{
3567+
/**
3568+
// FIXME: Reenable this check once menu items are
3569+
// correctly disabled when no event is selected, etc.
3570+
MessageBoxW(hWnd,
3571+
L"No selected items!",
3572+
szTitle,
3573+
MB_OK | MB_ICONERROR);
3574+
**/
3575+
break;
3576+
}
3577+
3578+
EventLogFilter = GetSelectedFilter(NULL);
3579+
if (EventLogFilter)
3580+
{
3581+
EVENTDETAIL_INFO DetailInfo = {EventLogFilter, iItem};
3582+
35363583
EventLogFilter_AddRef(EventLogFilter);
35373584
DialogBoxParamW(hInst,
35383585
MAKEINTRESOURCEW(IDD_EVENTDETAILS_DLG),
35393586
hWnd,
35403587
EventDetails,
3541-
(LPARAM)EventLogFilter);
3588+
(LPARAM)&DetailInfo);
35423589
EventLogFilter_Release(EventLogFilter);
35433590
}
35443591
break;
@@ -4272,6 +4319,7 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
42724319
{
42734320
LONG_PTR dwStyle;
42744321
RECT rcWnd, rect;
4322+
INT iEventItem;
42754323

42764324
hWndDetailsCtrl = CreateEventDetailsCtrl(hInst, hDlg, lParam);
42774325
if (!hWndDetailsCtrl)
@@ -4333,8 +4381,9 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
43334381
cxOld = rcWnd.right - rcWnd.left;
43344382
cyOld = rcWnd.bottom - rcWnd.top;
43354383

4336-
/* Show event info on dialog control */
4337-
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, 0);
4384+
/* Show event info in dialog control */
4385+
iEventItem = (lParam != 0 ? ((PEVENTDETAIL_INFO)lParam)->iEventItem : 0);
4386+
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, (LPARAM)iEventItem);
43384387

43394388
// SetWindowPos(hWndDetailsCtrl, NULL,
43404389
// 0, 0,

base/applications/mscutils/eventvwr/evtdetctl.c

Lines changed: 87 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
// FIXME:
1616
#define EVENT_MESSAGE_EVENTTEXT_BUFFER (1024*10)
17+
extern WCHAR szTitle[];
1718
extern HWND hwndListView;
1819
extern BOOL
1920
GetEventMessage(IN LPCWSTR KeyName,
@@ -24,7 +25,9 @@ GetEventMessage(IN LPCWSTR KeyName,
2425

2526
typedef struct _DETAILDATA
2627
{
28+
/* Data initialized from EVENTDETAIL_INFO */
2729
PEVENTLOGFILTER EventLogFilter;
30+
INT iEventItem;
2831

2932
BOOL bDisplayWords;
3033
HFONT hMonospaceFont;
@@ -37,8 +40,16 @@ typedef struct _DETAILDATA
3740

3841
static
3942
VOID
40-
DisplayEvent(HWND hDlg, PEVENTLOGFILTER EventLogFilter)
43+
DisplayEvent(
44+
_In_ HWND hDlg,
45+
_In_ PDETAILDATA pDetailData)
4146
{
47+
PEVENTLOGFILTER EventLogFilter = pDetailData->EventLogFilter;
48+
INT iItem = pDetailData->iEventItem;
49+
LVITEMW li;
50+
PEVENTLOGRECORD pevlr;
51+
BOOL bEventData;
52+
4253
WCHAR szEventType[MAX_PATH];
4354
WCHAR szTime[MAX_PATH];
4455
WCHAR szDate[MAX_PATH];
@@ -48,38 +59,22 @@ DisplayEvent(HWND hDlg, PEVENTLOGFILTER EventLogFilter)
4859
WCHAR szCategory[MAX_PATH];
4960
WCHAR szEventID[MAX_PATH];
5061
WCHAR szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER];
51-
BOOL bEventData = FALSE;
52-
LVITEMW li;
53-
PEVENTLOGRECORD pevlr;
54-
int iIndex;
55-
56-
/* Get index of selected item */
57-
iIndex = ListView_GetNextItem(hwndListView, -1, LVNI_SELECTED | LVNI_FOCUSED);
58-
if (iIndex == -1)
59-
{
60-
MessageBoxW(hDlg,
61-
L"No Items in ListView",
62-
L"Error",
63-
MB_OK | MB_ICONINFORMATION);
64-
return;
65-
}
6662

6763
li.mask = LVIF_PARAM;
68-
li.iItem = iIndex;
64+
li.iItem = iItem;
6965
li.iSubItem = 0;
70-
7166
ListView_GetItem(hwndListView, &li);
7267

7368
pevlr = (PEVENTLOGRECORD)li.lParam;
7469

75-
ListView_GetItemText(hwndListView, iIndex, 0, szEventType, ARRAYSIZE(szEventType));
76-
ListView_GetItemText(hwndListView, iIndex, 1, szDate, ARRAYSIZE(szDate));
77-
ListView_GetItemText(hwndListView, iIndex, 2, szTime, ARRAYSIZE(szTime));
78-
ListView_GetItemText(hwndListView, iIndex, 3, szSource, ARRAYSIZE(szSource));
79-
ListView_GetItemText(hwndListView, iIndex, 4, szCategory, ARRAYSIZE(szCategory));
80-
ListView_GetItemText(hwndListView, iIndex, 5, szEventID, ARRAYSIZE(szEventID));
81-
ListView_GetItemText(hwndListView, iIndex, 6, szUser, ARRAYSIZE(szUser));
82-
ListView_GetItemText(hwndListView, iIndex, 7, szComputer, ARRAYSIZE(szComputer));
70+
ListView_GetItemText(hwndListView, iItem, 0, szEventType, ARRAYSIZE(szEventType));
71+
ListView_GetItemText(hwndListView, iItem, 1, szDate, ARRAYSIZE(szDate));
72+
ListView_GetItemText(hwndListView, iItem, 2, szTime, ARRAYSIZE(szTime));
73+
ListView_GetItemText(hwndListView, iItem, 3, szSource, ARRAYSIZE(szSource));
74+
ListView_GetItemText(hwndListView, iItem, 4, szCategory, ARRAYSIZE(szCategory));
75+
ListView_GetItemText(hwndListView, iItem, 5, szEventID, ARRAYSIZE(szEventID));
76+
ListView_GetItemText(hwndListView, iItem, 6, szUser, ARRAYSIZE(szUser));
77+
ListView_GetItemText(hwndListView, iItem, 7, szComputer, ARRAYSIZE(szComputer));
8378

8479
SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, szDate);
8580
SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, szTime);
@@ -180,32 +175,23 @@ PrintWordDataLine(PWCHAR pBuffer, UINT uOffset, PULONG pData, UINT uLength)
180175

181176
static
182177
VOID
183-
DisplayEventData(HWND hDlg, BOOL bDisplayWords)
178+
DisplayEventData(
179+
_In_ HWND hDlg,
180+
_In_ PDETAILDATA pDetailData)
184181
{
182+
BOOL bDisplayWords = pDetailData->bDisplayWords;
183+
INT iItem = pDetailData->iEventItem;
185184
LVITEMW li;
186185
PEVENTLOGRECORD pevlr;
187-
int iIndex;
188186

189187
LPBYTE pData;
190188
UINT i, uOffset;
191189
UINT uBufferSize, uLineLength;
192190
PWCHAR pTextBuffer, pLine;
193191

194-
/* Get index of selected item */
195-
iIndex = ListView_GetNextItem(hwndListView, -1, LVNI_SELECTED | LVNI_FOCUSED);
196-
if (iIndex == -1)
197-
{
198-
MessageBoxW(hDlg,
199-
L"No Items in ListView",
200-
L"Error",
201-
MB_OK | MB_ICONINFORMATION);
202-
return;
203-
}
204-
205192
li.mask = LVIF_PARAM;
206-
li.iItem = iIndex;
193+
li.iItem = iItem;
207194
li.iSubItem = 0;
208-
209195
ListView_GetItem(hwndListView, &li);
210196

211197
pevlr = (PEVENTLOGRECORD)li.lParam;
@@ -800,7 +786,12 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
800786
}
801787
SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)pData);
802788

803-
pData->EventLogFilter = (PEVENTLOGFILTER)lParam;
789+
if (lParam != 0)
790+
{
791+
PEVENTDETAIL_INFO DetailInfo = (PEVENTDETAIL_INFO)lParam;
792+
pData->EventLogFilter = DetailInfo->EventLogFilter;
793+
pData->iEventItem = DetailInfo->iEventItem;
794+
}
804795
pData->bDisplayWords = FALSE;
805796
pData->hMonospaceFont = CreateMonospaceFont();
806797

@@ -811,12 +802,6 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
811802

812803
InitDetailsDlgCtrl(hDlg, pData);
813804

814-
#if 0
815-
/* Show event info on dialog box */
816-
DisplayEvent(hDlg, pData->EventLogFilter);
817-
DisplayEventData(hDlg, pData->bDisplayWords);
818-
#endif
819-
820805
// OnSize(hDlg, pData, pData->cxOld, pData->cyOld);
821806
return (INT_PTR)TRUE;
822807
}
@@ -835,39 +820,76 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
835820
return (INT_PTR)TRUE;
836821

837822
case EVT_DISPLAY:
823+
{
824+
pData->iEventItem = (INT)lParam;
838825
if (pData->EventLogFilter)
839826
{
840-
/* Show event info on dialog box */
841-
DisplayEvent(hDlg, pData->EventLogFilter);
842-
DisplayEventData(hDlg, pData->bDisplayWords);
827+
/* Show event info in control */
828+
DisplayEvent(hDlg, pData);
829+
DisplayEventData(hDlg, pData);
843830
}
844831
return (INT_PTR)TRUE;
832+
}
845833

846834
case WM_COMMAND:
847835
switch (LOWORD(wParam))
848836
{
849837
case IDC_PREVIOUS:
838+
case IDC_NEXT:
850839
{
851-
SendMessageW(hwndListView, WM_KEYDOWN, VK_UP, 0);
840+
BOOL bPrev = (LOWORD(wParam) == IDC_PREVIOUS);
841+
INT iItem, iSel;
842+
843+
/* Select the previous/next item from our current one */
844+
iItem = ListView_GetNextItem(hwndListView,
845+
pData->iEventItem,
846+
bPrev ? LVNI_ABOVE : LVNI_BELOW);
847+
if (iItem == -1)
848+
{
849+
// TODO: Localization.
850+
if (MessageBoxW(hDlg,
851+
bPrev
852+
? L"You have reached the beginning of the event log. Do you want to continue from the end?"
853+
: L"You have reached the end of the event log. Do you want to continue from the beginning?",
854+
szTitle,
855+
MB_YESNO | MB_ICONQUESTION)
856+
== IDNO)
857+
{
858+
break;
859+
}
860+
861+
/* Determine from where to restart */
862+
if (bPrev)
863+
iItem = ListView_GetItemCount(hwndListView) - 1;
864+
else
865+
iItem = 0;
866+
}
852867

853-
/* Show event info on dialog box */
854-
if (pData->EventLogFilter)
868+
/*
869+
* Deselect the currently selected items in the list view.
870+
* (They may be different from our current one, if multiple
871+
* event details are being displayed concurrently!)
872+
*/
873+
iSel = -1;
874+
while ((iSel = ListView_GetNextItem(hwndListView, iSel, LVNI_SELECTED)) != -1)
855875
{
856-
DisplayEvent(hDlg, pData->EventLogFilter);
857-
DisplayEventData(hDlg, pData->bDisplayWords);
876+
ListView_SetItemState(hwndListView, iSel,
877+
0, LVIS_FOCUSED | LVIS_SELECTED);
858878
}
859-
return (INT_PTR)TRUE;
860-
}
861879

862-
case IDC_NEXT:
863-
{
864-
SendMessageW(hwndListView, WM_KEYDOWN, VK_DOWN, 0);
880+
/* Select the new item */
881+
ListView_SetItemState(hwndListView, iItem,
882+
LVIS_FOCUSED | LVIS_SELECTED,
883+
LVIS_FOCUSED | LVIS_SELECTED);
884+
ListView_EnsureVisible(hwndListView, iItem, FALSE);
885+
886+
pData->iEventItem = iItem;
865887

866-
/* Show event info on dialog box */
888+
/* Show event info in control */
867889
if (pData->EventLogFilter)
868890
{
869-
DisplayEvent(hDlg, pData->EventLogFilter);
870-
DisplayEventData(hDlg, pData->bDisplayWords);
891+
DisplayEvent(hDlg, pData);
892+
DisplayEventData(hDlg, pData);
871893
}
872894
return (INT_PTR)TRUE;
873895
}
@@ -883,7 +905,7 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
883905
if (pData->EventLogFilter)
884906
{
885907
pData->bDisplayWords = (LOWORD(wParam) == IDC_WORDRADIO);
886-
DisplayEventData(hDlg, pData->bDisplayWords);
908+
DisplayEventData(hDlg, pData);
887909
}
888910
return (INT_PTR)TRUE;
889911
}

base/applications/mscutils/eventvwr/evtdetctl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
#ifndef _EVTDETCTL_H_
1111
#define _EVTDETCTL_H_
1212

13+
/* Optional structure passed by pointer
14+
* as LPARAM to CreateEventDetailsCtrl() */
15+
typedef struct _EVENTDETAIL_INFO
16+
{
17+
PEVENTLOGFILTER EventLogFilter;
18+
INT iEventItem;
19+
} EVENTDETAIL_INFO, *PEVENTDETAIL_INFO;
20+
1321
#define EVT_SETFILTER (WM_APP + 2)
1422
#define EVT_DISPLAY (WM_APP + 3)
1523

0 commit comments

Comments
 (0)