(娱乐)魔改浏览器-任务栏图标右上角加提示徽章

news2024/11/16 1:48:23

一、目标:

  • 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;
}

注意:

  1. 将ico图标位置(变量iconPath )替换成你图标的位置,必须是ico其他格式不行。
  2. LOG(ERROR)是用来打印错误日志的,可以忽略
  3. 最终实现原理是调用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;
}
  • 效果:

在这里插入图片描述

五、优化

  • 还需要优化的是想改成,白色圆形,透明背景。但稍微尝试了下,没改对。
  • 就这样吧,调试太费时间了。题主懒,集帅自行优化吧

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

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

相关文章

道路横幅检测数据集 2000张 街道横幅 带标注 voc yolo

项目背景&#xff1a; 城市中的街道横幅通常用于广告宣传、公共通知等目的&#xff0c;但在某些情况下&#xff0c;它们也可能影响交通安全或市容市貌。因此&#xff0c;对街道横幅进行自动化检测不仅可以帮助城市管理机构及时发现并处理不当悬挂的横幅&#xff0c;还可以辅助…

12.Java基础概念-面向对象-static

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 Facts speak louder than words&#xff01; 一、static关键字的含义…

葡萄叶病害检测系统源码分享

葡萄叶病害检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

无人机之飞行高度篇

无人机的飞行高度受到多种因素的制约&#xff0c;包括无人机本身的性能、无线信号的强度与稳定性&#xff0c;以及国家相关的法律法规等。具体而言&#xff0c;不同类型的无人机有不同的飞行高度限制&#xff1a; 微型无人机&#xff1a;飞行高度一般不得超过50米。这类无人机…

新生们必看!大学开学必备清单,教你快人一步适应学校生活

新生们&#xff0c;开学的脚步临近&#xff0c;你们是否已经准备好迎接全新的校园生活了呢&#xff1f;即将是一段充满挑战和机遇的旅程&#xff0c;为了让大家能够更快地适应新环境&#xff0c;我们特别整理了大学开学必备清单&#xff0c;教你快人一步适应学校生活。新生们必…

[C语言]第十节 函数栈帧的创建和销毁一基础知识到高级技巧的全景探索

10.1. 什么是函数栈帧 我们在写 C 语言代码的时候&#xff0c;经常会把一个独立的功能抽象为函数&#xff0c;所以 C 程序是以函数为基本单位的。 那函数是如何调用的&#xff1f;函数的返回值又是如何待会的&#xff1f;函数参数是如何传递的&#xff1f;这些问题都和函数栈帧…

Flask-JWT-Extended登录验证

1. 介绍 """安装:pip install Flask-JWT-Extended创建对象 初始化与app绑定jwt JWTManager(app) # 初始化JWTManager设置 Cookie 的选项:除了设置 cookie 的名称和值之外&#xff0c;你还可以指定其他的选项&#xff0c;例如&#xff1a;过期时间 (max_age)&…

VulhubSkyTower靶机详解

项目地址 https://download.vulnhub.com/skytower/SkyTower.zip项目配置 我们下载一个VirtualBox&#xff0c;这是官网 Downloads – Oracle VirtualBox 安装到默认路径就行 打开后点击注册 选择解压后的vbox文件 然后点击左上角管理 点击导出虚拟电脑&#xff0c;选中后…

Vue(12)——路由的基本使用

VueRouter 作用&#xff1a;修改地址栏路径时&#xff0c;切换显示匹配的组件 基本步骤&#xff08;固定&#xff09; 下载&#xff1a;下载VueRouter模块到当前工程引入安装注册创建路由对象注入&#xff0c;将路由对象注入到new Vue 实例中&#xff0c;建立关联 发现了#/表…

移动端如何实现智能语音交互

智能语音交互&#xff08;Intelligent Speech Interaction&#xff09;是基于语音识别、语音合成、自然语言理解等技术&#xff0c;为企业在多种实际应用场景下&#xff0c;赋予产品“能听、会说、懂你”式的智能人机交互功能。适用于智能问答、智能质检、法庭庭审实时记录、实…

CICD 持续集成与持续交付

目录 一 CICD是什么 1.1 持续集成&#xff08;Continuous Integration&#xff09; 1.2 持续部署&#xff08;Continuous Deployment&#xff09; 1.3 持续交付&#xff08;Continuous Delivery&#xff09; 二 git工具使用 2.1 git简介 2.2 git 工作流程 三 部署git …

IntelliJ IDEA 2024.1 新特性下载安装激活方法

概述 IntelliJ IDEA 2024.1 发布了一系列令人期待新特性&#xff0c;可以帮助您提高开发效率。比如&#xff1a;全行代码补全、SpringBean 补全和自动装配、多语句内联端点、新版终端、编辑器中粘性行、AI Assistant 编码助手、改进的日志工作流、重命名嵌入提示、为整行代码提…

【北京迅为】《STM32MP157开发板使用手册》- 第三十三章Cortex-M4 DMA实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

《锐捷AP 胖模式配置示例》

目录 WEB配置方式: 1. 登录 AP 管理界面 2. 配置无线服务 3. 配置射频参数 4. 配置 VLAN (如果需要) 5. 配置 IP 地址 6. 其他高级设置(根据需求) 命令行配置: 1. 进入特权模式 2. 进入全局配置模式 3. 配置管理 IP 地址 4. 创建无线 SSID 5. 配置 SSID 加密…

Selenium打开浏览器后闪退问题解决

笔者这两天在做一个自动化方案&#xff0c;用来优化数据统计。其中一部分数据需要通过云上堡垒机跳转访问&#xff0c;而这个堡垒机在笔者日常使用的火狐浏览器上运行不是很正常&#xff08;表现在有些复制粘贴按钮显示不太灵敏&#xff09;。 但在Edge浏览器上基本正常&#…

工行软件开发中心积极推进低代码平台建设,助力金融业务快速研发

工行软件开发中心融合现有研发体系,打造全链路可视化研发。平台整体架构建立于行内新一代前后端分离研发体系之上,引入可视化技术,构建业务研发资产,承接现有服务体系,基于数据模型驱动技术及代码扩展能力,快速实现应用开发,并整合行内研发支撑体系,实现应用的快速构建…

python定时发送邮件的功能如何实现自动化?

Python定时发送邮件教程&#xff1f;如何用Python发送电子邮件&#xff1f; Python定时发送邮件不仅能够帮助我们自动处理日常的邮件发送任务&#xff0c;还能在特定时间点触发邮件发送&#xff0c;确保信息的及时传达。AokSend将详细探讨如何利用Python实现定时发送邮件的自动…

开放式耳机好用吗?哪个开放式耳机好用?

现在市面上的开放式耳机真的越来越火了&#xff0c;所以很多小伙伴也会来问我&#xff0c;有哪些品牌值得入手&#xff0c;开放式耳机到底好不好用的这个问题&#xff0c;作为专业的开放式耳机测评博主对于这个问题当然是信手拈来啦&#xff0c;这篇文章就来告诉大家如何才能选…

算法基础-扩展欧几里得算法

扩展欧几里得 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);int n in.nextInt();while (n-- > 0) {int a in.nextInt();int b in.nextInt();int[] m exgcd(a, b);System.out.println(m[0] " " m[1]);}}…

【ollama 下载不下来的问题解决】

国内从官网下载ollama经常遇到下载不下来&#xff0c;或者卡住的问题&#xff0c;今天给大家分享解决这个问题的方法。 官网 官网地址&#xff1a;https://ollama.com/download 但是官网地址&#xff0c;就一直卡住&#xff0c;一直下载不下来&#xff0c;所以选用下面的方法…