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
由上面的代码不难看出flutter
的window
应用程序使用的是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 Studio
在main.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_window
和window_manager
进行Flutter
的window
应用程序编程,bitsdojo_window
和 window_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
功能:
- 自定义窗口边框:允许开发者自定义窗口的边框和标题栏,可以实现无边框窗口并完全控制窗口的外观和行为。
- 窗口拖动:提供简单的 API 用于实现自定义标题栏的拖动。
- 窗口按钮:允许自定义最小化、最大化和关闭按钮的行为。
- 窗口透明度:支持设置窗口的透明度。
- 多平台支持:支持 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
功能:
- 窗口管理:提供多种窗口管理功能,包括窗口最小化、最大化、恢复、隐藏、显示等。
- 窗口信息:可以获取窗口的位置、大小、标题等信息。
- 窗口事件:支持窗口的各种事件监听,如窗口关闭、聚焦、失焦等事件。
- 多平台支持:支持 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_window
和 window_manager
当然是可以的,但需要注意它们可能在某些功能上存在冲突或重叠,因此需要谨慎管理。方法如下,仅供参考:
(1)设置初始化代码
在 main.dart
文件中初始化 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;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)处理冲突和集成
在整合过程中,注意以下几点:
- 窗口初始化:确保
window_manager
和bitsdojo_window
的初始化代码不互相干扰。window_manager
用于窗口管理,bitsdojo_window
用于自定义窗口外观。 - 窗口事件:如果需要监听窗口事件,如最小化、最大化等,优先使用
window_manager
提供的事件处理机制。 - 自定义边框和按钮:使用
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:',),],),),),);}
}
如果觉得文章写的不错,就随手点个赞再走吧!😊
相关文章:

Flutter框架高阶——Window应用程序设置窗体窗口背景完全透明
文章目录 1.修改 main.cpp1)C 与 Win32 API2)EnableTransparency()3)中文注释 2.编写 Flutter 代码1)bitsdojo_window2)window_manager3)区别对比4)同时使用(1)设置初始化…...
HJ39判断两个IP是否属于同一子网
提示:文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 HJ39判断两个IP是否属于同一子网 一、 代码: 第一版代码没有对掩码网络号进行处理。一开始对非法字段的理解就是value大于255。然后执行示例, 254.255.0.0 85.122.52.249 10.57.…...

opencv学习笔记(2)
设置鼠标回调函数 setMouseCallback(winname, callback, userdata) winname:窗口名字 callback:回调函数 userdata:传回callback中 callback(event, x, y, flags,userdata) event:鼠标事件 x: 鼠标的x坐标 y: 鼠标的y坐标 flags:鼠标键和组合键 userdata:setMouseCallback传回…...

分享vs code十大好用的插件
1.Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code 将 VS Code 界面改成简体中文。 2.PDF Viewer 在VS Code 中打开 PDF文件。 3.TODO Highlight 这个扩展会突出显示您的待办事项注释,并提醒存在未完成的注释或任务。 该扩展附带了内…...
MySQL支持哪些特殊字符
MySQL支持多种特殊字符,这些字符在SQL语句中具有特定的含义,需要在使用时特别注意。以下是一些MySQL中的特殊字符及其相关信息: 引号: 单引号():用于定义字符串。如果字符串中包含单引号本身&…...
c语言中的宏是什么?
宏的定义及用途 C语言中的宏是一种预处理指令,它允许程序员定义一个名称,该名称可以代表一段代码或一个值。宏的主要用途是简化代码的编写,提高代码的可读性和可维护性,以及实现代码的重复利用。 宏的定义使用#define指令&#…...

采购信息记录标准编码范围维护以及如何开发获取编码范围
上图是配置的点,在这里可以获取到对应的编号范围以及对象名称 下面的话是官方就如何取编号的技术文档 SAP Help Portal...

渗透测试基础(四) MS08-067 漏洞攻击
1. 漏洞介绍 漏洞描述 Microsoft Windows Server服务RPC请求缓冲区溢出漏洞Windows的Server服务在处理特质RPC请求时存在缓冲区溢出漏洞,远程攻击者可以通过发送恶意的RPC请求触发这个溢出,导致完全入侵用户系统,以SYSTEM权限执行任意指令。…...
vmware 虚拟机保留数据扩展C盘
1,在默认安装系统的时候,VMWARE一般给C盘50G,很多人想着够用了,但是后面慢慢的安装各种大型软件,游戏,才发现,悔时已晚。 2,有很多人虚拟机其实就是拿来游戏多开,但是当…...

vscode cmake c++ include 设置
在这里设置编译器路径,include路径等等。 一个奇怪的现象是同一项目放在VS中可以cmake生成,并正常运行,但是放在VSCODE中cmake生成时会报错,如iostream、limits等头文件找不到。当在VS中运行执行完成调试后,在运行VSC…...
2024-06-19 高等数学(统计学和概率论-高等工科数学)
学习数学时,有效的笔记方法可以帮助你更好地理解和记忆概念、公式和解题技巧。下面是一个数学笔记的基本模本,你可以根据自己的需求进行调整: 1. **标题**:写上日期和课程名称,例如“2024-06-19 高等数学”。 2. **课…...

idea 创建properties文件,解决乱码
设置properties文件编码 点击file->Settings File Encodings->设置utf-8 重新创建.properties文件才生效...

树莓派4B学习笔记11:PC端网线SSH连接树莓派_网线连接请求超时问题解决
今日继续学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi) 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1: 今日学习使用网线连接树莓派,网线可以提供更…...

适合营销的叙事可视化
背景 数据可视化与数据故事化的差异和相似点,以及它们如何协同工作,将你的数据转化为清晰、简洁、可操作的信息,以便您的组织使用。 什么是数据可视化? 数据可视化通过图像传达信息——这是你所收集数据的视觉表示。通过提供原…...

Spring Cloud全家桶(上)【Nacos、OpenFeign、LoadBalancer、GateWay、金丝雀灰色发布】
0.零基础入门微服务实战课 1.微服务和 Spring Cloud1.1 什么是微服务?1.2 什么是 Spring Cloud?1.3 微服务 VS Spring Cloud 2.为什么要学微服务?3.Spring Cloud 组件介绍1.什么是 Nacos?1.1 Nacos 功能1.1.1 配置中心1.1.2 注册中心 1.2 Na…...
GPRS与4G网络:技术差异与应用选择
在移动通信的发展历程中,GPRS(General Packet Radio Service)和4G(Fourth-Generation)技术都扮演着举足轻重的角色。虽然两者都旨在提供无线数据传输服务,但在数据传输速率、延迟和覆盖范围等方面ÿ…...

【Spring】1. Maven项目管理
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…...

工业制造领涉及的8大常见管理系统,如mes、scada、aps、wms等
在工业生产和制造领域有一些常见的管理系统,很多小伙伴分不清,这次大美B端工场带领大家了解清楚。 MES(Manufacturing Execution System,制造执行系统): MES是一种用于监控、控制和优化生产过程的软件系统…...
Lianwei 安全周报|2024.06.17
新的一周又开始了,以下是本周「Lianwei周报」,我们总结推荐了本周的政策/标准/指南最新动态、热点资讯和安全事件,保证大家不错过本周的每一个重点! 政策/标准/指南最新动态 01 IDC:2024 第一季度中国安全硬件市场规模…...

海量数据处理利器 Roaring BitMap 原理介绍
作者:来自 vivo 互联网服务器团队- Zheng Rui 本文结合个人理解梳理了BitMap及Roaring BitMap的原理及使用,分别主要介绍了Roaring BitMap的存储方式及三种container类型及Java中Roaring BitMap相关API使用。 一、引言 在进行大数据开发时,…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...

向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...
调试快捷键 pycharm vscode
目录 调试快捷键 pycharm vscode 修改快捷键 方法 1:通过菜单打开 方法 2:用快捷键打开 调试快捷键 pycharm Resume Program F9 Step Over F8 两个离的比较近,比较方便,比vscode的好。 vscode Continue F5 改为F9 S…...

[electron]预脚本不显示内联script
script-src self 是 Content Security Policy (CSP) 中的一个指令,它的作用是限制加载和执行 JavaScript 脚本的来源。 具体来说: self 表示 当前源。也就是说,只有来自当前网站或者当前页面所在域名的 JavaScript 脚本才被允许执行。"…...
Unity基础-Mathf相关
Unity基础-Mathf相关 一、Mathf数学工具 概述 Mathf是Unity中封装好用于数学计算的工具结构体,提供了丰富的数学计算方法,特别适用于游戏开发场景。它是Unity开发中最常用的数学工具之一,能够帮助我们处理各种数学计算和插值运算。 Mathf…...

大语言模型解析
1. Input Embedding embedding:将自然语言翻译成index 每个index对应一个embedding,embedding需要训练,embedding是一个数组...