【问题标题】:IDataobject->SetData failedIDataobject->SetData 失败
【发布时间】:2011-02-11 01:26:30
【问题描述】:

我尝试使用 IDataObject 将一些文本放入剪贴板。但是 GlobalUnlock 失败了。我做错了什么?

IDataObject *obj;
HRESULT ret;
assert(S_OK == OleGetClipboard(&obj));

FORMATETC fmtetc = {0};
fmtetc.cfFormat = CF_TEXT;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;

STGMEDIUM medium = {0};
medium.tymed = TYMED_HGLOBAL;
char* str = "string";

medium.hGlobal = GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, strlen(str)+1); 
char* pMem = (char*)GlobalLock(medium.hGlobal);
strcpy(pMem,str);
assert(GlobalUnlock(medium.hGlobal) != 0); // !!! ERROR
assert(S_OK == obj->SetData(&fmtetc,&medium,TRUE));
assert(S_OK == OleSetClipboard(obj));

【问题讨论】:

  • 那么,当 GlobalUnlock() 失败时,GetLastError() 是什么?另外,你确定 GlobaAlloc() 和 GlobalLock() 成功了吗?
  • GetLastError 在失败时不包含任何信息。而且,alloc/lock 没有问题。

标签: c++ windows com


【解决方案1】:

好吧,在查看documentation 之后,这是意料之中的:

返回值

如果在递减锁计数后内存对象仍处于锁状态,则返回值为非零值。如果在递减锁计数后内存对象被解锁,则函数返回零,GetLastError 返回 NO_ERROR。

如果函数失败,返回值为零,GetLastError 返回一个不是 NO_ERROR 的值。

所以你的断言是错误的;应该是:

assert(GlobalUnlock(medium.hGlobal) == 0 && GetLastError() == NO_ERROR);

【讨论】:

  • 我多么愚蠢,我已经纠正了。但是 SetData 仍然失败。返回E_FAIL,GetLastError返回0。实际上,我可以使用OleGetClipboard来获取写入接口吗?
  • 我最终决定使用 Windows API SetClipboardData。这更容易。
猜你喜欢
  • 2021-01-16
  • 2020-09-09
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2012-10-22
  • 2010-12-25
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多