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: - { - 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; } 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)