C++ 异形窗口

news2025/1/16 21:37:43

本文参考:Duilib源码

原理:分层窗口,通过定时器和手动触发绘画窗口
由于GDI对透明通道支持不是很好,最好选择GDI+进行绘画。

1.设置窗口属性WS_EX_LAYERED和绘画定时器
 DWORD dwStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
 SetWindowLong(hWnd, GWL_EXSTYLE, dwStyle | WS_EX_LAYERED);
 ::SetTimer(hWnd, LAYEREDUPDATE_TIMERID, 10L, NULL);
2.UpdateLayeredWindow绘画窗口并且支持透明度设置
void onPaint()
{
	if (::IsIconic(hWnd))return 0;
	 RECT rtWindow;
     GetWindowRect(hWnd, &rtWindow);
     COLORREF *pOffscreenBits = NULL;
     PAINTSTRUCT ps;
     HDC hdc = BeginPaint(hWnd, &ps);
     HDC hDcOffscreen = ::CreateCompatibleDC(hdc);
     //创建支持透明通道的BITMAP,pOffscreenBits位图的起始位置,默认色值为ARGB。默认值为0
     HBITMAP hbmpOffscreen = CreateARGB32Bitmap(hdc, rtWindow.right - rtWindow.left, rtWindow.bottom - rtWindow.top, &pOffscreenBits);
     HBITMAP hOldBitmap = (HBITMAP) ::SelectObject(hDcOffscreen, hbmpOffscreen);

	 RECT rtPaint = { 0,0,rtWindow.right - rtWindow.left, rtWindow.bottom - rtWindow.top };
     PaintContent(hDcOffscreen, rtPaint);
     
	//绘画分层窗口,将BITMAP展示出来,如果PaintContent内容为空,则整个界面什么都没有,因为完全透明
	BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
 	SIZE sizeWnd = { rtWindow.right - rtWindow.left, rtWindow.bottom - rtWindow.top };
    POINT ptPos = { rtWindow.left, rtWindow.top };
	POINT ptSrc = { 0,0 };
	UpdateLayeredWindow(hWnd, hdc, &ptPos, &sizeWnd, hDcOffscreen, &ptSrc, 0, &bf, ULW_ALPHA);
    DeleteDC(hDcOffscreen);
    DeleteObject(hbmpOffscreen);
    EndPaint(hWnd, &ps);
}
//创建32位支持透明通道的位图
HBITMAP CreateARGB32Bitmap(HDC hDC, int cx, int cy, COLORREF** pBits)
{
	LPBITMAPINFO lpbiSrc = NULL;
	lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
	if (lpbiSrc == NULL) return NULL;

	lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	lpbiSrc->bmiHeader.biWidth = cx;
	lpbiSrc->bmiHeader.biHeight = cy;
	lpbiSrc->bmiHeader.biPlanes = 1;
	lpbiSrc->bmiHeader.biBitCount = 32;
	lpbiSrc->bmiHeader.biCompression = BI_RGB;
	lpbiSrc->bmiHeader.biSizeImage = cx * cy;
	lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
	lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
	lpbiSrc->bmiHeader.biClrUsed = 0;
	lpbiSrc->bmiHeader.biClrImportant = 0;

	HBITMAP hBitmap = CreateDIBSection(hDC, lpbiSrc, DIB_RGB_COLORS, (void**)pBits, NULL, NULL);
	delete[] lpbiSrc;
	return hBitmap;
}
//通过gdi的方式实现支持Alpha填充背景色的功能
void DrawColor(HDC hDC, const RECT& rc, DWORD color)
{
    COLORREF* pColors = nullptr;
    HDC hMemDC = ::CreateCompatibleDC(hDC);
    HBITMAP hBitMap = CreateARGB32Bitmap(hDC, rc.right - rc.left, rc.bottom - rc.top, &pColors);
    ::SelectObject(hMemDC, hBitMap);

    COLORREF* pTempOffscreenBits = NULL;
    for (LONG y = 0; y < rc.bottom - rc.top; ++y) {
        for (LONG x = 0; x < rc.right - rc.left; ++x) {
            pTempOffscreenBits = pColors + y * (rc.right - rc.left) + x;
           
            *pTempOffscreenBits = color;
        }
    }
    BLENDFUNCTION bf = { AC_SRC_OVER, 0, GetAValue(color), AC_SRC_ALPHA };
    AlphaBlend(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, bf);
    DeleteObject(hBitMap);
    DeleteDC(hMemDC);
}
void PaintContent(HDC hDc, RECT rcPaint)
{
	RECT rtPaint = { 0,0,rcPaint.right - rcPaint.left, rcPaint.bottom - rcPaint.top };
	RECT rcItem1 = { rtPaint.left + 10,rtPaint.top + 10,rcItem1.left + 100,rcItem1.top + 100 };

	RECT rcItem2 = { rcItem1.right + 10,rtPaint.top + 10,rcItem2.left + 100,rcItem2.top + 100 };
	//DrawColor(hDc, rcItem1, 0xad00ff00);

	HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALL));
	DrawIcon(hDc, rcItem2.right + 10, rcItem2.top, hIcon);
	::SetBkMode(hDc, TRANSPARENT);
	::SetTextColor(hDc, RGB(255, 0, 0));
	std::wstring strText = L"Hellow word!!中国";
	DrawText(hDc, strText.c_str(), strText.size(), &rcItem2, DT_SINGLELINE | DT_VCENTER);

	RECT rcItem3 = { rcItem1.right + 10,rcItem1.bottom + 10,rcItem3.left + 100,rcItem3.top + 100 };
	Gdiplus::Image img(L"E:\\work\\PMS\\yiletu\\xiaoyi\\xyBar\\binx86\\Debug\\skin\\res\\yiletoo.png");
	Gdiplus::Graphics g(hDc);
	g.DrawImage(&img, (INT)rcItem3.left, (INT)rcItem3.top);
    Gdiplus::Font ft(L"宋体", 18);
    Gdiplus::PointF pt = { (REAL)rcItem3.right + 10.0f,(REAL)rcItem3.top };
    Gdiplus::SolidBrush b(Color(0x99, 0xff, 0, 0));
    g.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
    g.SetPixelOffsetMode(PixelOffsetModeDefault);
    g.SetCompositingMode(CompositingModeSourceOver);
    g.SetCompositingQuality(CompositingQualityDefault);
    g.DrawString(strText.c_str(), strText.size(), &ft, pt, &b);

    Gdiplus::RectF rtf = { (REAL)rcItem1.left,(REAL)rcItem1.top,(REAL)rcItem1.right - rcItem1.left,(REAL)rcItem1.bottom - rcItem1.top };
    g.FillRectangle(&b, rtf);
}

效果图:
在这里插入图片描述

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

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

相关文章

es6(八)—— set(集合) 和map的使用

ES6的系列文章目录 第一章 Python 机器学习入门之pandas的使用 文章目录 ES6的系列文章目录一、set&#xff08;集合&#xff09;0. 定义1. 基本使用2.常用方法&#xff08;1&#xff09;代码&#xff08;2&#xff09;效果&#xff08;3&#xff09;遍历 二、map0. 定义1. 基…

【AIFEM案例操作】压力容器强度分析

AIFEM是由天洑自主研发的一款通用的智能结构仿真软件&#xff0c;助力用户解决固体结构相关的静力学、动力学、振动、热力学等实际工程问题&#xff0c;软件提供高效的前后处理工具和高精度的有限元求解器&#xff0c;帮助用户快速、深入地评估结构的力学性能&#xff0c;加速产…

chatgpt图片识别、生成图片、语音对话多模态深度试玩

大模型替代人的工作的能力&#xff0c;越来越明显了。最近chatgpt支持多模态了&#xff0c;看这大佬们玩的不易乐乎&#xff0c;手痒也想试一试&#xff0c;因此有给openai上供了20刀。 另外我是gpt的拥护者&#xff0c;但是周围的同事有对此担忧&#xff0c;因为他们长期积累的…

协同创新、奔赴未来——“华为云杯”2023人工智能创新应用大赛华丽谢幕

9月27日&#xff0c;在苏州工业园区管理委员会、华为云计算技术有限公司的指导下&#xff0c;由SISPARK&#xff08;苏州国际科技园&#xff09;、华为&#xff08;苏州&#xff09;人工智能创新中心联合主办&#xff0c;东北大学工业智能与系统优化国家级前沿科学中心、浙江大…

nginx 配置相关详解

目录 Nginx的优点 Nginx简介 Nginx的优点 可以高并发连接 内存消耗少 成本低廉 配置文件非常易懂 稳定性高 内置有健康的检查功能 支持Rewrite重写 支持热部署 Nginx与Apache的对比 Nginx多进程工作原理跟设计 Nginx是如何实现高性能的 事件驱动模型 多进程机制…

kettle-数据库解密与各种跳接线标记含义

1.加密 进入kettle的安装目录 windows系统命令行执行&#xff1a;Encr.bat -kettle 123 linux/mac系统命令行执行&#xff1a;encr.sh -kettle 123 可生成Encrypted 2be98afc86aa7f2e4cb79ce10bec3fd89&#xff0c;即为123对应的kettle加密后的密码。 2.解密&#xff08;主…

信钰证券:股票的中线和年线?

股票商场一直是许多人注重的焦点。关于股票出资者来说&#xff0c;技巧和战略很重要。而股票的中线和年线便是股票出资中最基本的技术目标之一。这两个目标可以帮忙股民精确判别价格走势&#xff0c;拟定出资方案。在此我们将从几个角度分析股票的中线和年线的重要性。 什么是…

【Redis深度专题】「踩坑技术提升」一文教会你如何在支持Redis在低版本Jedis情况下兼容Redis的ACL机制

Redis低版本客户端兼容高版本Jedis不支持ACL的问题 首先&#xff0c;针对于Redis6.0之后&#xff0c;已经可以支持通过ACL的访问控制列表的机制进行控制多个用户进行权限控制访问&#xff0c;并且更加精细的控制权限访问处理模式&#xff0c;更加的偏向于RBAC模型的机制体系。…

【非root用户、CentOS系统】中使用源码安装gcc/g++的教程

1.引言 系统&#xff1a;CentOS-7.9 显卡驱动版本&#xff1a;460 CUDA Version: 11.2 &#x1f33c;基于本地环境选择安装gcc-10.1.0 &#x1f449; gcc下载网址 2.安装说明 下载好对应的gcc的安装包并解压&#xff1a; 打开gcc-10.1.0/contrib/download_prerequisites&#…

《视觉 SLAM 十四讲》V2 第 8 讲 视觉里程计2 【如何根据图像 估计 相机运动】【光流 —> 直接法】

OpenCV关于 光流的教程 文章目录 第 8 讲 视觉里程计 28.2 光流8.3 实践&#xff1a; LK 光流 【Code】本讲 CMakeLists.txt 8.4 直接法8.5 实践&#xff1a; 双目的稀疏直接法 【Code】8.5.4 直接法的优缺点 习题 8√ 题1 光流方法题2题3题4题5 第 8 讲 视觉里程计 2 P205 …

vue3脚手架搭建

一.安装 vue3.0 脚手架 如果之前安装了2.0的脚手架&#xff0c;要先卸载掉&#xff0c;输入&#xff1a; npm uninstall vue-cli -g 进行全局卸载 1.安装node.js&#xff08;npm&#xff09; node.js&#xff1a;简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是…

Linux高性能服务器编程——ch2笔记

第2章 IP 协议详解 2.1 IP服务的特点 无状态&#xff1a;IP通信双方不同步传输数据的状态信息。IP数据报相互独立&#xff0c;缺点是无法处理乱序和重复的IP数据报。上层协议如果是面向连接的协议&#xff08;TCP&#xff09;&#xff0c;能够自己处理乱序和重复的报文段。IP…

【Leetcode】 707. 设计链表

你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 prev 以指示链表中的上一个节点…

英语——分享篇——每日200词——1201-1400

1201——wound——[wu:nd]——n.伤口&#xff0c;创伤——wound——wo我(拼音)un联合国(编码)d狗(编码dog)——我在联合国治好了狗的伤口——The nurse cleaned the wound .——护士清洗了伤口。 1202——from——[frɒm]——prep.来自&#xff0c;从&#xff0c;由于——from—…

正点原子嵌入式linux驱动开发——pinctrl和gpio子系统

在上一篇笔记中&#xff0c;学习编写了基于设备树的LED驱动&#xff0c;但是驱动的本质还是没变&#xff0c;都是配置LED灯 所使用的GPIO寄存器&#xff0c;驱动开发方式和裸机基本没区别。Linux是一个庞大而完善的系统&#xff0c;尤其是驱动框架&#xff0c;像GPIO这种最基本…

C++11 正则表达式详解

目录 1 正则表达式语法1.1 字符和特殊字符1.2 限定符1.3 定位符1.4 选择和反向引用 2 C正则表达式标准库常用接口3 C正则表达式模板的使用3.1 匹配&#xff08;Match&#xff09;3.2 搜索&#xff08;Search&#xff09;3.3 分词&#xff08;Tokenize&#xff09;3.4 替换&…

【前端学习】—ES6新增的方法有哪些(十五)

【前端学习】—ES6新增的方法有哪些&#xff08;十五&#xff09; 一 、ES6中新增的方法 &#xff08;一&#xff09;、Object.is() //用于判断两个值/数据类型是否相等/* 特点&#xff1a;不仅可以对值类型进行正常处理&#xff0c;对象类型的值也可以处理对于特殊的值NaN 也…

分享一下怎么做多门店小程序

近年来&#xff0c;随着互联网的普及和移动支付的兴起&#xff0c;越来越多的商家开始涉足线上业务&#xff0c;开发自己的小程序。对于拥有多家门店的连锁品牌来说&#xff0c;开发多门店小程序是一个非常不错的选择。本文将围绕多门店小程序的制作展开讨论&#xff0c;希望能…

阿里8年经验之谈 —— 如何选择合适的自动化测试工具?

自动化测试是高质量软件交付领域中最重要的实践之一。在今天的敏捷开发方法中&#xff0c;几乎任一软件开发过程都需要在开发阶段的某个时候进行自动化测试&#xff0c;以加速回归测试的工作。自动化测试工具可以帮助测试人员以及整个团队专注于自动化工具无法处理的各自任务&a…

【网络安全 --- XSS绕过】xss绕过手法及思路你了解吗?常见及常用的绕过手法了解一下吧

本次博客以pikachu靶场为例&#xff0c;需要安装靶场可以参考以下博客&#xff08;都包含工具&#xff0c;镜像下载地址&#xff09; 一&#xff0c;工具资源下载 1-1 VMware虚拟机的安装 请参考以下博客&#xff0c;包含资源下载地址&#xff08;若已安装请忽略&#xff09;…