You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:51:03