From 03b1abfbb58b90755236c2663b9226bf9adf5b78 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 17 Feb 2024 10:29:50 +0800 Subject: [PATCH] Add native I18N for windows --- .github/workflows/windows.yml | 4 +++ pubspec.lock | 48 +++++++++++++++++++++++++------ windows/CMakeLists.txt | 2 +- windows/flutter/CMakeLists.txt | 7 ++++- windows/resources/resource.h | 5 ++-- windows/resources/resources.rc | 2 ++ windows/runner/flutter_window.cpp | 37 ++++++++++++++++++++---- 7 files changed, 88 insertions(+), 17 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 540482d..2440b5d 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -32,6 +32,10 @@ jobs: channel: stable - name: Build run: flutter build windows --release + - name: Setup msbuild + uses: microsoft/setup-msbuild@v2 + - name: Build resources + run: cd windows/resources && msbuild /p:Configuration=Release && COPY /Y "x64/Release/resources.dll" "../../build/windows/x64/runner/Release/resources.dll" - name: Package files run: cd build/windows/x64/runner/Release && 7z a -mx9 -y ../../../../../windows.7z - name: Upload files diff --git a/pubspec.lock b/pubspec.lock index 03f6443..9166e06 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -486,6 +486,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.92" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -514,26 +538,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -578,10 +602,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: @@ -987,6 +1011,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" watcher: dependency: transitive description: diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index c85dcc2..98e9e37 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -39,7 +39,7 @@ add_definitions(-DUNICODE -D_UNICODE) # of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /W4 /wd"4100") target_compile_options(${TARGET} PRIVATE /EHsc) target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt index 930d207..903f489 100644 --- a/windows/flutter/CMakeLists.txt +++ b/windows/flutter/CMakeLists.txt @@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake) # https://github.com/flutter/flutter/issues/57146. set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + # === Flutter Library === set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") @@ -92,7 +97,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ + ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS diff --git a/windows/resources/resource.h b/windows/resources/resource.h index 3a592c3..cc43d05 100644 --- a/windows/resources/resource.h +++ b/windows/resources/resource.h @@ -1,12 +1,13 @@ //{{NO_DEPENDENCIES}} -// Microsoft Visual C++ 生成的包含文件。 -// 供 resources.rc 使用 +// Microsoft Visual C++ 鐢熸垚鐨勫寘鍚枃浠躲 +// 渚 resources.rc 浣跨敤 // #define IDS_JPEG 101 #define IDS_PNG 102 #define IDS_GIF 103 #define IDR_VERSION2 103 #define IDS_ZIP 104 +#define IDS_ALL_FILES 105 // Next default values for new objects // diff --git a/windows/resources/resources.rc b/windows/resources/resources.rc index bd4a75d..078cb4c 100644 --- a/windows/resources/resources.rc +++ b/windows/resources/resources.rc @@ -94,6 +94,7 @@ BEGIN IDS_PNG "PNG 鏂囦欢" IDS_GIF "GIF 鏂囦欢" IDS_ZIP "ZIP 鏂囦欢" + IDS_ALL_FILES "鎵鏈夋枃浠" END #endif // 涓枃(绠浣擄紝涓浗) resources @@ -156,6 +157,7 @@ BEGIN IDS_PNG "PNG File" IDS_GIF "GIF File" IDS_ZIP "ZIP File" + IDS_ALL_FILES "All Files" END #endif // 鑻辫(缇庡浗) resources diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp index 1052259..1690fac 100644 --- a/windows/runner/flutter_window.cpp +++ b/windows/runner/flutter_window.cpp @@ -18,8 +18,30 @@ #include "fileop.h" #include "wchar_util.h" +#include "../resources/resource.h" + using namespace std; +static HMODULE resourceModule = NULL; +static bool resourceModuleTryLoad = false; + +wstring gettext(DWORD messageId, wstring text) { + if (!resourceModuleTryLoad) { + resourceModule = LoadLibraryExW(L"resources.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); + resourceModuleTryLoad = true; + } + if (resourceModule) { + LPWSTR buf; + DWORD len; + if (!(len = LoadStringW(resourceModule, messageId, (LPWSTR)&buf, 0))) { + return text; + } + wstring tmp(buf, len); + return tmp; + } + return text; +} + #define MAX_PATH_SIZE 32768 FlutterWindow::FlutterWindow(const flutter::DartProject& project) @@ -39,16 +61,20 @@ void filterDirname(std::string& dirName) { void updateDataFromMimeType(std::wstring& defExt, std::wstring& filter, std::string mimeType) { if (mimeType == "image/jpeg") { - filter.append(std::wstring(L"JPEG File(*.jpg)\0*.jpg\0", 23)); + filter.append(gettext(IDS_JPEG, L"JPEG File")); + filter.append(std::wstring(L"(*.jpg)\0*.jpg\0", 14)); defExt = L"jpg"; } else if (mimeType == "image/png") { - filter.append(std::wstring(L"PNG File(*.png)\0*.png\0", 22)); + filter.append(gettext(IDS_PNG, L"PNG File")); + filter.append(std::wstring(L"(*.png)\0*.png\0", 14)); defExt = L"png"; } else if (mimeType == "image/gif") { - filter.append(std::wstring(L"GIF File(*.gif)\0*.gif\0", 22)); + filter.append(gettext(IDS_GIF, L"GIF File")); + filter.append(std::wstring(L"(*.gif)\0*.gif\0", 14)); defExt = L"gif"; } else if (mimeType == "application/zip") { - filter.append(std::wstring(L"ZIP File(*.zip)\0*.zip\0", 22)); + filter.append(gettext(IDS_ZIP, L"ZIP File")); + filter.append(std::wstring(L"(*.zip)\0*.zip\0", 14)); defExt = L"zip"; } } @@ -137,7 +163,8 @@ bool FlutterWindow::OnCreate() { std::wstring filter; std::wstring defExt; updateDataFromMimeType(defExt, filter, *mimeType); - filter.append(std::wstring(L"All Files\0*.*\0\0", 15)); + filter.append(gettext(IDS_ALL_FILES, L"All Files")); + filter.append(std::wstring(L"\0*.*\0\0", 6)); ofn.lpstrFilter = filter.c_str(); ofn.lpstrDefExt = defExt.empty() ? nullptr : defExt.c_str(); wchar_t wFileNameBuf[MAX_PATH_SIZE];