mirror of
https://github.com/reactos/reactos
synced 2025-10-07 08:52:45 +02:00
Compare commits
10 Commits
powermeter
...
hbelusca/o
Author | SHA1 | Date | |
---|---|---|---|
|
7cd78a81fb | ||
|
32cacdd7c4 | ||
|
7dbc0e683b | ||
|
dbc0c37750 | ||
|
bfa63932ce | ||
|
5456e195db | ||
|
87eac43fb9 | ||
|
fe6de816d6 | ||
|
f19c62c80e | ||
|
378a335468 |
@@ -1978,7 +1978,6 @@ EnumEventsThread(IN LPVOID lpParameter)
|
||||
BOOL bResult = TRUE; /* Read succeeded */
|
||||
HANDLE hProcessHeap = GetProcessHeap();
|
||||
PSID pLastSid = NULL;
|
||||
INT nItems;
|
||||
|
||||
UINT uStep = 0, uStepAt = 0, uPos = 0;
|
||||
|
||||
@@ -1998,7 +1997,8 @@ EnumEventsThread(IN LPVOID lpParameter)
|
||||
SYSTEMTIME time;
|
||||
LVITEMW lviEventItem;
|
||||
|
||||
EnableEventDetailsButtons(hwndEventDetails, FALSE);
|
||||
/* Disable the Previous/Next buttons */
|
||||
SendMessageW(hwndEventDetails, EVT_DISPLAY, FALSE, (LPARAM)-1);
|
||||
|
||||
/* Save the current event log filter globally */
|
||||
EventLogFilter_AddRef(EventLogFilter);
|
||||
@@ -2265,9 +2265,6 @@ Quit:
|
||||
/* All events loaded */
|
||||
|
||||
Cleanup:
|
||||
nItems = ListView_GetItemCount(hwndListView);
|
||||
EnableEventDetailsButtons(hwndEventDetails, (nItems > 0));
|
||||
|
||||
ShowWindow(hwndStatusProgress, SW_HIDE);
|
||||
SendMessageW(hwndListView, LVM_PROGRESS, 0, FALSE);
|
||||
|
||||
@@ -2298,6 +2295,11 @@ Cleanup:
|
||||
/* Resume list view redraw */
|
||||
SendMessageW(hwndListView, WM_SETREDRAW, TRUE, 0);
|
||||
|
||||
/* Re-enable the Previous/Next buttons, keeping the current event details
|
||||
* displayed, if any. Don't auto-select the first list item but wait for
|
||||
* the user to do it. */
|
||||
SendMessageW(hwndEventDetails, EVT_DISPLAY, FALSE, 0);
|
||||
|
||||
EventLogFilter_Release(EventLogFilter);
|
||||
|
||||
CloseHandle(hStopEnumEvent);
|
||||
@@ -3342,7 +3344,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
MB_OK | MB_ICONERROR);
|
||||
break;
|
||||
}
|
||||
SendMessageW(hwndEventDetails, EVT_DISPLAY, 0, (LPARAM)pnmv->iItem);
|
||||
SendMessageW(hwndEventDetails, EVT_DISPLAY, TRUE, (LPARAM)pnmv->iItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4347,9 +4349,9 @@ EventDetails(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
cxOld = rcWnd.right - rcWnd.left;
|
||||
cyOld = rcWnd.bottom - rcWnd.top;
|
||||
|
||||
/* Show event info in dialog control */
|
||||
iEventItem = (lParam != 0 ? ((PEVENTDETAIL_INFO)lParam)->iEventItem : 0);
|
||||
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, 0, (LPARAM)iEventItem);
|
||||
/* Display the event info in the dialog */
|
||||
iEventItem = (lParam != 0 ? ((PEVENTDETAIL_INFO)lParam)->iEventItem : -1);
|
||||
SendMessageW(hWndDetailsCtrl, EVT_DISPLAY, TRUE, (LPARAM)iEventItem);
|
||||
|
||||
// SetWindowPos(hWndDetailsCtrl, NULL,
|
||||
// 0, 0,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* PURPOSE: Event Details Control.
|
||||
* COPYRIGHT: Copyright 2007 Marc Piulachs <marc.piulachs@codexchange.net>
|
||||
* Copyright 2008-2016 Eric Kohl <eric.kohl@reactos.org>
|
||||
* Copyright 2016-2022 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
* Copyright 2016-2025 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#include "eventvwr.h"
|
||||
@@ -16,6 +16,7 @@
|
||||
#define EVENT_MESSAGE_EVENTTEXT_BUFFER (1024*10)
|
||||
extern WCHAR szTitle[];
|
||||
extern HWND hwndListView;
|
||||
|
||||
extern BOOL
|
||||
GetEventMessage(IN LPCWSTR KeyName,
|
||||
IN LPCWSTR SourceName,
|
||||
@@ -25,6 +26,9 @@ GetEventMessage(IN LPCWSTR KeyName,
|
||||
|
||||
typedef struct _DETAILDATA
|
||||
{
|
||||
/* The event record being displayed */
|
||||
PEVENTLOGRECORD pevlr;
|
||||
|
||||
/* Data initialized from EVENTDETAIL_INFO */
|
||||
PEVENTLOGFILTER EventLogFilter;
|
||||
INT iEventItem;
|
||||
@@ -38,16 +42,21 @@ typedef struct _DETAILDATA
|
||||
} DETAILDATA, *PDETAILDATA;
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
DisplayEventData(
|
||||
_In_ HWND hDlg,
|
||||
_In_ PDETAILDATA pDetailData);
|
||||
|
||||
static
|
||||
VOID
|
||||
DisplayEvent(
|
||||
_In_ HWND hDlg,
|
||||
_In_ PDETAILDATA pDetailData)
|
||||
{
|
||||
PEVENTLOGRECORD pevlr;
|
||||
PEVENTLOGFILTER EventLogFilter = pDetailData->EventLogFilter;
|
||||
INT iItem = pDetailData->iEventItem;
|
||||
LVITEMW li;
|
||||
PEVENTLOGRECORD pevlr;
|
||||
BOOL bEventData;
|
||||
|
||||
WCHAR szEventType[MAX_PATH];
|
||||
@@ -60,12 +69,13 @@ DisplayEvent(
|
||||
WCHAR szEventID[MAX_PATH];
|
||||
WCHAR szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER];
|
||||
|
||||
/* Retrieve and cache the pointer to the selected event item */
|
||||
LVITEMW li;
|
||||
li.mask = LVIF_PARAM;
|
||||
li.iItem = iItem;
|
||||
li.iSubItem = 0;
|
||||
ListView_GetItem(hwndListView, &li);
|
||||
|
||||
pevlr = (PEVENTLOGRECORD)li.lParam;
|
||||
pevlr = pDetailData->pevlr = (PEVENTLOGRECORD)li.lParam;
|
||||
|
||||
ListView_GetItemText(hwndListView, iItem, 0, szEventType, ARRAYSIZE(szEventType));
|
||||
ListView_GetItemText(hwndListView, iItem, 1, szDate, ARRAYSIZE(szDate));
|
||||
@@ -87,11 +97,13 @@ DisplayEvent(
|
||||
|
||||
bEventData = (pevlr->DataLength > 0);
|
||||
EnableDlgItem(hDlg, IDC_BYTESRADIO, bEventData);
|
||||
EnableDlgItem(hDlg, IDC_WORDRADIO, bEventData);
|
||||
EnableDlgItem(hDlg, IDC_WORDSRADIO, bEventData);
|
||||
|
||||
// FIXME: At the moment we support only one event log in the filter
|
||||
GetEventMessage(EventLogFilter->EventLogs[0]->LogName, szSource, pevlr, szEventText);
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTTEXTEDIT, szEventText);
|
||||
|
||||
DisplayEventData(hDlg, pDetailData);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -179,22 +191,17 @@ DisplayEventData(
|
||||
_In_ HWND hDlg,
|
||||
_In_ PDETAILDATA pDetailData)
|
||||
{
|
||||
PEVENTLOGRECORD pevlr = pDetailData->pevlr;
|
||||
BOOL bDisplayWords = pDetailData->bDisplayWords;
|
||||
INT iItem = pDetailData->iEventItem;
|
||||
LVITEMW li;
|
||||
PEVENTLOGRECORD pevlr;
|
||||
|
||||
LPBYTE pData;
|
||||
UINT i, uOffset;
|
||||
UINT uBufferSize, uLineLength;
|
||||
PWCHAR pTextBuffer, pLine;
|
||||
|
||||
li.mask = LVIF_PARAM;
|
||||
li.iItem = iItem;
|
||||
li.iSubItem = 0;
|
||||
ListView_GetItem(hwndListView, &li);
|
||||
if (!pevlr)
|
||||
return;
|
||||
|
||||
pevlr = (PEVENTLOGRECORD)li.lParam;
|
||||
if (pevlr->DataLength == 0)
|
||||
{
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTDATAEDIT, L"");
|
||||
@@ -651,7 +658,7 @@ OnSize(HWND hDlg, PDETAILDATA pData, INT cx, INT cy)
|
||||
0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
hItemWnd = GetDlgItem(hDlg, IDC_WORDRADIO);
|
||||
hItemWnd = GetDlgItem(hDlg, IDC_WORDSRADIO);
|
||||
GetWindowRect(hItemWnd, &rect);
|
||||
MapWindowPoints(HWND_DESKTOP /*NULL*/, hDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
|
||||
// OffsetRect(&rect, 0, y);
|
||||
@@ -728,6 +735,46 @@ OnSize(HWND hDlg, PDETAILDATA pData, INT cx, INT cy)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
EnableNavigationArrows(
|
||||
_In_ HWND hDlg,
|
||||
_In_ BOOL bEnable)
|
||||
{
|
||||
/* Enable Previous/Next only if there is more than one item in the list */
|
||||
if (bEnable)
|
||||
bEnable &= (ListView_GetItemCount(hwndListView) > 1);
|
||||
EnableDlgItem(hDlg, IDC_PREVIOUS, bEnable);
|
||||
EnableDlgItem(hDlg, IDC_NEXT, bEnable);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
ClearContents(
|
||||
_In_ HWND hDlg)
|
||||
{
|
||||
/* Disable the Previous/Next and Copy buttons */
|
||||
EnableNavigationArrows(hDlg, FALSE);
|
||||
EnableDlgItem(hDlg, IDC_COPY, FALSE);
|
||||
|
||||
/* Disable the Bytes/Words mode buttons */
|
||||
EnableDlgItem(hDlg, IDC_BYTESRADIO, FALSE);
|
||||
EnableDlgItem(hDlg, IDC_WORDSRADIO, FALSE);
|
||||
|
||||
/* Clear the data fields */
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTUSERSTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTSOURCESTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTCOMPUTERSTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTCATEGORYSTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTIDSTATIC, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTTYPESTATIC, L"");
|
||||
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTTEXTEDIT, L"");
|
||||
SetDlgItemTextW(hDlg, IDC_EVENTDATAEDIT, L"");
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
InitDetailsDlgCtrl(HWND hDlg, PDETAILDATA pData)
|
||||
@@ -759,8 +806,22 @@ InitDetailsDlgCtrl(HWND hDlg, PDETAILDATA pData)
|
||||
|
||||
/* Note that the RichEdit control never gets themed under WinXP+; one would have to write code to simulate Edit-control theming */
|
||||
|
||||
SendDlgItemMessageW(hDlg, pData->bDisplayWords ? IDC_WORDRADIO : IDC_BYTESRADIO, BM_SETCHECK, BST_CHECKED, 0);
|
||||
SendDlgItemMessageW(hDlg, pData->bDisplayWords ? IDC_WORDSRADIO : IDC_BYTESRADIO, BM_SETCHECK, BST_CHECKED, 0);
|
||||
SendDlgItemMessageW(hDlg, IDC_EVENTDATAEDIT, WM_SETFONT, (WPARAM)pData->hMonospaceFont, (LPARAM)TRUE);
|
||||
|
||||
//ClearContents(hDlg);
|
||||
if (pData->iEventItem != -1)
|
||||
{
|
||||
EnableNavigationArrows(hDlg, TRUE);
|
||||
EnableDlgItem(hDlg, IDC_COPY, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableNavigationArrows(hDlg, FALSE);
|
||||
EnableDlgItem(hDlg, IDC_COPY, FALSE);
|
||||
}
|
||||
EnableDlgItem(hDlg, IDC_BYTESRADIO, FALSE);
|
||||
EnableDlgItem(hDlg, IDC_WORDSRADIO, FALSE);
|
||||
}
|
||||
|
||||
/* Message handler for Event Details control */
|
||||
@@ -806,9 +867,8 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
pData->scPos.x = pData->scPos.y = 0;
|
||||
|
||||
InitDetailsDlgCtrl(hDlg, pData);
|
||||
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_BYTESRADIO), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_WORDRADIO), FALSE);
|
||||
/* NOTE: Showing the event (if any) is currently delayed to later */
|
||||
// SendMessageW(hDlg, EVT_DISPLAY, TRUE, (LPARAM)pData->iEventItem);
|
||||
|
||||
// OnSize(hDlg, pData, pData->cxOld, pData->cyOld);
|
||||
return (INT_PTR)TRUE;
|
||||
@@ -824,17 +884,58 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
return (INT_PTR)TRUE;
|
||||
|
||||
case EVT_SETFILTER:
|
||||
{
|
||||
/* Disable the display first, before changing the current filter */
|
||||
pData->pevlr = NULL;
|
||||
pData->iEventItem = -1;
|
||||
ClearContents(hDlg);
|
||||
pData->EventLogFilter = (PEVENTLOGFILTER)lParam;
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
|
||||
case EVT_DISPLAY:
|
||||
{
|
||||
pData->iEventItem = (INT)lParam;
|
||||
if (pData->EventLogFilter)
|
||||
if (wParam)
|
||||
{
|
||||
/* Show event info in control */
|
||||
DisplayEvent(hDlg, pData);
|
||||
DisplayEventData(hDlg, pData);
|
||||
INT iEventItem = (INT)lParam;
|
||||
|
||||
/* If no filter is set, don't change anything */
|
||||
if (!pData->EventLogFilter)
|
||||
return (INT_PTR)TRUE;
|
||||
|
||||
/* If we re-enable display from previously disabled state, re-enable the buttons */
|
||||
if ((pData->iEventItem == -1) && (iEventItem != -1))
|
||||
{
|
||||
EnableNavigationArrows(hDlg, TRUE);
|
||||
EnableDlgItem(hDlg, IDC_COPY, TRUE);
|
||||
}
|
||||
else
|
||||
/* If we disable display from previously enabled state, clear and disable it */
|
||||
if ((pData->iEventItem != -1) && (iEventItem == -1))
|
||||
{
|
||||
ClearContents(hDlg);
|
||||
}
|
||||
|
||||
/* Set the new item */
|
||||
pData->pevlr = NULL;
|
||||
pData->iEventItem = iEventItem;
|
||||
|
||||
/* Display the event info, if there is one */
|
||||
if (pData->iEventItem != -1)
|
||||
DisplayEvent(hDlg, pData);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable or disable the Previous/Next buttons,
|
||||
* but keep the existing contents, if any */
|
||||
EnableNavigationArrows(hDlg, (lParam != -1));
|
||||
|
||||
// HACK: Disable the Bytes/Words mode buttons
|
||||
// because we won't have access anymore to the
|
||||
// event data. (This will be fixed in the future.)
|
||||
pData->pevlr = NULL; // Invalidate also the cache.
|
||||
EnableDlgItem(hDlg, IDC_BYTESRADIO, FALSE);
|
||||
EnableDlgItem(hDlg, IDC_WORDSRADIO, FALSE);
|
||||
}
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
@@ -846,25 +947,33 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
case IDC_NEXT:
|
||||
{
|
||||
BOOL bPrev = (LOWORD(wParam) == IDC_PREVIOUS);
|
||||
INT iItem, iSel, nItems = ListView_GetItemCount(hwndListView);
|
||||
WCHAR szText[200];
|
||||
INT nItems = ListView_GetItemCount(hwndListView);
|
||||
INT iItem, iSel;
|
||||
|
||||
if (nItems <= 0) /* No items? */
|
||||
break;
|
||||
|
||||
/* Get the index of the first selected item */
|
||||
iSel = ListView_GetNextItem(hwndListView, -1, LVNI_SELECTED);
|
||||
|
||||
/* Select the previous/next item from our current one */
|
||||
iItem = ListView_GetNextItem(hwndListView, -1, LVNI_ALL | LVNI_SELECTED);
|
||||
iItem = ListView_GetNextItem(hwndListView, iItem,
|
||||
iItem = ListView_GetNextItem(hwndListView, iSel,
|
||||
(bPrev ? LVNI_ABOVE : LVNI_BELOW));
|
||||
if (iItem < 0 || iItem >= nItems)
|
||||
{
|
||||
LoadStringW(hInst,
|
||||
(bPrev ? IDS_CONTFROMEND : IDS_CONTFROMBEGINNING),
|
||||
szText, _countof(szText));
|
||||
if (MessageBoxW(hDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO)
|
||||
break;
|
||||
/* Confirm selection restart only if an item was previously
|
||||
* selected. If not, just proceed with default selection. */
|
||||
if (iSel != -1)
|
||||
{
|
||||
WCHAR szText[200];
|
||||
LoadStringW(hInst,
|
||||
(bPrev ? IDS_CONTFROMEND : IDS_CONTFROMBEGINNING),
|
||||
szText, _countof(szText));
|
||||
if (MessageBoxW(hDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) != IDYES)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Determine from where to restart */
|
||||
/* Determine where to restart from */
|
||||
iItem = (bPrev ? (nItems - 1) : 0);
|
||||
}
|
||||
|
||||
@@ -886,14 +995,12 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
LVIS_FOCUSED | LVIS_SELECTED);
|
||||
ListView_EnsureVisible(hwndListView, iItem, FALSE);
|
||||
|
||||
pData->pevlr = NULL;
|
||||
pData->iEventItem = iItem;
|
||||
|
||||
/* Show event info in control */
|
||||
/* Display the event info */
|
||||
if (pData->EventLogFilter)
|
||||
{
|
||||
DisplayEvent(hDlg, pData);
|
||||
DisplayEventData(hDlg, pData);
|
||||
}
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
|
||||
@@ -903,15 +1010,11 @@ EventDetailsCtrl(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
return (INT_PTR)TRUE;
|
||||
|
||||
case IDC_BYTESRADIO:
|
||||
case IDC_WORDRADIO:
|
||||
{
|
||||
case IDC_WORDSRADIO:
|
||||
pData->bDisplayWords = (LOWORD(wParam) == IDC_WORDSRADIO);
|
||||
if (pData->EventLogFilter)
|
||||
{
|
||||
pData->bDisplayWords = (LOWORD(wParam) == IDC_WORDRADIO);
|
||||
DisplayEventData(hDlg, pData);
|
||||
}
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -962,11 +1065,3 @@ CreateEventDetailsCtrl(HINSTANCE hInstance,
|
||||
MAKEINTRESOURCEW(IDD_EVENTDETAILS_CTRL),
|
||||
hParentWnd, EventDetailsCtrl, lParam);
|
||||
}
|
||||
|
||||
VOID
|
||||
EnableEventDetailsButtons(HWND hWnd, BOOL bEnable)
|
||||
{
|
||||
EnableDlgItem(hWnd, IDC_PREVIOUS, bEnable);
|
||||
EnableDlgItem(hWnd, IDC_NEXT, bEnable);
|
||||
EnableDlgItem(hWnd, IDC_COPY, bEnable);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* PURPOSE: Event Details Control.
|
||||
* COPYRIGHT: Copyright 2007 Marc Piulachs <marc.piulachs@codexchange.net>
|
||||
* Copyright 2008-2016 Eric Kohl <eric.kohl@reactos.org>
|
||||
* Copyright 2016-2022 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
* Copyright 2016-2025 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -24,5 +24,3 @@ HWND
|
||||
CreateEventDetailsCtrl(HINSTANCE hInstance,
|
||||
HWND hParentWnd,
|
||||
LPARAM lParam);
|
||||
|
||||
VOID EnableEventDetailsButtons(HWND hWnd, BOOL bEnable);
|
||||
|
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Описание:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "&Данни:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "&Байтове", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Думи", IDC_WORDRADIO, 85, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Думи", IDC_WORDSRADIO, 85, 140, 34, 8
|
||||
LTEXT "&Данни:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -81,17 +81,17 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Datum:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "&Datum:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Zdroj:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Zdroj:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Čas:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "Č&as:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Kategorie:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Kategorie:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Typ:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "T&yp:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "ID události:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "&ID události:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Uživatel:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Popis:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ata:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Byty", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Bajty", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Slova", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Da&ta:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
@@ -203,7 +203,7 @@ END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BYTES_FORMAT "byty" // "%s bytes"
|
||||
IDS_BYTES_FORMAT "bajtů" // "%s bytes"
|
||||
// "%1!ls! (%2!ls! bytes)"
|
||||
END
|
||||
|
||||
|
@@ -82,21 +82,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Datum:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "&Datum:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Quelle:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Quelle:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Zeit:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "&Zeit:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Kategorie:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Kategorie:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Typ:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "&Typ:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Ereignis-ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "E&reignis-ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Benutzer:", IDC_STATIC, 8, 35, 36, 8
|
||||
LTEXT "B&enutzer:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Computer:", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "C&omputer:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "&Bezeichnung:", IDC_STATIC, 8, 65, 45, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&aten:", IDC_DETAILS_STATIC, 8, 140, 24, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Wörter", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "D&aten:", IDC_DETAILS_STATIC, 8, 140, 24, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -81,17 +81,17 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Ημερομηνία:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "&Ημερομηνία:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Πηγή:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "Πη&γή:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Ώρα:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "&Ώρα:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Κατηγορία:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Κατηγορία:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Τύπος:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "&Τύπος:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "EventID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "Event &ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Χρήστης:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Περιγραφή:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "Δ&εδομένα:", IDC_DETAILS_STATIC, 8, 140, 40, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 49, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 87, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 87, 140, 34, 8
|
||||
LTEXT "Δ&εδομένα:", IDC_DETAILS_STATIC, 8, 140, 40, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -83,21 +83,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Date:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ate:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Source:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Source:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Time:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "Ti&me:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Category:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Category:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Type:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "Typ&e:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Event ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "Event &ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&User:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Computer:", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "C&omputer:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -107,9 +107,9 @@ BEGIN
|
||||
LTEXT "&Description:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ata:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Da&ta:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -84,17 +84,17 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Fecha:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "&Fecha:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Origen:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Origen:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Hora:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "&Hora:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Categoría:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Categoría:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "&Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "ID de evento:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "&ID de evento:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Usuario:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
@@ -108,9 +108,9 @@ BEGIN
|
||||
LTEXT "&Descripción:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&atos:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "D&atos:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -82,21 +82,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Date :", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ate :", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Source :", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Source :", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Heure :", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "&Heure :", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Catégorie :", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Catégorie :", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Type :", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "&Type :", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Événement :", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "É&vénement :", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Utilisateur :", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Ordinateur :", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "O&rdinateur :", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "&Description :", IDC_STATIC, 8, 65, 45, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "Données :", IDC_DETAILS_STATIC, 8, 140, 35, 8//FIXME: add accel
|
||||
AUTORADIOBUTTON "&Octets", IDC_BYTESRADIO, 50, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Mots", IDC_WORDRADIO, 88, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Mots", IDC_WORDSRADIO, 88, 140, 34, 8
|
||||
LTEXT "Do&nnées :", IDC_DETAILS_STATIC, 8, 140, 35, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
@@ -168,8 +168,8 @@ BEGIN
|
||||
IDS_CLEAREVENTS_MSG "Voulez-vous enregistrer ce journal d'événements avant de l'effacer ?"
|
||||
IDS_RESTOREDEFAULTS "Voulez-vous vraiment réinitialiser tous les paramètres pour ce journal aux valeurs par défaut ?"
|
||||
IDS_EVENTSTRINGIDNOTFOUND "La description pour l'événement d'ID ( %lu ) dans la source ( %s ) ne peut être trouvée. L'ordinateur local pourrait ne pas avoir les informations registres nécessaires ou les fichiers DLL de message pour afficher les messages depuis un ordinateur distant.\n\nLes informations suivantes font partie de l'événement :\n\n"
|
||||
IDS_CONTFROMBEGINNING "You have reached the end of the event log. Do you want to continue from the beginning?"
|
||||
IDS_CONTFROMEND "You have reached the beginning of the event log. Do you want to continue from the end?"
|
||||
IDS_CONTFROMBEGINNING "Vous avez atteint la fin du journal d'événements. Voulez-vous continuer depuis le début ?"
|
||||
IDS_CONTFROMEND "Vous avez atteint le début du journal d'événements. Voulez-vous continuer depuis la fin ?"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
|
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "תיאור:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "נתונים:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "בתים", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "מילים", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "מילים", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "נתונים:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -82,21 +82,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Data:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ata:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Sorgente:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Sorgente:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Ore:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "&Ore:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Categoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Categoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "T&ipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "IDEvento:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "ID &Evento:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&UTente:", IDC_STATIC, 8, 35, 36, 8
|
||||
LTEXT "&Utente:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Computer:", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "Co&mputer:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "&Descrizione:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ati:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Da&ti:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "説明(&D):", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "データ(&A):", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "バイト(&B)", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "ワード(&W)", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "ワード(&W)", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "データ(&A):", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "설명(&D):", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "데이터(&A):", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "바이트(&B)", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "글자(&W)", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "글자(&W)", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "데이터(&A):", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -81,21 +81,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Dato:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ato:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Kilde:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Kilde:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tid:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "Ti&d:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Kategori:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "Katego&ri:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Type:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "Typ&e:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Hendelse ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "&Hendelse ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Bruker:", IDC_STATIC, 8, 35, 36, 8
|
||||
LTEXT "Br&uker:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Datamaskin:", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "Data&maskin:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Beskrivelse:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ata:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Tegn", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Ord", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "Teg&n", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Ord", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Da&ta:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -108,9 +108,9 @@ BEGIN
|
||||
LTEXT "&Opis:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ane:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Bajty", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Słowa", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Słowa", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "D&ane:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -81,21 +81,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Data:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ata:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Fonte:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Fonte:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tempo:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "T&empo:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Categoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Categoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "&Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "EventID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "Event &ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Usuário:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Computador:", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "Co&mputador:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Descrição:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "Dad&os:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Dad&os:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -81,21 +81,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Data:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ata:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 50, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Origem:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "O&rigem:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Hora:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "&Hora:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 50, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Categoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Categoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "&Tipo:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 50, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "EventID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "Event &ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Utilizador:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 50, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Computador:", IDC_STATIC, 8, 45, 40, 8
|
||||
LTEXT "Co&mputador:", IDC_STATIC, 8, 45, 40, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 50, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Descrição:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "Dad&os:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Dad&os:", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
@@ -203,7 +203,7 @@ END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BYTES_FORMAT "bytes" // "%s bytes"
|
||||
IDS_BYTES_FORMAT "bajtów" // "%s bytes"
|
||||
// "%1!ls! (%2!ls! bytes)"
|
||||
END
|
||||
|
||||
|
@@ -83,21 +83,21 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Dată:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ată:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Sursă:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "&Sursă:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Oră:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "O&ră:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Categorie:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Categorie:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tip:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "T&ip:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "ID Eveniment:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "ID &Eveniment:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Utilizator:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "&Calculator:", IDC_STATIC, 8, 45, 36, 8
|
||||
LTEXT "Ca&lculator:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
@@ -107,9 +107,9 @@ BEGIN
|
||||
LTEXT "&Descriere:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ate:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&8 biți", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&16 biți", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&16 biți", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Da&te:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
@@ -205,7 +205,7 @@ END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BYTES_FORMAT "octeți" // "%s bytes"
|
||||
IDS_BYTES_FORMAT "octeţi" // "%s bytes"
|
||||
// "%1!ls! (%2!ls! bytes)"
|
||||
END
|
||||
|
||||
|
@@ -109,9 +109,9 @@ BEGIN
|
||||
LTEXT "&Описание:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "&Данные:", IDC_DETAILS_STATIC, 8, 140, 30, 8
|
||||
AUTORADIOBUTTON "&Байты", IDC_BYTESRADIO, 49, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Слова", IDC_WORDRADIO, 87, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Слова", IDC_WORDSRADIO, 87, 140, 34, 8
|
||||
LTEXT "&Данные:", IDC_DETAILS_STATIC, 8, 140, 30, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Popis:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "Ú&daje:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Bajty", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Slová", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Slová", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Ú&daje:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
@@ -203,7 +203,7 @@ END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_BYTES_FORMAT "bytes" // "%s bytes"
|
||||
IDS_BYTES_FORMAT "bajtov" // "%s bytes"
|
||||
// "%1!ls! (%2!ls! bytes)"
|
||||
END
|
||||
|
||||
|
@@ -81,33 +81,33 @@ IDD_EVENTDETAILS_CTRL DIALOGEX 0, 0, 266, 215
|
||||
STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Data:", IDC_STATIC, 8, 5, 31, 8
|
||||
LTEXT "D&ata:", IDC_STATIC, 8, 5, 31, 8
|
||||
EDITTEXT IDC_EVENTDATESTATIC, 46, 5, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Burimi:", IDC_STATIC, 103, 5, 36, 8
|
||||
LTEXT "B&urimi:", IDC_STATIC, 103, 5, 36, 8
|
||||
EDITTEXT IDC_EVENTSOURCESTATIC, 140, 5, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Ora:", IDC_STATIC, 8, 15, 31, 8
|
||||
LTEXT "O&ra:", IDC_STATIC, 8, 15, 31, 8
|
||||
EDITTEXT IDC_EVENTTIMESTATIC, 46, 15, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Kategoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
LTEXT "&Kategoria:", IDC_STATIC, 103, 15, 36, 8
|
||||
EDITTEXT IDC_EVENTCATEGORYSTATIC, 140, 15, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Tipi:", IDC_STATIC, 8, 25, 31, 8
|
||||
LTEXT "T&ipi:", IDC_STATIC, 8, 25, 31, 8
|
||||
EDITTEXT IDC_EVENTTYPESTATIC, 46, 25, 47, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "NgjarjeID:", IDC_STATIC, 103, 25, 36, 8
|
||||
LTEXT "&Ngjarje ID:", IDC_STATIC, 103, 25, 36, 8
|
||||
EDITTEXT IDC_EVENTIDSTATIC, 140, 25, 82, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Përdoruesi:", IDC_STATIC, 8, 35, 36, 8//FIXME: add accel
|
||||
LTEXT "Për&doruesi:", IDC_STATIC, 8, 35, 36, 8
|
||||
EDITTEXT IDC_EVENTUSERSTATIC, 46, 35, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
LTEXT "Kompjuteri:", IDC_STATIC, 8, 45, 36, 8//FIXME: add accel
|
||||
LTEXT "Ko&mpjuteri:", IDC_STATIC, 8, 45, 36, 8
|
||||
EDITTEXT IDC_EVENTCOMPUTERSTATIC, 46, 45, 152, 8, ES_LEFT | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL
|
||||
|
||||
PUSHBUTTON "", IDC_PREVIOUS, 230, 5, 28, 14, BS_ICON
|
||||
PUSHBUTTON "", IDC_NEXT, 230, 21, 28, 14, BS_ICON
|
||||
PUSHBUTTON "", IDC_COPY, 230, 37, 28, 14, BS_ICON
|
||||
|
||||
LTEXT "Përshkrimi:", IDC_STATIC, 8, 65, 39, 8//FIXME: add accel
|
||||
LTEXT "&Përshkrimi:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ata:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Bytes", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Word", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Words", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Da&ta:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -105,9 +105,9 @@ BEGIN
|
||||
LTEXT "&Beskrivning:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "D&ata:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Byte", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Ord", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Ord", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "D&ata:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "Açıklama:", IDC_STATIC, 8, 65, 39, 8//FIXME: add accel
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "Veri:", IDC_DETAILS_STATIC, 8, 140, 20, 8//FIXME: add accel
|
||||
AUTORADIOBUTTON "&Baytlar", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "Sö&zcük", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "Sö&zcükler", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Veri:", IDC_DETAILS_STATIC, 8, 140, 20, 8//FIXME: add accel
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -107,9 +107,9 @@ BEGIN
|
||||
LTEXT "&Опис:", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
AUTORADIOBUTTON "&Байти", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Слова", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "Д&aта:", IDC_DETAILS_STATIC, 8, 140, 20, 8
|
||||
AUTORADIOBUTTON "&Байт", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "&Слово", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -107,9 +107,9 @@ BEGIN
|
||||
LTEXT "描述(&D):", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "数据(&A):", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "字节(&B)", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "字(&W)", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "字(&W)", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "数据(&A):", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "描述(&D):", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "資料(&A):", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "位元組(&B)", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "位元(&W)", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "字(&W)", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "資料(&A):", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -106,9 +106,9 @@ BEGIN
|
||||
LTEXT "描述(&D):", IDC_STATIC, 8, 65, 39, 8
|
||||
CONTROL "", IDC_EVENTTEXTEDIT, RICHEDIT_CLASS, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER, 8, 76, 250, 60
|
||||
|
||||
LTEXT "資料(&A):", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
AUTORADIOBUTTON "位元組(&B)", IDC_BYTESRADIO, 39, 140, 34, 8
|
||||
AUTORADIOBUTTON "位元(&W)", IDC_WORDRADIO, 77, 140, 34, 8
|
||||
AUTORADIOBUTTON "字(&W)", IDC_WORDSRADIO, 77, 140, 34, 8
|
||||
LTEXT "資料(&A):", IDC_DETAILS_STATIC, 8, 140, 25, 8
|
||||
EDITTEXT IDC_EVENTDATAEDIT, 8, 150, 250, 60, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER
|
||||
END
|
||||
|
||||
|
@@ -50,7 +50,7 @@
|
||||
#define IDC_EVENTTEXTEDIT 1011
|
||||
#define IDC_DETAILS_STATIC -2
|
||||
#define IDC_BYTESRADIO 1012
|
||||
#define IDC_WORDRADIO 1013
|
||||
#define IDC_WORDSRADIO 1013
|
||||
#define IDC_EVENTDATAEDIT 1014
|
||||
#define IDC_DISPLAYNAME 1015
|
||||
#define IDC_LOGNAME 1016
|
||||
|
@@ -157,7 +157,7 @@ ProcessDeviceClassChangeEvent(
|
||||
DPRINT("Interface arrival: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
|
||||
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)pData);
|
||||
}
|
||||
else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_ARRIVAL, &RpcStatus))
|
||||
else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_REMOVAL, &RpcStatus))
|
||||
{
|
||||
DPRINT("Interface removal: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
|
||||
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, DBT_DEVICEREMOVECOMPLETE, (LPARAM)pData);
|
||||
|
@@ -1,290 +1,470 @@
|
||||
/*
|
||||
* SHAppBarMessage implementation
|
||||
*
|
||||
* Copyright 2008 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO: freedesktop _NET_WM_STRUT integration
|
||||
*
|
||||
* TODO: find when a fullscreen app is in the foreground and send FULLSCREENAPP
|
||||
* notifications
|
||||
*
|
||||
* TODO: detect changes in the screen size and send ABN_POSCHANGED ?
|
||||
*
|
||||
* TODO: multiple monitor support
|
||||
* PROJECT: ReactOS Explorer
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: AppBar implementation
|
||||
* COPYRIGHT: Copyright 2008 Vincent Povirk for CodeWeavers
|
||||
* Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
//
|
||||
// Adapted from Wine appbar.c .
|
||||
//
|
||||
|
||||
#include "precomp.h"
|
||||
#include "appbar.h"
|
||||
|
||||
#include <wine/list.h>
|
||||
|
||||
#define GetPrimaryTaskbar() FindWindowW(L"Shell_TrayWnd", NULL)
|
||||
|
||||
struct appbar_cmd
|
||||
CAppBarManager::CAppBarManager()
|
||||
: m_hAppBarDPA(NULL)
|
||||
{
|
||||
DWORD dwMsg;
|
||||
ULONG return_map;
|
||||
DWORD return_process;
|
||||
struct _AppBarData abd;
|
||||
};
|
||||
}
|
||||
|
||||
struct appbar_response
|
||||
CAppBarManager::~CAppBarManager()
|
||||
{
|
||||
ULONGLONG result;
|
||||
struct _AppBarData abd;
|
||||
};
|
||||
DestroyAppBarDPA();
|
||||
}
|
||||
|
||||
struct appbar_data
|
||||
PAPPBAR CAppBarManager::FindAppBar(_In_ HWND hwndAppBar) const
|
||||
{
|
||||
struct list entry;
|
||||
HWND hwnd;
|
||||
UINT callback_msg;
|
||||
UINT edge;
|
||||
RECT rc;
|
||||
BOOL space_reserved;
|
||||
/* BOOL autohide; */
|
||||
};
|
||||
if (!m_hAppBarDPA)
|
||||
return NULL;
|
||||
|
||||
static struct list appbars = LIST_INIT(appbars);
|
||||
|
||||
static struct appbar_data* get_appbar(HWND hwnd)
|
||||
{
|
||||
struct appbar_data* data;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(data, &appbars, struct appbar_data, entry)
|
||||
INT nItems = DPA_GetPtrCount(m_hAppBarDPA);
|
||||
while (--nItems >= 0)
|
||||
{
|
||||
if (data->hwnd == hwnd)
|
||||
return data;
|
||||
PAPPBAR pAppBar = (PAPPBAR)DPA_GetPtr(m_hAppBarDPA, nItems);
|
||||
if (pAppBar && hwndAppBar == pAppBar->hWnd)
|
||||
return pAppBar;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void appbar_notify_all(HMONITOR hMon, UINT uMsg, HWND hwndExclude, LPARAM lParam)
|
||||
void CAppBarManager::EliminateAppBar(_In_ INT iItem)
|
||||
{
|
||||
struct appbar_data* data;
|
||||
LocalFree(DPA_GetPtr(m_hAppBarDPA, iItem));
|
||||
DPA_DeletePtr(m_hAppBarDPA, iItem);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(data, &appbars, struct appbar_data, entry)
|
||||
void CAppBarManager::DestroyAppBarDPA()
|
||||
{
|
||||
if (!m_hAppBarDPA)
|
||||
return;
|
||||
|
||||
INT nItems = DPA_GetPtrCount(m_hAppBarDPA);
|
||||
while (--nItems >= 0)
|
||||
{
|
||||
if (data->hwnd == hwndExclude)
|
||||
continue;
|
||||
|
||||
if (hMon && hMon != MonitorFromWindow(data->hwnd, MONITOR_DEFAULTTONULL))
|
||||
continue;
|
||||
|
||||
SendMessageW(data->hwnd, data->callback_msg, uMsg, lParam);
|
||||
::LocalFree(DPA_GetPtr(m_hAppBarDPA, nItems));
|
||||
}
|
||||
|
||||
DPA_Destroy(m_hAppBarDPA);
|
||||
m_hAppBarDPA = NULL;
|
||||
}
|
||||
|
||||
/* send_poschanged: send ABN_POSCHANGED to every appbar except one */
|
||||
static void send_poschanged(HWND hwnd)
|
||||
// ABM_NEW
|
||||
BOOL CAppBarManager::OnAppBarNew(_In_ const APPBAR_COMMAND *pData)
|
||||
{
|
||||
appbar_notify_all(NULL, ABN_POSCHANGED, hwnd, 0);
|
||||
}
|
||||
HWND hWnd = (HWND)UlongToHandle(pData->abd.hWnd32);
|
||||
|
||||
/* appbar_cliprect: cut out parts of the rectangle that interfere with existing appbars */
|
||||
static void appbar_cliprect( HWND hwnd, RECT *rect )
|
||||
{
|
||||
struct appbar_data* data;
|
||||
LIST_FOR_EACH_ENTRY(data, &appbars, struct appbar_data, entry)
|
||||
if (m_hAppBarDPA)
|
||||
{
|
||||
if (data->hwnd == hwnd)
|
||||
if (FindAppBar(hWnd))
|
||||
{
|
||||
/* we only care about appbars that were added before this one */
|
||||
return;
|
||||
}
|
||||
if (data->space_reserved)
|
||||
{
|
||||
/* move in the side that corresponds to the other appbar's edge */
|
||||
switch (data->edge)
|
||||
{
|
||||
case ABE_BOTTOM:
|
||||
rect->bottom = min(rect->bottom, data->rc.top);
|
||||
break;
|
||||
case ABE_LEFT:
|
||||
rect->left = max(rect->left, data->rc.right);
|
||||
break;
|
||||
case ABE_RIGHT:
|
||||
rect->right = min(rect->right, data->rc.left);
|
||||
break;
|
||||
case ABE_TOP:
|
||||
rect->top = max(rect->top, data->rc.bottom);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static UINT_PTR handle_appbarmessage(DWORD msg, _AppBarData *abd)
|
||||
{
|
||||
struct appbar_data* data;
|
||||
HWND hwnd = abd->hWnd;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case ABM_NEW:
|
||||
if (get_appbar(hwnd))
|
||||
{
|
||||
/* fail when adding an hwnd the second time */
|
||||
ERR("Already exists: %p\n", hWnd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data = (struct appbar_data*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct appbar_data));
|
||||
if (!data)
|
||||
{
|
||||
ERR("out of memory\n");
|
||||
return FALSE;
|
||||
}
|
||||
data->hwnd = hwnd;
|
||||
data->callback_msg = abd->uCallbackMessage;
|
||||
|
||||
list_add_tail(&appbars, &data->entry);
|
||||
|
||||
return TRUE;
|
||||
case ABM_REMOVE:
|
||||
if ((data = get_appbar(hwnd)))
|
||||
{
|
||||
list_remove(&data->entry);
|
||||
|
||||
send_poschanged(hwnd);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
}
|
||||
else
|
||||
WARN("removing hwnd %p not on the list\n", hwnd);
|
||||
return TRUE;
|
||||
case ABM_QUERYPOS:
|
||||
if (abd->uEdge > ABE_BOTTOM)
|
||||
WARN("invalid edge %i for %p\n", abd->uEdge, hwnd);
|
||||
appbar_cliprect( hwnd, &abd->rc );
|
||||
return TRUE;
|
||||
case ABM_SETPOS:
|
||||
if (abd->uEdge > ABE_BOTTOM)
|
||||
{
|
||||
WARN("invalid edge %i for %p\n", abd->uEdge, hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
if ((data = get_appbar(hwnd)))
|
||||
{
|
||||
/* calculate acceptable space */
|
||||
appbar_cliprect( hwnd, &abd->rc );
|
||||
|
||||
if (!EqualRect(&abd->rc, &data->rc))
|
||||
send_poschanged(hwnd);
|
||||
|
||||
/* reserve that space for this appbar */
|
||||
data->edge = abd->uEdge;
|
||||
data->rc = abd->rc;
|
||||
data->space_reserved = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("app sent ABM_SETPOS message for %p without ABM_ADD\n", hwnd);
|
||||
}
|
||||
return TRUE;
|
||||
case ABM_GETSTATE:
|
||||
TRACE("SHAppBarMessage(ABM_GETSTATE)\n");
|
||||
return (g_TaskbarSettings.sr.AutoHide ? ABS_AUTOHIDE : 0) |
|
||||
(g_TaskbarSettings.sr.AlwaysOnTop ? ABS_ALWAYSONTOP : 0);
|
||||
case ABM_SETSTATE:
|
||||
TRACE("SHAppBarMessage(ABM_SETSTATE lparam=%s)\n", wine_dbgstr_longlong(abd->lParam));
|
||||
hwnd = GetPrimaryTaskbar();
|
||||
if (hwnd)
|
||||
{
|
||||
TaskbarSettings settings = g_TaskbarSettings;
|
||||
settings.sr.AutoHide = (abd->lParam & ABS_AUTOHIDE) != 0;
|
||||
settings.sr.AlwaysOnTop = (abd->lParam & ABS_ALWAYSONTOP) != 0;
|
||||
SendMessageW(hwnd, TWM_SETTINGSCHANGED, 0, (LPARAM)&settings);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case ABM_GETTASKBARPOS:
|
||||
TRACE("SHAppBarMessage(ABM_GETTASKBARPOS, hwnd=%p)\n", hwnd);
|
||||
abd->uEdge = g_TaskbarSettings.sr.Position;
|
||||
abd->hWnd = GetPrimaryTaskbar();
|
||||
return abd->hWnd && GetWindowRect(abd->hWnd, &abd->rc);
|
||||
case ABM_ACTIVATE:
|
||||
return TRUE;
|
||||
case ABM_GETAUTOHIDEBAR:
|
||||
FIXME("SHAppBarMessage(ABM_GETAUTOHIDEBAR, hwnd=%p, edge=%x): stub\n", hwnd, abd->uEdge);
|
||||
if (abd->uEdge == g_TaskbarSettings.sr.Position && g_TaskbarSettings.sr.AutoHide)
|
||||
return (SIZE_T)GetPrimaryTaskbar();
|
||||
return NULL;
|
||||
case ABM_SETAUTOHIDEBAR:
|
||||
FIXME("SHAppBarMessage(ABM_SETAUTOHIDEBAR, hwnd=%p, edge=%x, lparam=%s): stub\n",
|
||||
hwnd, abd->uEdge, wine_dbgstr_longlong(abd->lParam));
|
||||
return TRUE;
|
||||
case ABM_WINDOWPOSCHANGED:
|
||||
return TRUE;
|
||||
default:
|
||||
FIXME("SHAppBarMessage(%x) unimplemented\n", msg);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT appbar_message ( COPYDATASTRUCT* cds )
|
||||
{
|
||||
struct appbar_cmd cmd;
|
||||
UINT_PTR result;
|
||||
HANDLE return_hproc;
|
||||
HANDLE return_map;
|
||||
LPVOID return_view;
|
||||
struct appbar_response* response;
|
||||
|
||||
if (cds->cbData != sizeof(struct appbar_cmd))
|
||||
return TRUE;
|
||||
|
||||
RtlCopyMemory(&cmd, cds->lpData, cds->cbData);
|
||||
|
||||
result = handle_appbarmessage(cmd.dwMsg, &cmd.abd);
|
||||
|
||||
return_hproc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, cmd.return_process);
|
||||
if (return_hproc == NULL)
|
||||
{
|
||||
ERR("couldn't open calling process\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!DuplicateHandle(return_hproc, UlongToHandle(cmd.return_map), GetCurrentProcess(), &return_map, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
ERR("couldn't duplicate handle\n");
|
||||
CloseHandle(return_hproc);
|
||||
return TRUE;
|
||||
}
|
||||
CloseHandle(return_hproc);
|
||||
|
||||
return_view = MapViewOfFile(return_map, FILE_MAP_WRITE, 0, 0, sizeof(struct appbar_response));
|
||||
|
||||
if (return_view)
|
||||
{
|
||||
response = (struct appbar_response*)return_view;
|
||||
response->result = result;
|
||||
response->abd = cmd.abd;
|
||||
|
||||
UnmapViewOfFile(return_view);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("couldn't map view of file\n");
|
||||
const UINT c_nGrow = 4;
|
||||
m_hAppBarDPA = DPA_Create(c_nGrow);
|
||||
if (!m_hAppBarDPA)
|
||||
{
|
||||
ERR("Out of memory\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(return_map);
|
||||
PAPPBAR pAppBar = (PAPPBAR)::LocalAlloc(LPTR, sizeof(*pAppBar));
|
||||
if (pAppBar)
|
||||
{
|
||||
pAppBar->hWnd = hWnd;
|
||||
pAppBar->uEdge = UINT_MAX;
|
||||
pAppBar->uCallbackMessage = pData->abd.uCallbackMessage;
|
||||
if (DPA_InsertPtr(m_hAppBarDPA, INT_MAX, pAppBar) >= 0)
|
||||
return TRUE; // Success!
|
||||
|
||||
::LocalFree(pAppBar);
|
||||
}
|
||||
|
||||
ERR("Out of memory\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ABM_REMOVE
|
||||
void CAppBarManager::OnAppBarRemove(_In_ const APPBAR_COMMAND *pData)
|
||||
{
|
||||
if (!m_hAppBarDPA)
|
||||
return;
|
||||
|
||||
HWND hWnd = (HWND)UlongToHandle(pData->abd.hWnd32);
|
||||
INT nItems = DPA_GetPtrCount(m_hAppBarDPA);
|
||||
while (--nItems >= 0)
|
||||
{
|
||||
PAPPBAR pAppBar = (PAPPBAR)DPA_GetPtr(m_hAppBarDPA, nItems);
|
||||
if (!pAppBar)
|
||||
continue;
|
||||
|
||||
if (pAppBar->hWnd == hWnd)
|
||||
{
|
||||
RECT rcOld = pAppBar->rc;
|
||||
EliminateAppBar(nItems);
|
||||
StuckAppChange(hWnd, &rcOld, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ABM_QUERYPOS
|
||||
void CAppBarManager::OnAppBarQueryPos(_Inout_ PAPPBAR_COMMAND pData)
|
||||
{
|
||||
HWND hWnd = (HWND)UlongToHandle(pData->abd.hWnd32);
|
||||
PAPPBAR pAppBar1 = FindAppBar(hWnd);
|
||||
if (!pAppBar1)
|
||||
{
|
||||
ERR("Not found: %p\n", hWnd);
|
||||
return;
|
||||
}
|
||||
|
||||
PAPPBARDATA3264 pOutput = AppBar_LockOutput(pData);
|
||||
if (!pOutput)
|
||||
{
|
||||
ERR("!pOutput: %d\n", pData->dwProcessId);
|
||||
return;
|
||||
}
|
||||
pOutput->rc = pData->abd.rc;
|
||||
|
||||
if (::IsRectEmpty(&pOutput->rc))
|
||||
ERR("IsRectEmpty\n");
|
||||
|
||||
HMONITOR hMon1 = ::MonitorFromRect(&pOutput->rc, MONITOR_DEFAULTTOPRIMARY);
|
||||
ASSERT(hMon1 != NULL);
|
||||
|
||||
// Subtract tray rectangle from pOutput->rc if necessary
|
||||
if (hMon1 == GetMonitor() && !IsAutoHideState())
|
||||
{
|
||||
APPBAR dummyAppBar;
|
||||
dummyAppBar.uEdge = GetPosition();
|
||||
GetDockedRect(&dummyAppBar.rc);
|
||||
AppBarSubtractRect(&dummyAppBar, &pOutput->rc);
|
||||
}
|
||||
|
||||
// Subtract area from pOutput->rc
|
||||
UINT uEdge = pData->abd.uEdge;
|
||||
INT nItems = DPA_GetPtrCount(m_hAppBarDPA);
|
||||
while (--nItems >= 0)
|
||||
{
|
||||
PAPPBAR pAppBar2 = (PAPPBAR)DPA_GetPtr(m_hAppBarDPA, nItems);
|
||||
if (!pAppBar2 || pAppBar1->hWnd == pAppBar2->hWnd)
|
||||
continue;
|
||||
|
||||
if ((Edge_IsVertical(uEdge) || !Edge_IsVertical(pAppBar2->uEdge)) &&
|
||||
(pAppBar1->uEdge != uEdge || !AppBarOutsideOf(pAppBar1, pAppBar2)))
|
||||
{
|
||||
if (pAppBar1->uEdge == uEdge || pAppBar2->uEdge != uEdge)
|
||||
continue;
|
||||
}
|
||||
|
||||
HMONITOR hMon2 = ::MonitorFromRect(&pAppBar2->rc, MONITOR_DEFAULTTONULL);
|
||||
if (hMon1 == hMon2)
|
||||
AppBarSubtractRect(pAppBar2, &pOutput->rc);
|
||||
}
|
||||
|
||||
AppBar_UnLockOutput(pOutput);
|
||||
}
|
||||
|
||||
// ABM_SETPOS
|
||||
void CAppBarManager::OnAppBarSetPos(_Inout_ PAPPBAR_COMMAND pData)
|
||||
{
|
||||
HWND hWnd = (HWND)UlongToHandle(pData->abd.hWnd32);
|
||||
PAPPBAR pAppBar = FindAppBar(hWnd);
|
||||
if (!pAppBar)
|
||||
return;
|
||||
|
||||
OnAppBarQueryPos(pData);
|
||||
|
||||
PAPPBARDATA3264 pOutput = AppBar_LockOutput(pData);
|
||||
if (!pOutput)
|
||||
return;
|
||||
|
||||
RECT rcOld = pAppBar->rc, rcNew = pData->abd.rc;
|
||||
BOOL bChanged = !::EqualRect(&rcOld, &rcNew);
|
||||
|
||||
pAppBar->rc = rcNew;
|
||||
pAppBar->uEdge = pData->abd.uEdge;
|
||||
|
||||
AppBar_UnLockOutput(pOutput);
|
||||
|
||||
if (bChanged)
|
||||
StuckAppChange(hWnd, &rcOld, &rcNew, FALSE);
|
||||
}
|
||||
|
||||
void CAppBarManager::OnAppBarNotifyAll(
|
||||
_In_opt_ HMONITOR hMon,
|
||||
_In_opt_ HWND hwndIgnore,
|
||||
_In_ DWORD dwNotify,
|
||||
_In_opt_ LPARAM lParam)
|
||||
{
|
||||
TRACE("%p, %p, 0x%X, %p\n", hMon, hwndIgnore, dwNotify, lParam);
|
||||
|
||||
if (!m_hAppBarDPA)
|
||||
return;
|
||||
|
||||
INT nItems = DPA_GetPtrCount(m_hAppBarDPA);
|
||||
while (--nItems >= 0)
|
||||
{
|
||||
PAPPBAR pAppBar = (PAPPBAR)DPA_GetPtr(m_hAppBarDPA, nItems);
|
||||
if (!pAppBar || pAppBar->hWnd == hwndIgnore)
|
||||
continue;
|
||||
|
||||
HWND hwndAppBar = pAppBar->hWnd;
|
||||
if (!::IsWindow(hwndAppBar))
|
||||
{
|
||||
EliminateAppBar(nItems);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hMon || hMon == ::MonitorFromWindow(hwndAppBar, MONITOR_DEFAULTTONULL))
|
||||
::PostMessageW(hwndAppBar, pAppBar->uCallbackMessage, dwNotify, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
/// @param pAppBar The target AppBar to subtract.
|
||||
/// @param prc The rectangle to be subtracted.
|
||||
void CAppBarManager::AppBarSubtractRect(_In_ PAPPBAR pAppBar, _Inout_ PRECT prc)
|
||||
{
|
||||
switch (pAppBar->uEdge)
|
||||
{
|
||||
case ABE_LEFT: prc->left = max(prc->left, pAppBar->rc.right); break;
|
||||
case ABE_TOP: prc->top = max(prc->top, pAppBar->rc.bottom); break;
|
||||
case ABE_RIGHT: prc->right = min(prc->right, pAppBar->rc.left); break;
|
||||
case ABE_BOTTOM: prc->bottom = min(prc->bottom, pAppBar->rc.top); break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Is pAppBar1 outside of pAppBar2?
|
||||
BOOL CAppBarManager::AppBarOutsideOf(
|
||||
_In_ const APPBAR *pAppBar1,
|
||||
_In_ const APPBAR *pAppBar2)
|
||||
{
|
||||
if (pAppBar1->uEdge != pAppBar2->uEdge)
|
||||
return FALSE;
|
||||
|
||||
switch (pAppBar2->uEdge)
|
||||
{
|
||||
case ABE_LEFT: return pAppBar1->rc.left >= pAppBar2->rc.left;
|
||||
case ABE_TOP: return pAppBar1->rc.top >= pAppBar2->rc.top;
|
||||
case ABE_RIGHT: return pAppBar1->rc.right <= pAppBar2->rc.right;
|
||||
case ABE_BOTTOM: return pAppBar1->rc.bottom <= pAppBar2->rc.bottom;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get rectangle of the tray window.
|
||||
/// @param prcDocked The pointer to the rectangle to be received.
|
||||
void CAppBarManager::GetDockedRect(_Out_ PRECT prcDocked)
|
||||
{
|
||||
*prcDocked = *GetTrayRect();
|
||||
if (IsAutoHideState() && IsHidingState())
|
||||
ComputeHiddenRect(prcDocked, GetPosition());
|
||||
}
|
||||
|
||||
/// Compute the position and size of the hidden TaskBar.
|
||||
/// @param prc The rectangle before hiding TaskBar.
|
||||
/// @param uSide The side of TaskBar (ABE_...).
|
||||
void CAppBarManager::ComputeHiddenRect(_Inout_ PRECT prc, _In_ UINT uSide)
|
||||
{
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
HMONITOR hMonitor = ::MonitorFromRect(prc, MONITOR_DEFAULTTONULL);
|
||||
if (!::GetMonitorInfoW(hMonitor, &mi))
|
||||
return;
|
||||
RECT rcMon = mi.rcMonitor;
|
||||
|
||||
INT cxy = Edge_IsVertical(uSide) ? (prc->bottom - prc->top) : (prc->right - prc->left);
|
||||
switch (uSide)
|
||||
{
|
||||
case ABE_LEFT:
|
||||
prc->right = rcMon.left + GetSystemMetrics(SM_CXFRAME) / 2;
|
||||
prc->left = prc->right - cxy;
|
||||
break;
|
||||
case ABE_TOP:
|
||||
prc->bottom = rcMon.top + GetSystemMetrics(SM_CYFRAME) / 2;
|
||||
prc->top = prc->bottom - cxy;
|
||||
break;
|
||||
case ABE_RIGHT:
|
||||
prc->left = rcMon.right - GetSystemMetrics(SM_CXFRAME) / 2;
|
||||
prc->right = prc->left + cxy;
|
||||
break;
|
||||
case ABE_BOTTOM:
|
||||
prc->top = rcMon.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
|
||||
prc->bottom = prc->top + cxy;
|
||||
break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// This function is called when AppBar and/or TaskBar is being moved, removed, and/or updated.
|
||||
/// @param hwndTarget The target window. Optional.
|
||||
/// @param prcOld The old position and size. Optional.
|
||||
/// @param prcNew The new position and size. Optional.
|
||||
/// @param bTray TRUE if the tray is being moved.
|
||||
void
|
||||
CAppBarManager::StuckAppChange(
|
||||
_In_opt_ HWND hwndTarget,
|
||||
_In_opt_ const RECT *prcOld,
|
||||
_In_opt_ const RECT *prcNew,
|
||||
_In_ BOOL bTray)
|
||||
{
|
||||
RECT rcWorkArea1, rcWorkArea2;
|
||||
HMONITOR hMon1 = NULL;
|
||||
UINT flags = 0;
|
||||
enum { SET_WORKAREA_1 = 1, SET_WORKAREA_2 = 2, NEED_SIZING = 4 }; // for flags
|
||||
|
||||
if (prcOld)
|
||||
{
|
||||
hMon1 = (bTray ? GetPreviousMonitor() : ::MonitorFromRect(prcOld, MONITOR_DEFAULTTONEAREST));
|
||||
if (hMon1)
|
||||
{
|
||||
WORKAREA_TYPE type1 = RecomputeWorkArea(GetTrayRect(), hMon1, &rcWorkArea1);
|
||||
if (type1 == WORKAREA_IS_NOT_MONITOR)
|
||||
flags = SET_WORKAREA_1;
|
||||
if (type1 == WORKAREA_SAME_AS_MONITOR)
|
||||
flags = NEED_SIZING;
|
||||
}
|
||||
}
|
||||
|
||||
if (prcNew)
|
||||
{
|
||||
HMONITOR hMon2 = ::MonitorFromRect(prcNew, MONITOR_DEFAULTTONULL);
|
||||
if (hMon2 && hMon2 != hMon1)
|
||||
{
|
||||
WORKAREA_TYPE type2 = RecomputeWorkArea(GetTrayRect(), hMon2, &rcWorkArea2);
|
||||
if (type2 == WORKAREA_IS_NOT_MONITOR)
|
||||
flags |= SET_WORKAREA_2;
|
||||
else if (type2 == WORKAREA_SAME_AS_MONITOR && !flags)
|
||||
flags = NEED_SIZING;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SET_WORKAREA_1)
|
||||
{
|
||||
UINT fWinIni = ((flags == SET_WORKAREA_1 && GetDesktopWnd()) ? SPIF_SENDCHANGE : 0);
|
||||
::SystemParametersInfoW(SPI_SETWORKAREA, TRUE, &rcWorkArea1, fWinIni);
|
||||
RedrawDesktop(GetDesktopWnd(), &rcWorkArea1);
|
||||
}
|
||||
|
||||
if (flags & SET_WORKAREA_2)
|
||||
{
|
||||
UINT fWinIni = (GetDesktopWnd() ? SPIF_SENDCHANGE : 0);
|
||||
::SystemParametersInfoW(SPI_SETWORKAREA, TRUE, &rcWorkArea2, fWinIni);
|
||||
RedrawDesktop(GetDesktopWnd(), &rcWorkArea2);
|
||||
}
|
||||
|
||||
if (bTray || flags == NEED_SIZING)
|
||||
::SendMessageW(GetDesktopWnd(), WM_SIZE, 0, 0);
|
||||
|
||||
// Post ABN_POSCHANGED messages to AppBar windows
|
||||
OnAppBarNotifyAll(NULL, hwndTarget, ABN_POSCHANGED, TRUE);
|
||||
}
|
||||
|
||||
void CAppBarManager::RedrawDesktop(_In_ HWND hwndDesktop, _Inout_ PRECT prc)
|
||||
{
|
||||
if (!hwndDesktop)
|
||||
return;
|
||||
::MapWindowPoints(NULL, hwndDesktop, (POINT*)prc, sizeof(*prc) / sizeof(POINT));
|
||||
::RedrawWindow(hwndDesktop, prc, 0, RDW_ALLCHILDREN | RDW_ERASE | RDW_INVALIDATE);
|
||||
}
|
||||
|
||||
/// Re-compute the work area.
|
||||
/// @param prcTray The position and size of the tray window
|
||||
/// @param hMonitor The monitor of the work area to re-compute.
|
||||
/// @param prcWorkArea The work area to be re-computed.
|
||||
WORKAREA_TYPE
|
||||
CAppBarManager::RecomputeWorkArea(
|
||||
_In_ const RECT *prcTray,
|
||||
_In_ HMONITOR hMonitor,
|
||||
_Out_ PRECT prcWorkArea)
|
||||
{
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
if (!::GetMonitorInfoW(hMonitor, &mi))
|
||||
return WORKAREA_NO_TRAY_AREA;
|
||||
|
||||
if (IsAutoHideState())
|
||||
*prcWorkArea = mi.rcMonitor;
|
||||
else
|
||||
::SubtractRect(prcWorkArea, &mi.rcMonitor, prcTray);
|
||||
|
||||
if (m_hAppBarDPA)
|
||||
{
|
||||
INT nItems = DPA_GetPtrCount(m_hAppBarDPA);
|
||||
while (--nItems >= 0)
|
||||
{
|
||||
PAPPBAR pAppBar = (PAPPBAR)DPA_GetPtr(m_hAppBarDPA, nItems);
|
||||
if (pAppBar && hMonitor == ::MonitorFromRect(&pAppBar->rc, MONITOR_DEFAULTTONULL))
|
||||
AppBarSubtractRect(pAppBar, prcWorkArea);
|
||||
}
|
||||
}
|
||||
|
||||
if (!::EqualRect(prcWorkArea, &mi.rcWork))
|
||||
return WORKAREA_IS_NOT_MONITOR;
|
||||
|
||||
if (IsAutoHideState() || ::IsRectEmpty(prcTray))
|
||||
return WORKAREA_NO_TRAY_AREA;
|
||||
|
||||
return WORKAREA_SAME_AS_MONITOR;
|
||||
}
|
||||
|
||||
PAPPBAR_COMMAND
|
||||
CAppBarManager::GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
|
||||
{
|
||||
PAPPBAR_COMMAND pData = (PAPPBAR_COMMAND)pCopyData->lpData;
|
||||
|
||||
if (pCopyData->cbData != sizeof(*pData) ||
|
||||
pData->abd.cbSize != sizeof(pData->abd))
|
||||
{
|
||||
ERR("Invalid AppBar message\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pData;
|
||||
}
|
||||
|
||||
// WM_COPYDATA TABDMC_APPBAR
|
||||
LRESULT CAppBarManager::OnAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
|
||||
{
|
||||
PAPPBAR_COMMAND pData = GetAppBarMessage(pCopyData);
|
||||
if (!pData)
|
||||
return 0;
|
||||
|
||||
switch (pData->dwMessage)
|
||||
{
|
||||
case ABM_NEW:
|
||||
return OnAppBarNew(pData);
|
||||
case ABM_REMOVE:
|
||||
OnAppBarRemove(pData);
|
||||
break;
|
||||
case ABM_QUERYPOS:
|
||||
OnAppBarQueryPos(pData);
|
||||
break;
|
||||
case ABM_SETPOS:
|
||||
OnAppBarSetPos(pData);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
FIXME("0x%X\n", pData->dwMessage);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
96
base/shell/explorer/appbar.h
Normal file
96
base/shell/explorer/appbar.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Explorer
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: AppBar implementation
|
||||
* COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct tagAPPBAR
|
||||
{
|
||||
HWND hWnd;
|
||||
UINT uCallbackMessage;
|
||||
UINT uEdge;
|
||||
RECT rc;
|
||||
} APPBAR, *PAPPBAR;
|
||||
|
||||
static inline PAPPBARDATA3264
|
||||
AppBar_LockOutput(_In_ PAPPBAR_COMMAND pData)
|
||||
{
|
||||
return (PAPPBARDATA3264)SHLockShared(UlongToHandle(pData->hOutput32), pData->dwProcessId);
|
||||
}
|
||||
|
||||
static inline VOID
|
||||
AppBar_UnLockOutput(_Out_ PAPPBARDATA3264 pOutput)
|
||||
{
|
||||
SHUnlockShared(pOutput);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
Edge_IsVertical(_In_ UINT uEdge)
|
||||
{
|
||||
return uEdge == ABE_TOP || uEdge == ABE_BOTTOM;
|
||||
}
|
||||
|
||||
// Return value of CAppBarManager::RecomputeWorkArea
|
||||
enum WORKAREA_TYPE
|
||||
{
|
||||
WORKAREA_NO_TRAY_AREA = 0,
|
||||
WORKAREA_IS_NOT_MONITOR = 1,
|
||||
WORKAREA_SAME_AS_MONITOR = 2,
|
||||
};
|
||||
|
||||
class CAppBarManager
|
||||
{
|
||||
public:
|
||||
CAppBarManager();
|
||||
virtual ~CAppBarManager();
|
||||
|
||||
LRESULT OnAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData);
|
||||
|
||||
protected:
|
||||
HDPA m_hAppBarDPA; // DPA (Dynamic Pointer Array)
|
||||
|
||||
PAPPBAR FindAppBar(_In_ HWND hwndAppBar) const;
|
||||
void EliminateAppBar(_In_ INT iItem);
|
||||
void DestroyAppBarDPA();
|
||||
void AppBarSubtractRect(_In_ PAPPBAR pAppBar, _Inout_ PRECT prc);
|
||||
BOOL AppBarOutsideOf(_In_ const APPBAR *pAppBar1, _In_ const APPBAR *pAppBar2);
|
||||
void ComputeHiddenRect(_Inout_ PRECT prc, _In_ UINT uSide);
|
||||
PAPPBAR_COMMAND GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData);
|
||||
void GetDockedRect(_Out_ PRECT prcDocked);
|
||||
|
||||
BOOL OnAppBarNew(_In_ const APPBAR_COMMAND *pData);
|
||||
void OnAppBarRemove(_In_ const APPBAR_COMMAND *pData);
|
||||
void OnAppBarQueryPos(_Inout_ PAPPBAR_COMMAND pData);
|
||||
void OnAppBarSetPos(_Inout_ PAPPBAR_COMMAND pData);
|
||||
|
||||
void OnAppBarNotifyAll(
|
||||
_In_opt_ HMONITOR hMon,
|
||||
_In_opt_ HWND hwndIgnore,
|
||||
_In_ DWORD dwNotify,
|
||||
_In_opt_ LPARAM lParam);
|
||||
|
||||
WORKAREA_TYPE
|
||||
RecomputeWorkArea(
|
||||
_In_ const RECT *prcTray,
|
||||
_In_ HMONITOR hMonitor,
|
||||
_Out_ PRECT prcWorkArea);
|
||||
|
||||
void StuckAppChange(
|
||||
_In_opt_ HWND hwndTarget,
|
||||
_In_opt_ const RECT *prcOld,
|
||||
_In_opt_ const RECT *prcNew,
|
||||
_In_ BOOL bTray);
|
||||
|
||||
void RedrawDesktop(_In_ HWND hwndDesktop, _Inout_ PRECT prc);
|
||||
|
||||
virtual BOOL IsAutoHideState() const = 0;
|
||||
virtual BOOL IsHidingState() const = 0;
|
||||
virtual HMONITOR GetMonitor() const = 0;
|
||||
virtual HMONITOR GetPreviousMonitor() const = 0;
|
||||
virtual INT GetPosition() const = 0;
|
||||
virtual const RECT* GetTrayRect() = 0;
|
||||
virtual HWND GetDesktopWnd() const = 0;
|
||||
};
|
@@ -1,30 +1,16 @@
|
||||
/*
|
||||
* ReactOS Explorer
|
||||
*
|
||||
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
|
||||
* Copyright 2018-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*
|
||||
* this library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* this library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* PROJECT: ReactOS Explorer
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Tray window implementation
|
||||
* COPYRIGHT: Copyright 2006-2007 Thomas Weidenmueller <w3seek@reactos.org>
|
||||
* Copyright 2018-2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <commoncontrols.h>
|
||||
#include "appbar.h"
|
||||
|
||||
HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
|
||||
LRESULT appbar_message(COPYDATASTRUCT* cds);
|
||||
void appbar_notify_all(HMONITOR hMon, UINT uMsg, HWND hwndExclude, LPARAM lParam);
|
||||
|
||||
#define WM_APP_TRAYDESTROY (WM_APP + 0x100)
|
||||
|
||||
@@ -56,8 +42,6 @@ void appbar_notify_all(HMONITOR hMon, UINT uMsg, HWND hwndExclude, LPARAM lParam
|
||||
#define IDHK_DESKTOP 0x1fe
|
||||
#define IDHK_PAGER 0x1ff
|
||||
|
||||
static const WCHAR szTrayWndClass[] = L"Shell_TrayWnd";
|
||||
|
||||
enum { NONE, TILED, CASCADED } g_Arrangement = NONE;
|
||||
|
||||
struct WINDOWPOSBACKUPDATA
|
||||
@@ -323,6 +307,7 @@ class CTrayWindow :
|
||||
public CComCoClass<CTrayWindow>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public CWindowImpl < CTrayWindow, CWindow, CControlWinTraits >,
|
||||
public CAppBarManager,
|
||||
public ITrayWindow,
|
||||
public IShellDesktopTray,
|
||||
public IOleWindow,
|
||||
@@ -684,35 +669,35 @@ public:
|
||||
break;
|
||||
|
||||
case ID_SHELL_CMD_TILE_WND_H:
|
||||
appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
|
||||
OnAppBarNotifyAll(NULL, NULL, ABN_WINDOWARRANGE, TRUE);
|
||||
if (g_Arrangement == NONE)
|
||||
{
|
||||
BackupWindowPos();
|
||||
}
|
||||
TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
|
||||
appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
|
||||
OnAppBarNotifyAll(NULL, NULL, ABN_WINDOWARRANGE, FALSE);
|
||||
g_Arrangement = TILED;
|
||||
break;
|
||||
|
||||
case ID_SHELL_CMD_TILE_WND_V:
|
||||
appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
|
||||
OnAppBarNotifyAll(NULL, NULL, ABN_WINDOWARRANGE, TRUE);
|
||||
if (g_Arrangement == NONE)
|
||||
{
|
||||
BackupWindowPos();
|
||||
}
|
||||
TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
|
||||
appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
|
||||
OnAppBarNotifyAll(NULL, NULL, ABN_WINDOWARRANGE, FALSE);
|
||||
g_Arrangement = TILED;
|
||||
break;
|
||||
|
||||
case ID_SHELL_CMD_CASCADE_WND:
|
||||
appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, TRUE);
|
||||
OnAppBarNotifyAll(NULL, NULL, ABN_WINDOWARRANGE, TRUE);
|
||||
if (g_Arrangement == NONE)
|
||||
{
|
||||
BackupWindowPos();
|
||||
}
|
||||
CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
|
||||
appbar_notify_all(NULL, ABN_WINDOWARRANGE, NULL, FALSE);
|
||||
OnAppBarNotifyAll(NULL, NULL, ABN_WINDOWARRANGE, FALSE);
|
||||
g_Arrangement = CASCADED;
|
||||
break;
|
||||
|
||||
@@ -2518,11 +2503,14 @@ ChangePos:
|
||||
|
||||
LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT *)lParam;
|
||||
PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam;
|
||||
if (!pCopyData)
|
||||
return FALSE;
|
||||
|
||||
switch (pCopyData->dwData)
|
||||
{
|
||||
case TABDMC_APPBAR:
|
||||
return appbar_message(pCopyData);
|
||||
return OnAppBarMessage(pCopyData);
|
||||
case TABDMC_NOTIFY:
|
||||
case TABDMC_LOADINPROC:
|
||||
return ::SendMessageW(m_TrayNotify, uMsg, wParam, lParam);
|
||||
@@ -2951,7 +2939,7 @@ HandleTrayContextMenu:
|
||||
LRESULT Ret = FALSE;
|
||||
/* FIXME: We can't check with IsChild whether the hwnd is somewhere inside
|
||||
the rebar control! But we shouldn't forward messages that the band
|
||||
site doesn't handle, such as other controls (start button, tray window */
|
||||
site doesn't handle, such as other controls (start button, tray window) */
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
@@ -3386,7 +3374,7 @@ HandleTrayContextMenu:
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_WND_CLASS_EX(szTrayWndClass, CS_DBLCLKS, COLOR_3DFACE)
|
||||
DECLARE_WND_CLASS_EX(L"Shell_TrayWnd", CS_DBLCLKS, COLOR_3DFACE)
|
||||
|
||||
BEGIN_MSG_MAP(CTrayWindow)
|
||||
if (m_StartMenuBand != NULL)
|
||||
@@ -3577,6 +3565,24 @@ HandleTrayContextMenu:
|
||||
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
|
||||
END_COM_MAP()
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AppBar section
|
||||
//
|
||||
// See also: appbar.cpp
|
||||
// TODO: freedesktop _NET_WM_STRUT integration
|
||||
// TODO: find when a fullscreen app is in the foreground and send FULLSCREENAPP notifications
|
||||
// TODO: detect changes in the screen size and send ABN_POSCHANGED ?
|
||||
// TODO: multiple monitor support
|
||||
|
||||
BOOL IsAutoHideState() const override { return g_TaskbarSettings.sr.AutoHide; }
|
||||
BOOL IsHidingState() const override { return m_AutoHideState == AUTOHIDE_HIDING; }
|
||||
HMONITOR GetMonitor() const override { return m_Monitor; }
|
||||
HMONITOR GetPreviousMonitor() const override { return m_PreviousMonitor; }
|
||||
INT GetPosition() const override { return m_Position; }
|
||||
const RECT* GetTrayRect() override { return &m_TrayRects[m_Position]; }
|
||||
HWND GetDesktopWnd() const override { return m_DesktopWnd; }
|
||||
};
|
||||
|
||||
class CTrayWindowCtxMenu :
|
||||
|
@@ -85,7 +85,7 @@ list(APPEND SOURCE
|
||||
CFolderItemVerbs.cpp)
|
||||
|
||||
list(APPEND PCH_SKIP_SOURCE
|
||||
wine/appbar.c
|
||||
appbar.c
|
||||
wine/classes.c
|
||||
wine/clipboard.c
|
||||
wine/control.c
|
||||
|
129
dll/win32/shell32/appbar.c
Normal file
129
dll/win32/shell32/appbar.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Shell32
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: SHAppBarMessage implementation
|
||||
* COPYRIGHT: Copyright 2008 Vincent Povirk for CodeWeavers
|
||||
* Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winuser.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <undocshell.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(appbar);
|
||||
|
||||
static UINT32
|
||||
AppBar_CopyIn(
|
||||
_In_ const VOID *pvSrc,
|
||||
_In_ SIZE_T dwSize,
|
||||
_In_ DWORD dwProcessId)
|
||||
{
|
||||
HANDLE hMem = SHAllocShared(NULL, dwSize, dwProcessId);
|
||||
if (!hMem)
|
||||
return 0;
|
||||
|
||||
PVOID pvDest = SHLockShared(hMem, dwProcessId);
|
||||
if (!pvDest)
|
||||
{
|
||||
SHFreeShared(hMem, dwProcessId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CopyMemory(pvDest, pvSrc, dwSize);
|
||||
SHUnlockShared(pvDest);
|
||||
return HandleToUlong(hMem);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
AppBar_CopyOut(
|
||||
_In_ UINT32 hOutput32,
|
||||
_Out_ PVOID pvDest,
|
||||
_In_ SIZE_T cbDest,
|
||||
_In_ DWORD dwProcessId)
|
||||
{
|
||||
HANDLE hOutput = UlongToHandle(hOutput32);
|
||||
PVOID pvSrc = SHLockShared(hOutput, dwProcessId);
|
||||
if (pvSrc)
|
||||
{
|
||||
CopyMemory(pvDest, pvSrc, cbDest);
|
||||
SHUnlockShared(pvSrc);
|
||||
}
|
||||
|
||||
SHFreeShared(hOutput, dwProcessId);
|
||||
return pvSrc != NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHAppBarMessage [SHELL32.@]
|
||||
*/
|
||||
UINT_PTR
|
||||
WINAPI
|
||||
SHAppBarMessage(
|
||||
_In_ DWORD dwMessage,
|
||||
_Inout_ PAPPBARDATA pData)
|
||||
{
|
||||
TRACE("dwMessage=%d, pData={cb=%d, hwnd=%p}\n", dwMessage, pData->cbSize, pData->hWnd);
|
||||
|
||||
HWND hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
|
||||
if (!hTrayWnd || pData->cbSize > sizeof(*pData))
|
||||
{
|
||||
WARN("%p, %d\n", hTrayWnd, pData->cbSize);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
APPBAR_COMMAND cmd;
|
||||
cmd.abd.cbSize = sizeof(cmd.abd);
|
||||
cmd.abd.hWnd32 = HandleToUlong(pData->hWnd); // Truncated on x64, as on Windows!
|
||||
cmd.abd.uCallbackMessage = pData->uCallbackMessage;
|
||||
cmd.abd.uEdge = pData->uEdge;
|
||||
cmd.abd.rc = pData->rc;
|
||||
cmd.abd.lParam64 = pData->lParam;
|
||||
cmd.dwMessage = dwMessage;
|
||||
cmd.hOutput32 = 0;
|
||||
cmd.dwProcessId = GetCurrentProcessId();
|
||||
|
||||
/* Make output data if necessary */
|
||||
switch (dwMessage)
|
||||
{
|
||||
case ABM_QUERYPOS:
|
||||
case ABM_SETPOS:
|
||||
case ABM_GETTASKBARPOS:
|
||||
cmd.hOutput32 = AppBar_CopyIn(&cmd.abd, sizeof(cmd.abd), cmd.dwProcessId);
|
||||
if (!cmd.hOutput32)
|
||||
{
|
||||
ERR("AppBar_CopyIn: %d\n", dwMessage);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send WM_COPYDATA message */
|
||||
COPYDATASTRUCT copyData = { TABDMC_APPBAR, sizeof(cmd), &cmd };
|
||||
UINT_PTR ret = SendMessageW(hTrayWnd, WM_COPYDATA, (WPARAM)pData->hWnd, (LPARAM)©Data);
|
||||
|
||||
/* Copy back output data */
|
||||
if (cmd.hOutput32)
|
||||
{
|
||||
if (!AppBar_CopyOut(cmd.hOutput32, &cmd.abd, sizeof(cmd.abd), cmd.dwProcessId))
|
||||
{
|
||||
ERR("AppBar_CopyOut: %d\n", dwMessage);
|
||||
return FALSE;
|
||||
}
|
||||
pData->hWnd = UlongToHandle(cmd.abd.hWnd32);
|
||||
pData->uCallbackMessage = cmd.abd.uCallbackMessage;
|
||||
pData->uEdge = cmd.abd.uEdge;
|
||||
pData->rc = cmd.abd.rc;
|
||||
pData->lParam = (LPARAM)cmd.abd.lParam64;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@@ -861,7 +861,8 @@ HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y)
|
||||
_MenuItemSelect(MPOS_FULLCANCEL);
|
||||
|
||||
TRACE("Before InvokeCommand\n");
|
||||
CMINVOKECOMMANDINFO cmi = { sizeof(cmi), 0, hwnd };
|
||||
// Note: Not passing hwnd to InvokeCommand because it can be a BaseBar window that is about to die
|
||||
CMINVOKECOMMANDINFO cmi = { sizeof(cmi), 0, NULL };
|
||||
cmi.lpVerb = MAKEINTRESOURCEA(uCommand - idCmdFirst);
|
||||
if (GetKeyState(VK_SHIFT) < 0)
|
||||
cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
|
||||
|
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* SHAppBarMessage implementation
|
||||
*
|
||||
* Copyright 2008 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
//
|
||||
// Adapted from Wine appbar.c .
|
||||
//
|
||||
|
||||
#include <wine/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winerror.h>
|
||||
#include <shellapi.h>
|
||||
#include <winuser.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <undocshell.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
#include "shell32_main.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(appbar);
|
||||
|
||||
struct appbar_cmd
|
||||
{
|
||||
DWORD dwMsg;
|
||||
ULONG return_map;
|
||||
DWORD return_process;
|
||||
struct _AppBarData abd;
|
||||
};
|
||||
|
||||
struct appbar_response
|
||||
{
|
||||
ULONGLONG result;
|
||||
struct _AppBarData abd;
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
* SHAppBarMessage [SHELL32.@]
|
||||
*/
|
||||
UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
|
||||
{
|
||||
struct appbar_cmd command;
|
||||
struct appbar_response* response;
|
||||
HANDLE return_map;
|
||||
LPVOID return_view;
|
||||
HWND appbarmsg_window;
|
||||
COPYDATASTRUCT cds;
|
||||
|
||||
UINT_PTR ret = 0;
|
||||
|
||||
TRACE("msg=%d, data={cb=%d, hwnd=%p}\n", msg, data->cbSize, data->hWnd);
|
||||
|
||||
/* These members are message dependent */
|
||||
switch(msg)
|
||||
{
|
||||
case ABM_NEW:
|
||||
TRACE("callback: %x\n", data->uCallbackMessage);
|
||||
break;
|
||||
|
||||
case ABM_GETAUTOHIDEBAR:
|
||||
TRACE("edge: %d\n", data->uEdge);
|
||||
break;
|
||||
|
||||
case ABM_QUERYPOS:
|
||||
case ABM_SETPOS:
|
||||
TRACE("edge: %d, rc: %s\n", data->uEdge, wine_dbgstr_rect(&data->rc));
|
||||
break;
|
||||
|
||||
case ABM_GETTASKBARPOS:
|
||||
TRACE("rc: %s\n", wine_dbgstr_rect(&data->rc));
|
||||
break;
|
||||
|
||||
case ABM_SETAUTOHIDEBAR:
|
||||
TRACE("edge: %d, lParam: %lx\n", data->uEdge, data->lParam);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("unknown msg: %d\n", msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (data->cbSize < sizeof(APPBARDATA))
|
||||
{
|
||||
WARN("data at %p is too small\n", data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
command.dwMsg = msg;
|
||||
command.abd.hWnd = data->hWnd;
|
||||
command.abd.uCallbackMessage = data->uCallbackMessage;
|
||||
command.abd.uEdge = data->uEdge;
|
||||
command.abd.rc = data->rc;
|
||||
command.abd.lParam = data->lParam;
|
||||
|
||||
return_map = CreateFileMappingW(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(struct appbar_response), NULL);
|
||||
if (return_map == NULL)
|
||||
{
|
||||
ERR("couldn't create file mapping\n");
|
||||
return 0;
|
||||
}
|
||||
command.return_map = HandleToUlong( return_map );
|
||||
|
||||
command.return_process = GetCurrentProcessId();
|
||||
|
||||
appbarmsg_window = FindWindowW(L"Shell_TrayWnd", NULL);
|
||||
if (appbarmsg_window == NULL)
|
||||
{
|
||||
ERR("couldn't find appbar window\n");
|
||||
CloseHandle(return_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cds.dwData = TABDMC_APPBAR;
|
||||
cds.cbData = sizeof(command);
|
||||
cds.lpData = &command;
|
||||
|
||||
SendMessageW(appbarmsg_window, WM_COPYDATA, (WPARAM)data->hWnd, (LPARAM)&cds);
|
||||
|
||||
return_view = MapViewOfFile(return_map, FILE_MAP_READ, 0, 0, sizeof(struct appbar_response));
|
||||
if (return_view == NULL)
|
||||
{
|
||||
ERR("MapViewOfFile failed\n");
|
||||
CloseHandle(return_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
response = return_view;
|
||||
|
||||
ret = response->result;
|
||||
if (ret)
|
||||
{
|
||||
data->hWnd = response->abd.hWnd;
|
||||
data->uCallbackMessage = response->abd.uCallbackMessage;
|
||||
data->uEdge = response->abd.uEdge;
|
||||
data->rc = response->abd.rc;
|
||||
data->lParam = response->abd.lParam;
|
||||
}
|
||||
UnmapViewOfFile(return_view);
|
||||
|
||||
CloseHandle(return_map);
|
||||
|
||||
return ret;
|
||||
}
|
@@ -840,6 +840,7 @@ ClassPnp(
|
||||
}
|
||||
else
|
||||
DeviceExtension->FileHandle = NULL;
|
||||
IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, TRUE);
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
@@ -854,6 +855,7 @@ ClassPnp(
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, FALSE);
|
||||
if (DeviceExtension->FileHandle)
|
||||
{
|
||||
ZwClose(DeviceExtension->FileHandle);
|
||||
|
@@ -10,6 +10,9 @@
|
||||
#include <shlwapi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* Based on https://github.com/katahiromz/AppBarSample */
|
||||
|
||||
//#define VERBOSE
|
||||
@@ -264,15 +267,15 @@ protected:
|
||||
switch (id)
|
||||
{
|
||||
case ID_ACTION:
|
||||
PostMessage(s_hwnd2, WM_COMMAND, ID_ACTION + 1, 0);
|
||||
PostMessageW(s_hwnd2, WM_COMMAND, ID_ACTION + 1, 0);
|
||||
break;
|
||||
case ID_ACTION + 1:
|
||||
hThread = CreateThread(NULL, 0, ActionThreadFunc, this, 0, NULL);
|
||||
if (!hThread)
|
||||
{
|
||||
skip("failed to create thread\n");
|
||||
PostMessage(s_hwnd1, WM_CLOSE, 0, 0);
|
||||
PostMessage(s_hwnd2, WM_CLOSE, 0, 0);
|
||||
PostMessageW(s_hwnd1, WM_CLOSE, 0, 0);
|
||||
PostMessageW(s_hwnd2, WM_CLOSE, 0, 0);
|
||||
return;
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
@@ -438,8 +441,10 @@ protected:
|
||||
|
||||
BOOL AppBar_SetSide(HWND hwnd, UINT uSide)
|
||||
{
|
||||
RECT rc;
|
||||
SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
||||
HMONITOR hMon = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
::GetMonitorInfo(hMon, &mi);
|
||||
RECT rc = mi.rcWork;
|
||||
|
||||
BOOL fAutoHide = FALSE;
|
||||
if (m_fAutoHide)
|
||||
@@ -452,18 +457,21 @@ protected:
|
||||
|
||||
switch (uSide)
|
||||
{
|
||||
case ABE_TOP:
|
||||
rc.bottom = rc.top + m_cyHeight;
|
||||
break;
|
||||
case ABE_BOTTOM:
|
||||
rc.top = rc.bottom - m_cyHeight;
|
||||
break;
|
||||
case ABE_LEFT:
|
||||
rc.right = rc.left + m_cxWidth;
|
||||
break;
|
||||
case ABE_RIGHT:
|
||||
rc.left = rc.right - m_cxWidth;
|
||||
break;
|
||||
case ABE_TOP:
|
||||
rc.bottom = rc.top + m_cyHeight;
|
||||
break;
|
||||
case ABE_BOTTOM:
|
||||
rc.top = rc.bottom - m_cyHeight;
|
||||
break;
|
||||
case ABE_LEFT:
|
||||
rc.right = rc.left + m_cxWidth;
|
||||
break;
|
||||
case ABE_RIGHT:
|
||||
rc.left = rc.right - m_cxWidth;
|
||||
break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
APPBARDATA abd = { sizeof(abd) };
|
||||
@@ -680,6 +688,7 @@ protected:
|
||||
AppBar_Register(hwnd);
|
||||
AppBar_SetSide(hwnd, ABE_TOP);
|
||||
|
||||
DPRINT1("OnCreate(%p) done\n", hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -975,6 +984,9 @@ public:
|
||||
RECT rc1, rc2, rcWork;
|
||||
DWORD dwTID = GetWindowThreadProcessId(s_hwnd1, NULL);
|
||||
|
||||
DPRINT1("DoAction\n");
|
||||
Sleep(INTERVAL);
|
||||
|
||||
GetWindowRect(s_hwnd1, &rc1);
|
||||
GetWindowRect(s_hwnd2, &rc2);
|
||||
GetWorkArea(&rcWork);
|
||||
@@ -990,7 +1002,7 @@ public:
|
||||
ok_long(rcWork.top, s_rcWorkArea.top + 110);
|
||||
ok_long(rcWork.right, s_rcWorkArea.right);
|
||||
ok_long(rcWork.bottom, s_rcWorkArea.bottom);
|
||||
PostMessage(s_hwnd1, WM_CLOSE, 0, 0);
|
||||
PostMessageW(s_hwnd1, WM_CLOSE, 0, 0);
|
||||
Sleep(INTERVAL);
|
||||
|
||||
GetWindowRect(s_hwnd2, &rc2);
|
||||
@@ -1101,7 +1113,7 @@ public:
|
||||
ok_long(rcWork.right, s_rcWorkArea.right);
|
||||
ok_long(rcWork.bottom, s_rcWorkArea.bottom);
|
||||
|
||||
PostMessage(s_hwnd2, WM_QUIT, 0, 0);
|
||||
PostMessageW(s_hwnd2, WM_QUIT, 0, 0);
|
||||
PostThreadMessage(dwTID, WM_QUIT, 0, 0);
|
||||
#undef INTERVAL
|
||||
}
|
||||
@@ -1124,7 +1136,16 @@ START_TEST(SHAppBarMessage)
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINT1("SM_CMONITORS: %d\n", GetSystemMetrics(SM_CMONITORS));
|
||||
if (GetSystemMetrics(SM_CMONITORS) != 1)
|
||||
{
|
||||
skip("Multi-monitor not supported yet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &s_rcWorkArea, FALSE);
|
||||
DPRINT1("s_rcWorkArea: %d, %d, %d, %d\n",
|
||||
s_rcWorkArea.left, s_rcWorkArea.top, s_rcWorkArea.right, s_rcWorkArea.bottom);
|
||||
|
||||
HWND hwnd1 = Window::DoCreateMainWnd(hInstance, TEXT("Test1"), 80, 80,
|
||||
WS_POPUP | WS_THICKFRAME | WS_CLIPCHILDREN);
|
||||
@@ -1145,7 +1166,7 @@ START_TEST(SHAppBarMessage)
|
||||
s_hwnd1 = hwnd1;
|
||||
s_hwnd2 = hwnd2;
|
||||
|
||||
PostMessage(hwnd1, WM_COMMAND, ID_ACTION, 0);
|
||||
PostMessageW(hwnd1, WM_COMMAND, ID_ACTION, 0);
|
||||
|
||||
Window::DoMainLoop();
|
||||
}
|
||||
|
@@ -494,7 +494,12 @@ FindExecutableW(
|
||||
_In_opt_ LPCWSTR lpDirectory,
|
||||
_Out_writes_(MAX_PATH) LPWSTR lpResult);
|
||||
|
||||
UINT_PTR WINAPI SHAppBarMessage(_In_ DWORD, _Inout_ PAPPBARDATA);
|
||||
UINT_PTR
|
||||
WINAPI
|
||||
SHAppBarMessage(
|
||||
_In_ DWORD dwMessage,
|
||||
_Inout_ PAPPBARDATA pData);
|
||||
|
||||
BOOL WINAPI Shell_NotifyIconA(_In_ DWORD, _In_ PNOTIFYICONDATAA);
|
||||
BOOL WINAPI Shell_NotifyIconW(_In_ DWORD, _In_ PNOTIFYICONDATAW);
|
||||
|
||||
|
@@ -1,23 +1,14 @@
|
||||
/*
|
||||
* Copyright 1999, 2000 Juergen Schmied
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* PROJECT: ReactOS Shell
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Undocumented shell definitions
|
||||
* COPYRIGHT: Copyright 1999, 2000 Juergen Schmied
|
||||
* Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#ifndef __WINE_UNDOCSHELL_H
|
||||
#define __WINE_UNDOCSHELL_H
|
||||
#pragma once
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#ifndef SHSTDAPI
|
||||
#if defined(_SHELL32_) /* DECLSPEC_IMPORT disabled because of CORE-6504: */ || TRUE
|
||||
@@ -1231,8 +1222,33 @@ typedef struct SFVM_CUSTOMVIEWINFO_DATA
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
/*
|
||||
* Private structures for internal AppBar messaging.
|
||||
* These structures can be sent from 32-bit shell32 to 64-bit Explorer.
|
||||
* See also: https://learn.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
|
||||
* > ... only the lower 32 bits are significant, so it is safe to truncate the handle
|
||||
*/
|
||||
#include <pshpack8.h>
|
||||
typedef struct tagAPPBARDATA3264
|
||||
{
|
||||
DWORD cbSize; /* == sizeof(APPBARDATA3264) */
|
||||
UINT32 hWnd32;
|
||||
UINT uCallbackMessage;
|
||||
UINT uEdge;
|
||||
RECT rc;
|
||||
LONGLONG lParam64;
|
||||
} APPBARDATA3264, *PAPPBARDATA3264;
|
||||
typedef struct tagAPPBAR_COMMAND
|
||||
{
|
||||
APPBARDATA3264 abd;
|
||||
DWORD dwMessage;
|
||||
UINT32 hOutput32; /* For shlwapi!SHAllocShared */
|
||||
DWORD dwProcessId;
|
||||
} APPBAR_COMMAND, *PAPPBAR_COMMAND;
|
||||
#include <poppack.h>
|
||||
|
||||
C_ASSERT(sizeof(APPBAR_COMMAND) == 0x38);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* __WINE_UNDOCSHELL_H */
|
||||
|
@@ -406,7 +406,7 @@ LdrProcessRelocationBlockLongLong(
|
||||
{
|
||||
Offset = SWAPW(*TypeOffset) & 0xFFF;
|
||||
Type = SWAPW(*TypeOffset) >> 12;
|
||||
ShortPtr = (PUSHORT)(RVA(Address, Offset));
|
||||
ShortPtr = (PUSHORT)RVA(Address, Offset);
|
||||
/*
|
||||
* Don't relocate within the relocation section itself.
|
||||
* GCC/LD generates sometimes relocation records for the relocation section.
|
||||
@@ -415,12 +415,12 @@ LdrProcessRelocationBlockLongLong(
|
||||
*/
|
||||
/*
|
||||
if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
|
||||
(ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
|
||||
(ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
|
||||
{*/
|
||||
switch (Type)
|
||||
{
|
||||
/* case IMAGE_REL_BASED_SECTION : */
|
||||
/* case IMAGE_REL_BASED_REL32 : */
|
||||
/* case IMAGE_REL_BASED_SECTION: */
|
||||
/* case IMAGE_REL_BASED_REL32: */
|
||||
case IMAGE_REL_BASED_ABSOLUTE:
|
||||
break;
|
||||
|
||||
@@ -490,7 +490,6 @@ LdrRelocateImageWithBias(
|
||||
UNREFERENCED_PARAMETER(LoaderName);
|
||||
|
||||
NtHeaders = RtlImageNtHeader(BaseAddress);
|
||||
|
||||
if (NtHeaders == NULL)
|
||||
return Invalid;
|
||||
|
||||
@@ -511,17 +510,16 @@ LdrRelocateImageWithBias(
|
||||
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
|
||||
|
||||
while (RelocationDir < RelocationEnd &&
|
||||
SWAPW(RelocationDir->SizeOfBlock) > 0)
|
||||
SWAPW(RelocationDir->SizeOfBlock) > 0)
|
||||
{
|
||||
Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||
Address = (ULONG_PTR)RVA(BaseAddress, SWAPD(RelocationDir->VirtualAddress));
|
||||
TypeOffset = (PUSHORT)(RelocationDir + 1);
|
||||
|
||||
RelocationDir = LdrProcessRelocationBlockLongLong(Address,
|
||||
Count,
|
||||
TypeOffset,
|
||||
Delta);
|
||||
|
||||
Count,
|
||||
TypeOffset,
|
||||
Delta);
|
||||
if (RelocationDir == NULL)
|
||||
{
|
||||
DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
|
||||
|
@@ -4,83 +4,596 @@
|
||||
#include <typedefs.h>
|
||||
#include <pecoff.h>
|
||||
|
||||
static
|
||||
void
|
||||
Usage(void)
|
||||
{
|
||||
printf("Converts a coff object file into a raw binary file.\n"
|
||||
"Syntax: obj2bin <source file> <dest file> <base address>\n");
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
RelocateSection(
|
||||
char *pData,
|
||||
IMAGE_SECTION_HEADER *pSectionHeader,
|
||||
PIMAGE_SYMBOL pSymbols,
|
||||
unsigned int iOffset)
|
||||
#if 0
|
||||
#ifdef ASSERT
|
||||
#undef ASSERT
|
||||
#define ASSERT(x) \
|
||||
do { if (!(x)) { fprintf(stderr, "Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__); exit(-1);} } while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned __int64 ULONGLONG, *PULONGLONG;
|
||||
|
||||
typedef union _IMAGE_OPTIONAL_HEADER_PTR_3264
|
||||
{
|
||||
unsigned int i, nOffset;
|
||||
PIMAGE_OPTIONAL_HEADER32 p32;
|
||||
PIMAGE_OPTIONAL_HEADER64 p64;
|
||||
PVOID pHdr;
|
||||
} IMAGE_OPTIONAL_HEADER_PTR_3264, *PIMAGE_OPTIONAL_HEADER_PTR_3264;
|
||||
|
||||
#ifdef _PPC_
|
||||
#define SWAPD(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
|
||||
#define SWAPW(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
|
||||
#define SWAPQ(x) ((SWAPD((x)&0xffffffff) << 32) | (SWAPD((x)>>32)))
|
||||
#else
|
||||
#define SWAPD(x) (x)
|
||||
#define SWAPW(x) (x)
|
||||
#define SWAPQ(x) (x)
|
||||
#endif
|
||||
|
||||
#define ROUND_DOWN(n, align) \
|
||||
(((ULONG_PTR)(n)) & ~((align) - 1l))
|
||||
|
||||
#define ROUND_UP(n, align) \
|
||||
ROUND_DOWN(((ULONG_PTR)(n)) + (align) - 1, (align))
|
||||
|
||||
#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
|
||||
|
||||
#define IMAGE_REL_BASED_ABSOLUTE 0
|
||||
#define IMAGE_REL_BASED_HIGH 1
|
||||
#define IMAGE_REL_BASED_LOW 2
|
||||
#define IMAGE_REL_BASED_HIGHLOW 3
|
||||
#define IMAGE_REL_BASED_HIGHADJ 4
|
||||
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
|
||||
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
|
||||
#define IMAGE_REL_BASED_IA64_IMM64 9
|
||||
#define IMAGE_REL_BASED_DIR64 10
|
||||
|
||||
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
|
||||
|
||||
|
||||
/* Relocation for OBJ files only */
|
||||
static BOOLEAN
|
||||
ObjRelocateSection(
|
||||
IN OUT PVOID pData,
|
||||
IN PIMAGE_SECTION_HEADER pSection,
|
||||
IN PIMAGE_SYMBOL pSymbols,
|
||||
IN ULONG iOffset)
|
||||
{
|
||||
ULONG i, nOffset;
|
||||
PVOID pSectionData;
|
||||
PIMAGE_RELOCATION pReloc;
|
||||
char *pSection;
|
||||
WORD *p16;
|
||||
DWORD *p32;
|
||||
PUSHORT p16;
|
||||
PULONG p32;
|
||||
|
||||
pSection = pData + pSectionHeader->PointerToRawData;
|
||||
|
||||
/* Calculate pointer to relocation table */
|
||||
pReloc = (PIMAGE_RELOCATION)(pData + pSectionHeader->PointerToRelocations);
|
||||
/* Calculate pointers to section and relocation table */
|
||||
pSectionData = RVA(pData, pSection->PointerToRawData);
|
||||
|
||||
/* Loop all relocations */
|
||||
for (i = 0; i < pSectionHeader->NumberOfRelocations; i++)
|
||||
pReloc = (PIMAGE_RELOCATION)RVA(pData, pSection->PointerToRelocations);
|
||||
for (i = 0; i < pSection->NumberOfRelocations; ++i, ++pReloc)
|
||||
{
|
||||
nOffset = pReloc->VirtualAddress - pSectionHeader->VirtualAddress;
|
||||
nOffset = pReloc->VirtualAddress - pSection->VirtualAddress;
|
||||
|
||||
if (nOffset > pSectionHeader->SizeOfRawData) continue;
|
||||
if (nOffset > pSection->SizeOfRawData) continue;
|
||||
|
||||
switch (pReloc->Type)
|
||||
{
|
||||
/* case IMAGE_REL_BASED_ABSOLUTE: */
|
||||
case IMAGE_REL_I386_ABSOLUTE:
|
||||
case 16:
|
||||
p16 = (void*)(pSection + nOffset);
|
||||
*p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
|
||||
// case IMAGE_REL_AMD64_ABSOLUTE:
|
||||
case 16: /* gas-type relocation */
|
||||
p16 = (PUSHORT)RVA(pSectionData, nOffset);
|
||||
*p16 += (USHORT)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_I386_REL16:
|
||||
p16 = (void*)(pSection + nOffset);
|
||||
*p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
|
||||
p16 = (PUSHORT)RVA(pSectionData, nOffset);
|
||||
*p16 += (USHORT)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_I386_DIR32:
|
||||
p32 = (void*)(pSection + nOffset);
|
||||
*p32 += (DWORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
|
||||
p32 = (PULONG)RVA(pSectionData, nOffset);
|
||||
*p32 += (ULONG)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown relocation type %u, address 0x%x\n",
|
||||
pReloc->Type, (unsigned)pReloc->VirtualAddress);
|
||||
return 0;
|
||||
fprintf(stderr, "Unknown relocation type %u, address 0x%x\n",
|
||||
pReloc->Type, (ULONG_PTR)pReloc->VirtualAddress);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pReloc++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
ProcessOBJFile(
|
||||
IN OUT PVOID pData,
|
||||
IN PIMAGE_FILE_HEADER pFileHeader,
|
||||
IN PCSTR pszSectionName OPTIONAL,
|
||||
IN ULONG nBaseAddress,
|
||||
IN FILE* pDestFile)
|
||||
{
|
||||
PIMAGE_SECTION_HEADER pSection;
|
||||
PIMAGE_SYMBOL pSymbols;
|
||||
ULONG i;
|
||||
|
||||
/* Default to '.text' section if none has been specified by the user */
|
||||
if (!pszSectionName)
|
||||
pszSectionName = ".text";
|
||||
|
||||
/* Calculate table pointers */
|
||||
pSymbols = RVA(pData, pFileHeader->PointerToSymbolTable);
|
||||
|
||||
/* Loop all sections */
|
||||
pSection = RVA(pFileHeader + 1, pFileHeader->SizeOfOptionalHeader);
|
||||
for (i = 0; i < pFileHeader->NumberOfSections; ++i, ++pSection)
|
||||
{
|
||||
/* Check if this is the '.text' section */
|
||||
if ((strcmp((char*)pSection->Name, pszSectionName) == 0) &&
|
||||
(pSection->SizeOfRawData != 0))
|
||||
{
|
||||
if (!ObjRelocateSection(pData,
|
||||
pSection,
|
||||
pSymbols,
|
||||
nBaseAddress))
|
||||
{
|
||||
fprintf(stderr, "Failed to process relocations for section '%s'\n",
|
||||
(char*)pSection->Name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Write the section to the destination file */
|
||||
if (!fwrite(RVA(pData, pSection->PointerToRawData),
|
||||
pSection->SizeOfRawData, 1, pDestFile))
|
||||
{
|
||||
fprintf(stderr, "Failed to write %u bytes to destination file\n",
|
||||
(unsigned int)pSection->SizeOfRawData);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nBaseAddress += pSection->SizeOfRawData;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Relocation for PE images only */
|
||||
static PIMAGE_BASE_RELOCATION
|
||||
LdrProcessRelocationBlockLongLong(
|
||||
IN ULONG_PTR Address,
|
||||
IN ULONG Count,
|
||||
IN PUSHORT TypeOffset,
|
||||
IN LONGLONG Delta)
|
||||
{
|
||||
SHORT Offset;
|
||||
USHORT Type;
|
||||
ULONG i;
|
||||
PUSHORT ShortPtr;
|
||||
PULONG LongPtr;
|
||||
PULONGLONG LongLongPtr;
|
||||
|
||||
for (i = 0; i < Count; ++i, ++TypeOffset)
|
||||
{
|
||||
Offset = SWAPW(*TypeOffset) & 0xFFF;
|
||||
Type = SWAPW(*TypeOffset) >> 12;
|
||||
ShortPtr = (PUSHORT)RVA(Address, Offset);
|
||||
/*
|
||||
* Don't relocate within the relocation section itself.
|
||||
* GCC/LD generates sometimes relocation records for the relocation section.
|
||||
* This is a bug in GCC/LD.
|
||||
* Fix for it disabled, since it was only in ntoskrnl and not in ntdll
|
||||
*/
|
||||
/*
|
||||
if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
|
||||
(ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
|
||||
{*/
|
||||
switch (Type)
|
||||
{
|
||||
/* case IMAGE_REL_BASED_SECTION: */
|
||||
/* case IMAGE_REL_BASED_REL32: */
|
||||
case IMAGE_REL_BASED_ABSOLUTE:
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGH:
|
||||
*ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (Delta & 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_LOW:
|
||||
*ShortPtr = SWAPW(*ShortPtr) + LOWORD(Delta & 0xFFFF);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
LongPtr = (PULONG)RVA(Address, Offset);
|
||||
*LongPtr = SWAPD(*LongPtr) + (Delta & 0xFFFFFFFF);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_DIR64:
|
||||
LongLongPtr = (/*PUINT64*/PULONGLONG)RVA(Address, Offset);
|
||||
*LongLongPtr = SWAPQ(*LongLongPtr) + Delta;
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHADJ:
|
||||
case IMAGE_REL_BASED_MIPS_JMPADDR:
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Unknown/unsupported fixup type %hu.\n"
|
||||
"Address %p, Current %u, Count %u, *TypeOffset %x\n",
|
||||
Type, (PVOID)Address, i, Count, SWAPW(*TypeOffset));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (PIMAGE_BASE_RELOCATION)TypeOffset;
|
||||
}
|
||||
|
||||
static ULONG
|
||||
LdrRelocateImage(
|
||||
IN PVOID BaseAddress,
|
||||
IN PIMAGE_NT_HEADERS NtHeaders,
|
||||
IN LONGLONG AdditionalBias,
|
||||
IN ULONG Success,
|
||||
IN ULONG Conflict,
|
||||
IN ULONG Invalid)
|
||||
{
|
||||
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
||||
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||
ULONG Count;
|
||||
ULONG_PTR Address;
|
||||
PUSHORT TypeOffset;
|
||||
LONGLONG Delta;
|
||||
|
||||
if (SWAPW(NtHeaders->FileHeader.Characteristics) & IMAGE_FILE_RELOCS_STRIPPED)
|
||||
{
|
||||
return Conflict;
|
||||
}
|
||||
|
||||
RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
|
||||
if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
|
||||
{
|
||||
return Success;
|
||||
}
|
||||
|
||||
Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
|
||||
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
|
||||
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
|
||||
|
||||
while (RelocationDir < RelocationEnd &&
|
||||
SWAPW(RelocationDir->SizeOfBlock) > 0)
|
||||
{
|
||||
Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||
Address = (ULONG_PTR)RVA(BaseAddress, SWAPD(RelocationDir->VirtualAddress));
|
||||
TypeOffset = (PUSHORT)(RelocationDir + 1);
|
||||
|
||||
RelocationDir = LdrProcessRelocationBlockLongLong(Address,
|
||||
Count,
|
||||
TypeOffset,
|
||||
Delta);
|
||||
if (RelocationDir == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error during call to LdrProcessRelocationBlockLongLong()!\n");
|
||||
return Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
ParsePEImage(
|
||||
IN PVOID pData,
|
||||
IN ULONG nFileSize,
|
||||
OUT PIMAGE_NT_HEADERS* pNtHeaders,
|
||||
OUT PIMAGE_FILE_HEADER* pFileHeader)
|
||||
{
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pData;
|
||||
IMAGE_OPTIONAL_HEADER_PTR_3264 OptHeader;
|
||||
ULONG NtHeaderOffset;
|
||||
ULONG TotalHeadersSize = 0;
|
||||
|
||||
/* Ensure it's a PE image */
|
||||
if (!(nFileSize >= sizeof(IMAGE_DOS_HEADER) && pDosHeader->e_magic == IMAGE_DOS_SIGNATURE))
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "Not a valid PE image!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the offset to the NT headers */
|
||||
NtHeaderOffset = pDosHeader->e_lfanew;
|
||||
|
||||
/* Make sure the file header fits into the size */
|
||||
TotalHeadersSize += NtHeaderOffset +
|
||||
FIELD_OFFSET(IMAGE_NT_HEADERS, FileHeader) + (sizeof(((IMAGE_NT_HEADERS *)0)->FileHeader));
|
||||
if (TotalHeadersSize >= nFileSize)
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "NT headers beyond image size!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now get a pointer to the NT Headers */
|
||||
*pNtHeaders = (PIMAGE_NT_HEADERS)RVA(pData, NtHeaderOffset);
|
||||
|
||||
/* Verify the PE Signature */
|
||||
if ((*pNtHeaders)->Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "Invalid image NT signature!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ensure this is an executable image */
|
||||
if (((*pNtHeaders)->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "Invalid executable image!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the COFF header */
|
||||
*pFileHeader = &(*pNtHeaders)->FileHeader;
|
||||
|
||||
/* Check for the presence of the optional header */
|
||||
if ((*pFileHeader)->SizeOfOptionalHeader == 0)
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "Unsupported PE image (no optional header)!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Make sure the optional file header fits into the size */
|
||||
TotalHeadersSize += (*pFileHeader)->SizeOfOptionalHeader;
|
||||
if (TotalHeadersSize >= nFileSize)
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "NT optional header beyond image size!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Retrieve the optional header and be sure that its size corresponds to its signature */
|
||||
OptHeader.pHdr = (PVOID)(*pFileHeader + 1);
|
||||
if (!((*pFileHeader)->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32) &&
|
||||
OptHeader.p32->Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) &&
|
||||
!((*pFileHeader)->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64) &&
|
||||
OptHeader.p64->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) )
|
||||
{
|
||||
/* Fail */
|
||||
fprintf(stderr, "Invalid or unrecognized NT optional header!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
ProcessPEImage(
|
||||
IN OUT PVOID pData,
|
||||
IN PIMAGE_NT_HEADERS pNtHeaders,
|
||||
IN PIMAGE_FILE_HEADER pFileHeader,
|
||||
IN PCSTR pszSectionName OPTIONAL,
|
||||
IN ULONG nBaseAddress,
|
||||
IN FILE* pDestFile)
|
||||
{
|
||||
PVOID pImage;
|
||||
IMAGE_OPTIONAL_HEADER_PTR_3264 OptHeader;
|
||||
PIMAGE_SECTION_HEADER pSection;
|
||||
ULONG SizeOfImage, SizeOfHeaders, SectionAlignment;
|
||||
ULONG SectionSize, RawSize;
|
||||
ULONG FirstSectionVA, EndOfImage;
|
||||
ULONG i;
|
||||
BOOLEAN Success = FALSE; // Assume failure.
|
||||
|
||||
/* Be sure the user didn't pass inconsistent information */
|
||||
ASSERT(&pNtHeaders->FileHeader == pFileHeader);
|
||||
|
||||
/* Retrieve the optional header, its validity has been checked in ParsePEImage() */
|
||||
OptHeader.pHdr = (PVOID)(pFileHeader + 1);
|
||||
|
||||
/* Find the actual size of the image in memory, and the size of the headers in the file */
|
||||
if (OptHeader.p32->Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
SizeOfImage = OptHeader.p32->SizeOfImage;
|
||||
SizeOfHeaders = OptHeader.p32->SizeOfHeaders;
|
||||
SectionAlignment = OptHeader.p32->SectionAlignment;
|
||||
}
|
||||
else if (OptHeader.p64->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
||||
{
|
||||
SizeOfImage = OptHeader.p64->SizeOfImage;
|
||||
SizeOfHeaders = OptHeader.p64->SizeOfHeaders;
|
||||
SectionAlignment = OptHeader.p64->SectionAlignment;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user specified a section, search for it,
|
||||
* and bail out early if it doesn't exist.
|
||||
*/
|
||||
if (pszSectionName)
|
||||
{
|
||||
pSection = RVA(pFileHeader + 1, pFileHeader->SizeOfOptionalHeader);
|
||||
for (i = 0; i < pFileHeader->NumberOfSections; ++i, ++pSection)
|
||||
{
|
||||
if (strcmp((char*)pSection->Name, pszSectionName) == 0)
|
||||
break; /* Found it */
|
||||
}
|
||||
if (i >= pFileHeader->NumberOfSections)
|
||||
{
|
||||
fprintf(stderr, "Section '%s' not found in the PE image.\n", pszSectionName);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are actually no sections in this image (strange...) just return early */
|
||||
if (pFileHeader->NumberOfSections == 0)
|
||||
{
|
||||
fprintf(stderr, "This PE image does not have any sections!\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Allocate memory for the binary memory-mapped image */
|
||||
pImage = malloc(SizeOfImage);
|
||||
if (!pImage)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate %lu bytes\n", SizeOfImage);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Iterate through the sections and load them. Find also which section actually starts first. */
|
||||
pSection = RVA(pFileHeader + 1, pFileHeader->SizeOfOptionalHeader);
|
||||
FirstSectionVA = ULONG_MAX;
|
||||
EndOfImage = 0;
|
||||
for (i = 0; i < pFileHeader->NumberOfSections; ++i, ++pSection)
|
||||
{
|
||||
//
|
||||
// TODO: Skip the .reloc and .debug sections.
|
||||
// Partially done later in this loop.
|
||||
//
|
||||
|
||||
/* Make sure that the section fits within the image */
|
||||
if ((pSection->VirtualAddress > SizeOfImage) ||
|
||||
(RVA(pImage, pSection->VirtualAddress) < pImage))
|
||||
{
|
||||
fprintf(stderr, "Section '%s' outside of the image.\n", (char*)pSection->Name);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Get the section virtual size and the raw size */
|
||||
SectionSize = pSection->Misc.VirtualSize;
|
||||
RawSize = pSection->SizeOfRawData;
|
||||
|
||||
/* Handle a case when VirtualSize equals 0 */
|
||||
if (SectionSize == 0)
|
||||
SectionSize = RawSize;
|
||||
|
||||
/* If PointerToRawData is 0, then force its size to be also 0 */
|
||||
if (pSection->PointerToRawData == 0)
|
||||
RawSize = 0;
|
||||
/* Truncate the loaded size to the VirtualSize extents */
|
||||
else if (RawSize > SectionSize)
|
||||
RawSize = SectionSize;
|
||||
|
||||
//
|
||||
// Partial TODO (see at the beginning of the loop):
|
||||
// Still reserve the size of the .reloc section, but it will really be
|
||||
// skipped only if it is at either the beginning or the end of the image.
|
||||
//
|
||||
if (strcmp((char*)pSection->Name, ".reloc") == 0)
|
||||
{
|
||||
/* Keep its contents for now, but don't count it in the evaluation of the limits */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find the start and end of what we should copy later */
|
||||
if (!pszSectionName)
|
||||
{
|
||||
/* Start at the very first section and end at the very last one */
|
||||
FirstSectionVA = min(FirstSectionVA, pSection->VirtualAddress);
|
||||
EndOfImage = max(EndOfImage, pSection->VirtualAddress + SectionSize);
|
||||
}
|
||||
else if (strcmp((char*)pSection->Name, pszSectionName) == 0)
|
||||
{
|
||||
/* Start and end only at the boundaries of this section */
|
||||
FirstSectionVA = pSection->VirtualAddress;
|
||||
EndOfImage = pSection->VirtualAddress + SectionSize;
|
||||
}
|
||||
EndOfImage = ROUND_UP(EndOfImage, SectionAlignment);
|
||||
}
|
||||
|
||||
/* Actually read the section (if its size is not 0) */
|
||||
if (RawSize != 0)
|
||||
{
|
||||
/* Read this section from the file, size = SizeOfRawData */
|
||||
RtlCopyMemory(RVA(pImage, pSection->VirtualAddress),
|
||||
RVA(pData, pSection->PointerToRawData),
|
||||
RawSize);
|
||||
}
|
||||
|
||||
/* Size of data is less than the virtual size - fill up the remainder with zeroes */
|
||||
if (RawSize < SectionSize)
|
||||
{
|
||||
RtlZeroMemory(RVA(pImage, pSection->VirtualAddress + RawSize),
|
||||
SectionSize - RawSize);
|
||||
}
|
||||
}
|
||||
if ((FirstSectionVA == ULONG_MAX) || (EndOfImage == 0))
|
||||
{
|
||||
fprintf(stderr, "Failed to find any valid section?\n");
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
|
||||
/* Relocate the image */
|
||||
if (!(BOOLEAN)LdrRelocateImage(pImage,
|
||||
pNtHeaders,
|
||||
(ULONG_PTR)nBaseAddress
|
||||
- (ULONG_PTR)RVA(pImage, FirstSectionVA),
|
||||
TRUE,
|
||||
TRUE, /* In case of conflict still return success */
|
||||
FALSE))
|
||||
{
|
||||
fprintf(stderr, "Failed to relocate image!\n");
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the selected section, or all of them, to the destination file.
|
||||
* We therefore exclude all PE headers as wanted (we create a flat "PE" binary).
|
||||
*/
|
||||
SizeOfImage = EndOfImage - FirstSectionVA;
|
||||
if (!fwrite(RVA(pImage, FirstSectionVA), SizeOfImage, 1, pDestFile))
|
||||
{
|
||||
fprintf(stderr, "Failed to write %u bytes to destination file\n", SizeOfImage);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
Success = TRUE;
|
||||
|
||||
Quit:
|
||||
free(pImage);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Usage(void)
|
||||
{
|
||||
printf("Converts a COFF object file or a relocatable PE image into a RAW binary file.\n"
|
||||
"Syntax: obj2bin <source file> <dest file> <base address> [section name]\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int nErrorCode = 0;
|
||||
char *pszSourceFile;
|
||||
char *pszDestFile;
|
||||
char *pszSectionName;
|
||||
unsigned long nFileSize, nBaseAddress;
|
||||
FILE *pSourceFile, *pDestFile;
|
||||
IMAGE_FILE_HEADER *pFileHeader;
|
||||
IMAGE_SECTION_HEADER *pSectionHeader;
|
||||
unsigned int i;
|
||||
PIMAGE_DOS_HEADER pDosHeader;
|
||||
PIMAGE_NT_HEADERS pNtHeaders;
|
||||
PIMAGE_FILE_HEADER pFileHeader;
|
||||
char *pData;
|
||||
PIMAGE_SYMBOL pSymbols;
|
||||
|
||||
if ((argc != 4) || (strcmp(argv[1], "--help") == 0))
|
||||
if (!(argc == 4 || argc == 5) || (strcmp(argv[1], "--help") == 0))
|
||||
{
|
||||
Usage();
|
||||
return -1;
|
||||
@@ -89,6 +602,7 @@ int main(int argc, char *argv[])
|
||||
pszSourceFile = argv[1];
|
||||
pszDestFile = argv[2];
|
||||
nBaseAddress = strtol(argv[3], 0, 16);
|
||||
pszSectionName = ((argc == 5) ? argv[4] : NULL);
|
||||
|
||||
pSourceFile = fopen(pszSourceFile, "rb");
|
||||
if (!pSourceFile)
|
||||
@@ -120,7 +634,7 @@ int main(int argc, char *argv[])
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* Close source file */
|
||||
/* Close the source file */
|
||||
fclose(pSourceFile);
|
||||
|
||||
/* Open the destination file */
|
||||
@@ -132,47 +646,73 @@ int main(int argc, char *argv[])
|
||||
return -5;
|
||||
}
|
||||
|
||||
/* Calculate table pointers */
|
||||
pFileHeader = (IMAGE_FILE_HEADER*)pData;
|
||||
pSymbols = (void*)(pData + pFileHeader->PointerToSymbolTable);
|
||||
pSectionHeader = (void*)(((char*)(pFileHeader + 1)) + pFileHeader->SizeOfOptionalHeader);
|
||||
|
||||
/* Loop all sections */
|
||||
for (i = 0; i < pFileHeader->NumberOfSections; i++)
|
||||
/* Check whether this is a pure COFF file or a PE image */
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)pData;
|
||||
if (nFileSize >= sizeof(IMAGE_DOS_HEADER) && pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
/* Check if this is '.text' section */
|
||||
if ((strcmp((char*)pSectionHeader->Name, ".text") == 0) &&
|
||||
(pSectionHeader->SizeOfRawData != 0))
|
||||
/* This is a PE image, parse it */
|
||||
if (!ParsePEImage(pData, nFileSize, &pNtHeaders, &pFileHeader))
|
||||
{
|
||||
if (!RelocateSection(pData,
|
||||
pSectionHeader,
|
||||
pSymbols,
|
||||
nBaseAddress))
|
||||
{
|
||||
free(pData);
|
||||
fclose(pDestFile);
|
||||
return -7;
|
||||
}
|
||||
|
||||
/* Write the section to the destination file */
|
||||
if (!fwrite(pData + pSectionHeader->PointerToRawData,
|
||||
pSectionHeader->SizeOfRawData, 1, pDestFile))
|
||||
{
|
||||
free(pData);
|
||||
fclose(pDestFile);
|
||||
fprintf(stderr, "Failed to write %u bytes to destination file\n",
|
||||
(unsigned int)pSectionHeader->SizeOfRawData);
|
||||
return -6;
|
||||
}
|
||||
|
||||
nBaseAddress += pSectionHeader->SizeOfRawData;
|
||||
fprintf(stderr, "ParsePEImage() failed.\n");
|
||||
nErrorCode = -6;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
pSectionHeader++;
|
||||
}
|
||||
else if (nFileSize >= sizeof(IMAGE_FILE_HEADER) /* == IMAGE_SIZEOF_FILE_HEADER */)
|
||||
{
|
||||
/* Get the COFF header */
|
||||
pNtHeaders = NULL;
|
||||
pFileHeader = (PIMAGE_FILE_HEADER)pData;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unrecognized format!\n");
|
||||
nErrorCode = -6;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
free(pData);
|
||||
fclose(pDestFile);
|
||||
if (// pFileHeader->Machine != IMAGE_FILE_MACHINE_UNKNOWN &&
|
||||
pFileHeader->Machine != IMAGE_FILE_MACHINE_I386 &&
|
||||
pFileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
|
||||
{
|
||||
fprintf(stderr, "Unsupported machine type 0x%04x!\n", pFileHeader->Machine);
|
||||
nErrorCode = -7;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (pNtHeaders == NULL)
|
||||
{
|
||||
/* OBJ file - Default to '.text' section if none has been specified by the user */
|
||||
if (!ProcessOBJFile(pData,
|
||||
pFileHeader,
|
||||
(pszSectionName ? pszSectionName : ".text"),
|
||||
nBaseAddress,
|
||||
pDestFile))
|
||||
{
|
||||
fprintf(stderr, "ProcessOBJFile() failed.\n");
|
||||
nErrorCode = -8;
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PE image - Either extract only the section specified by the user, or all of them */
|
||||
if (!ProcessPEImage(pData,
|
||||
pNtHeaders,
|
||||
pFileHeader,
|
||||
pszSectionName,
|
||||
nBaseAddress,
|
||||
pDestFile))
|
||||
{
|
||||
fprintf(stderr, "ProcessPEImage() failed.\n");
|
||||
nErrorCode = -8;
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
|
||||
Quit:
|
||||
fclose(pDestFile);
|
||||
free(pData);
|
||||
|
||||
return nErrorCode;
|
||||
}
|
||||
|
Reference in New Issue
Block a user