.cur 鼠标光标文件读取

news2024/11/25 7:12:31

 备份icon掩码开发代码-CSDN博客

代码改写自

目前bug是高度不足,顶上的几十个像素图片打印需要加常数,

i的改写是 i/3,参考上面链接的自简书的代码

#include <stdio.h>
#include <windows.h>
#pragma warning(disable : 4996)					// visual studio 宏定义,避免移植到Visual studio编译报错 

// 核心代码自
//https://learn.microsoft.com/en-us/previous-versions/ms997538(v=msdn.10)


//掩码图,其中有 XOR AND 俩图片,都是用一个bit 0表示黑,1表示白,即一个字节对应八个像素
typedef struct
{
	BITMAPINFOHEADER   icHeader;      // DIB header
	RGBQUAD         icColors[1];   // Color table
	BYTE            icXOR[1];      // DIB bits for XOR mask
	BYTE            icAND[1];      // DIB bits for AND mask
} ICONIMAGE, *LPICONIMAGE;
// 一个ICON 文件有多个图片,是因为不同机器上识别不同格式图片,这里是紧随ICON文件头之后的图片信息结构体
typedef struct
{
	BYTE        bWidth;          // Width, in pixels, of the image
	BYTE        bHeight;         // Height, in pixels, of the image
	BYTE        bColorCount;     // Number of colors in image (0 if >=8bpp)
	BYTE        bReserved;       // Reserved ( must be 0)
	WORD        wPlanes;         // Color Planes
	WORD        wBitCount;       // Bits per pixel
	DWORD       dwBytesInRes;    // How many bytes in this resource?
	DWORD       dwImageOffset;   // Where in the file is this image?
} ICONDIRENTRY, *LPICONDIRENTRY;


// ICON 文件头
typedef struct
{
	WORD           idReserved;   // Reserved (must be 0)
	WORD           idType;       // Resource Type (1 for icons)
	WORD           idCount;      // How many images?
	ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
} ICONDIR, *LPICONDIR;


// 用于显示 Icon 的全部结构体数据 ,如果正常显示,说明微软的代码靠谱
void showIcon(LPICONDIR pIconDir,LPICONDIRENTRY pIconDirEntry,LPICONIMAGE pIconImage)
{
	printf("pIconDir\n");
	printf("%0x\n",pIconDir->idReserved);
	printf("%0x\n",pIconDir->idType);
	printf("idCount = %0x\n",pIconDir->idCount);

	printf("pIconDirEntry\n");
	printf("bHeight = %d\n",pIconDirEntry->bHeight);
	printf("bWidth = %d\n",pIconDirEntry->bWidth);
	printf("%0x\n",pIconDirEntry->bColorCount);
	printf("%0x\n",pIconDirEntry->bReserved);
	printf("wPlanes = %d\n",pIconDirEntry->wPlanes);
	printf("wBitCount = %d\n",pIconDirEntry->wBitCount);
	printf("dwBytesInRes = %ld\n",pIconDirEntry->dwBytesInRes);
	printf("dwImageOffset = %ld\n",pIconDirEntry->dwImageOffset);

	printf("pIconImage->icHeader\n");
//	https://zhuanlan.zhihu.com/p/339055549
//	https://blog.csdn.net/wangwenjing90/article/details/8537355
//	https://blog.csdn.net/weixin_44350503/article/details/90082061
	printf("%ld\n",pIconImage->icHeader.biSize);					// biSize = BMP头的info头部分的文件大小(以字节为单位)
//	icHeader 结构的 biHeight 成员表示 XOR 和 AND 掩码的组合高度。
	printf("icHeader.biHeight = %ld\n",pIconImage->icHeader.biHeight);
	printf("icHeader.biWidth =  %ld\n",pIconImage->icHeader.biWidth);

	printf("%d\n",pIconImage->icHeader.biPlanes);					// biPlanes 颜色平面数 https://blog.csdn.net/mmxida/article/details/122362449#:~:text=%E5%9C%A8%E4%B8%80%E4%B8%AA%E9%BB%98%E8%AE%A4%E7%9A%8416%E8%89%B2%E7%9A%84%E8%B0%83%E8%89%B2%E6%9D%BF%E4%B8%AD%EF%BC%8C%E9%A2%9C%E8%89%B2%E8%A2%AB%E7%B3%BB%E7%BB%9F%E6%8C%89%E7%85%A7%E4%B8%80%E5%AE%9A%E7%9A%84%E8%A7%84%E5%88%99%E8%BF%9B%E8%A1%8C%E5%88%86%E9%85%8D%EF%BC%8C%E4%BE%8B%E5%A6%82%E4%BD%8D0%E8%A1%A8%E7%A4%BA%E8%93%9D%E8%89%B2%E9%80%9A%E9%81%93%EF%BC%8C%E4%BD%8D1%E8%A1%A8%E7%A4%BA%E7%BB%BF%E8%89%B2%E9%80%9A%E9%81%93%EF%BC%8C%E4%BD%8D2%E8%A1%A8%E7%A4%BA%E7%BA%A2%E8%89%B2%E9%80%9A%E9%81%93%EF%BC%8C%E4%BD%8D4%E8%A1%A8%E7%A4%BA%E5%BC%BA%E5%BA%A6%E9%80%9A%E9%81%93%E3%80%82%20%E6%A0%B9%E6%8D%AE%E8%BF%99%E4%B8%AA%E8%A7%84%E5%88%99%EF%BC%8C%E8%BF%994%E4%B8%AA%E4%BD%8D%E5%8F%AF%E4%BB%A5%E8%A2%AB%E8%A7%A3%E9%87%8A%E4%B8%BA%EF%BC%9A%E5%BC%BA%E5%BA%A6%E5%B9%B3%E9%9D%A2%EF%BC%8C%E7%BA%A2%E8%89%B2%E5%B9%B3%E9%9D%A2%EF%BC%8C%E7%BB%BF%E8%89%B2%E5%B9%B3%E9%9D%A2%E5%92%8C%E8%93%9D%E8%89%B2%E5%B9%B3%E9%9D%A2%E3%80%82%20%E5%AF%B9%E4%BA%8E%E6%9C%80%E5%90%8E%E4%B8%89%E4%B8%AA%E5%B9%B3%E9%9D%A2%EF%BC%8C%E6%82%A8%E5%8F%AF%E4%BB%A5%E6%83%B3%E8%B1%A1%E6%AF%8F%E4%B8%AA%E5%B9%B3%E9%9D%A2%E9%83%BD%E4%BB%A3%E8%A1%A8%E4%BA%86%E5%A6%82%E6%9E%9C%E5%8F%AA%E6%9C%89%E7%9B%B8%E5%BA%94%E7%9A%84%E7%94%B5%E5%AD%90%E6%9E%AA%E5%9C%A8%E5%8F%91%E5%B0%84%E6%97%B6%E4%BD%A0%E7%9C%8B%E5%88%B0%E7%9A%84%E6%83%85%E5%86%B5%E3%80%82%20%E7%94%B1%E4%BA%8E%E8%BF%99%E6%98%AFEGA%E7%9A%84%E6%9C%AC%E6%9C%BA%E9%A2%9C%E8%89%B2%E6%A0%BC%E5%BC%8F%EF%BC%8C%E5%9B%A0%E6%AD%A4%E9%9C%80%E8%A6%81%E6%9C%89%E4%B8%80%E7%A7%8D%E6%96%B9%E6%B3%95%E5%9C%A8BITMAP%E7%BB%93%E6%9E%84%E4%B8%AD%E8%A1%A8%E8%BE%BE%E8%BF%99%E7%A7%8D%E9%A2%9C%E8%89%B2%E6%A0%BC%E5%BC%8F%EF%BC%8C%E4%BB%A5%E4%BE%BF,Windows%E5%8F%AF%E4%BB%A5%E8%A1%A8%E7%A4%BA%E4%B8%8E%E8%AE%BE%E5%A4%87%E7%9B%B8%E5%85%B3%E7%9A%84%E4%BD%8D%E5%9B%BE%E3%80%82%20%E5%9B%A0%E6%AD%A4%E8%AF%9E%E7%94%9F%E4%BA%86%E5%B9%B3%E9%9D%A2%E9%A2%9C%E8%89%B2%E6%A0%BC%E5%BC%8F%E3%80%82%20%E5%AF%B9%E4%BA%8E16%E8%89%B2%E5%B9%B3%E9%9D%A2%E7%9A%84%E4%BD%8D%E5%9B%BE%EF%BC%8C%E5%B9%B3%E9%9D%A2%E6%95%B0%E4%B8%BA%204%EF%BC%8C%E6%AF%8F%E4%B8%AA%E5%83%8F%E7%B4%A0%E7%9A%84%E4%BD%8D%E6%95%B0%E4%B8%BA%201%E3%80%82
	printf("icHeader.biBitCount = %d\n",pIconImage->icHeader.biBitCount);					// biBitCount 每个像素的位数 图像位深度:1,4,8,16,24,32
	printf("压缩方式序号 = %ld\n",pIconImage->icHeader.biCompression);				// biCompression 图像数据压缩类型:0(BI_RGB,不压缩),1(BI_RLE8,8比特游程编码),2(BI_RLE4,4比特游程编码),3(BI_BITFIELDS,比特域),4(BI_JPEG),5(BI_PNG)
	printf("biSizeImage = %ld\n",pIconImage->icHeader.biSizeImage);				// biSizeImage 图像大小,用BI_RGB格式时,可设置为0.

//	https://blog.csdn.net/wangwenjing90/article/details/8537355
	printf("%ld\n",pIconImage->icHeader.biXPelsPerMeter);			// biXPelsPerMeter 水平分辨率,用于多图片存进 ICON时,在不同设备上像素密集程度不同,用于选取密集程度较接近当前设备的图片 ,但是一般不用管。
	printf("%ld\n",pIconImage->icHeader.biYPelsPerMeter);			// biYpelxPerMeter 垂直分辨率
	printf("%ld\n",pIconImage->icHeader.biClrUsed); 				// biCLrUsed 颜色索引数,查颜色表 https://blog.csdn.net/OrdinaryMatthew/article/details/114644916
	printf("%ld\n",pIconImage->icHeader.biClrImportant);			// biClrImortant 对图像显示有重要影响的颜色索引数,0表示都重要

	// 文件最顶上的微软教程链接中解释 is Colors 对应颜色表,因为 icHeader的 颜色索引不用了,isColors 成为了索引
	printf("pIconImage->icColors[0]\n");							// icColors 成员是 RGBQUAD 的数组。此数组中的元素数是通过检查 icHeader 成员来确定的。
	printf("%d\n",pIconImage->icColors[0].rgbRed);
	printf("%d\n",pIconImage->icColors[0].rgbGreen);
	printf("%d\n",pIconImage->icColors[0].rgbBlue);
	printf("%d\n",pIconImage->icColors[0].rgbReserved);


	printf("\n");
}
// 按名称复刻,发现isColor就是当前的像素数据
void showBitmap(LPICONIMAGE pIconImage)
{
	HWND hWindow;                                                //窗口句柄
	HDC hDc;                                                     //绘图设备环境句柄
	int yOffset = 150;
	hWindow = GetForegroundWindow();
	hDc = GetDC(hWindow);

	printf("height = %ld\n",pIconImage->icHeader.biHeight);
	printf("width = %ld\n",pIconImage->icHeader.biWidth);
	int posX=0, posY=0;

	for (int i = 0; i < pIconImage->icHeader.biWidth*pIconImage->icHeader.biHeight/3; i++) 				// 除以二是因为 biHeight 计算的是掩码图 和色彩图的总数
	{
		 
		char red = pIconImage->icColors[i].rgbBlue;
		char blue= pIconImage->icColors[i].rgbGreen;
		char green= pIconImage->icColors[i].rgbRed;
		
		posX = i/3 % pIconImage->icHeader.biWidth;
		posY = pIconImage->icHeader.biHeight/3 - i/3 /pIconImage->icHeader.biWidth + 300;				// 从下往上打印
		SetPixel(hDc, posX, posY, RGB(red, green, blue));
	}

//	for (int i = 0; i < 100003; i++) 				// 除以二是因为 biHeight 计算的是掩码图 和色彩图的总数
//	{
//
//		posX = i % 100;
//		posY = i / 100;				// 从下往上打印
//		SetPixel(hDc, posX, posY, RGB(250, 255, 100));
//	}
}



int main()
{
	LPICONDIR pIconDir;							// 用于记录一个完整的ICON 数据头
//	https://blog.csdn.net/jeanphorn/article/details/44982273
	HANDLE hFile=  CreateFile("12.cur",GENERIC_READ,
	                          FILE_SHARE_READ,
	                          NULL,
	                          OPEN_EXISTING,        //打开已存在的文件
	                          FILE_ATTRIBUTE_NORMAL,
	                          NULL);
	DWORD dwBytesRead;								// 要读取的字节数,DROWD 就是 unsigned _long32 ctrl+鼠标左键可查
	// We need an ICONDIR to hold the data
	pIconDir = (LPICONDIR)malloc( sizeof( ICONDIR ) );
// Read the Reserved word
	dwBytesRead=1;
	ReadFile( hFile, &(pIconDir->idReserved), sizeof( WORD ), &dwBytesRead, NULL );
// Read the Type word - make sure it is 1 for icons
	dwBytesRead=1;
	ReadFile( hFile, &(pIconDir->idType), sizeof( WORD ), &dwBytesRead, NULL );
// Read the count - how many images in this file?
	dwBytesRead=1;						// deByteRead=1 是指读的 1个 WORD ,就是读取一个字,这里对应读取两个字节因为unsigned short是两个字节
	ReadFile( hFile, &(pIconDir->idCount), sizeof( WORD ), &dwBytesRead, NULL );
// Reallocate IconDir so that idEntries has enough room for idCount elements
	pIconDir = (LPICONDIR)realloc( pIconDir, ( sizeof( WORD ) * 3 ) +
	                               ( sizeof( ICONDIRENTRY ) * pIconDir->idCount ) );
// Read the ICONDIRENTRY elements
	ReadFile( hFile, pIconDir->idEntries, pIconDir->idCount * sizeof(ICONDIRENTRY),
	          &dwBytesRead, NULL );
// Loop through and read in each image
	int i;
	LPICONIMAGE pIconImage;
	for(i=0; i<pIconDir->idCount; i++)
	{
		// Allocate memory to hold the image
		pIconImage =(LPICONIMAGE) malloc( pIconDir->idEntries[i].dwBytesInRes );
		// Seek to the location in the file that has the image
		SetFilePointer( hFile, pIconDir->idEntries[i].dwImageOffset,
		                NULL, FILE_BEGIN );
		// Read the image data
		dwBytesRead=1; // 字节数已经在 dwBytesInRes 中给出了,所以 dwBytesRead 成为 1就是 只读取一次
		ReadFile( hFile, pIconImage, pIconDir->idEntries[i].dwBytesInRes,
		          &dwBytesRead, NULL );
		// Here, pIconImage is an ICONIMAGE structure. Party on it :)

		//显示读取的数据信息
		showIcon(pIconDir,&pIconDir->idEntries[i],pIconImage);
		// Then, free the associated memory

		showBitmap(pIconImage);

		Sleep(20000);

		free( pIconImage );
	}
// Clean up the ICONDIR memory
	free( pIconDir );
	return 0;
}



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

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

相关文章

[lesson20]初始化列表的使用

初始化列表的使用 类成员的初始化 C中提供了初始化列表对成员变量进行初始化 语法规则 注意事项 成员的初始化顺序与成员的声明顺序相同成员的初始化顺序与初始化列表中的位置无关初始化列表先于构造函数的函数体执行 类中的const成员 类中的const成员会被分配空间的类中…

【Linux】环境搭建

昙花一现&#xff0c;却等待了整个白昼 蝉鸣一夏&#xff0c;却蛰伏了几个四季 目录 购买云服务器 总结 使用 XShell 远程登陆到 Linux 利用Linux编写一个简单C程序 ⭐toush -- 创建文件 ⭐vi -- 文本编译器 ⭐ll -- 查看文件的显示结果分析 ⭐gcc -o ⭐cat -- 查看源代码 契子…

利用细粒度检索增强和自我检查提升对话式问题解答能力

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Boosting Conversational Question Answering with Fine-Grained Retrieval-Augmentation and Self-Check 论文地址&#xff1a;https://arxiv.org/abs/2403.18243 检索增强生成…

【报错】AttributeError: ‘NoneType‘ object has no attribute ‘pyplot_show‘(已解决)

【报错】AttributeError: ‘NoneType’ object has no attribute ‘pyplot_show’ 问题描述&#xff1a;python可视化出现下面报错 我的原始代码&#xff1a; import matplotlib.pyplot as pltplt.figure() plt.plot(x, y, bo-) plt.axis(equal) plt.xlabel(X) plt.ylabe…

最短路径问题——(弗洛伊德算法与迪杰斯特拉算法)

最短路径问题——&#xff08;弗洛伊德算法与迪杰斯特拉算法&#xff09;【板子】 题目&#xff1a; 对于下面的图片所给出的关系,回答下面两个问题&#xff1a; 利用迪杰斯特拉算法求点A到每一个点之间的最小距离。利用弗洛伊德算法求每两个点之间的最短路径。 &#xff0…

[RK3399 Linux] 使用ubuntu 20.04.5制作rootfs

一、ubuntu base ubuntu base是用于为特定需求创建自定义映像的最小rootfs,是ubuntu可以运行的最小环境。 1.1 下载源码 下载ubuntu-base的方式有很多,可以从官方的地址:ttp://cdimage.ubuntu.com/ubuntu-base/releases。 也可以其它镜像地址下载,如清华源:https://mi…

弹性云服务器性能对比(内附测试数据),快快网络服务器崭露头角

随着计算技术的不断革新&#xff0c;云服务器已成为企业和个人部署应用与服务的首选。尤其线上业务日益盛行的今天&#xff0c;云服务商的实力更是备受瞩目。对于企业而言&#xff0c;高稳定&#xff0c;存储速度都是不可或缺的基本要求&#xff0c;这些都对公有云的云端编解码…

算法 囚犯幸存者

题目 主类 public static List<Prisoner> prisoners new ArrayList<Prisoner>(); public static List<Prisoner> remainPrisoners new ArrayList<Prisoner>(); public static Prisoner lastPrisoner null;public static void main(String[] args) …

Fastgpt配合chatglm+m3e或ollama+m3e搭建个人知识库

概述&#xff1a; 人工智能大语言模型是近年来人工智能领域的一项重要技术&#xff0c;它的出现标志着自然语言处理领域的重大突破。这些模型利用深度学习和大规模数据训练&#xff0c;能够理解和生成人类语言&#xff0c;为各种应用场景提供了强大的文本处理能力。AI大语言模…

VulnHub靶机-easy_cloudantivirus 打靶

easy_cloudantivirus 靶机 目录 easy_cloudantivirus 靶机一、导入虚拟机配置二、攻击方式主机发现端口扫描web渗透-SQL注入命令注入反弹shellssh爆破提权 一、导入虚拟机配置 靶机地址&#xff1a; https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453/下载完成&am…

golang实现定时监控 CLOSE_WAIT 连接的数量

文章目录 go实现定时检查大量的 CLOSE_WAIT 连接背景&#xff1a;为什么监控指定端口上的 CLOSE_WAIT 连接数量原因&#xff1a;什么是CLOSE_WAITgo实现定时检查大量的 CLOSE_WAIT 连接参考 go实现定时检查大量的 CLOSE_WAIT 连接 监控指定端口的连接状态&#xff0c;特别是关…

阿里云服务器公网带宽费用全解析(不同计费模式)

阿里云服务器公网带宽怎么收费&#xff1f;北京地域服务器按固定带宽计费一个月23元/M&#xff0c;按使用流量计费0.8元/GB&#xff0c;云服务器地域不同实际带宽价格也不同&#xff0c;阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表&#xff1a; 公网…

了解 RISC-V IOMMU

了解 RISC-V IOMMU 个人作为 IOMMU 初学者&#xff0c;从初学者的角度介绍我眼中 RISCV 的 IOMMU 如果有些描述不够专业&#xff0c;还请谅解&#xff0c;也欢迎讨论 部分内容来自 https://zhuanlan.zhihu.com/p/679957276&#xff08;对于 RISCV IOMMU 规范手册的翻译&#xf…

这是雷军的简历,落魄时卡里只有冰冷的40亿

互联网新词儿 周五了&#xff0c;来点放松的&#xff08;嗯&#xff1f;周五&#xff1f;不是上了五天班了吗&#xff0c;为什么不是周六 如果说哪一种炫富秀优越并不伤人&#xff0c;那一定是富含"幽默感"的脱口秀式的吹牛。 我印象中&#xff0c;江湖上还是有这么个…

UDP网络程序

上一章中&#xff0c;我们介绍了socket&#xff0c;以及TCP/UDP协议。这一章带大家实现几个UDP协议的网络服务。我们需要一个 服务端和一个客户端。 1.服务端实现 1.1socket函数 #include <sys/types.h> #include <sys/socket.h>int socket(int domain, in…

Vue结合el-table实现合并单元格(以及高亮单元表头和指定行)

实现效果如下&#xff1a; 思路&#xff1a; 1.首先使用动态表头表格。 2.其次实现动态计算合并单元格。&#xff08;计算规则 传递需要合并的字段&#xff09; 3.然后封装公共的计算单元格方法 export导出供多个页面使用。 4.同时需要封装成公共的组件供多个页面使用。 5…

Hi3861 OpenHarmony嵌入式应用入门--鸿蒙开发环境搭建

目录 简介 准备材料 安装开发环境 配置开发工具和sdk 新建工程 代码编译 简介 本篇将进行hi3861开发环境的搭建&#xff0c;并能够编译默认工程。 准备材料 华为集成开发环境工具DevEco Device Tool 华为集成开发环境IDE DevEco Device Tool下载 | HarmonyOS设备开发 …

书生潽语趣味 demo

创建开发机 使用 InternLM2-Chat-1.8B 模型生成 300 字的小故事 运行猪八戒模型试一下

linux使用docker实现redis主从复制和哨兵模式

目录 1. 拉取redis镜像 2.使用可视化redis工具 3. 设置从redis 4.设置哨兵模式 5. 使用docker-compose快速创建 1. 拉取redis镜像 docker pull redis 默认拉取最新的镜像。 然后pull结束后使用docker images检查镜像&#xff1a; 然后docker run创建container容器 首先…

统计 | Levene检验

Levene检验是方差齐性检验的一种&#xff0c;即检验各组样本方差是否相等的一种统计方法.它通常用于方差分析&#xff08;ANOVA&#xff09;前的一个步骤。Levene检验的零假设是各组的方差相等。 Levene检验的数学步骤如下&#xff1a; 1. 数据准备&#xff1a; 假设我们有个…