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

检测窗口是否最大化兼容 Win10/11

检测窗口是否最大化(窗口覆盖或独占全屏)兼容 Win10/11

问题描述

在 Win10/11 上有很多 UWP 进程,检测窗口是否最大化将迎来新的挑战。这些窗口以其不能够使用 Win32 的 IsWindowVisible 获取窗口可见性为特征。此时,必须使用 DWM API 来判断窗口的可见性状态。

代码实现

下面的代码实现了一个工具类检测当前桌面是否被覆盖,以及覆盖窗口的信息。(此代码参考 CustomDesktop 开源项目,并做了预览桌面时的逃逸规则)

“Singleton.h” :

#pragma oncenamespace cd
{template<class T>class Singleton{protected:Singleton() = default;virtual ~Singleton() = default;public:static T& GetInstance(){static T s_instance;return s_instance;}};#define DECL_SINGLETON(T) friend class Singleton<T>
#define DECL_SINGLETON_DEFAULT(T) \DECL_SINGLETON(T); \private: \T() = default; \~T() = default
}

“CheckCovered.h”:

#pragma once
#include "Singleton.h"
#include <thread>
#include <memory>namespace cd
{// 检测桌面是否被遮挡了class CheckCovered final : public Singleton<CheckCovered>{DECL_SINGLETON(CheckCovered);public:bool IsReady() { return m_runThreadFlag; }bool Init();bool Uninit();private:CheckCovered();~CheckCovered();std::unique_ptr<std::thread> m_thread;bool m_runThreadFlag = true;bool m_isCovered = false;HWND m_coveredByHwnd = NULL;void CheckCoveredThread();bool IsDesktopCovered();};
}

“CheckCovered.cpp” :

#include "CheckCovered.h"#ifdef _WIN64
#include <Dwmapi.h>
#endifnamespace cd
{CheckCovered::CheckCovered(){Init();}CheckCovered::~CheckCovered(){Uninit();}bool CheckCovered::Init(){m_runThreadFlag = true;/* 在主线程中执行函数,可以用来做 dllmain 中不能完成的初始化,通过自定义消息实现// MYDLL_API void WINAPI ExecInMainThread(std::function<void()> function);CD_API void WINAPI ExecInMainThread(std::function<void()> function){PostMessage(g_global.m_fileListWnd, WM_EXEC_FUNCTION, reinterpret_cast<WPARAM>(new decltype(function)(std::move(function))), NULL);}*/ExecInMainThread([this]{ m_thread = std::make_unique<std::thread>(&CheckCovered::CheckCoveredThread, this); });return true;}bool CheckCovered::Uninit(){m_runThreadFlag = false;if (m_thread != nullptr && m_thread->joinable())m_thread->join();m_thread = nullptr;return true;}void CheckCovered::CheckCoveredThread(){while (m_runThreadFlag){if (IsDesktopCovered()){if (!m_isCovered){m_isCovered = true;//ExecInMainThread([]{ g_desktopCoveredEvent(); });#ifdef _DEBUGWCHAR windowName[100], className[100];GetWindowTextW(m_coveredByHwnd, windowName, _countof(windowName));GetClassNameW(m_coveredByHwnd, className, _countof(className));_RPTFW2(_CRT_WARN, L"桌面被 %s (%s) 遮挡\n", windowName, className);
#endif}}else{if (m_isCovered){m_isCovered = false;//ExecInMainThread([]{ g_desktopUncoveredEvent(); });_RPTF0(_CRT_WARN, "桌面从被遮挡恢复\n");}}for (int i = 0; i < 10; i++){if (!m_runThreadFlag)break;Sleep(100);}}}bool CheckCovered::IsDesktopCovered(){m_coveredByHwnd = NULL;// 对于 D3D 独占全屏的程序,不能用 IsZoomed 判断全屏// TODO:兼容多屏幕int screenWidth = GetSystemMetrics(SM_CXSCREEN);int screenHeight = GetSystemMetrics(SM_CYSCREEN);HWND hwnd = GetForegroundWindow();if (hwnd != GLOBAL_YOUR_WINDOW) // GLOBAL_YOUR_WINDOW 是你要检测是否被全屏幕覆盖的窗口{RECT rect;GetWindowRect(hwnd, &rect);if (rect.left == 0 && rect.top == 0&& rect.right == screenWidth && rect.bottom == screenHeight){WCHAR wsClassName[MAX_PATH] = { 0 };GetClassNameW(hwnd, wsClassName, MAX_PATH);if (wcsstr(wsClassName, L"LivePreview") == NULL) {  // 预览桌面窗口出现时,恢复动画播放m_coveredByHwnd = hwnd;return true;}else {m_coveredByHwnd = nullptr;return false;}}}EnumWindows([](HWND hwnd, LPARAM pCoveredByHwnd)->BOOL {
#ifdef _WIN64// 对于 win10 app,不能用 IsWindowVisible 判断是否可见DWORD cloaked = 0;DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked));if (cloaked != 0)return TRUE;
#endif// 有最大化的窗口而且可见则被遮挡(最小化也是不可见)if (IsZoomed(hwnd) && IsWindowVisible(hwnd)){*(HWND*)pCoveredByHwnd = hwnd;return FALSE;}return TRUE;}, (LPARAM)&m_coveredByHwnd);if (m_coveredByHwnd != nullptr) {WCHAR wsClassName[MAX_PATH] = { 0 };GetClassNameW(m_coveredByHwnd, wsClassName, MAX_PATH);if (wcsstr(wsClassName, L"LivePreview") == NULL) {  // 预览桌面窗口出现时,恢复动画播放return true;}else {m_coveredByHwnd = nullptr;return false;}}return false;}
}

这里有两个点要说一下,一是此代码需要完善多桌面的情况,二是此代码考虑了预览桌面时候会产生一个窗口覆盖全屏的情况(LivePreview),为了避免检测失效,应该排除此时的覆盖情况(代码中也已经初步实现了)。


本文发布于:2024.06.10.

相关文章:

检测窗口是否最大化兼容 Win10/11

检测窗口是否最大化&#xff08;窗口覆盖或独占全屏&#xff09;兼容 Win10/11 问题描述 在 Win10/11 上有很多 UWP 进程&#xff0c;检测窗口是否最大化将迎来新的挑战。这些窗口以其不能够使用 Win32 的 IsWindowVisible 获取窗口可见性为特征。此时&#xff0c;必须使用 D…...

【qsort函数】

前言 我们要学习qsort函数并利用冒泡函数仿照qsort函数 首先我们要了解一下qsort&#xff08;快速排序&#xff09; 这是函数的的基本参数 void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*)); 简单解释一下 base&#xff1a;指向…...

python类元编程示例-使用类型注解来检查转换属性值的类框架

用三种方式实现使用类型注解来检查转换属性值的类框架 1 __init_subclass__方式 1.1 代码实现 from collections.abc import Callable # <1> from typing import Any, NoReturn, get_type_hints from typing import Dict, Typeclass Field:def __init__(self, name: …...

Python3 笔记:字符串的 zfill() 和 rjust()

1、zfill() 方法返回指定长度的字符串&#xff0c;原字符串右对齐&#xff0c;前面填充0。 语法&#xff1a;str.zfill(width) width &#xff1a;指定字符串的长度。原字符串右对齐&#xff0c;前面填充0。 str1 2546 str2 2 print(str1.zfill(10)) # 运行结果&#xff1…...

SpringBoot项目启动提示端口号占用

Windows环境下&#xff0c;SpringBoot项目启动时报端口号占用&#xff1a; *************************** APPLICATION FAILED TO START ***************************Description:Web server failed to start. Port 8080 was already in use.Action:Identify and stop the proc…...

音视频开发23 FFmpeg 音频重采样

代码实现的功能 目的是 将&#xff1a; 一个采样率为 44100&#xff0c;采样通道为 2&#xff0c;格式为 AV_SAMPLE_FMT_DBL 的 in.pcm 数据 转换成 一个采样率为 48000&#xff0c;采样通道为 1&#xff0c;格式为 AV_SAMPLE_FMT_S16 的 out.pcm 数据 1.重采样 1.1 为什么要重…...

windows系统下安装fnm

由于最近做项目要切换多个node版本&#xff0c;查询了一下常用的有nvm和fnm这两种&#xff0c;对比了一下选择了fnm。 下载fnm 有两种方式&#xff0c;目前最新版本是1.37.0&#xff1a; 1.windows下打开powershell&#xff0c;执行以下命令下载fnm winget install Schniz.f…...

【Linux网络】传输层协议 - UDP

文章目录 一、传输层&#xff08;运输层&#xff09;运输层的特点复用和分用再谈端口号端口号范围划分认识知名端口号&#xff08;Well-Know Port Number&#xff09;两个问题① 一个进程是否可以绑定多个端口号&#xff1f;② 一个端口号是否可以被多个进程绑定&#xff1f; n…...

debugger(四):源代码

〇、前言 终于来到令人激动的源代码 level 了&#xff0c;这里将会有一些很有意思的算法&#xff0c;来实现源代码级别的调试&#xff0c;这将会非常有趣。 一、使用 libelfin 库 我们不可能直接去读取整个 .debug info 段来进行设置&#xff0c;这是没有必要的&#xff0c;…...

基于运动控制卡的圆柱坐标机械臂设计

1 方案简介 介绍一种基于运动控制卡制作一款scara圆柱坐标的机械臂设计方案&#xff0c;该方案控制器用运动控制卡制作一台三轴机械臂&#xff0c;用于自动抓取和放料操作。 2 组成部分 该机械臂的组成部分有研华运动控制卡&#xff0c;触摸屏&#xff0c;三轴圆柱坐标的平面运…...

MongoDBTemplate-基本文档查询

文章目录 流程概述步骤1&#xff1a;创建一个MongoDB的连接步骤2&#xff1a;创建一个查询对象Query步骤3&#xff1a;设置需要查询的字段步骤4&#xff1a;使用查询对象执行查询操作 流程概述 步骤描述步骤1创建一个MongoDB的连接步骤2创建一个查询对象Query步骤3设置需要查询…...

23种设计模式——创建型模式

设计模式 文章目录 设计模式创建型模式单例模式 [1-小明的购物车](https://kamacoder.com/problempage.php?pid1074)工厂模式 [2-积木工厂](https://kamacoder.com/problempage.php?pid1076)抽象⼯⼚模式 [3-家具工厂](https://kamacoder.com/problempage.php?pid1077)建造者…...

idm究竟有哪些优势

IDM&#xff08;Internet Download Manager&#xff09;是一款广受好评的下载管理工具&#xff0c;其主要优势包括&#xff1a; 高速下载&#xff1a;IDM支持最大32线程的下载&#xff0c;可以显著提升下载速度1。文件分类下载&#xff1a;IDM可以根据文件后缀进行分类&#x…...

如何学习Golang语言!

第一部分&#xff1a;Go语言概述 起源与设计哲学&#xff1a;Go语言由Robert Griesemer、Rob Pike和Ken Thompson三位Google工程师设计&#xff0c;旨在解决现代编程中的一些常见问题&#xff0c;如编译速度、运行效率和并发编程。主要特点&#xff1a;Go语言的语法简单、编译…...

Redis系列之淘汰策略介绍

Redis系列之淘汰策略介绍 文章目录 为什么需要Redis淘汰策略&#xff1f;Redis淘汰策略分类Redis数据淘汰流程源码验证淘汰流程Redis中的LRU算法Redis中的LFU算法 为什么需要Redis淘汰策略&#xff1f; 由于Redis内存是有大小的&#xff0c;当内存快满的时候&#xff0c;又没有…...

sql 调优

sql 调优 SQL调优是一个复杂的过程&#xff0c;涉及多个方面&#xff0c;包括查询优化、索引优化、表结构优化等。以下是一些基本的SQL调优策略&#xff1a; 使用索引&#xff1a;确保查询中涉及的列都有适当的索引。 查询优化&#xff1a;避免使用SELECT *&#xff0c;只选取…...

【UML用户指南】-13-对高级结构建模-包

目录 1、名称 2、元素 3、可见性 4、引入与引出 用包把建模元素安排成可作为一个组来处理的较大组块。可以控制这些元素的可见性&#xff0c;使一些元素在包外是可见的&#xff0c;而另一些元素要隐藏在包内。也可以用包表示系统体系结构的不同视图。 狗窝并不复杂&#x…...

前端面试题日常练-day63 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末 1. TypeScript中&#xff0c;以下哪个关键字用于声明一个类的构造函数&#xff1f; a) constructor b) init c) create d) initialize 2. 在TypeScript中&#xff0c;以下哪个符号用于声明可选的函…...

GAN的入门理解

这一篇主要是关于生成对抗网络的模型笔记&#xff0c;有一些简单的证明和原理&#xff0c;是根据李宏毅老师的课程整理的&#xff0c;下面有链接。本篇文章主要就是梳理基础的概念和训练过程&#xff0c;如果有什么问题的话也可以指出的。 李宏毅老师的课程链接 1.概述 GAN是…...

43【PS 作图】颜色速途

1 通过PS让画面细节模糊&#xff0c;避免被过多的颜色干扰 2 分析画面的颜色 3 作图 参考网站&#xff1a; 色感不好要怎么提升呢&#xff1f;分享一下我是怎么练习色感的&#xff01;_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1h1421Z76p/?spm_id_from333.1007.…...

定个小目标之刷LeetCode热题(13)

今天来看看这道题&#xff0c;介绍两种解法 第一种动态规划&#xff0c;代码如下 class Solution {public int maxSubArray(int[] nums) {int pre 0, maxAns nums[0];for (int x : nums) {// 计算当前最大前缀和pre Math.max(pre x, x);// 更新最大前缀和maxAns Math.ma…...

【AI大模型】Prompt Engineering

目录 什么是提示工程&#xff08;Prompt Engineering&#xff09; Prompt 调优 Prompt 的典型构成 「定义角色」为什么有效&#xff1f; 防止 Prompt 攻击 攻击方式 1&#xff1a;著名的「奶奶漏洞」 攻击方式 2&#xff1a;Prompt 注入 防范措施 1&#xff1a;Prompt 注…...

centos安装vscode的教程

centos安装vscode的教程 步骤一&#xff1a;打开vscode官网找到历史版本 历史版本链接 步骤二&#xff1a;找到文件下载的位置 在命令行中输入&#xff08;稍等片刻即可打开&#xff09;&#xff1a; /usr/share/code/bin/code关闭vscode后&#xff0c;可在应用程序----编程…...

面试题------>MySQL!!!

一、连接查询 ①&#xff1a;左连接left join &#xff08;小表在左&#xff0c;大表在右&#xff09; ②&#xff1a;右连接right join&#xff08;小表在右&#xff0c;大表在左&#xff09; 二、聚合函数 SQL 中提供的聚合函数可以用来统计、求和、求最值等等 COUNT&…...

英伟达:史上最牛一笔天使投资

200万美元的天使投资&#xff0c;让刚成立就面临倒闭风险的英伟达由危转安&#xff0c;并由此缔造了一个2.8万亿美元的市值神话。 这是全球风投史上浓墨重彩的一笔。 前不久&#xff0c;黄仁勋在母校斯坦福大学的演讲中&#xff0c;提到了人生中的第一笔融资——1993年&#x…...

PDF分页处理:技术与实践

引言 在数字化办公和学习中&#xff0c;PDF文件因其便携性和格式稳定性而广受欢迎。然而&#xff0c;处理大型PDF文件时&#xff0c;我们经常需要将其拆分成单独的页面&#xff0c;以便于管理和分享。本文将探讨如何使用Python编程语言和一些流行的库来实现PDF文件的分页处理。…...

数据可视化——pyecharts库绘图

目录 官方文档 使用说明&#xff1a; 点击基本图表 可以点击你想要的图表 安装&#xff1a; 一些例图&#xff1a; 柱状图&#xff1a; 效果&#xff1a; 折线图&#xff1a; 效果&#xff1a; 环形图&#xff1a; 效果&#xff1a; 南丁格尔图&#xff08;玫瑰图&am…...

Python的return和yield,哪个是你的菜?

目录 1、return基础介绍 &#x1f4da; 1.1 return用途&#xff1a;数据返回 1.2 return执行&#xff1a;函数终止 1.3 return深入&#xff1a;无返回值情况 2、yield核心概念 &#x1f347; 2.1 yield与迭代器 2.2 生成器函数构建 2.3 yield的暂停与续行特性 3、retur…...

持续总结中!2024年面试必问 20 道分布式、微服务面试题(七)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 20 道分布式、微服务面试题&#xff08;六&#xff09;-CSDN博客 十三、请解释什么是服务网格&#xff08;Service Mesh&#xff09;&#xff1f; 服务网格&#xff08;Service Mesh&#xff09;是一种用于处理服…...

AJAX 跨域

这里写目录标题 同源策略JSONPJSONP 是怎么工作的JSONP 的使用原生JSONP实践CORS 同源策略 同源&#xff1a; 协议、域名、端口号 必须完全相同、 当然网页的URL和AJAX请求的目标资源的URL两者之间的协议、域名、端口号必须完全相同。 AJAX是默认遵循同源策略的&#xff0c;不…...

建设医院网站ppt/杭州seo渠道排名

sqlserver2005连接远程服务器报错&#xff0c;以前用得好好的。今天上班来了就报错。郁闷&#xff01;&#xff01;&#xff01;转载于:https://www.cnblogs.com/dreamstill/archive/2006/07/21/456793.html...

软件公司网站模板图片/百度关键词排名推广话术

华为畅享20 plus终于正式发布了&#xff01;那么在畅享20 plus的小功能配件表现怎么样呢&#xff1f;比如说大家非常关心的nfc和红外功能。那么华为畅享20 plus有nfc吗?华为畅享20 plus支持红外功能吗?小编告诉你答案&#xff01;华为畅享20 plus有nfc吗?华为畅享20 plus没有…...

用rp做网站不用写前段代码/sem 优化软件

一、项目创建区别 使用基于IntelliJ的IDE&#xff0c;都会对project和module的关系比较糊涂。用简单的一句话来概括是&#xff1a; IntelliJ系中的Project相当于Eclipse系中的workspace。IntelliJ系中的Module相当于Eclipse系中的Project。IntelliJ中一个Project可以包括多个Mo…...

九江的网站建设公司/关键词网站排名软件

一维对流方程 ∂u∂tc∂u∂x0\frac{\partial u}{\partial t}c\frac{\partial u}{\partial x}0∂t∂u​c∂x∂u​0&#xff0c;取c1c1c1&#xff0c;现用伪谱法求解∂u∂t∂u∂x0\frac{\partial u}{\partial t}\frac{\partial u}{\partial x}0∂t∂u​∂x∂u​0。 初场为u0(x)e−…...

网站建设需要做的事情/免费网络营销推广软件

在PHP中&#xff0c;数组函数 array_uintersect_assoc () 使用用户提供的回调函数比较值&#xff0c;用内置的函数比较键&#xff0c;计算数组交集。 函数语法&#xff1a; array_udiff_assoc ( array $array1 , array $array2 [, array $array3... ], callable $value_compar…...

香港域名注册商/广州seo网络优化公司

生物信息学跟计算机一样&#xff0c;更新换代都是比较快的&#xff0c;还不能说当年我们用的经典软件&#xff0c;可能在现代来说已经过时了&#xff0c;因而与时俱进对于生物信息人员来说是很重要的。当我们尝试使用EBI上的在线工具ClustalW2进行比对时&#xff0c;我们发现他…...