Shell 剪贴板格式
Shell 剪贴板格式用于标识通过剪贴板传输的 Shell 数据类型。 大多数 Shell 剪贴板格式标识某种类型的数据,例如文件名列表或指向项标识符列表 (PIDL) 的指针。 但是,某些格式用于源和目标之间的通信。 他们可以通过支持 Shell 操作(例如 优化移动 和 delete_on_paste)来加快数据传输过程。 Shell 数据始终包含在 数据对象 中,该对象使用 FORMATETC 结构作为一种更常规的方式来描述数据。 结构的 cfFormat 成员设置为特定数据项的剪贴板格式。 其他成员提供其他信息,例如数据传输机制。 数据包含在随附的 STGMEDIUM 结构中。
注意
标准剪贴板格式标识符的格式为 CF_XXX。 一个常见示例是CF_TEXT,用于传输 ANSI 文本数据。 这些标识符具有预定义的值,可直接与 FORMATETC 结构一起使用。 除了 CF_HDROP,不预定义 Shell 格式标识符。 除 DragWindow 外,它们的格式CFSTR_XXX。 为了将这些值与预定义格式区分开来,它们通常称为“简单 格式”。 但是,与预定义格式不同,它们必须同时由源和目标注册,然后才能用于传输数据。 若要注册 Shell 格式,请包含 Shlobj.h 头文件并将 CFSTR_XXX 格式标识符传递给 RegisterClipboardFormat。 此函数返回有效的剪贴板格式值,然后可用作 FORMATETC 结构的 cfFormat 成员。
此处,Shell 剪贴板格式根据它们的使用方式分为三组。
传输文件系统对象的格式
这些格式用于传输一个或多个文件或其他 Shell 对象。
- CF_HDROP
- CFSTR_FILECONTENTS
- CFSTR_FILEDESCRIPTOR
- CFSTR_FILENAME
- CFSTR_FILENAMEMAP
- CFSTR_MOUNTEDVOLUME
- CFSTR_SHELLIDLIST
- CFSTR_SHELLIDLISTOFFSET
CF_HDROP
传输一组现有文件的位置时使用此剪贴板格式。 与其他 Shell 格式不同,它是预定义的,因此无需调用 RegisterClipboardFormat。 数据由 STGMEDIUM 结构组成,该结构包含全局内存对象。 结构的 hGlobal 成员指向 DROPFILES 结构作为其 hGlobal 成员。
DROPFILES 结构的 pFiles 成员包含与包含文件名的以 null 结尾的双字符数组的偏移量。 如果要从数据对象中提取CF_HDROP格式,则可以使用 DragQueryFile 从全局内存对象中提取单个文件名。 如果要创建要放置在数据对象中的CF_HDROP格式,则需要构造文件名数组。
文件名数组由一系列字符串组成,每个字符串包含一个文件的完全限定路径,包括终止 NULL 字符。 在最后一个字符串中追加一个 额外的 null 字符以终止数组。 例如,如果正在传输c:\temp1.txt和c:\temp2.txt的文件,则字符数组如下所示:
c:\temp1.txt'\0'c:\temp2.txt'\0''\0'
注意
在此示例中,“\0”用于表示 null 字符,而不是应包含的文本字符。
如果对象作为拖放操作的一部分复制到剪贴板,则 DROPFILES 结构的 pt 成员包含放置对象的点的坐标。 可以使用 DragQueryPoint 提取光标坐标。
如果数据对象中存在此格式,则 OLE 拖动循环使用非 OLE 放置目标模拟 WM_DROPFILES 功能。 如果你的应用程序是 Windows 3.1 系统上拖放操作的源,这一点很重要。
CFSTR_FILECONTENTS
此格式标识符与 CFSTR_FILEDESCRIPTOR 格式一起使用,以像传输文件一样传输数据,无论其实际存储方式如何。 数据由表示一个文件内容的 STGMEDIUM 结构组成。 文件通常表示为流对象,这避免了将文件的内容放置在内存中。 在这种情况下,STGMEDIUM 结构的 tymed 成员设置为 TYMED_ISTREAM,文件由 IStream 接口表示。 该文件也可以是存储或全局内存对象 (TYMED_ISTORAGE或TYMED_HGLOBAL) 。 关联的CFSTR_FILEDESCRIPTOR格式包含每个文件的 FILEDESCRIPTOR 结构,该结构指定文件的名称和属性。
目标将与CFSTR_FILECONTENTS格式关联的数据视为文件。 当目标调用 IDataObject::GetData 来提取数据时,它通过将 FORMATETC 结构的 lindex 成员设置为文件 FILEDESCRIPTOR 结构的从零开始的索引(采用随附的CFSTR_FILEDESCRIPTOR格式)来指定特定文件。 然后,目标使用返回的接口指针或全局内存句柄提取数据。
CFSTR_FILEDESCRIPTOR
此格式标识符与 CFSTR_FILECONTENTS 格式一起使用,以一组文件的形式传输数据。 这两种格式是传输未存储为文件系统文件的 Shell 对象的首选方法。 例如,这些格式可用于将一组电子邮件作为单个文件传输,即使每封电子邮件实际上作为数据块存储在数据库中。 数据由 STGMEDIUM 结构组成,该结构包含全局内存对象。 结构的 hGlobal 成员指向 FILEGROUPDESCRIPTOR 结构,该结构后跟一个数组,其中包含组中每个文件的一个 FILEDESCRIPTOR 结构。 对于每个 FILEDESCRIPTOR 结构,都有一个单独的CFSTR_FILECONTENTS格式,其中包含文件的内容。 若要标识特定文件的CFSTR_FILECONTENTS格式,请将 FORMATETC 结构的 lIndex 值设置为文件的 FILEDESCRIPTOR 结构的从零开始的索引。
CFSTR_FILEDESCRIPTOR格式通常用于像传输一组文件一样传输数据,而不管实际存储方式如何。 从目标的角度来看,每种CFSTR_FILECONTENTS格式都表示单个文件,并相应地进行处理。 但是,源可以采用它选择的任何方式存储数据。 虽然CSFTR_FILECONTENTS格式可能对应于单个文件,但它也可以表示源从数据库或文本文档提取的数据。
CFSTR_FILENAME
此格式标识符用于传输单个文件。 数据由 STGMEDIUM 结构组成,该结构包含全局内存对象。 结构的 hGlobal 成员指向包含文件的完全限定文件路径的单个 以 null 结尾的字符串。 此格式已被 CF_HDROP 取代,但支持与 Windows 3.1 应用程序向后兼容。
CFSTR_FILENAMEMAP
重命名和传输 CF_HDROP 格式的一组文件时,将使用此格式标识符。 数据由包含全局内存对象的 STGMEDIUM 结构组成。 结构的 hGlobal 成员指向以 null 结尾的双字符数组。 此数组包含每个文件的新名称,其顺序与文件以随附CF_HDROP格式列出的顺序相同。 字符数组的格式与CF_HDROP用于列出传输的文件的格式相同。
CFSTR_MOUNTEDVOLUME
此格式标识符用于传输已装载卷上的路径。 它类似于 CF_HDROP,但它只包含一个路径,并且可以处理在将卷装载到文件夹上时可能需要的较长路径字符串来表示路径。 数据由包含全局内存对象的 STGMEDIUM 结构组成。 结构的 hGlobal 成员指向包含完全限定文件路径的单个 以 null 结尾的字符串。 路径字符串必须以“\”字符结尾,后跟终止 NULL。
在 Windows 2000 之前,卷只能装载在驱动器号上。 对于具有 NTFS 格式驱动器的 Windows 2000 及更高版本系统,还可以将卷装载到空文件夹上。 此功能允许在不占用驱动器号的情况下装载卷。 装载的卷可以使用任何当前支持的格式,包括 FAT、FAT32、NTFS 和 CDFS。
可以通过实现属性表处理程序将页面添加到驱动器 属性属性表。 如果卷装载在驱动器号上,则 Shell 会使用 CF_HDROP 格式将路径信息传递给处理程序。 对于 Windows 2000 及更高版本的系统,当卷装载到驱动器号上时,将使用CF_HDROP格式,就像在早期系统中一样。 但是,如果卷装载在文件夹上,则使用 CFSTR_MOUNTEDVOLUME 格式标识符而不是CF_HDROP。
如果仅使用驱动器号装载卷,则仅使用 CF_HDROP ,现有属性表处理程序将像在早期系统中那样工作。 但是,如果希望处理程序显示文件夹和驱动器号上装载的卷的页面,处理程序必须能够理解CSFTR_MOUNTEDVOLUME和CF_HDROP格式。
CFSTR_SHELLIDLIST
传输一个或多个现有命名空间对象的位置时使用此格式标识符。 它的使用方式与 CF_HDROP 大致相同,但它包含 PIDL 而不是文件系统路径。 使用 PIDL 允许CFSTR_SHELLIDLIST格式处理虚拟对象和文件系统对象。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向 CIDA 结构。
CIDA 结构的 aoffset 成员是一个数组,其中包含要传输的每个 PIDL 的 ITEMIDLIST 结构开头的偏移量。 若要提取特定 PIDL,请先确定其索引。 然后,将对应于该索引的 aoffset 值添加到 CIDA 结构的地址。
aoffset 的第一个元素包含父文件夹的完全限定 PIDL 的偏移量。 如果此 PIDL 为空,则父文件夹为桌面。 数组的每个剩余元素都包含一个要传输的 PIDL 的偏移量。 所有这些 PIDL 都相对于父文件夹的 PIDL。
以下两个宏可用于从 CIDA 结构检索 PIDL。 第一个 采用指向 结构的指针,并检索父文件夹的 PIDL。 第二个采用指向 结构的指针,并检索由其从零开始的索引标识的其他 PIDL 之一。
#define GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
#define GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
注意
这些宏返回的值是指向 PIDL 的 ITEMIDLIST 结构的指针。 由于这些结构的长度各不相同,因此必须通过遍历 每个 ITEMIDLIST 结构的 SHITEMID 结构来确定结构的末尾,直到达到标记末尾的两字节 NULL 。
CFSTR_SHELLIDLISTOFFSET
此格式标识符用于 CF_HDROP、 CFSTR_SHELLIDLIST和 CFSTR_FILECONTENTS 等格式,以指定传输后一组对象的位置。 数据由包含全局内存对象的 STGMEDIUM 结构组成。 结构的 hGlobal 成员指向 POINT 结构的数组。 第一个结构指定包含该组的矩形左上角的屏幕坐标(以像素为单位)。 结构的其余部分指定各个对象相对于组的位置的位置。 它们的顺序必须与用于以关联格式列出对象的顺序相同。
传输虚拟对象的格式
CFSTR_SHELLIDLIST格式可用于传输文件系统和虚拟对象。 但是,也有几种专用格式用于传输特定类型的虚拟对象。
CFSTR_NETRESOURCES
传输网络资源(如域或服务器)时使用此格式标识符。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向 NRESARRAY 结构。 该结构的 nr 成员指示 NETRESOURCE 结构,其 lpRemoteName 成员包含标识网络资源的 null 终止字符串。 然后,放置目标可以将数据与任何 Windows 网络 (WNet) API 函数(如 WNetAddConnection)结合使用,对对象执行网络操作。
CFSTR_PRINTERGROUP
传输打印机的友好名称时使用此格式标识符。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向格式与 CF_HDROP相同的字符串。 但是,DROPFILES 结构的 pFiles 成员包含打印机的一个或多个友好名称,而不是文件路径。
CFSTR_INETURL
此格式标识符替换 CFSTR_SHELLURL (弃用) 。 如果希望应用程序操作剪贴板 URL,请使用 CFSTR_INETURL 而不是CFSTR_SHELLURL (弃用) 。 此格式提供了单个 URL 的最佳剪贴板表示形式。 如果未定义 UNICODE,应用程序将检索 URL 的CF_TEXT/CFSTR_SHELLURL版本。 如果定义了 UNICODE,应用程序将检索 URL 的CF_UNICODE版本。
CFSTR_SHELLURL (已弃用)
注意
此格式标识符已弃用;请改用 CFSTR_INETURL。
源和目标之间的通信格式
这些格式标识符允许在源和目标之间进行通信。 这些格式随数据一起提供,使应用程序可以更好地控制涉及 Shell 对象的移动-复制-粘贴或拖放操作。
- CFSTR_INDRAGLOOP
- CFSTR_LOGICALPERFORMEDDROPEFFECT
- CFSTR_PASTESUCCEEDED
- CFSTR_PERFORMEDDROPEFFECT
- CFSTR_PREFERREDDROPEFFECT
- CFSTR_TARGETCLSID
- CFSTR_UNTRUSTEDDRAGDROP
- DragWindow
CFSTR_INDRAGLOOP
数据对象使用此格式标识符来指示它是否处于拖放循环中。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向 DWORD 值。 如果 DWORD 值为非零值,则数据对象位于拖放循环中。 如果值设置为零,则数据对象不在拖放循环中。
某些放置目标可能会调用 IDataObject::GetData ,并尝试在对象仍处于拖放循环中时提取数据。 为每个此类事件完全呈现 对象可能会导致拖动光标停止。 如果数据对象支持CFSTR_INDRAGLOOP,则目标可以改用该格式来检查拖放循环的状态,并避免在实际删除对象之前对对象进行内存密集型呈现。 要呈现的内存密集型格式仍应包含在 FORMATETC 枚举器和对 IDataObject::QueryGetData 的调用中。 如果数据对象未设置CFSTR_INDRAGLOOP,则其作用应与值设置为零一样。
CFSTR_LOGICALPERFORMEDDROPEFFECT
版本 5.0。此格式标识符允许放置源调用数据对象的 IDataObject::GetData 方法,以确定 Shell 数据传输的结果。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向包含 DROPEFFECT 值的 DWORD。
CFSTR_PERFORMEDDROPEFFECT格式标识符旨在允许目标向数据对象指示实际发生的操作。 但是,Shell 尽可能对文件系统对象使用 优化的移动 。 在这种情况下,Shell 通常会将CFSTR_PERFORMEDDROPEFFECT值设置为DROPEFFECT_NONE,以向数据对象指示原始数据已被删除。 因此,源无法使用CFSTR_PERFORMEDDROPEFFECT值来确定已发生的操作。 虽然大多数源不需要此信息,但也有一些例外情况。 例如,即使经过优化的移动不需要源删除任何数据,源可能仍需要更新相关数据库以指示文件已被移动或复制。
如果源需要知道发生的操作,它可以调用数据对象的 IDataObject::GetData 方法并请求CFSTR_LOGICALPERFORMEDDROPEFFECT格式。 此格式实质上反映了操作完成后用户的观点。 如果创建新文件并删除了原始文件,则用户会看到移动操作,并且格式的数据值设置为DROPEFFECT_MOVE。 如果原始文件仍然存在,则用户会看到复制操作,并且格式的数据值设置为DROPEFFECT_COPY。 如果创建了链接,则会DROPEFFECT_LINK格式的数据值。
CFSTR_PASTESUCCEEDED
目标使用此格式标识符通过其 IDataObject::SetData 方法通知数据对象粘贴时删除操作成功。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向包含 DROPEFFECT 值的 DWORD。 此格式用于通知数据对象应完成剪切操作并删除原始数据(如有必要)。 有关详细信息,请参阅 粘贴时删除操作。
CFSTR_PERFORMEDDROPEFFECT
目标使用此格式标识符通过其 IDataObject::SetData 方法通知数据对象数据传输的结果。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向设置为相应 DROPEFFECT 值的 DWORD,通常DROPEFFECT_MOVE或DROPEFFECT_COPY。
当操作的结果可以是移动或复制时(例如,在 优化的移动 或粘贴时删除操作中),通常使用此格式。 它为目标提供了一种可靠的方法来告知数据对象实际发生的情况。 之所以引入,是因为 DoDragDrop 返回的 pdwEffect 值不能可靠地指示发生了哪个操作。 CFSTR_PERFORMEDDROPEFFECT格式是指示发生了未优化移动的可靠方法。
CFSTR_PREFERREDDROPEFFECT
源使用此格式标识符来指定其首选数据传输方法是移动还是复制。 放置目标通过调用数据对象的 IDataObject::GetData 方法请求此格式。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向 DWORD 值。 如果首选移动操作,此值设置为DROPEFFECT_MOVE;如果首选复制操作,则此值设置为DROPEFFECT_COPY。
当源可以支持移动或复制操作时,将使用此功能。 它使用 CFSTR_PREFERREDDROPEFFECT 格式将其首选项传达给目标。 由于目标没有接受请求的义务,因此目标必须使用CFSTR_PERFORMEDDROPEFFECT格式调用源的 IDataObject::SetData 方法,以告知数据对象实际执行了哪个操作。
通过 粘贴时删除 操作,CFSTR_PREFERREDDROPFORMAT格式用于告知目标源是执行剪切还是复制。 通过拖放操作,可以使用 CFSTR_PREFERREDDROPFORMAT 来指定 Shell 的操作。 如果不存在此格式,Shell 会根据上下文执行默认操作。 例如,如果用户从一个卷拖动文件并将其放在另一个卷上,则 Shell 的默认操作是复制该文件。 通过在数据对象中包含CFSTR_PREFERREDDROPFORMAT格式,可以替代默认操作,并显式告知 Shell 复制、移动或链接文件。 如果用户选择使用右侧按钮拖动,CFSTR_PREFERREDDROPFORMAT在 拖放 快捷菜单上指定默认命令。 用户仍可自由选择菜单上的其他命令。
在 Microsoft Internet Explorer 4.0 之前,应用程序通过在 FILEDESCRIPTOR 结构的 dwFlags 成员中设置FD_LINKUI来指示它正在传输快捷方式文件类型。 然后,目标必须使用对 IDataObject::GetData 的可能耗时调用来确定是否设置了FD_LINKUI标志。 现在,指示正在传输快捷方式的首选方法是使用设置为 DROPEFFECT_LINK 的 CFSTR_PREFERREDDROPEFFECT 格式。 但是,为了与旧系统向后兼容,源仍应设置FD_LINKUI标志。
CFSTR_TARGETCLSID
目标使用此格式标识符向源提供其 CLSID。 数据是包含全局内存对象的 STGMEDIUM 结构。 结构的 hGlobal 成员指向放置目标的 CLSID GUID。
此格式主要用于通过将对象拖动到回收站来删除对象。 在回收站中删除对象时,将调用源的 IDataObject::SetData 方法,CFSTR_TARGETCLSID格式设置为回收站的 CLSID (CLSID_RecycleBin) 。 然后,源可以删除原始对象。
CFSTR_UNTRUSTEDDRAGDROP
Windows Internet Explorer 和 Windows Shell 使用此格式标识符提供一种机制,通过该机制阻止或提示来自 Internet Explorer 的拖放操作以及 URLACTION_SHELL_ENHANCED_DRAGDROP_SECURITY 标志。
CFSTR_UNTRUSTEDDRAGDROP 由拖放操作的源添加,以指定数据对象可能包含不受信任的数据。 数据由包含全局内存对象的 STGMEDIUM 结构表示。 结构的 hGlobal 成员指向设置为适当的 URL 操作标志的 DWORD,以使用 PUAF_ENFORCERESTRICTED 标志通过IInternetSecurityManager::P rocessUrlAction 方法检查策略。
DragWindow
此格式在拖放操作中用于标识对象的拖动图像 (窗口) ,以便可以动态更新其视觉信息。 将对象拖动到放置目标上时,应用程序会更新其 DROPDESCRIPTION 结构,以响应 IDropTarget::D ragOver 或 IDropSource::GiveFeedback 方法。 DROPDESCRIPTION 更新为新的 DROPIMAGETYPE 值,该值指示要应用于拖动窗口视觉对象的修饰;例如,指示正在复制而不是移动文件,或者无法将对象拖放到该位置。 但是,在对象收到 DDWM_UPDATEWINDOW 消息之前,不会更新视觉对象。 此格式向DDWM_UPDATEWINDOW邮件的发件人提供收件人拖动窗口的 HWND。
剪贴板数据的类型为 TYMED_HGLOBAL。 它是 HWND 的 DWORD 表示形式。 可将数据传递给 Basetsd.h 中定义的 ULongToHandle 函数,以提供 64 位 HWND 用于 64 位 Windows。
此格式不需要包含 Shlobj.h。