diff --git a/dll/win32/uxtheme/CMakeLists.txt b/dll/win32/uxtheme/CMakeLists.txt index 3124014046b7a..b95e8c85841f0 100644 --- a/dll/win32/uxtheme/CMakeLists.txt +++ b/dll/win32/uxtheme/CMakeLists.txt @@ -12,6 +12,7 @@ list(APPEND SOURCE ncscrollbar.c nonclient.c property.c + resource.h stylemap.c system.c themehooks.c @@ -26,9 +27,12 @@ if(DLL_EXPORT_VERSION GREATER_EQUAL 0x600) pngsup.cpp) endif() +file(GLOB uxtheme_rc_deps ${CMAKE_CURRENT_SOURCE_DIR}/version.rc ${CMAKE_CURRENT_SOURCE_DIR}/lang/*.rc) +add_rc_deps(uxtheme.rc ${uxtheme_rc_deps}) + add_library(uxtheme MODULE ${SOURCE} - version.rc + uxtheme.rc ${CMAKE_CURRENT_BINARY_DIR}/uxtheme.def) set_module_type(uxtheme win32dll) diff --git a/dll/win32/uxtheme/lang/en-US.rc b/dll/win32/uxtheme/lang/en-US.rc new file mode 100644 index 0000000000000..9daf142f2a986 --- /dev/null +++ b/dll/win32/uxtheme/lang/en-US.rc @@ -0,0 +1,20 @@ +/* + * PROJECT: ReactOS uxtheme.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: English (United States) resource file + * TRANSLATORS: Copyright 2011-2019 Giannis Adamopoulos + * Copyright 2023 Ethan Rodensky + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +/* Strings */ + +STRINGTABLE +BEGIN + IDS_MESSAGEBOX "Message Box" + IDS_ACTIVEWIN "Active Window" + IDS_INACTIVEWIN "Inactive Window" + IDS_OK "OK" + IDS_WINTEXT "Window Text" +END diff --git a/dll/win32/uxtheme/nonclient.c b/dll/win32/uxtheme/nonclient.c index 7ff8f46acfaf0..9118d91ed48b3 100644 --- a/dll/win32/uxtheme/nonclient.c +++ b/dll/win32/uxtheme/nonclient.c @@ -1193,6 +1193,27 @@ DrawWindowForNCPreview( } } +LPWSTR +LoadResourceString( + _In_ HINSTANCE hInstance, + _In_ UINT uID) +{ + LPWSTR lpszDestBuf = NULL, lpszResourceString = NULL; + size_t iStrSize = 0; + + // When passing a zero-length buffer size, LoadString(...) returns a + // read-only pointer buffer to the program's resource string. + iStrSize = LoadStringW(hInstance, uID, (LPWSTR)&lpszResourceString, 0); + + if (lpszResourceString && ((lpszDestBuf = HeapAlloc(GetProcessHeap(), 0, (iStrSize + 1) * sizeof(WCHAR))) != NULL)) + { + wcsncpy(lpszDestBuf, lpszResourceString, iStrSize); + lpszDestBuf[iStrSize] = L'\0'; // NULL-terminate the string + } + + return lpszDestBuf; +} + HRESULT WINAPI DrawNCPreview(HDC hDC, DWORD DNCP_Flag, LPRECT prcPreview, @@ -1207,6 +1228,8 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, HRESULT hres; HTHEMEFILE hThemeFile; DRAW_CONTEXT context; + LPWSTR szText; + int len; /* Create a dummy window that will be used to trick the paint funtions */ memset(&DummyPreviewWindowClass, 0, sizeof(DummyPreviewWindowClass)); @@ -1218,7 +1241,7 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, if (!RegisterClassExW(&DummyPreviewWindowClass)) return E_FAIL; - hwndDummy = CreateWindowExW(0, L"DummyPreviewWindowClass", L"Active window", WS_OVERLAPPEDWINDOW | WS_VSCROLL, 30, 30, 300, 150, 0, 0, hDllInst, NULL); + hwndDummy = CreateWindowExW(0, L"DummyPreviewWindowClass", L"", WS_OVERLAPPEDWINDOW | WS_VSCROLL, 30, 30, 300, 150, 0, 0, hDllInst, NULL); if (!hwndDummy) return E_FAIL; @@ -1247,12 +1270,22 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, /* Draw inactive preview window */ context.Active = FALSE; - SetWindowTextW(hwndDummy, L"Inactive Window"); + szText = LoadResourceString(hDllInst, IDS_INACTIVEWIN); + if (szText) + { + SetWindowTextW(hwndDummy, szText); + HeapFree(GetProcessHeap(), 0, szText); + } DrawWindowForNCPreview(hDC, &context, rcAdjPreview.left, rcAdjPreview.top, rcAdjPreview.right - 17, rcAdjPreview.bottom - 20, TRUE, NULL); /* Draw active preview window */ context.Active = TRUE; - SetWindowTextW(hwndDummy, L"Active Window"); + szText = LoadResourceString(hDllInst, IDS_ACTIVEWIN); + if (szText) + { + SetWindowTextW(hwndDummy, szText); + HeapFree(GetProcessHeap(), 0, szText); + } DWORD textDrawFlags = DT_NOPREFIX | DT_SINGLELINE | DT_WORDBREAK; RECT rcWindowClient; @@ -1265,12 +1298,18 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, if (textFont) SelectFont(hDC, textFont); - SetTextColor(hDC, GetThemeSysColor(context.theme, TMT_WINDOWTEXT)); - DrawThemeText(context.theme, hDC, WP_DIALOG, 0, L"Window Text", -1, DT_LEFT | DT_TOP | textDrawFlags, 0, &rcWindowClient); + len = LoadStringW(hDllInst, IDS_WINTEXT, (LPWSTR)&szText, 0); + if (len > 0) + DrawThemeText(context.theme, hDC, WP_DIALOG, 0, szText, len, DT_LEFT | DT_TOP | textDrawFlags, 0, &rcWindowClient); /* Draw preview dialog window */ - SetWindowTextW(hwndDummy, L"Message Box"); + szText = LoadResourceString(hDllInst, IDS_MESSAGEBOX); + if (szText) + { + SetWindowTextW(hwndDummy, szText); + HeapFree(GetProcessHeap(), 0, szText); + } DWORD dwStyleNew = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME; SetWindowLongPtr(hwndDummy, GWL_STYLE, dwStyleNew); DWORD dwExStyleNew = WS_EX_DLGMODALFRAME; @@ -1307,12 +1346,13 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, rcBtn.bottom -= btnContentMargins.cyBottomHeight; } - LPCWSTR btnText = L"OK"; LOGFONTW lfBtn; if ((GetThemeFont(hBtnTheme, hDC, btnPart, btnState, TMT_FONT, &lfBtn) != S_OK) && textFont) SelectFont(hDC, textFont); - DrawThemeText(hBtnTheme, hDC, btnPart, btnState, btnText, -1, DT_CENTER | DT_VCENTER | textDrawFlags, 0, &rcBtn); + len = LoadStringW(hDllInst, IDS_OK, (LPWSTR)&szText, 0); + if (len > 0) + DrawThemeText(hBtnTheme, hDC, btnPart, btnState, szText, len, DT_CENTER | DT_VCENTER | textDrawFlags, 0, &rcBtn); CloseThemeData(hBtnTheme); } diff --git a/dll/win32/uxtheme/resource.h b/dll/win32/uxtheme/resource.h new file mode 100644 index 0000000000000..15953420cd8ce --- /dev/null +++ b/dll/win32/uxtheme/resource.h @@ -0,0 +1,16 @@ +/* + * PROJECT: ReactOS uxtheme.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Main resource header file + * COPYRIGHT: Copyright 2011-2019 Giannis Adamopoulos + * Copyright 2023 Ethan Rodensky + */ + +#pragma once + +/* Resources */ +#define IDS_MESSAGEBOX 2000 +#define IDS_ACTIVEWIN 2001 +#define IDS_INACTIVEWIN 2002 +#define IDS_OK 2003 +#define IDS_WINTEXT 2004 diff --git a/dll/win32/uxtheme/uxtheme.rc b/dll/win32/uxtheme/uxtheme.rc new file mode 100644 index 0000000000000..e834de541034d --- /dev/null +++ b/dll/win32/uxtheme/uxtheme.rc @@ -0,0 +1,18 @@ +/* + * PROJECT: ReactOS uxtheme.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Main resource file + * COPYRIGHT: Copyright 2011-2019 Giannis Adamopoulos + * Copyright 2023 Ethan Rodensky + */ + +#include "resource.h" + +/* UTF-8 */ +#pragma code_page(65001) + +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif + +#include "version.rc" diff --git a/dll/win32/uxtheme/uxthemep.h b/dll/win32/uxtheme/uxthemep.h index 6c8e62b8135fe..5a047d7fcddb7 100644 --- a/dll/win32/uxtheme/uxthemep.h +++ b/dll/win32/uxtheme/uxthemep.h @@ -3,6 +3,8 @@ #include +#include "resource.h" + #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H