Flutter框架高阶——Window应用程序设置窗体窗口背景完全透明

文章目录

    • 1.修改 main.cpp
      • 1)C++ 与 Win32 API
      • 2)EnableTransparency()
      • 3)中文注释
    • 2.编写 Flutter 代码
      • 1)bitsdojo_window
      • 2)window_manager
      • 3)区别对比
      • 4)同时使用
        • (1)设置初始化代码
        • (2)处理冲突和集成

Flutter的文件结构如下,找到图中的main.cpp的文件
在这里插入图片描述

1.修改 main.cpp

main.cpp文件中的代码应该和下面差不多:

#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>#include "flutter_window.h"
#include "utils.h"int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,_In_ wchar_t *command_line, _In_ int show_command) {// Attach to console when present (e.g., 'flutter run') or create a// new console when running with a debugger.if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {CreateAndAttachConsole();}// 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<std::string> 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(1280, 720);if (!window.Create(L"untitled", origin, size)) {return EXIT_FAILURE;}window.SetQuitOnClose(true);::MSG msg;while (::GetMessage(&msg, nullptr, 0, 0)) {::TranslateMessage(&msg);::DispatchMessage(&msg);}::CoUninitialize();return EXIT_SUCCESS;
}

1)C++ 与 Win32 API

由上面的代码不难看出flutterwindow应用程序使用的是C++语言,通过 Win32 API 与 Windows 操作系统进行交互实现。所以让窗口变得透明,对窗口的背景颜色进行设置,并启用层叠窗口样式。就要在main.cpp文件中做一些更改:

  • 在创建窗口时,设置窗口的样式为层叠窗口。
  • 使用SetLayeredWindowAttributes函数设置窗口透明度。
#include <flutter/dart_project.h>
// 省略代码...
#include "utils.h"// 下面是新加的代码---------------------------------------------------------
#include<bitsdojo_window_windows/bitsdojo_window_plugin.h>
auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP);void EnableTransparency(HWND hwnd) {SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);COLORREF colorKey = RGB(255, 255, 255); BYTE alpha = 0;SetLayeredWindowAttributes(hwnd, colorKey, alpha, LWA_ALPHA);
} 
// 到这里结束---------------------------------------------------------------int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,                      _In_ wchar_t *command_line, _In_ int show_command) {// 省略代码...if (!window.Create(L"untitled", origin, size)) {return EXIT_FAILURE;}// 下面是新加的代码------------------------------------------------------EnableTransparency(window.GetHandle());     // 到这里结束-----------------------------------------------------------window.SetQuitOnClose(true);// 省略代码...return EXIT_SUCCESS;
}               

2)EnableTransparency()

// 启用透明度的函数
void EnableTransparency(HWND hwnd) {// 设置窗口样式为分层SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);// 设置透明色和alphaCOLORREF colorKey = RGB(255, 255, 255); // The color to make transparent// 透明程度:透明度水平(0 - 255,0完全透明,255完全不透明)BYTE alpha = 0;SetLayeredWindowAttributes(hwnd, colorKey, alpha, LWA_ALPHA);
}

EnableTransparency函数:这是一个新的函数,函数名随意,它接收窗口句柄作为参数,并设置窗口为层叠样式(WS_EX_LAYERED),然后通过SetLayeredWindowAttributes函数设置窗口的透明度。这里的透明度由alpha参数决定,取值范围是0到255,其中0表示完全透明,255表示完全不透明。

EnableTransparency(window.GetHandle());     

window.Create之后调用EnableTransparency:在创建窗口之后,我们调用EnableTransparency函数并传递窗口句柄,以使窗口透明。

GetHandle函数属于Win32Window类,它返回后台窗口句柄,使客户端能够设置图标和其他窗口属性。如果窗口已被销毁,则返回nullptr。

3)中文注释

使用Android Studiomain.cpp文件中使用中文注释容易报文件编码的错误,在文件中指定编码格式或者在编辑器中修改编码格式都能解决,不过不用中文注释应该是最简单直接的做法。

// 错误信息示例
P:\FlutterProject\flutter_clock-master\untitled\windows\runner\main.cpp(1,1): error C2220: 以下警告被视为错误 [P:\FlutterProject\flutter_clock-master\untitled\build\windows\x64\runner\untitled.vcxproj]
P:\FlutterProject\flutter_clock-master\untitled\windows\runner\main.cpp(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 [P:\FlutterProject\flutter_clock-master\untitled\build\windows\x64\runner\untitled.vcxproj]
Exception: Build process failed.

2.编写 Flutter 代码

网上有两个包bitsdojo_windowwindow_manager进行Flutterwindow应用程序编程,bitsdojo_windowwindow_manager 是两个用于 Flutter 桌面应用开发的包,咱们已经修改了main.cpp,只要在组件中设置背景即可,这两个包都能实现,下面列出bitsdojo_window的实现:

import 'package:flutter/material.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';void main() {runApp(const MyApp());doWhenWindowReady(() {appWindow.show();});
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(color: Colors.transparent,theme: ThemeData(// 设置窗口的背景颜色scaffoldBackgroundColor: Colors.transparent,),home: Container(color: Colors.transparent),);}
}

上面几乎把存在的组件都设置成了transparent,所以现在窗口的透明与否完全由组件说了算,两个包只要写一条让窗体显示的代码(如上面的 appWindow.show();)即可。既然提到这两个包,这里说明一下它们两个的区别:

1)bitsdojo_window

功能

  1. 自定义窗口边框:允许开发者自定义窗口的边框和标题栏,可以实现无边框窗口并完全控制窗口的外观和行为。
  2. 窗口拖动:提供简单的 API 用于实现自定义标题栏的拖动。
  3. 窗口按钮:允许自定义最小化、最大化和关闭按钮的行为。
  4. 窗口透明度:支持设置窗口的透明度。
  5. 多平台支持:支持 Windows、macOS 和 Linux。

典型用例

  • 需要高度自定义窗口外观和行为的应用。
  • 希望实现无边框窗口并自行处理窗口标题栏和按钮。

示例代码

import 'package:bitsdojo_window/bitsdojo_window.dart';void main() {runApp(MyApp());// Initialize bitsdojo_windowdoWhenWindowReady(() {final initialSize = Size(600, 450);appWindow.minSize = initialSize;appWindow.size = initialSize;appWindow.alignment = Alignment.center;appWindow.show();});
}

2)window_manager

功能

  1. 窗口管理:提供多种窗口管理功能,包括窗口最小化、最大化、恢复、隐藏、显示等。
  2. 窗口信息:可以获取窗口的位置、大小、标题等信息。
  3. 窗口事件:支持窗口的各种事件监听,如窗口关闭、聚焦、失焦等事件。
  4. 多平台支持:支持 Windows、macOS 和 Linux。

典型用例

  • 需要对窗口进行全面控制和管理的应用。
  • 需要监听窗口事件或获取窗口状态信息的应用。

示例代码

import 'package:window_manager/window_manager.dart';void main() async {WidgetsFlutterBinding.ensureInitialized();await windowManager.ensureInitialized();WindowOptions windowOptions = WindowOptions(size: Size(800, 600),center: true,title: 'My Flutter App',);windowManager.waitUntilReadyToShow(windowOptions, () async {await windowManager.show();await windowManager.focus();});runApp(MyApp());
}

3)区别对比

  • bitsdojo_window:侧重于窗口外观的高度自定义,特别是无边框窗口的实现和自定义窗口控制按钮。
  • window_manager:提供全面的窗口管理功能,适合需要对窗口进行各种操作和事件处理的应用。

选择哪个包取决于你的具体需求:如果你需要自定义窗口的外观和行为,bitsdojo_window 是一个很好的选择;如果你需要全面的窗口管理功能,window_manager 可能更适合你。

4)同时使用

当然有大聪明就想了,我都用可不可以呢?在同一个 Flutter 项目中同时使用 bitsdojo_windowwindow_manager 当然是可以的,但需要注意它们可能在某些功能上存在冲突或重叠,因此需要谨慎管理。方法如下,仅供参考:

(1)设置初始化代码

main.dart 文件中初始化 bitsdojo_windowwindow_manager,确保它们不互相干扰:

import 'package:flutter/material.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:window_manager/window_manager.dart';void main() async {WidgetsFlutterBinding.ensureInitialized();// Initialize window_managerawait windowManager.ensureInitialized();WindowOptions windowOptions = WindowOptions(size: Size(800, 600),center: true,title: 'My Flutter App',);windowManager.waitUntilReadyToShow(windowOptions, () async {await windowManager.show();await windowManager.focus();});runApp(MyApp());// Initialize bitsdojo_windowdoWhenWindowReady(() {final initialSize = Size(800, 600);appWindow.minSize = initialSize;appWindow.size = initialSize;appWindow.alignment = Alignment.center;appWindow.show();});
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: MyHomePage(),);}
}class MyHomePage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Flutter Demo Home Page'),),body: WindowBorder(color: Colors.black,width: 1,child: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text('You have pushed the button this many times:',),],),),),);}
}
(2)处理冲突和集成

在整合过程中,注意以下几点:

  1. 窗口初始化:确保 window_managerbitsdojo_window 的初始化代码不互相干扰。window_manager 用于窗口管理,bitsdojo_window 用于自定义窗口外观。
  2. 窗口事件:如果需要监听窗口事件,如最小化、最大化等,优先使用 window_manager 提供的事件处理机制。
  3. 自定义边框和按钮:使用 bitsdojo_window 自定义窗口边框和按钮时,确保这些自定义不会影响 window_manager 的功能。

以下是一个实现透明窗口并管理窗口事件的示例:

import 'package:flutter/material.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:window_manager/window_manager.dart';void main() async {WidgetsFlutterBinding.ensureInitialized();// Initialize window_managerawait windowManager.ensureInitialized();WindowOptions windowOptions = WindowOptions(size: Size(800, 600),center: true,title: 'My Flutter App',);windowManager.waitUntilReadyToShow(windowOptions, () async {await windowManager.show();await windowManager.focus();});runApp(MyApp());// Initialize bitsdojo_windowdoWhenWindowReady(() {final initialSize = Size(800, 600);appWindow.minSize = initialSize;appWindow.size = initialSize;appWindow.alignment = Alignment.center;// Set the window to be transparentappWindow.setEffect(effect: WindowEffect.transparent,color: Colors.transparent,);appWindow.show();});
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: MyHomePage(),);}
}class MyHomePage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Flutter Demo Home Page'),),body: WindowBorder(color: Colors.black,width: 1,child: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text('You have pushed the button this many times:',),],),),),);}
}

如果觉得文章写的不错,就随手点个赞再走吧!😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

winRar去广告记录

效果&#xff1a;双击winRar.exe&#xff0c;不会弹出广告窗口&#xff0c;但会弹出使用时间许可警告&#xff0c;效果不是很完美。 工具&#xff1a;everything.exe&#xff08;非必须&#xff09;、sublime text&#xff08;非必须&#xff09;、spyxx.exe&#xff08;非必须…

【Python】已解决:pymssql引发的MSSQLDatabaseException错误

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;pymssql引发的MSSQLDatabaseException错误 一、分析问题背景 在Python中使用pymssql库与Microsoft SQL Server数据库交互时&#xff0c;有时会遇到pymssql._mss…

系统安全设计规范(Word原件)

1.1安全建设原则 1.2 安全管理体系 1.3 安全管理规范 1.4 数据安全保障措施 1.4.1 数据库安全保障 1.4.2 操作系统安全保障 1.4.3 病毒防治 1.5安全保障措施 1.5.1实名认证保障 1.5.2 接口安全保障 1.5.3 加密传输保障 1.5.4终端安全保障 资料获取&#xff1a;私信或者进主页。…

Redis数据库的删除和安装

Redis数据库的删除和安装 1、删除Redis数据库2、下载Redis数据库 1、删除Redis数据库 没有下载过的&#xff0c;可以直接跳到下面的安装过程↓ 我们电脑中如果有下载过Redis数据库&#xff0c;要更换版本的话&#xff0c;其实Redis数据库的删除是比较简单的&#xff0c;打开我…

微型操作系统内核源码详解系列五(五):cm3下Pendsv切换任务上篇

系列一&#xff1a;微型操作系统内核源码详解系列一&#xff1a;rtos内核源码概论篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列二&#xff1a;微型操作系统内核源码详解系列二&#xff1a;数据结构和对象篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列…

Bilibili开源发布轻量级 Index 系列语言模型:2.8T 训练数据,支持角色扮演

Bilibili首次发布 Index 系列模型中的轻量版本&#xff1a;Index-1.9B 系列 本次开源的 Index-1.9B系列包含以下模型&#xff1a; Index-1.9Bbase:基座模型&#xff0c;具有 19 亿 非词嵌入参数量&#xff0c;在 2.8T 中英文为主的语料上预训练&#xff0c;多个评测基准上与…

已解决java.util.concurrent.BrokenBarrierException异常的正确解决方法,亲测有效!!!

已解决java.util.concurrent.BrokenBarrierException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 分析错误日志 检查线程中断 设置合理的等待时间 优化代码逻辑 使用同步…

[数据概念|方案实操]清华数据大讲堂5-数据要素化治理的理论方法与工程实践

“ 数据要素化是资产化的重要前提和实现路径” 鼹鼠哥公众号链接在 [数据概念|方案实操]清华数据大讲堂5-数据要素化治理的理论方法与工程实践 (qq.com) 2024年6月5日&#xff0c;清华数据大讲堂第五讲开讲。 中国电子信息产业集团副总 陆志鹏 以《数据要素化治理的理论方法与…

Adobe Photoshop图像处理软件下载安装,ps 2024版本安装包分享

Adobe Photoshop&#xff0c;这款业界闻名的图像处理软件&#xff0c;简称“PS”&#xff0c;以其强大的功能和广泛的应用领域&#xff0c;赢得了无数设计师、摄影师和创意工作者的青睐。 在Photoshop的世界里&#xff0c;用户能够随心所欲地对图像进行裁剪、缩放、调整色彩和…

视频共享融合赋能平台LntonCVS视频监控业务平台建设安全煤矿矿井应用方案

随着我国经济的飞速增长&#xff0c;煤炭作为主要的能源之一&#xff0c;在我国的能源结构中扮演着至关重要的角色。然而&#xff0c;煤矿事故的频繁发生&#xff0c;不仅造成了巨大的人员伤亡和财产损失&#xff0c;也对社会产生了深远的负面影响。因此&#xff0c;实现煤矿的…

程序员如何高效读代码?

程序员高效读代码的技巧包括以下几点&#xff1a; 明确阅读目的&#xff1a;在开始阅读代码之前&#xff0c;先明确你的阅读目的。是为了理解整个系统的架构&#xff1f;还是为了修复一个具体的bug&#xff1f;或者是为了了解某个功能是如何实现的&#xff1f;明确目的可以帮助…

国产自研编程语言“仓颉”来了!

在 6.21 召开的华为开发者大会&#xff08;HDC2024&#xff09;上,华为自研的国产编程语言“仓颉”终于对外正式发布了&#xff01; 随着万物互联以及智能时代的到来&#xff0c;软件的形态将发生巨大的变化。一方面&#xff0c;移动应用和移动互联网领域仍然强力驱动人机交互…

颠覆多跳事实验证!Causal Walk 前门调整技术引领去偏新纪元

Causal Walk: Debiasing Multi-Hop Fact Verifcation with Front-Door Adjustment 论文地址: Causal Walk: Debiasing Multi-Hop Fact Verification with Front-Door Adjustment| Proceedings of the AAAI Conference on Artificial Intelligencehttps://ojs.aaai.org/index.p…

ctfshow web其他 web450--web460

web450 <?phphighlight_file(__FILE__); $ctfshow$_GET[ctfshow];if(preg_match(/^[a-z][\^][a-z][\^][a-z]$/, $ctfshow)){ //小写字母^小写字母^小写字母eval("($ctfshow)();"); }?ctfshowphpinfo^phpinfo^phpinfoweb451 <?phphighlight_file(__FILE__…

【深度学习系列】全面指南:安装TensorFlow的CPU和GPU版本

本博客旨在为初学者提供一份全面的指南&#xff0c;介绍如何根据个人电脑的配置选择并安装适合的TensorFlow版本。内容涵盖了如何查看电脑显卡型号以确定是安装CPU还是GPU版本的TensorFlow&#xff0c;创建Python虚拟环境&#xff0c;以及使用conda命令查找可用的TensorFlow版本…

FPGA早鸟课程第二弹 | Vivado 设计静态时序分析和实际约束

在FPGA设计领域&#xff0c;时序约束和静态时序分析是提升系统性能和稳定性的关键。社区推出的「Vivado 设计静态时序分析和实际约束」课程&#xff0c;旨在帮助工程师们掌握先进的设计技术&#xff0c;优化设计流程&#xff0c;提高开发效率。 课程介绍 关于课程 权威认证&…

常用主流sip协议软电话客户端软件有哪些?—— 筑梦之路

Ekiga 官网地址&#xff1a;Ekiga ~ Free Your Speech Ekiga&#xff0c;原名GnomeMeeting&#xff0c;支持Windows和Linux&#xff0c;是一个兼容SIP和H.323的视频会议程序&#xff0c;兼容VoIP&#xff0c;IP电话&#xff0c;通过Ekiga可以与使用任何SIP和H.323软硬件的远程…

Vue.js 自定义组件的三种用法

1.创建项目 创建项目,你可以参考我以前的博文,这里省略了 项目的目录结构如下: 接着,我们在 src/components 目录下创建一个自定义的组件 SplashHello.vue,示例代码如下所示: <template><div><p>{{ title }}</p><p>{{ message }}</p&…

C++初学者指南第一步---13.聚合类型

C初学者指南第一步—13.聚合类型 文章目录 C初学者指南第一步---13.聚合类型1. 类型分类&#xff08;简化&#xff09;2. 如何定义和使用3. 为什么选择自定义类型/数据聚合&#xff1f;4. 聚合类型初始化5.混合6. 复制7. 值和引用的语义8.聚合的向量(std::vector)9.最令人烦恼的…