当前位置: 首页 > news >正文

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:',),],),),),);}
}

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

相关文章:

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

文章目录 1.修改 main.cpp1&#xff09;C 与 Win32 API2&#xff09;EnableTransparency()3&#xff09;中文注释 2.编写 Flutter 代码1&#xff09;bitsdojo_window2&#xff09;window_manager3&#xff09;区别对比4&#xff09;同时使用&#xff08;1&#xff09;设置初始化…...

HJ39判断两个IP是否属于同一子网

提示&#xff1a;文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 HJ39判断两个IP是否属于同一子网 一、 代码&#xff1a; 第一版代码没有对掩码网络号进行处理。一开始对非法字段的理解就是value大于255。然后执行示例&#xff0c; 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 这个扩展会突出显示您的待办事项注释&#xff0c;并提醒存在未完成的注释或任务。 该扩展附带了内…...

MySQL支持哪些特殊字符

MySQL支持多种特殊字符&#xff0c;这些字符在SQL语句中具有特定的含义&#xff0c;需要在使用时特别注意。以下是一些MySQL中的特殊字符及其相关信息&#xff1a; 引号&#xff1a; 单引号&#xff08;&#xff09;&#xff1a;用于定义字符串。如果字符串中包含单引号本身&…...

c语言中的宏是什么?

宏的定义及用途 C语言中的宏是一种预处理指令&#xff0c;它允许程序员定义一个名称&#xff0c;该名称可以代表一段代码或一个值。宏的主要用途是简化代码的编写&#xff0c;提高代码的可读性和可维护性&#xff0c;以及实现代码的重复利用。 宏的定义使用#define指令&#…...

采购信息记录标准编码范围维护以及如何开发获取编码范围

上图是配置的点&#xff0c;在这里可以获取到对应的编号范围以及对象名称 下面的话是官方就如何取编号的技术文档 SAP Help Portal...

渗透测试基础(四) MS08-067 漏洞攻击

1. 漏洞介绍 漏洞描述 Microsoft Windows Server服务RPC请求缓冲区溢出漏洞Windows的Server服务在处理特质RPC请求时存在缓冲区溢出漏洞&#xff0c;远程攻击者可以通过发送恶意的RPC请求触发这个溢出&#xff0c;导致完全入侵用户系统&#xff0c;以SYSTEM权限执行任意指令。…...

vmware 虚拟机保留数据扩展C盘

1&#xff0c;在默认安装系统的时候&#xff0c;VMWARE一般给C盘50G&#xff0c;很多人想着够用了&#xff0c;但是后面慢慢的安装各种大型软件&#xff0c;游戏&#xff0c;才发现&#xff0c;悔时已晚。 2&#xff0c;有很多人虚拟机其实就是拿来游戏多开&#xff0c;但是当…...

vscode cmake c++ include 设置

在这里设置编译器路径&#xff0c;include路径等等。 一个奇怪的现象是同一项目放在VS中可以cmake生成&#xff0c;并正常运行&#xff0c;但是放在VSCODE中cmake生成时会报错&#xff0c;如iostream、limits等头文件找不到。当在VS中运行执行完成调试后&#xff0c;在运行VSC…...

2024-06-19 高等数学(统计学和概率论-高等工科数学)

学习数学时&#xff0c;有效的笔记方法可以帮助你更好地理解和记忆概念、公式和解题技巧。下面是一个数学笔记的基本模本&#xff0c;你可以根据自己的需求进行调整&#xff1a; 1. **标题**&#xff1a;写上日期和课程名称&#xff0c;例如“2024-06-19 高等数学”。 2. **课…...

idea 创建properties文件,解决乱码

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

树莓派4B学习笔记11:PC端网线SSH连接树莓派_网线连接请求超时问题解决

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习使用网线连接树莓派&#xff0c;网线可以提供更…...

适合营销的叙事可视化

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

Spring Cloud全家桶(上)【Nacos、OpenFeign、LoadBalancer、GateWay、金丝雀灰色发布】

0.零基础入门微服务实战课 1.微服务和 Spring Cloud1.1 什么是微服务&#xff1f;1.2 什么是 Spring Cloud&#xff1f;1.3 微服务 VS Spring Cloud 2.为什么要学微服务&#xff1f;3.Spring Cloud 组件介绍1.什么是 Nacos?1.1 Nacos 功能1.1.1 配置中心1.1.2 注册中心 1.2 Na…...

GPRS与4G网络:技术差异与应用选择

在移动通信的发展历程中&#xff0c;GPRS&#xff08;General Packet Radio Service&#xff09;和4G&#xff08;Fourth-Generation&#xff09;技术都扮演着举足轻重的角色。虽然两者都旨在提供无线数据传输服务&#xff0c;但在数据传输速率、延迟和覆盖范围等方面&#xff…...

【Spring】1. Maven项目管理

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…...

工业制造领涉及的8大常见管理系统,如mes、scada、aps、wms等

在工业生产和制造领域有一些常见的管理系统&#xff0c;很多小伙伴分不清&#xff0c;这次大美B端工场带领大家了解清楚。 MES&#xff08;Manufacturing Execution System&#xff0c;制造执行系统&#xff09;&#xff1a; MES是一种用于监控、控制和优化生产过程的软件系统…...

Lianwei 安全周报|2024.06.17

新的一周又开始了&#xff0c;以下是本周「Lianwei周报」&#xff0c;我们总结推荐了本周的政策/标准/指南最新动态、热点资讯和安全事件&#xff0c;保证大家不错过本周的每一个重点&#xff01; 政策/标准/指南最新动态 01 IDC&#xff1a;2024 第一季度中国安全硬件市场规模…...

海量数据处理利器 Roaring BitMap 原理介绍

作者&#xff1a;来自 vivo 互联网服务器团队- Zheng Rui 本文结合个人理解梳理了BitMap及Roaring BitMap的原理及使用&#xff0c;分别主要介绍了Roaring BitMap的存储方式及三种container类型及Java中Roaring BitMap相关API使用。 一、引言 在进行大数据开发时&#xff0c;…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...