diff --git a/dll/win32/uxtheme/CMakeLists.txt b/dll/win32/uxtheme/CMakeLists.txt index 3124014046b..92a6f0cb292 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}/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 00000000000..0426d212d3a --- /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 2014 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 d21d02c6c51..441e27c4cf9 100644 --- a/dll/win32/uxtheme/nonclient.c +++ b/dll/win32/uxtheme/nonclient.c @@ -1193,6 +1193,28 @@ DrawWindowForNCPreview( } } +VOID +SetWindowResourceText( + _In_ HWND hwnd, + _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(hDllInst, uID, (LPWSTR)&lpszResourceString, 0); + + if (lpszResourceString && ((lpszDestBuf = HeapAlloc(GetProcessHeap(), 0, (iStrSize + 1) * sizeof(WCHAR))) != NULL)) + { + wcsncpy(lpszDestBuf, lpszResourceString, iStrSize); + lpszDestBuf[iStrSize] = UNICODE_NULL; // NULL-terminate the string + + SetWindowTextW(hwnd, lpszDestBuf); + HeapFree(GetProcessHeap(), 0, lpszDestBuf); + } +} + HRESULT WINAPI DrawNCPreview(HDC hDC, DWORD DNCP_Flag, LPRECT prcPreview, @@ -1207,6 +1229,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 +1242,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", NULL, WS_OVERLAPPEDWINDOW | WS_VSCROLL, 30, 30, 300, 150, 0, 0, hDllInst, NULL); if (!hwndDummy) return E_FAIL; @@ -1247,12 +1271,12 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, /* Draw inactive preview window */ context.Active = FALSE; - SetWindowTextW(hwndDummy, L"Inactive Window"); + SetWindowResourceText(hwndDummy, IDS_INACTIVEWIN); 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"); + SetWindowResourceText(hwndDummy, IDS_ACTIVEWIN); DWORD textDrawFlags = DT_NOPREFIX | DT_SINGLELINE | DT_WORDBREAK; RECT rcWindowClient; @@ -1266,10 +1290,12 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, 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"); + SetWindowResourceText(hwndDummy, IDS_MESSAGEBOX); DWORD dwStyleNew = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME; SetWindowLongPtr(hwndDummy, GWL_STYLE, dwStyleNew); DWORD dwExStyleNew = WS_EX_DLGMODALFRAME; @@ -1306,12 +1332,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 00000000000..4c1fcde3131 --- /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 2014 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 00000000000..8ea019dfcc2 --- /dev/null +++ b/dll/win32/uxtheme/uxtheme.rc @@ -0,0 +1,24 @@ +/* + * 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 2014 Giannis Adamopoulos + * Copyright 2023 Ethan Rodensky + */ + +#include + +#include "resource.h" + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS uxtheme.dll" +#define REACTOS_STR_INTERNAL_NAME "uxtheme" +#define REACTOS_STR_ORIGINAL_FILENAME "uxtheme.dll" +#include + +/* UTF-8 */ +#pragma code_page(65001) + +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif diff --git a/dll/win32/uxtheme/uxthemep.h b/dll/win32/uxtheme/uxthemep.h index 6c8e62b8135..5a047d7fcdd 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 diff --git a/dll/win32/uxtheme/version.rc b/dll/win32/uxtheme/version.rc deleted file mode 100644 index fdeec0a0ab6..00000000000 --- a/dll/win32/uxtheme/version.rc +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2003 Kevin Koltzau - * - * 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 - */ - -#define WINE_FILENAME_STR "uxtheme.dll" - -#include