翻译《The Old New Thing》- What a drag: Dragging a virtual file (HGLOBAL edition)

What a drag: Dragging a virtual file (HGLOBAL edition) - The Old New Thing (microsoft.com)
https://devblogs.microsoft.com/oldnewthing/20080318-00/?p=23083
Raymond Chen 2008年03月18日
拖拽虚拟文件(HGLOBAL 版本)
现在我们已经对简单的数据对象有所了解,让我们来做点稍微复杂但极其有用的事情:拖拽一个虚拟文件。实现这一功能的方法有很多,但我将从最简单的方法开始,即虚拟文件以内存块的形式表示。
记住,这个系列的副标题是“这是你能做的最少”。你可以(甚至应该)做很多可选的事情,但我将从绝对最小化的部分开始。
对我们一直在研究的拖拽/放置程序进行以下更改。首先,更改数据类型的枚举:
enum {DATA_FILEGROUPDESCRIPTOR,DATA_FILECONTENTS,DATA_NUM,DATA_INVALID = -1,
};
拖拽虚拟文件的核心剪贴板格式是 FILEGROUPDESCRIPTOR,它描述了正在拖拽的文件数量以及它们的各种信息。对于文件组描述符中的每个文件,你必须提供相关的文件内容,由 CFSTR_FILECONTENTS 剪贴板格式表示。
CTinyDataObject::CTinyDataObject() : m_cRef(1)
{SetFORMATETC(&m_rgfe[DATA_FILEGROUPDESCRIPTOR],RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR));SetFORMATETC(&m_rgfe[DATA_FILECONTENTS],RegisterClipboardFormat(CFSTR_FILECONTENTS),TYMED_HGLOBAL, /* lindex */ 0);
}
初始化文件组描述符条目和之前看到的差不多。注意,结构体称为 FILEGROUPDESCRIPTOR,但剪贴板格式是 CFSTR_FILEDESCRIPTOR 而不是“group”。这可能最初是一个印刷错误,但现在我们只能接受它。
文件内容条目有一个转折:lindex 是零,而不是 -1。文件内容剪贴板格式使用 lindex 作为从零开始的索引,选择调用者所谈论的是哪个虚拟文件。由于我们只有一个虚拟文件,它的索引是零。
和以前一样,所有真正的工作都在数据对象的核心,即 IDataObject::GetData 方法中。
HRESULT CTinyDataObject::GetData(FORMATETC *pfe, STGMEDIUM *pmed)
{ZeroMemory(pmed, sizeof(*pmed));switch (GetDataIndex(pfe)) {case DATA_FILEGROUPDESCRIPTOR:{FILEGROUPDESCRIPTOR fgd;ZeroMemory(&fgd, sizeof(fgd));fgd.cItems = 1;StringCchCopy(fgd.fgd[0].cFileName,ARRAYSIZE(fgd.fgd[0].cFileName),TEXT("Dummy"));pmed->tymed = TYMED_HGLOBAL;return CreateHGlobalFromBlob(&fgd, sizeof(fgd),GMEM_MOVEABLE, &pmed->hGlobal);}case DATA_FILECONTENTS:pmed->tymed = TYMED_HGLOBAL;return CreateHGlobalFromBlob("Dummy", 5,GMEM_MOVEABLE, &pmed->hGlobal);}return DV_E_FORMATETC;
}
当调用者请求文件组描述符时,我们填写一个 FILEGROUPDESCRIPTOR 结构体,在填写之前清零我们不关心的字节,以避免信息泄露漏洞。正如我指出的,我们从做绝对最小的必要事情开始,这在虚拟文件传输的情况下仅仅包括指定有多少虚拟文件以及它们的名称。
当调用者请求文件零(我们唯一拥有的)的内容时,我们生成一个包含“Dummy”这个词的五字节内存块。
运行这个程序,并将不可见的对象拖出客户端区域并将其放置到桌面上。哇,你的虚拟文件已经被复制到桌面上,并变成了一个真实的文件。(你甚至可以将它拖放到Outlook邮件撰写窗口中,它将作为附件出现!)
这里还有一些问题,但我们已经至少完成了拖拽由内存块表示的虚拟文件的绝对最小必要事项。让我们看看其中一些可选特性,其中一些对您和最终用户都有重大影响。
首先,您可能已经注意到创建的 Dummy 文件在末尾可能有一些垃圾字节。我说“可能”,因为这些垃圾字节的存在取决于堆管理器的感受。如果您只提供 HGLOBAL,则内存块大小的唯一指示是 GlobalSize 函数的输出。但 GlobalSize 函数返回的大小不需要等于传递给 GlobalAlloc 的大小;唯一的保证是它至少和请求的大小一样大。它可能更大,这是由于内部堆管理,例如将所有分配舍入到最近的16字节的倍数。如果进行了这样的舍入,那么创建的 Dummy 文件将包含那些额外的垃圾字节。
为了避免这个问题,在 FILEGROUPDESCRIPTOR 中设置 FD_FILESIZE 标志,并在 nFileSizeLow 和 nFileSizeHigh 成员中指定确切的文件大小:
在 FILEGROUPDESCRIPTOR 中指定文件大小也有利于最终用户,因为它为文件复制进度条提供了它应该接收多少字节的信息。没有它,进度条不知道那个虚拟文件中有多少字节。它最终在请求文件内容时找到,但它是从每个文件复制时逐个学习的。进度对话框没有机会预先收集这些信息,以提供有意义的进度反馈。
另一个可选细节,您可能希望利用的是,在 FILEGROUPDESCRIPTOR 中指定文件属性和修改时间。例如,您可能希望在复制时使文件隐藏,或者您可能希望自定义最后修改时间。
我们来做一些事情。我们将在文件组描述符中指定文件大小以避免垃圾并改善进度反馈,并将最后修改时间设置为特定日期。
case DATA_FILEGROUPDESCRIPTOR:
{FILEGROUPDESCRIPTOR fgd;ZeroMemory(&fgd, sizeof(fgd));fgd.cItems = 1;fgd.fgd[0].dwFlags = FD_FILESIZE | FD_WRITESTIME;fgd.fgd[0].nFileSizeLow = 5;fgd.fgd[0].ftLastWriteTime.dwLowDateTime = 0x256d4000;fgd.fgd[0].ftLastWriteTime.dwHighDateTime = 0x01bf53eb;StringCchCopy(fgd.fgd[0].cFileName,ARRAYSIZE(fgd.fgd[0].cFileName),TEXT("Dummy"));pmed->tymed = TYMED_HGLOBAL;return CreateHGlobalFromBlob(&fgd, sizeof(fgd),GMEM_MOVEABLE, &pmed->hGlobal);
}
现在,当您放置文件时,它在末尾将没有任何垃圾字节,时间戳将是2000年1月1日午夜UTC。(由于文件太小,您不会注意到进度条有任何改进。)
尽管我们没有做很多,但这对许多人来说可能已经足够了,尤其是那些只想允许用户从他们的程序中拖拽一个对象并将其放入资源管理器窗口以创建相应文件的人,只要 HGLOBAL 是文件内容的方便格式。这对于小文件是合适的,但随着文件变大,您必须一次性生成整个文件的事实可能变得昂贵。下次我们将看看一个替代方案。
相关文章:
翻译《The Old New Thing》- What a drag: Dragging a virtual file (HGLOBAL edition)
What a drag: Dragging a virtual file (HGLOBAL edition) - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080318-00/?p23083 Raymond Chen 2008年03月18日 拖拽虚拟文件(HGLOBAL 版本) 现在我们已经对简单的数据…...
SA316系列音频传输模块-传输距离升级音质不打折
SA316是思为无线研发的一款远距离音频传输模块,音频采样率为48K,传输距离可达200M。为了满足更多用户需求,思为无线在SA316基础上进一步增加传输距离推出SA316F30。相比SA316性能,同样其采用48K采样,-96dBm灵敏度&…...
【机器学习】智能选择的艺术:决策树在机器学习中的深度剖析
在机器学习的分类和回归问题中,决策树是一种广泛使用的算法。决策树模型因其直观性、易于理解和实现,以及处理分类和数值特征的能力而备受欢迎。本文将解释决策树算法的概念、原理、应用、优化方法以及未来的发展方向。 🚀时空传送门 &#x…...
电脑缺少运行库,无法启动程序
在我们使用一些软件的时候,由于电脑缺少一些运行库,导致无法启动应用软件,此时需要我们安装缺少的运行库。 比如当电脑提示: Cannot load library Qt5Xlsx.dll 我们就需要下载C得运行库,以满足软件运行需要。 下载链…...
【计算机软考_初级篇】每日十题2
各位老师大家好,软考对于日常的知识储备和企业中的考试,或者说在校大学生来说,那用处是非常大的!!那么下面我们进入正题,软考呢是分两种语言,java和C,对于其他语言目前还没ÿ…...
HR人才测评,如何做营销人员岗位素质测评?
营销人员是企业中的重要角色,他们直接负责企业产品或服务的销售和推广,是企业中最直接影响销售业绩的人才之一。因此,营销人员的基本素质测评非常重要,能够有效评估营销人员的能力和潜力,为企业招聘和培养优秀的营销人…...
LabVIEW调用第三方硬件DLL常见问题及开发流程
在LabVIEW中调用第三方硬件DLL时,除了技术问题,还涉及开发流程、资料获取及与厂家的沟通协调。常见问题包括函数接口不兼容、数据类型转换错误、内存管理问题、线程安全性等。解决这些问题需确保函数声明准确、数据类型匹配、正确的内存管理及线程保护。…...
datax实现MySQL数据库迁移shell自动化脚本
datax实现MySQL数据库迁移 (1)生成python脚本 # codingutf-8 import json import getopt import os import sys import MySQLdb#MySQL相关配置,需根据实际情况作出修改 mysql_host "xxxx" mysql_port "3306" mysql_u…...
PostgreSQL的学习心得和知识总结(一百四十四)|深入理解PostgreSQL数据库之sendTuples的实现原理及功能修改
目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…...
C++数据结构之:链List
摘要: it人员无论是使用哪种高级语言开发东东,想要更高效有层次的开发程序的话都躲不开三件套:数据结构,算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合&am…...
10.Redis之set类型
谈到一个术语,这个术语很可能有多种含义~~ 1.Set 1) 集合. 2)设置 (和 get 相对应) 集合就是把一些有关联的数据放到一起~~ 1.集合中的元素是无序的! 【此处说的无序和 前面list这里的有序 是对应的, 有序: 顺序很重要. 变换一下顺序, 就是不同的 list 了 无序: 顺序不…...
SpringBoot + mongodb 删除集合中的数据
MongoTemplate是Spring Data MongoDB提供的一个工具类,用于与MongoDB进行交互。它提供了许多方法来执行数据库操作,包括删除数据。 本文将介绍如何使用Java MongoTemplate删除集合内的数据,并提供相应的代码示例。 1. 引入MongoTemplate 首…...
【日常记录】【JS】前端预览图片的两种方式,Base64预览和blob预览
文章目录 1、前言1、FileReader3、window.URL.createObjectURL4、参考链接 1、前言 一般来说,都是 后端返回给前端图片的url,前端直接把这个值插入到 img 的src 里面即可还有一种情况是前端需要预览一下图片,比如:上传头像按钮&a…...
每日刷题——杭电2156.分数矩阵和杭电2024.C语言合法标识符
杭电2156.分数矩阵 原题链接:Problem - 2156 题目描述 Problem Description:我们定义如下矩阵: 1/1 1/2 1/3 1/2 1/1 1/2 1/3 1/2 1/1 矩阵对角线上的元素始终是1/1,对角线两边分数的分母逐个递增。请求出这个矩阵的总和。 Input…...
爬虫学习--18.反爬斗争 selenium(3)
操作多窗口与页面切换 有时候窗口中有很多子tab页面。这时候肯定是需要进行切换的。selenium提供了一个叫做switch_to.window来进行切换,具体切换到哪个页面,可以从driver.window_handles中找到。 from selenium import webdriver from selenium.webdri…...
如何评价GPT-4o?
GPT-4o是OpenAI为聊天机器人ChatGPT发布的一款新语言模型,其名称中的“o”代表Omni,即全能的意思,凸显了其多功能的特性。这款模型在多个方面都有着显著的优势和进步。 首先,GPT-4o具有极强的多模态能力,它能够接受文本…...
算能BM1684+FPGA+AI+Camera推理边缘计算盒
搭载算丰智算芯片BM1684,是面向AI推理的边缘计算盒。高效适配市场上所有AI算法,实现视频结构化、人脸识别、行为分析、状态监测等应用,为智慧城市、智慧交通、智慧能源、智慧金融、智慧电信、智慧工业等领域进行AI赋能。 产品规格 处理器芯片…...
不同厂商SOC芯片在视频记录仪领域的应用
不同SoC公司芯片在不同产品上的应用信息: 大唐半导体 芯片型号: LC1860C (主控) LC1160 (PMU)产品应用: 红米2A (399元)大疆晓Spark技术规格: 28nm工艺,4个ARM Cortex-A7处理器,1.5GHz主频,2核MaliT628 GPU,1300万像…...
【Python入门学习笔记】Python3超详细的入门学习笔记,非常详细(适合小白入门学习)
Python3基础 想要获取pdf或markdown格式的笔记文件点击以下链接获取 Python入门学习笔记点击我获取 1,Python3 基础语法 1-1 编码 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指…...
通用代码生成器应用场景三,遗留项目反向工程
通用代码生成器应用场景三,遗留项目反向工程 如果您有一个遗留项目,要重新开发,或者源代码遗失,或者需要重新开发,但是希望复用原来的数据,并加快开发。 如果您的项目是通用代码生成器生成的,…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
