#include #include #include #include #include "flutter_window.h" #include "utils.h" #include // ✅ 为较旧的 Windows SDK 版本提供 DPI 感知常量定义 #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) #endif // 动态加载 SetProcessDpiAwarenessContext(Windows 10 v1607+) typedef BOOL(WINAPI* SetProcessDpiAwarenessContextFunc)(DPI_AWARENESS_CONTEXT); typedef HRESULT(WINAPI* SetProcessDpiAwarenessFunc)(PROCESS_DPI_AWARENESS); int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, _In_ wchar_t *command_line, _In_ int show_command) { // ✅ 关键修复:启用 PerMonitorV2 DPI 感知,确保高分辨率显示器上字体清晰 // 这必须在创建任何窗口之前调用 HMODULE user32 = LoadLibraryW(L"user32.dll"); if (user32) { auto set_dpi_aware_context = (SetProcessDpiAwarenessContextFunc)GetProcAddress( user32, "SetProcessDpiAwarenessContext"); if (set_dpi_aware_context) { set_dpi_aware_context(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); } FreeLibrary(user32); } // 备用方案:如果 SetProcessDpiAwarenessContext 不可用,尝试 SetProcessDpiAwareness (Vista+) HMODULE shcore = LoadLibraryW(L"shcore.dll"); if (shcore && !user32) { auto set_dpi_aware = (SetProcessDpiAwarenessFunc)GetProcAddress( shcore, "SetProcessDpiAwareness"); if (set_dpi_aware) { set_dpi_aware(PROCESS_PER_MONITOR_DPI_AWARE); } FreeLibrary(shcore); } // ✅ 删除此处权限检查: // 原因:manifest 中已配置 requireAdministrator,Windows 会自动检查权限 // 如果权限不足,系统会弹出 UAC 对话框 // 在此处重复检查会导致额外的系统命令执行和黑窗显示 // 权限检查已移到 Dart 端,延迟到应用完全加载后进行(2秒后) HANDLE hMutexInstance = CreateMutex(NULL, TRUE, L"HiFastVPNMutex"); HWND handle = FindWindowA(NULL, "HiFastVPN"); if (GetLastError() == ERROR_ALREADY_EXISTS) { flutter::DartProject project(L"data"); std::vector command_line_arguments = GetCommandLineArguments(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); FlutterWindow window(project); if (window.SendAppLinkToInstance(L"HiFastVPN")) { return false; } WINDOWPLACEMENT place = {sizeof(WINDOWPLACEMENT)}; GetWindowPlacement(handle, &place); ShowWindow(handle, SW_NORMAL); return 0; } // ✅ 改进:完全禁用控制台窗口 // AttachConsole 在某些情况下仍会显示控制台窗口导致黑屏 // BearVPN 是 GUI 应用,不需要控制台输出 // 日志通过 KRInitLogCollector 写入文件,无需控制台 // (已注释掉所有控制台相关代码) // Initialize COM, so that it is available for use in the library and/or // plugins. ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); flutter::DartProject project(L"data"); std::vector command_line_arguments = GetCommandLineArguments(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(375, 800); if (!window.Create(L"HiFastVPN", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true); ::MSG msg; while (::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } ::CoUninitialize(); ReleaseMutex(hMutexInstance); return EXIT_SUCCESS; }