2 * PROJECT: ReactOS Event Log Viewer
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/eventvwr/evtdetctl.c
5 * PURPOSE: Event Details Control
6 * PROGRAMMERS: Marc Piulachs (marc.piulachs at codexchange [dot] net)
12 #include "evtdetctl.h"
15 #define EVENT_MESSAGE_EVENTTEXT_BUFFER 1024*10
16 extern HWND hwndListView
;
18 GetEventMessage(IN LPCWSTR KeyName
,
19 IN LPCWSTR SourceName
,
20 IN PEVENTLOGRECORD pevlr
,
21 OUT PWCHAR EventText
);
24 typedef struct _DETAILDATA
26 PEVENTLOGFILTER EventLogFilter
;
34 } DETAILDATA
, *PDETAILDATA
;
39 DisplayEvent(HWND hDlg
, PEVENTLOGFILTER EventLogFilter
)
41 WCHAR szEventType
[MAX_PATH
];
42 WCHAR szTime
[MAX_PATH
];
43 WCHAR szDate
[MAX_PATH
];
44 WCHAR szUser
[MAX_PATH
];
45 WCHAR szComputer
[MAX_PATH
];
46 WCHAR szSource
[MAX_PATH
];
47 WCHAR szCategory
[MAX_PATH
];
48 WCHAR szEventID
[MAX_PATH
];
49 WCHAR szEventText
[EVENT_MESSAGE_EVENTTEXT_BUFFER
];
50 BOOL bEventData
= FALSE
;
52 PEVENTLOGRECORD pevlr
;
55 /* Get index of selected item */
56 iIndex
= ListView_GetNextItem(hwndListView
, -1, LVNI_SELECTED
| LVNI_FOCUSED
);
60 L
"No Items in ListView",
62 MB_OK
| MB_ICONINFORMATION
);
70 ListView_GetItem(hwndListView
, &li
);
72 pevlr
= (PEVENTLOGRECORD
)li
.lParam
;
74 ListView_GetItemText(hwndListView
, iIndex
, 0, szEventType
, ARRAYSIZE(szEventType
));
75 ListView_GetItemText(hwndListView
, iIndex
, 1, szDate
, ARRAYSIZE(szDate
));
76 ListView_GetItemText(hwndListView
, iIndex
, 2, szTime
, ARRAYSIZE(szTime
));
77 ListView_GetItemText(hwndListView
, iIndex
, 3, szSource
, ARRAYSIZE(szSource
));
78 ListView_GetItemText(hwndListView
, iIndex
, 4, szCategory
, ARRAYSIZE(szCategory
));
79 ListView_GetItemText(hwndListView
, iIndex
, 5, szEventID
, ARRAYSIZE(szEventID
));
80 ListView_GetItemText(hwndListView
, iIndex
, 6, szUser
, ARRAYSIZE(szUser
));
81 ListView_GetItemText(hwndListView
, iIndex
, 7, szComputer
, ARRAYSIZE(szComputer
));
83 SetDlgItemTextW(hDlg
, IDC_EVENTDATESTATIC
, szDate
);
84 SetDlgItemTextW(hDlg
, IDC_EVENTTIMESTATIC
, szTime
);
85 SetDlgItemTextW(hDlg
, IDC_EVENTUSERSTATIC
, szUser
);
86 SetDlgItemTextW(hDlg
, IDC_EVENTSOURCESTATIC
, szSource
);
87 SetDlgItemTextW(hDlg
, IDC_EVENTCOMPUTERSTATIC
, szComputer
);
88 SetDlgItemTextW(hDlg
, IDC_EVENTCATEGORYSTATIC
, szCategory
);
89 SetDlgItemTextW(hDlg
, IDC_EVENTIDSTATIC
, szEventID
);
90 SetDlgItemTextW(hDlg
, IDC_EVENTTYPESTATIC
, szEventType
);
92 bEventData
= (pevlr
->DataLength
> 0);
93 EnableDlgItem(hDlg
, IDC_BYTESRADIO
, bEventData
);
94 EnableDlgItem(hDlg
, IDC_WORDRADIO
, bEventData
);
96 // FIXME: At the moment we support only one event log in the filter
97 GetEventMessage(EventLogFilter
->EventLogs
[0]->LogName
, szSource
, pevlr
, szEventText
);
98 SetDlgItemTextW(hDlg
, IDC_EVENTTEXTEDIT
, szEventText
);
103 PrintByteDataLine(PWCHAR pBuffer
, UINT uOffset
, PBYTE pData
, UINT uLength
)
110 n
= swprintf(p
, L
"\r\n");
115 n
= swprintf(p
, L
"%04lx:", uOffset
);
119 for (i
= 0; i
< uLength
; i
++)
121 n
= swprintf(p
, L
" %02x", pData
[i
]);
126 for (i
= 0; i
< 9 - uLength
; i
++)
128 n
= swprintf(p
, L
" ");
133 for (i
= 0; i
< uLength
; i
++)
135 // NOTE: Normally iswprint should return FALSE for tabs...
136 n
= swprintf(p
, L
"%c", (iswprint(pData
[i
]) && (pData
[i
] != L
'\t')) ? pData
[i
] : L
'.');
146 PrintWordDataLine(PWCHAR pBuffer
, UINT uOffset
, PULONG pData
, UINT uLength
)
153 n
= swprintf(p
, L
"\r\n");
158 n
= swprintf(p
, L
"%04lx:", uOffset
);
162 for (i
= 0; i
< uLength
/ sizeof(ULONG
); i
++)
164 n
= swprintf(p
, L
" %08lx", pData
[i
]);
169 /* Display the remaining bytes if uLength was not a multiple of sizeof(ULONG) */
170 for (i
= (uLength
/ sizeof(ULONG
)) * sizeof(ULONG
); i
< uLength
; i
++)
172 n
= swprintf(p
, L
" %02x", ((PBYTE
)pData
)[i
]);
182 DisplayEventData(HWND hDlg
, BOOL bDisplayWords
)
185 PEVENTLOGRECORD pevlr
;
190 UINT uBufferSize
, uLineLength
;
191 PWCHAR pTextBuffer
, pLine
;
193 /* Get index of selected item */
194 iIndex
= ListView_GetNextItem(hwndListView
, -1, LVNI_SELECTED
| LVNI_FOCUSED
);
198 L
"No Items in ListView",
200 MB_OK
| MB_ICONINFORMATION
);
204 li
.mask
= LVIF_PARAM
;
208 ListView_GetItem(hwndListView
, &li
);
210 pevlr
= (PEVENTLOGRECORD
)li
.lParam
;
211 if (pevlr
->DataLength
== 0)
213 SetDlgItemTextW(hDlg
, IDC_EVENTDATAEDIT
, L
"");
218 uBufferSize
= ((pevlr
->DataLength
/ 8) + 1) * 26 * sizeof(WCHAR
);
220 uBufferSize
= ((pevlr
->DataLength
/ 8) + 1) * 43 * sizeof(WCHAR
);
222 pTextBuffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, uBufferSize
);
229 for (i
= 0; i
< pevlr
->DataLength
/ 8; i
++)
231 pData
= (LPBYTE
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
+ uOffset
);
234 uLineLength
= PrintWordDataLine(pLine
, uOffset
, (PULONG
)pData
, 8);
236 uLineLength
= PrintByteDataLine(pLine
, uOffset
, pData
, 8);
237 pLine
= pLine
+ uLineLength
;
242 if (pevlr
->DataLength
% 8 != 0)
244 pData
= (LPBYTE
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
+ uOffset
);
247 PrintWordDataLine(pLine
, uOffset
, (PULONG
)pData
, pevlr
->DataLength
% 8);
249 PrintByteDataLine(pLine
, uOffset
, pData
, pevlr
->DataLength
% 8);
252 SetDlgItemTextW(hDlg
, IDC_EVENTDATAEDIT
, pTextBuffer
);
254 HeapFree(GetProcessHeap(), 0, pTextBuffer
);
259 CreateMonospaceFont(VOID
)
261 LOGFONTW tmpFont
= {0};
267 tmpFont
.lfHeight
= -MulDiv(8, GetDeviceCaps(hDC
, LOGPIXELSY
), 72);
268 tmpFont
.lfWeight
= FW_NORMAL
;
269 wcscpy(tmpFont
.lfFaceName
, L
"Courier New");
271 hFont
= CreateFontIndirectW(&tmpFont
);
273 ReleaseDC(NULL
, hDC
);
280 CopyEventEntry(HWND hWnd
)
282 WCHAR tmpHeader
[512];
283 WCHAR szEventType
[MAX_PATH
];
284 WCHAR szSource
[MAX_PATH
];
285 WCHAR szCategory
[MAX_PATH
];
286 WCHAR szEventID
[MAX_PATH
];
287 WCHAR szDate
[MAX_PATH
];
288 WCHAR szTime
[MAX_PATH
];
289 WCHAR szUser
[MAX_PATH
];
290 WCHAR szComputer
[MAX_PATH
];
291 WCHAR evtDesc
[EVENT_MESSAGE_EVENTTEXT_BUFFER
];
296 /* Try to open the clipboard */
297 if (!OpenClipboard(hWnd
))
300 /* Get the formatted text needed to place the content into */
301 size
+= LoadStringW(hInst
, IDS_COPY
, tmpHeader
, ARRAYSIZE(tmpHeader
));
303 /* Grab all the information and get it ready for the clipboard */
304 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTTYPESTATIC
, szEventType
, ARRAYSIZE(szEventType
));
305 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTSOURCESTATIC
, szSource
, ARRAYSIZE(szSource
));
306 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTCATEGORYSTATIC
, szCategory
, ARRAYSIZE(szCategory
));
307 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTIDSTATIC
, szEventID
, ARRAYSIZE(szEventID
));
308 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTDATESTATIC
, szDate
, ARRAYSIZE(szDate
));
309 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTTIMESTATIC
, szTime
, ARRAYSIZE(szTime
));
310 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTUSERSTATIC
, szUser
, ARRAYSIZE(szUser
));
311 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTCOMPUTERSTATIC
, szComputer
, ARRAYSIZE(szComputer
));
312 size
+= GetDlgItemTextW(hWnd
, IDC_EVENTTEXTEDIT
, evtDesc
, ARRAYSIZE(evtDesc
));
314 size
++; /* Null-termination */
315 size
*= sizeof(WCHAR
);
318 * Consolidate the information into one big piece and
319 * sort out the memory needed to write to the clipboard.
321 hMem
= GlobalAlloc(GMEM_MOVEABLE
, size
);
322 if (hMem
== NULL
) goto Quit
;
324 output
= GlobalLock(hMem
);
331 StringCbPrintfW(output
, size
,
332 tmpHeader
, szEventType
, szSource
, szCategory
, szEventID
,
333 szDate
, szTime
, szUser
, szComputer
, evtDesc
);
337 /* We succeeded, empty the clipboard and write the data in it */
339 SetClipboardData(CF_UNICODETEXT
, hMem
);
342 /* Close the clipboard once we are done with it */
347 OnScroll(HWND hDlg
, PDETAILDATA pData
, INT nBar
, WORD sbCode
)
355 ASSERT(nBar
== SB_HORZ
|| nBar
== SB_VERT
);
357 GetClientRect(hDlg
, &rect
);
361 Maximum
= pData
->cxMin
- (rect
.right
-rect
.left
) /* pData->cxOld */;
362 pOriginXY
= &pData
->scPos
.x
;
364 else // if (nBar == SB_VERT)
366 Maximum
= pData
->cyMin
- (rect
.bottom
-rect
.top
) /* pData->cyOld */;
367 pOriginXY
= &pData
->scPos
.y
;
370 /* Set scrollbar sizes */
371 sInfo
.cbSize
= sizeof(sInfo
);
372 sInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_PAGE
| SIF_TRACKPOS
;
374 if (!GetScrollInfo(hDlg
, nBar
, &sInfo
))
381 case SB_LINEUP
: // SB_LINELEFT:
385 case SB_LINEDOWN
: // SB_LINERIGHT:
389 case SB_PAGEUP
: // SB_PAGELEFT:
390 sInfo
.nPos
-= sInfo
.nPage
;
393 case SB_PAGEDOWN
: // SB_PAGERIGHT:
394 sInfo
.nPos
+= sInfo
.nPage
;
398 sInfo
.nPos
= sInfo
.nTrackPos
;
401 case SB_THUMBPOSITION
:
402 sInfo
.nPos
= sInfo
.nTrackPos
;
405 case SB_TOP
: // SB_LEFT:
406 sInfo
.nPos
= sInfo
.nMin
;
409 case SB_BOTTOM
: // SB_RIGHT:
410 sInfo
.nPos
= sInfo
.nMax
;
417 sInfo
.nPos
= min(max(sInfo
.nPos
, 0), Maximum
);
419 if (oldPos
!= sInfo
.nPos
)
421 POINT scOldPos
= pData
->scPos
;
423 /* We now modify pData->scPos */
424 *pOriginXY
= sInfo
.nPos
;
427 (scOldPos
.x
- pData
->scPos
.x
),
428 (scOldPos
.y
- pData
->scPos
.y
),
433 SW_INVALIDATE
| SW_ERASE
| SW_SCROLLCHILDREN
);
435 sInfo
.fMask
= SIF_POS
;
436 SetScrollInfo(hDlg
, nBar
, &sInfo
, TRUE
);
438 // UpdateWindow(hDlg);
443 OnSize(HWND hDlg
, PDETAILDATA pData
, INT cx
, INT cy
)
446 INT sbVXSize
, sbHYSize
;
457 dwStyle
= GetWindowLongPtrW(hDlg
, GWL_STYLE
);
458 sbVXSize
= GetSystemMetrics(SM_CXVSCROLL
);
459 sbHYSize
= GetSystemMetrics(SM_CYHSCROLL
);
461 /* Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) */
462 if (dwStyle
& WS_HSCROLL
) cy
+= sbHYSize
; // Window currently has a horizontal scrollbar
463 if (dwStyle
& WS_VSCROLL
) cx
+= sbVXSize
; // Window currently has a vertical scrollbar
465 /* Compensate for added scroll bars in window */
466 if (cx
< pData
->cxMin
) cy
-= sbHYSize
; // Window will have a horizontal scroll bar
467 if (cy
< pData
->cyMin
) cx
-= sbVXSize
; // Window will have a vertical scroll bar
469 /* Set scrollbar sizes */
470 sInfo
.cbSize
= sizeof(sInfo
);
472 sInfo
.fMask
= SIF_POS
;
473 if (GetScrollInfo(hDlg
, SB_VERT
, &sInfo
))
474 scOldPos
.y
= sInfo
.nPos
;
476 scOldPos
.y
= pData
->scPos
.y
;
478 sInfo
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
480 if (pData
->cyMin
> cy
)
482 sInfo
.nMax
= pData
->cyMin
- 1;
484 sInfo
.nPos
= pData
->scPos
.y
;
485 SetScrollInfo(hDlg
, SB_VERT
, &sInfo
, TRUE
);
487 /* Display the scrollbar if needed */
488 if (!(dwStyle
& WS_VSCROLL
))
489 ShowScrollBar(hDlg
, SB_VERT
, TRUE
);
495 sInfo
.nMax
= pData
->cyMin
- 1;
497 sInfo
.nPos
= pData
->scPos
.y
;
498 sInfo
.nPos
= scOldPos
.y
;
499 SetScrollInfo(hDlg
, SB_VERT
, &sInfo
, TRUE
);
501 ShowScrollBar(hDlg
, SB_VERT
, FALSE
);
503 rect
.left
= cx
- sbVXSize
;
507 InvalidateRect(hDlg
, &rect
, TRUE
);
510 sInfo
.fMask
= SIF_POS
;
511 if (GetScrollInfo(hDlg
, SB_HORZ
, &sInfo
))
512 scOldPos
.x
= sInfo
.nPos
;
514 scOldPos
.x
= pData
->scPos
.x
;
516 sInfo
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
518 if (pData
->cxMin
> cx
)
520 sInfo
.nMax
= pData
->cxMin
- 1;
522 sInfo
.nPos
= pData
->scPos
.x
;
523 SetScrollInfo(hDlg
, SB_HORZ
, &sInfo
, TRUE
);
525 /* Display the scrollbar if needed */
526 if (!(dwStyle
& WS_HSCROLL
))
527 ShowScrollBar(hDlg
, SB_HORZ
, TRUE
);
533 sInfo
.nMax
= pData
->cxMin
- 1;
535 sInfo
.nPos
= pData
->scPos
.x
;
536 sInfo
.nPos
= scOldPos
.x
;
537 SetScrollInfo(hDlg
, SB_HORZ
, &sInfo
, TRUE
);
539 ShowScrollBar(hDlg
, SB_HORZ
, FALSE
);
543 rect
.top
= cy
- sbHYSize
;
545 InvalidateRect(hDlg
, &rect
, TRUE
);
548 if ((scOldPos
.x
!= pData
->scPos
.x
) || (scOldPos
.y
!= pData
->scPos
.y
))
551 // (scOldPos.x - pData->scPos.x),
552 (pData
->scPos
.x
- scOldPos
.x
),
553 // (scOldPos.y - pData->scPos.y),
554 (pData
->scPos
.y
- scOldPos
.y
),
559 SW_INVALIDATE
| SW_ERASE
| SW_SCROLLCHILDREN
);
561 pData
->scPos
= scOldPos
;
564 // /* Adjust the start of the visible area if we are attempting to show nonexistent areas */
565 // if ((pData->cxMin - pData->scPos.x) < cx) pData->scPos.x = pData->cxMin - cx;
566 // if ((pData->cyMin - pData->scPos.y) < cy) pData->scPos.y = pData->cyMin - cy;
567 // // InvalidateRect(GuiData->hWindow, NULL, TRUE);
569 /* Forbid resizing the control smaller than its minimal size */
570 if (cx
< pData
->cxMin
) cx
= pData
->cxMin
;
571 if (cy
< pData
->cyMin
) cy
= pData
->cyMin
;
573 if ((cx
!= pData
->cxOld
) || (cy
!= pData
->cyOld
))
575 hdwp
= BeginDeferWindowPos(8);
577 /* Move the edit boxes */
579 GetWindowRect(hDlg
, &rect
);
581 hItemWnd
= GetDlgItem(hDlg
, IDC_EVENTTEXTEDIT
);
582 GetWindowRect(hItemWnd
, &rect
);
583 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
584 // OffsetRect(&rect, 0, y);
585 // y += (cy - pData->cyOld) / 2 ; // + (cy - pData->cyOld) % 2;
586 /** y += (cy - pData->cyOld) / 2 ; // + (cy - pData->cyOld) % 2; **/
587 if (cy
>= pData
->cyOld
)
588 y
+= (cy
- pData
->cyOld
) / 2 + (cy
- pData
->cyOld
) % 2;
590 y
-= (pData
->cyOld
- cy
) / 2 + (pData
->cyOld
- cy
) % 2;
593 hdwp
= DeferWindowPos(hdwp
,
597 (rect
.right
- rect
.left
) + (cx
- pData
->cxOld
),
598 (rect
.bottom
- rect
.top
) + y
,
599 /** SWP_NOMOVE | **/ SWP_NOZORDER
| SWP_NOACTIVATE
);
601 hItemWnd
= GetDlgItem(hDlg
, IDC_DETAILS_STATIC
);
602 GetWindowRect(hItemWnd
, &rect
);
603 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
604 // OffsetRect(&rect, 0, y);
607 hdwp
= DeferWindowPos(hdwp
,
610 rect
.left
, rect
.top
+ y
,
612 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
614 hItemWnd
= GetDlgItem(hDlg
, IDC_BYTESRADIO
);
615 GetWindowRect(hItemWnd
, &rect
);
616 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
617 // OffsetRect(&rect, 0, y);
620 hdwp
= DeferWindowPos(hdwp
,
623 rect
.left
, rect
.top
+ y
,
625 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
627 hItemWnd
= GetDlgItem(hDlg
, IDC_WORDRADIO
);
628 GetWindowRect(hItemWnd
, &rect
);
629 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
630 // OffsetRect(&rect, 0, y);
633 hdwp
= DeferWindowPos(hdwp
,
636 rect
.left
, rect
.top
+ y
,
638 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
640 hItemWnd
= GetDlgItem(hDlg
, IDC_EVENTDATAEDIT
);
641 GetWindowRect(hItemWnd
, &rect
);
642 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
643 // OffsetRect(&rect, 0, y);
644 // // y -= (cy - pData->cyOld) % 2;
647 hdwp
= DeferWindowPos(hdwp
,
650 rect
.left
, rect
.top
+ y
,
651 (rect
.right
- rect
.left
) + (cx
- pData
->cxOld
),
652 (rect
.bottom
- rect
.top
) + y
,
653 SWP_NOZORDER
| SWP_NOACTIVATE
);
655 /* Move the buttons */
657 hItemWnd
= GetDlgItem(hDlg
, IDC_PREVIOUS
);
658 GetWindowRect(hItemWnd
, &rect
);
659 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
662 hdwp
= DeferWindowPos(hdwp
,
665 rect
.left
+ (cx
- pData
->cxOld
),
668 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
670 hItemWnd
= GetDlgItem(hDlg
, IDC_NEXT
);
671 GetWindowRect(hItemWnd
, &rect
);
672 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
675 hdwp
= DeferWindowPos(hdwp
,
678 rect
.left
+ (cx
- pData
->cxOld
),
681 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
683 hItemWnd
= GetDlgItem(hDlg
, IDC_COPY
);
684 GetWindowRect(hItemWnd
, &rect
);
685 MapWindowPoints(HWND_DESKTOP
/*NULL*/, hDlg
, (LPPOINT
)&rect
, sizeof(RECT
)/sizeof(POINT
));
688 hdwp
= DeferWindowPos(hdwp
,
691 rect
.left
+ (cx
- pData
->cxOld
),
694 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
697 EndDeferWindowPos(hdwp
);
706 InitDetailsDlgCtrl(HWND hDlg
, PDETAILDATA pData
)
710 HANDLE nextIcon
= LoadImageW(hInst
, MAKEINTRESOURCEW(IDI_NEXT
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
711 HANDLE prevIcon
= LoadImageW(hInst
, MAKEINTRESOURCEW(IDI_PREV
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
712 HANDLE copyIcon
= LoadImageW(hInst
, MAKEINTRESOURCEW(IDI_COPY
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
714 SendDlgItemMessageW(hDlg
, IDC_NEXT
, BM_SETIMAGE
, (WPARAM
)IMAGE_ICON
, (LPARAM
)nextIcon
);
715 SendDlgItemMessageW(hDlg
, IDC_PREVIOUS
, BM_SETIMAGE
, (WPARAM
)IMAGE_ICON
, (LPARAM
)prevIcon
);
716 SendDlgItemMessageW(hDlg
, IDC_COPY
, BM_SETIMAGE
, (WPARAM
)IMAGE_ICON
, (LPARAM
)copyIcon
);
718 /* Set the default read-only RichEdit color */
719 SendDlgItemMessageW(hDlg
, IDC_EVENTTEXTEDIT
, EM_SETBKGNDCOLOR
, 0, GetSysColor(COLOR_3DFACE
));
721 /* Enable RichEdit coloured and underlined links */
722 dwMask
= SendDlgItemMessageW(hDlg
, IDC_EVENTTEXTEDIT
, EM_GETEVENTMASK
, 0, 0);
723 SendDlgItemMessageW(hDlg
, IDC_EVENTTEXTEDIT
, EM_SETEVENTMASK
, 0, dwMask
| ENM_LINK
| ENM_MOUSEEVENTS
);
726 * Activate automatic URL recognition by the RichEdit control. For more information, see:
727 * https://blogs.msdn.microsoft.com/murrays/2009/08/31/automatic-richedit-hyperlinks/
728 * https://blogs.msdn.microsoft.com/murrays/2009/09/24/richedit-friendly-name-hyperlinks/
729 * https://msdn.microsoft.com/en-us/library/windows/desktop/bb787991(v=vs.85).aspx
731 SendDlgItemMessageW(hDlg
, IDC_EVENTTEXTEDIT
, EM_AUTOURLDETECT
, AURL_ENABLEURL
/* | AURL_ENABLEEAURLS */, 0);
733 /* Note that the RichEdit control never gets themed under WinXP+. One would have to write code to simulate Edit-control theming */
735 SendDlgItemMessageW(hDlg
, pData
->bDisplayWords
? IDC_WORDRADIO
: IDC_BYTESRADIO
, BM_SETCHECK
, BST_CHECKED
, 0);
736 SendDlgItemMessageW(hDlg
, IDC_EVENTDATAEDIT
, WM_SETFONT
, (WPARAM
)pData
->hMonospaceFont
, (LPARAM
)TRUE
);
739 /* Message handler for Event Details control */
742 EventDetailsCtrl(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
746 pData
= (PDETAILDATA
)GetWindowLongPtrW(hDlg
, DWLP_USER
);
754 pData
= (PDETAILDATA
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*pData
));
758 return (INT_PTR
)TRUE
;
760 SetWindowLongPtrW(hDlg
, DWLP_USER
, (LONG_PTR
)pData
);
762 pData
->EventLogFilter
= (PEVENTLOGFILTER
)lParam
;
763 pData
->bDisplayWords
= FALSE
;
764 pData
->hMonospaceFont
= CreateMonospaceFont();
766 GetClientRect(hDlg
, &rect
);
767 pData
->cxOld
= pData
->cxMin
= rect
.right
- rect
.left
;
768 pData
->cyOld
= pData
->cyMin
= rect
.bottom
- rect
.top
;
769 pData
->scPos
.x
= pData
->scPos
.y
= 0;
771 InitDetailsDlgCtrl(hDlg
, pData
);
774 /* Show event info on dialog box */
775 DisplayEvent(hDlg
, pData
->EventLogFilter
);
776 DisplayEventData(hDlg
, pData
->bDisplayWords
);
779 // OnSize(hDlg, pData, pData->cxOld, pData->cyOld);
780 return (INT_PTR
)TRUE
;
786 if (pData
->hMonospaceFont
)
787 DeleteObject(pData
->hMonospaceFont
);
788 HeapFree(GetProcessHeap(), 0, pData
);
790 return (INT_PTR
)TRUE
;
793 pData
->EventLogFilter
= (PEVENTLOGFILTER
)lParam
;
794 return (INT_PTR
)TRUE
;
797 if (pData
->EventLogFilter
)
799 /* Show event info on dialog box */
800 DisplayEvent(hDlg
, pData
->EventLogFilter
);
801 DisplayEventData(hDlg
, pData
->bDisplayWords
);
803 return (INT_PTR
)TRUE
;
806 switch (LOWORD(wParam
))
810 SendMessageW(hwndListView
, WM_KEYDOWN
, VK_UP
, 0);
812 /* Show event info on dialog box */
813 if (pData
->EventLogFilter
)
815 DisplayEvent(hDlg
, pData
->EventLogFilter
);
816 DisplayEventData(hDlg
, pData
->bDisplayWords
);
818 return (INT_PTR
)TRUE
;
823 SendMessageW(hwndListView
, WM_KEYDOWN
, VK_DOWN
, 0);
825 /* Show event info on dialog box */
826 if (pData
->EventLogFilter
)
828 DisplayEvent(hDlg
, pData
->EventLogFilter
);
829 DisplayEventData(hDlg
, pData
->bDisplayWords
);
831 return (INT_PTR
)TRUE
;
835 if (pData
->EventLogFilter
)
836 CopyEventEntry(hDlg
);
837 return (INT_PTR
)TRUE
;
840 if (pData
->EventLogFilter
)
842 pData
->bDisplayWords
= FALSE
;
843 DisplayEventData(hDlg
, pData
->bDisplayWords
);
845 return (INT_PTR
)TRUE
;
848 if (pData
->EventLogFilter
)
850 pData
->bDisplayWords
= TRUE
;
851 DisplayEventData(hDlg
, pData
->bDisplayWords
);
853 return (INT_PTR
)TRUE
;
861 switch (((LPNMHDR
)lParam
)->code
)
864 // TODO: Act on the activated RichEdit link!
870 OnScroll(hDlg
, pData
, SB_HORZ
, LOWORD(wParam
));
871 SetWindowLongPtrW(hDlg
, DWLP_MSGRESULT
, 0);
872 return (INT_PTR
)TRUE
;
875 OnScroll(hDlg
, pData
, SB_VERT
, LOWORD(wParam
));
876 SetWindowLongPtrW(hDlg
, DWLP_MSGRESULT
, 0);
877 return (INT_PTR
)TRUE
;
880 OnSize(hDlg
, pData
, LOWORD(lParam
), HIWORD(lParam
));
881 SetWindowLongPtrW(hDlg
, DWLP_MSGRESULT
, 0);
882 return (INT_PTR
)TRUE
;
885 return (INT_PTR
)FALSE
;
889 CreateEventDetailsCtrl(HINSTANCE hInstance
,
893 return CreateDialogParamW(hInstance
,
894 MAKEINTRESOURCEW(IDD_EVENTDETAILS_CTRL
),
895 hParentWnd
, EventDetailsCtrl
, lParam
);