https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ff3d1b7bb1644aa629dfb9a149956825f8e6502c

commit ff3d1b7bb1644aa629dfb9a149956825f8e6502c
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Mon Oct 3 02:29:49 2022 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Tue Oct 4 17:29:10 2022 +0200

    [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.)
---
 base/applications/mscutils/eventvwr/eventvwr.c  |  67 +++++++++--
 base/applications/mscutils/eventvwr/evtdetctl.c | 152 ++++++++++++++----------
 base/applications/mscutils/eventvwr/evtdetctl.h |   8 ++
 3 files changed, 153 insertions(+), 74 deletions(-)

diff --git a/base/applications/mscutils/eventvwr/eventvwr.c 
b/base/applications/mscutils/eventvwr/eventvwr.c
index a35daffab26..1dba37bf776 100644
--- a/base/applications/mscutils/eventvwr/eventvwr.c
+++ b/base/applications/mscutils/eventvwr/eventvwr.c
@@ -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,
diff --git a/base/applications/mscutils/eventvwr/evtdetctl.c 
b/base/applications/mscutils/eventvwr/evtdetctl.c
index 4cc6f9752cf..b476e4db847 100644
--- a/base/applications/mscutils/eventvwr/evtdetctl.c
+++ b/base/applications/mscutils/eventvwr/evtdetctl.c
@@ -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:
+                case IDC_NEXT:
                 {
-                    SendMessageW(hwndListView, WM_KEYDOWN, VK_UP, 0);
+                    BOOL bPrev = (LOWORD(wParam) == IDC_PREVIOUS);
+                    INT iItem, iSel;
+
+                    /* 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;
+                    }
 
-                    /* Show event info on dialog box */
-                    if (pData->EventLogFilter)
+                    /*
+                     * 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)
                     {
-                        DisplayEvent(hDlg, pData->EventLogFilter);
-                        DisplayEventData(hDlg, pData->bDisplayWords);
+                        ListView_SetItemState(hwndListView, iSel,
+                                              0, LVIS_FOCUSED | LVIS_SELECTED);
                     }
-                    return (INT_PTR)TRUE;
-                }
 
-                case IDC_NEXT:
-                {
-                    SendMessageW(hwndListView, WM_KEYDOWN, VK_DOWN, 0);
+                    /* 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 on dialog box */
+                    /* 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;
                 }
diff --git a/base/applications/mscutils/eventvwr/evtdetctl.h 
b/base/applications/mscutils/eventvwr/evtdetctl.h
index 5d6464ee8a9..a123232bf86 100644
--- a/base/applications/mscutils/eventvwr/evtdetctl.h
+++ b/base/applications/mscutils/eventvwr/evtdetctl.h
@@ -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)
 

Reply via email to