翻译《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 字符串。 当然你也可以为源码文件指…...

通用代码生成器应用场景三,遗留项目反向工程
通用代码生成器应用场景三,遗留项目反向工程 如果您有一个遗留项目,要重新开发,或者源代码遗失,或者需要重新开发,但是希望复用原来的数据,并加快开发。 如果您的项目是通用代码生成器生成的,…...

轻量级动态可监控线程池 - DynamicTp
一、背景介绍 使用线程池ThreadPoolExecutor的过程中你是否有以下痛点呢? 代码中创建了一个 ThreadPoolExecutor,但是不知道那几个核心参数设置多少比较合适凭经验设置参数值,上线后发现需要调整,改代码重新发布服务,…...

对于vsc中的vue命令 vue.json
打开vsc 然后在左下角有一个设置 2.点击用户代码片段 3.输入 vue.json回车 将此代码粘贴 (我的不一定都适合) { "vue2 template": { "prefix": "v2", "body": [ "<template>", " <…...

Spring Boot 官方不再支持 Spring Boot 的 2.x 版本!新idea如何创建java8项目
idea现在只能创建最少jdk17 使用 IDEA 内置的 Spring Initializr 创建 Spring Boot 新项目时,没有 Java 8 的选项了,只剩下了 > 17 的版本 是因为 Spring Boot 官方不再支持 Spring Boot 的 2.x 版本了,之后全力维护 3.x;而 …...

分享一个 ASP.NET Web Api 上传和读取 Excel的方案
前言 许多业务场景下需要处理和分析大量的数据,而 Excel 是业务人员常用的数据表格工具,因此,将 Excel 表格中内容上传并读取到网站,是一个很常见的功能,目前有许多成熟的开源或者商业的第三方库,比如 NPO…...

【算法实战】每日一题:将某个序列中内的每个元素都设为相同的值的最短次数(差分数组解法,附概念理解以及实战操作)
题目 将某个序列中内的每个元素都设为相同的值的最短次数 1.差分数组(后面的减去前面的值存储的位置可以理解为中间) 差分数组用于处理序列中的区间更新和查询问题。它存储序列中相邻元素之间的差值,而不是直接存储每个元素的值 怎么对某…...

EXCEL数据透视图中的日期字段,怎样自动分出年、季度、月的功能?
在excel里,这个果然是有个设置的地方,修改后就好了。 点击文件选项卡,选项,在高级里,将图示选项的勾选给取消,然后再创建数据透视表或透视图,日期就不会自动组合了: 这个选项只对新…...

【设计模式深度剖析】【1】【行为型】【模板方法模式】| 以烹饪过程为例加深理解
👈️上一篇:结构型设计模式对比 文章目录 模板方法模式定义英文原话直译如何理解呢? 2个角色类图代码示例 应用优点缺点使用场景 示例解析:以烹饪过程为例类图代码示例 模板方法模式 模板方法模式(Template Method Pattern&…...

JAVA:异步任务处理类CompletableFuture让性能提升一倍
一、前言 CompletableFuture 是 Java 8 引入的一个功能强大的类,用于异步编程。它表示一个可能尚未完成的计算的结果,你可以对其添加回调函数来在计算完成时执行某些操作。在 Spring Boot 应用中,CompletableFuture 可以用于提高应用的响应性…...

10Linux 进程管理学习笔记
Linux 进程管理 目录 文章目录 Linux 进程管理一.进程1.显示当前进程状态(ps)进程树(pstree)1.1实时显示进程信息(top)顶部概览信息:CPU 状态:内存状态:进程信息表头:进程列表:1.2(htop) 2.终止进程(kill)2.1通过名称…...

一些关于深度聚类以及部分对比学习的论文阅读笔记
目录 资料SwAV问题方法方法的创新点为什么有效有什么可以借鉴的地方聚类Multi-crop 代码 PCL代码 Feature Alignment and Uniformity for Test Time Adaptation代码 SimSiam 资料 深度聚类算法研究综述(很赞,从聚类方法和深度学习方法两个方面进行了总结࿰…...