Compare commits

...

10 Commits

Author SHA1 Message Date
Hermès Bélusca-Maïto
7cd78a81fb [OBJ2BIN] Code style only since here we can safely copy memory as the buffers do not overlap. 2025-04-28 21:26:58 +02:00
Hermès Bélusca-Maïto
32cacdd7c4 [OBJ2BIN] Add support for converting relocatable PE images to flat binaries.
- Use PE image relocation code adapted from rtl/image.c .

- Accepts an optional section name to be only converted, instead of
  the default '.text' section (for OBJ files), or all the sections
  (except '.reloc', for PE images).

- Add more validity checks for PE images.

- Possibility of supporting x64 PE images ??
2025-04-28 21:26:10 +02:00
Hermès Bélusca-Maïto
7dbc0e683b [RTL] Whitespace / minor code style fixes only. 2025-04-28 21:26:10 +02:00
Eric Kohl
dbc0c37750 [UMPNPMGR] Typo: Handle device interface removal events properly 2025-04-28 21:16:05 +02:00
Eric Kohl
bfa63932ce [MOUCLASS] Activate and deactivate the device interface for mouse devices 2025-04-28 21:14:20 +02:00
Hermès Bélusca-Maïto
5456e195db [EVENTVWR] Improve _some_ translations
- Add accelerators to the IDD_EVENTDETAILS_CTRL controls, in _some_
  translations but NOT all. Anyone is welcome to add the missing ones
  in the translations to their own language!

- Fix "Data" static text tab-ordering. It should be just before the
  IDC_EVENTDATAEDIT control, so that when pressing its accelerator,
  focus is given to the edit control and NOT on the Bytes/Words buttons.

- Change IDC_WORDRADIO -> IDC_WORDSRADIO
2025-04-28 18:02:45 +02:00
Hermès Bélusca-Maïto
87eac43fb9 [EVENTVWR] Improve details controls transition when updating events list
CORE-20021, CORE-20023, CORE-20037

Complements commits 1786a68256 (#7757) and d1aa59982d (#7921)

- When starting eventvwr, the details buttons are disabled and the fields
  are empty.

- During events enumeration, i.e. when refreshing the events list, the
  Previous/Next navigation arrow buttons are disabled. They get re-enabled
  once enumeration is done. No default event item is auto-selected at first.

- When the user selects an item, the details fields are filled (and the
  Copy button is enabled; the Byte/Word mode buttons are enabled only if
  the selected event has associated data).

- When changing the current filter via the TreeView, the events list is
  refreshed, but also the event details fields are emptied and buttons
  are disabled. The navigation arrows are re-enabled once enumeration is
  finished, but the details fields remain empty until an event is selected.

- Pressing the Previous/Next buttons just after the events list refresh
  (when no item is selected), automatically selects respectively the
  last/the first event in the list.
  The rationale for this behaviour is the following: in this situation,
  no item is selected, so it is as if the "current" item is at the same
  time, at the top and at the end (i.e. at the borders) of the list.

- Temporary HACK: When disabling the navigation arrows, this is usually
  because the events list is being refreshed, so we loose access to the
  event's data and we cannot use the bytes/words mode buttons anymore.
2025-04-28 17:53:16 +02:00
Hermès Bélusca-Maïto
fe6de816d6 [EVENTVWR] Update French (fr-FR) translation 2025-04-28 13:19:16 +02:00
Katayama Hirofumi MZ
f19c62c80e [EXPLORER][SHELL32][SHELL32_APITEST][SDK] AppBar: Initial support (#7778)
Supporting AppBars.
JIRA issue: CORE-7237
- Rewrite shell32!SHAppBarMessage
  function.
- Introduce CAppBarManager class in
  base/shell/explorer/appbar.cpp.
- Add support of ABM_NEW,
  ABM_REMOVE, ABM_QUERYPOS,
  and ABM_SETPOS messages for
  AppBar in Tray Window.
2025-04-28 19:08:13 +09:00
Whindmar Saksit
378a335468 [SHELL32] Don't pass menu band hwnd to InvokeCommand (#7945)
The menu band window is about to go away, don't pass it to InvokeCommand because it's invalid as an owner window for any dialogs the callee might display.
2025-04-28 00:24:15 +02:00
43 changed files with 1718 additions and 797 deletions

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View 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;
};

View File

@@ -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 :

View File

@@ -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
View 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)&copyData);
/* 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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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");

View File

@@ -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;
}