(娱乐)魔改浏览器-任务栏图标右上角加提示徽章
一、目标:
- windows中,打开chromium,任务栏中会出现一个chromium的图标。
- 我们的目标是给这个图标的右上角,加上"有1条新消息"的小提示图标,也叫徽章(badge)
- 注意:本章节纯属娱乐,有需要的集帅可以学习模仿。
具体效果如下:
二、修改源码:
- 打开:\ui\views\view.cc
1.头部追加:
#include <Shobjidl.h>
#include <windows.h>
#include <shellapi.h>
2.找到:
bool View::OnMousePressed(const ui::MouseEvent& event) {return false;
}
OnMousePressed()
函数是可以点击事件,每次点击浏览器头部时都会触发这个函数。
3.替换为:
void UpdateTaskbarIcon(HWND hwnd, HICON hIcon) {ITaskbarList3* pTaskbarList = nullptr;HRESULT hr = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTaskbarList));if (SUCCEEDED(hr)) {pTaskbarList->SetOverlayIcon(hwnd, hIcon, L"有1条新消息");pTaskbarList->Release(); LOG(ERROR) << "SetOverlayIcon成功调用"; }else{LOG(ERROR) << "ERRORERRORERROR"; }
}void SetTaskbarIconOverlay(HWND hwnd) {wchar_t className[256];GetClassName(hwnd, className, sizeof(className) / sizeof(wchar_t));LOG(ERROR) << "窗口类名"; LOG(ERROR) << className; LPCWSTR iconPath = L"C:/Users/Administrator/Desktop/favicon.ico";HICON hIcon = (HICON)LoadImage(NULL, iconPath, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);if (!hIcon) {MessageBox(hwnd, L"无法加载图标。", L"错误", MB_OK | MB_ICONERROR);} else {UpdateTaskbarIcon(hwnd, hIcon);}
}bool View::OnMousePressed(const ui::MouseEvent& event) {CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);LPCWSTR className = L"Chrome_WidgetWin_1";LPCWSTR windowName = nullptr; // 如果你不知道窗口的标题,可以设置为nullptr// 获取窗口句柄HWND hwnd = FindWindow(className, windowName);if (hwnd != NULL) {HWND parentHwnd = GetParent(hwnd);if (parentHwnd == NULL) {LOG(ERROR) << "hwnd 是一个顶级窗口"; } else {LOG(ERROR) << "hwnd 不是一个顶级窗口"; }}LOG(ERROR) << hwnd;wchar_t windowTitle[256];GetWindowText(hwnd, windowTitle, sizeof(windowTitle) / sizeof(wchar_t));LOG(ERROR) << "窗口标题"; LOG(ERROR) << windowTitle; bool isVisible = IsWindowVisible(hwnd);LOG(ERROR) << "isVisible"; LOG(ERROR) << isVisible; DWORD processId;GetWindowThreadProcessId(hwnd, &processId);LOG(ERROR) << "processId"; LOG(ERROR) << processId; SetTaskbarIconOverlay(hwnd);CoUninitialize();return false;
}
注意:
- 将ico图标位置(变量iconPath )替换成你图标的位置,必须是ico其他格式不行。
LOG(ERROR)
是用来打印错误日志的,可以忽略- 最终实现原理是调用win32编程api里的SetOverlayIcon()函数。
4.编译
ninja -C out/Default chrome
- 编译完成后,打开浏览器,一旦点击浏览器头部,图标就出现啦!
三、代码生成数字ico
- 有的同学想到要右上角希望是数字图标,我们总不能准备99张ico图标吧。
- 于是我们用代码在内存中生成ico
将上面的代码改成:
HICON CreateNumberIcon(int number) {if (number > 99) {number = 99;}// 创建一个16x16的位图HDC hdcScreen = GetDC(NULL);HDC hdcMem = CreateCompatibleDC(hdcScreen);BITMAPINFO bmi = {};bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmi.bmiHeader.biWidth = 16;bmi.bmiHeader.biHeight = -16; // 负值表示自上而下bmi.bmiHeader.biPlanes = 1;bmi.bmiHeader.biBitCount = 32; // 32位带透明通道bmi.bmiHeader.biCompression = BI_RGB;bmi.bmiHeader.biSizeImage = 0;bmi.bmiHeader.biXPelsPerMeter = 0;bmi.bmiHeader.biYPelsPerMeter = 0;bmi.bmiHeader.biClrUsed = 0;bmi.bmiHeader.biClrImportant = 0;void* pBits;HBITMAP hBitmap = CreateDIBSection(hdcMem, &bmi, DIB_RGB_COLORS, &pBits, NULL, 0);HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);// 设置背景为透明memset(pBits, 0, 16 * 16 * 4); // 初始化位图为透明// 设置字体和颜色HFONT hFont = CreateFont(14, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial");HFONT hOldFont = (HFONT)SelectObject(hdcMem, hFont);SetTextColor(hdcMem, RGB(255, 0, 0)); // 设置数字颜色为红色SetBkMode(hdcMem, TRANSPARENT);// 计算数字的居中位置std::wstring text = std::to_wstring(number);RECT rect = {0, 0, 16, 16};DrawText(hdcMem, text.c_str(), text.length(), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);// 清理SelectObject(hdcMem, hOldFont);DeleteObject(hFont);SelectObject(hdcMem, hOldBitmap);DeleteDC(hdcMem);ReleaseDC(NULL, hdcScreen);// 将位图转换为图标ICONINFO iconInfo = { TRUE, 0, 0, hBitmap, hBitmap };HICON hIcon = CreateIconIndirect(&iconInfo);DeleteObject(hBitmap);return hIcon;
}void UpdateTaskbarIcon(HWND hwnd, HICON hIcon) {ITaskbarList3* pTaskbarList = nullptr;HRESULT hr = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTaskbarList));if (SUCCEEDED(hr)) {pTaskbarList->SetOverlayIcon(hwnd, hIcon, L"新消息");pTaskbarList->Release(); LOG(ERROR) << "SetOverlayIcon成功调用"; }else{LOG(ERROR) << "ERRORERRORERROR"; }
}void SetTaskbarIconOverlay(HWND hwnd) {wchar_t className[256];GetClassName(hwnd, className, sizeof(className) / sizeof(wchar_t));LOG(ERROR) << "窗口类名"; LOG(ERROR) << className; //LPCWSTR iconPath = L"C:/Users/Administrator/Desktop/favicon.ico";//HICON hIcon = (HICON)LoadImage(NULL, iconPath, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);HICON hIcon = CreateNumberIcon(72);if (!hIcon) {MessageBox(hwnd, L"无法加载图标。", L"错误", MB_OK | MB_ICONERROR);} else {UpdateTaskbarIcon(hwnd, hIcon);}
}bool View::OnMousePressed(const ui::MouseEvent& event) {CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);LPCWSTR className = L"Chrome_WidgetWin_1";LPCWSTR windowName = nullptr; // 如果你不知道窗口的标题,可以设置为nullptr// 获取窗口句柄HWND hwnd = FindWindow(className, windowName);SetTaskbarIconOverlay(hwnd);bool isVisible = IsWindowVisible(hwnd);LOG(ERROR) << "isVisible"; LOG(ERROR) << isVisible; CoUninitialize();return false;
}
- 效果:
五、优化
- 还需要优化的是想改成,白色圆形,透明背景。但稍微尝试了下,没改对。
- 就这样吧,调试太费时间了。题主懒,集帅自行优化吧
相关文章:

(娱乐)魔改浏览器-任务栏图标右上角加提示徽章
一、目标: windows中,打开chromium,任务栏中会出现一个chromium的图标。我们的目标是给这个图标的右上角,加上"有1条新消息"的小提示图标,也叫徽章(badge)注意:本章节纯属娱乐,有需要…...

JVM相关
1.JVM内存区域 一个运行起来的java进程就是一个Java虚拟机,就需要从操作系统中申请一大块内存。 内存中会根据作用的不同被划分成不同的区域: (1)栈:存储的内容是代码在执行过程中,方法之间的调用关系&a…...
9.18 微信小程序开发笔记
如何获取英语单词的发音,使其能在小程序界面通过点击外发? 1.通过外界API获取(例如有道API) 不下载音频文件,每次需要时直接API获取发音,存储压力小。但是一般的API都有使用次数限制,在背单词…...
dpdk课程学习之练习笔记八(dpvs的了解)
只是看到这个,跟着流程做一下练习,了解这个东东是干啥的,再就是搭建环境,基于dpdk的环境,顺手也就练习dpdk的环境搭建了。 0:总结 1:知道了lvs能实现的功能,挺强大。 2࿱…...

Linux标准IO-系统调用详解
1.1 系统调用 系统调用(system call)其实是 Linux 内核提供给应用层的应用编程接口(API),是 Linux 应用层进入内核的入口。不止 Linux 系统,所有的操作系统都会向应用层提供系统调用,应用程序通…...

LeetCode004-两个有序数组的中位数-最优算法代码讲解
最有帮助的视频讲解 【LeetCode004-两个有序数组的中位数-最优算法代码讲解】 https://www.bilibili.com/video/BV1H5411c7oC/?share_sourcecopy_web&vd_sourceafbacdc02063c57e7a2ef256a4db9d2a 时间复杂度 O ( l o g ( m i n ( m , n ) ) ) O(log(min(m,n))) O(log(min(…...

Unity携程Coroutine用法
一.携程概述 官方的解释是,携程允许你可以在多个帧中执行任务。在Unity中,携程是一个可以暂停并在后续帧中从暂停处继续执行的方法。 二.携程写法 下面示例使用携程和Update打印前5帧的时间间隔,展示了携程的基础写法 using System.Colle…...

腾讯百度阿里华为常见算法面试题TOP100(5):子串、堆
之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 子串 560.和为K的子数组...

「数据科学」清洗数据,真实数据集中缺失值的查看与处理
在数据科学的工作过程中,我们通过查看数据的基本要素和元数据之后,需要根据查看的结果,考虑是否需要清洗数据。缺失值的查看与处理,就是清洗数据的一部分。如果我们的数据集中,存在缺失值的话,就需要考虑如…...

彩蛋岛 销冠大模型案例
彩蛋岛 销冠大模型案例 任务: https://kkgithub.com/InternLM/Tutorial/tree/camp3/docs/EasterEgg/StreamerSales 视频 https://www.bilibili.com/video/BV1f1421b7Du/?vd_source4ffecd6d839338c9390829e56a43ca8d 项目git地址: https://kkgithu…...

大数据Flink(一百二十一):Flink CDC基本介绍
文章目录 Flink CDC基本介绍 一、什么是CDC 二、CDC的实现机制 三、传统 CDC ETL 分析 四、基于 Flink CDC 的 ETL 分析 五、什么是 Flink CDC 六、…...
SqlServer自定义类型的使用
目录 前言分类基于标量类型新建查询语句 用户定义的表类型新建查询语句 基于 CLR新建查询语句 前言 最近接触了SqlServer的自定义类型–TYPE,在此记录一下所得 分类 在 SQL Server 中,用户定义的类型(User-Defined Types, UDT)…...
LeetCode 滑动窗口 滑动子数组的美丽值
滑动子数组的美丽值 给你一个长度为 n 的整数数组 nums ,请你求出每个长度为 k 的子数组的 美丽值 。 一个子数组的 美丽值 定义为:如果子数组中第 x 小整数 是 负数 ,那么美丽值为第 x 小的数,否则美丽值为 0 。 请你返回一个包含…...

【JavaEE初阶】多线程(4)
欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 线程安全的 第四个原因 代码举例: 分析原因 解决方法 方法1 方法2 wait(等待)和notify(通知) wait和sleep区别 线程安全的 第四个原因 内存可见性,引起的线程安全问…...

初识 C++ ( 1 )
引言:大家都说c是c的升级语言。我不懂这句话的含义后来看过解释才懂。 一、面向过程语言和面向对象语言 我们都知道C语言是面向过程语言,而C是面向对象语言,说C和C的区别,也就是在比较面向过程和面向对象的区别。 1.面向过程和面向…...

Python数据分析 Pandas库-初步认识
Python数据分析 Pandas库-初步认识 认识Pandas pandas是一个非常实用的Python工具,我们可以把它想象成一个超级强大的表格处理工具,它比Excel更智能,操作更为简单。pands可以从各种文件格式(CSV、JSON、SQL、Excel࿰…...

Flutter问题记录 - 适配Xcode 16和iOS 18
文章目录 前言开发环境问题及解决方案1. Upload Symbols Failed2. type UIApplication does not conform to protocol Launcher3. method does not override any method from its superclass 最后 前言 为了新的镜像功能升级了macOS 15和iOS 18,Xcode也不可避免的需…...

VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025
VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025 VMware ESXi 7.0U3q macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) ESXi 7.0U3 标准版集成 Intel 网卡、Realtek USB 网卡 和 NVMe 驱动 请访问原文链…...
大数相乘,大数相加
大数相乘: #include <iostream> #include <vector> #include <string>std::vector<int> multiply(const std::vector<int>& num1, const std::vector<int>& num2) {int n1 num1.size();int n2 num2.size();std::ve…...

Spring Boot配置文件敏感信息加密
一,背景 Spring Boot应用中的数据库、Redis、Nacos、MQ等的用户名、连接地址、密码在配置文件中一般都是明文存储,如果系统被系统攻破或者配置文件所在的目录读权限被破解,又或者是动态配置文件被窃取,内部人员或者黑客很容易通过…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
验证redis数据结构
一、功能验证 1.验证redis的数据结构(如字符串、列表、哈希、集合、有序集合等)是否按照预期工作。 2、常见的数据结构验证方法: ①字符串(string) 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...

VSCode 使用CMake 构建 Qt 5 窗口程序
首先,目录结构如下图: 运行效果: cmake -B build cmake --build build 运行: windeployqt.exe F:\testQt5\build\Debug\app.exe main.cpp #include "mainwindow.h"#include <QAppli...

CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...