c# - 什么是 Windows 剪贴板 CF_ 格式,如 -16230、-15835、-15834 等?
问题描述
我能找到的所有格式都在 MS 文档中。在尝试实现文件拖放(从我的应用程序到 Windows 的文件资源管理器)时,我收到很多对-16230、-15835、-15834 等值的GetData
请求cfFormat
,但我不知道它们是什么。
[当我尝试使用该功能将文件名从我的应用程序拖到文件资源管理器时的完整日志DoDragDrop
。]
Mouse Down
EnumFormatEtc
EnumFormatEtc::Next(1)
EnumFormatEtc::Next(1)
EnumFormatEtc::Reset
EnumFormatEtc::Next(1)
EnumFormatEtc::Next(1)
QueryGetData(cf = 15, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16230, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15835, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15834, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15833, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16215, ty = TYMED_ISTREAM, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
QueryGetData(cf = -16230, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15797, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
GetData(cf = -16206, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -15832, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
GetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
Returning null.
SetData(cf = -16207, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
SetData(cf = -15864, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
SetData(cf = -15835, ty = TYMED_HGLOBAL, asp = DVASPECT_CONTENT)
【相关代码】
public void GetData(ref FORMATETC format, out STGMEDIUM medium)
{
Debug.WriteLine($"GetData(cf = {format.cfFormat}, ty = {format.tymed}, asp = {format.dwAspect})");
if (format.cfFormat == CF_HDROP &&
(format.tymed & TYMED.TYMED_HGLOBAL) == TYMED.TYMED_HGLOBAL)
{
Debug.WriteLine("Returning file drop data");
var mem = CreateDropFiles(new[] { file1, file2
});
medium = new STGMEDIUM();
medium.tymed = TYMED.TYMED_HGLOBAL;
medium.unionmember = mem;
medium.pUnkForRelease = IntPtr.Zero;
}
else
{
Debug.WriteLine("Returning null.");
medium = new STGMEDIUM();
medium.tymed = TYMED.TYMED_NULL;
medium.unionmember = IntPtr.Zero;
medium.pUnkForRelease = IntPtr.Zero;
}
}
public int QueryGetData(ref FORMATETC format)
{
Debug.WriteLine($"QueryGetData(cf = {format.cfFormat}, ty = {format.tymed}, asp = {format.dwAspect})");
if (format.cfFormat == CF_HDROP)
return S_OK;
else
return DV_E_FORMATETC;
}
public void SetData(ref FORMATETC formatIn, ref STGMEDIUM medium, bool release)
{
Debug.WriteLine($"SetData(cf = {formatIn.cfFormat}, ty = {formatIn.tymed}, asp = {formatIn.dwAspect})");
}
我使用了FORMATETC
in System.Runtime.InteropServices.ComTypes
,它有public short cfFormat
,但是在 Windows 的 API 中,它被定义为CLIPFORMAT cfFormat
, which 又typedef WORD CLIPFORMAT
, which 又typedef unsigned short WORD;
。所以,对我来说,类型不匹配(短和无符号短)。我不确定这是否重要。
解决方案
首先,你说你有类型不匹配是对的。剪贴板格式未签名。让我们取一个值:
-16230
被视为一个签名的 WORD,这是
0xC09A
这不足为奇。RegisterClipboardFormat的文档是这样说的:
注册的剪贴板格式由 0xC000 到 0xFFFF 范围内的值标识。
剪贴板格式的文档中提到了其他可能的值:
应用程序可以通过定义 CF_PRIVATEFIRST 到 CF_PRIVATELAST 范围内的值来识别私有剪贴板格式
CF_PRIVATEFIRST
通过CF_PRIVATELAST
映射0x0200
到0x02FF
。
显然,您会看到其中一种已注册的剪贴板格式。要查看它到底是什么类型,您需要GetClipboardFormatName
在遇到值时调用。它可能会不时更改,因为这些值是在不同组件注册其剪贴板格式时分发的。
推荐阅读
- msbuild - 从另一个程序调用时,Msbuild 无法指定配置
- ios - 使用 Codable 从 2 个不同的 JSON 文件中实例化单个类,而不使用可选项
- angular - 如何以角度的一种形式(反应形式)编写多个验证器函数?
- android - ConstraintLayout margin_top 不起作用?
- c# - 读取多行并在空间 c# 控制台应用程序上拆分
- android - xml-Icons 显示为白色,带有 apilvl 24&25
- c# - 试图在 C# 中检索 Mysql 数据库中的图像,但 mysql 显示错误“参数无效”
- javascript - 为什么 electron 2.0 不支持 TypeScript (ES6) 导入?
- reactjs - 带有水平道具的平面列表样式
- javascript - 鼠标悬停时如何打开菜单折叠?