Flutter应用窗口如何在Win10/Win11系统始终固定显示于桌面?
Flutter Windows应用窗口固定到桌面实现方案
一、原生Win32代码修改(解决你修改win32_window.cpp未生效的问题)
直接修改Flutter Windows工程的windows/runner/win32_window.cpp文件,通过调整窗口父级、样式和消息拦截实现需求:
1. 修改窗口创建逻辑
找到CreateAndShow函数,替换窗口创建部分代码,将窗口绑定到桌面图标所在的Progman窗口,避免被Win+D最小化:
HWND Win32Window::CreateAndShow(const std::wstring& title, const Point& origin, const Size& size) { Destroy(); const wchar_t* window_class = L"FLUTTER_RUNNER_WIN32_WINDOW"; // 找到桌面图标容器窗口Progman HWND hProgMan = FindWindow(L"Progman", nullptr); HWND hParentWnd = hProgMan != nullptr ? hProgMan : GetDesktopWindow(); WNDCLASS window_class_struct{0}; window_class_struct.hInstance = GetModuleHandle(nullptr); window_class_struct.lpszClassName = window_class; window_class_struct.style = CS_HREDRAW | CS_VREDRAW; window_class_struct.hCursor = LoadCursor(nullptr, IDC_ARROW); window_class_struct.lpfnWndProc = WindowProc; RegisterClass(&window_class_struct); // 创建全屏无边框窗口,父级设为Progman hwnd_ = CreateWindowEx( WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW, // 不激活窗口、工具窗口样式 window_class, title.c_str(), WS_POPUP | WS_VISIBLE, // 无边框弹出窗口 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), // 全屏覆盖 hParentWnd, nullptr, GetModuleHandle(nullptr), this ); ShowWindow(hwnd_, SW_SHOW); return hwnd_; }
2. 拦截窗口消息,强制保持显示状态
找到WindowProc函数,添加消息拦截逻辑,阻止窗口被最小化或隐藏:
LRESULT CALLBACK Win32Window::WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // ... 保留原有代码 ... switch (msg) { // 拦截最小化命令,忽略Win+D触发的最小化 case WM_SYSCOMMAND: if ((wparam & 0xFFF0) == SC_MINIMIZE) { return 0; } break; // 强制窗口保持全屏和显示状态,防止被移动/隐藏 case WM_WINDOWPOSCHANGING: { WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lparam); wp->x = 0; wp->y = 0; wp->cx = GetSystemMetrics(SM_CXSCREEN); wp->cy = GetSystemMetrics(SM_CYSCREEN); wp->flags &= ~SWP_HIDEWINDOW; wp->flags |= SWP_SHOWWINDOW; return 0; } // ... 保留原有case逻辑 ... } return DefWindowProc(hwnd, msg, wparam, lparam); }
修改后重新编译Windows工程,窗口会嵌入桌面图标下方,Win+D等显示桌面操作不会影响它。
二、第三方库方案
如果不想修改原生代码,可以用以下Flutter插件简化实现:
1. win32插件(直接调用Win32 API)
在pubspec.yaml添加依赖:
dependencies: win32: ^5.0.0
在Dart代码中实现窗口绑定:
import 'package:win32/win32.dart'; import 'package:flutter/material.dart'; void fixWindowToDesktop() { // 获取当前Flutter窗口句柄 final hwnd = GetForegroundWindow(); // 找到Progman窗口 final hProgMan = FindWindow('Progman', nullptr); if (hProgMan != 0) { // 将窗口设为Progman的子窗口 SetParent(hwnd, hProgMan); // 设置全屏无边框样式 SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW); SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); // 强制窗口全屏显示 SetWindowPos( hwnd, HWND_BOTTOM, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_SHOWWINDOW ); } } void main() { runApp(const MyApp()); // 窗口初始化完成后执行绑定逻辑 WidgetsBinding.instance.addPostFrameCallback((_) { fixWindowToDesktop(); }); }
2. window_manager插件(窗口管理封装)
该插件提供窗口置顶、样式修改等功能,结合win32插件的父窗口绑定,可以快速实现需求。依赖添加:
dependencies: window_manager: ^0.3.0 win32: ^5.0.0
实现逻辑类似上述win32方案,通过window_manager设置窗口无边框,再用win32绑定到Progman窗口。
内容的提问来源于stack exchange,提问作者chenw
相关产品推荐
相关产品推荐

