Raymond Chen 2008年03月13日
麻烦的拖拽:拖拽统一资源定位符(URL)和文本
简要
这篇文章主要讲述了如何在Windows编程中实现一个可以同时处理文本和URL数据的拖拽功能,通过扩展数据类型枚举、设置格式等和响应数据请求来实现。
正文
我们已经学会了如何拖拽文本以及如何拖拽统一资源定位符(URL),但如果我们想要同时拖拽两者呢?这实际上是一个简单的问题,只需要声明你拥有两者(实际上是按需生成它们)。
首先,通过扩展数据类型的枚举来包括URL和文本:
enum {
DATA_URL,
DATA_TEXT,
DATA_NUM,
DATA_INVALID = -1,
};
在我们设置这个枚举时有一个微妙之处:我们把DATA_URL
放在DATA_TEXT
前面,这样由SHCreateStdEnumFormatEtc
生成的剪贴板格式就会按优先级顺序生成(质量最高的在前)。通过首先枚举URL,一个同时理解URL和文本格式的程序将会知道优先选择URL。在这个特定的例子中,这并不是非常关键,因为大多数文本编辑器都会自动检测URL(至少如果URL以“http:”开头的话),但在更一般的情况下,按优先级顺序枚举格式可以产生很大的不同。例如,你的数据对象可能同时提供富文本格式和纯文本格式的文本,如果一个同时理解这两种格式的程序默认使用富文本版本而不是纯文本版本,那可能会更好。
一旦我们有了这两种格式,我们需要对它们都做出响应。在我们的构造函数中,我们必须描述这两种格式,以便GetDataIndex
和EnumFormatEtc
了解它们。
CTinyDataObject::CTinyDataObject() : m_cRef(1)
{
SetFORMATETC(&m_rgfe[DATA_URL],
RegisterClipboardFormat(CFSTR_SHELLURL));
SetFORMATETC(&m_rgfe[DATA_TEXT], CF_TEXT);
}
然后是数据对象核心的更改,IDataObject::GetData
方法,反而显得平淡无奇:
HRESULT CTinyDataObject::GetData(FORMATETC *pfe, STGMEDIUM *pmed)
{
ZeroMemory(pmed, sizeof(*pmed));
switch (GetDataIndex(pfe)) {
case DATA_URL:
case DATA_TEXT:
pmed->tymed = TYMED_HGLOBAL;
return CreateHGlobalFromBlob(c_szURL, sizeof(c_szURL),
GMEM_MOVEABLE, &pmed->hGlobal);
}
return DV_E_FORMATETC;
}
无论调用者请求文本还是URL,我们都给他们返回相同的字符串。
当您运行这个程序时,请注意它结合了前两个程序的功能。您可以将文本拖入Wordpad,将URL拖放到Firefox上,并将URL拖放到Internet Explorer上。
这些都只是热身。休息一会儿之后,我们将开始在我们的数据对象中提供更复杂的数据。
标签:Old,URL,TEXT,Locator,pmed,文本,DATA,拖拽 From: https://blog.csdn.net/weixin_41863029/article/details/139393017