About OLE, Drag and Drop

nicotinism 2004-05-06 12:52:08
我想实现类似WinRAR中将目录/文件拖拽出来的功能,实现方法如下:

(1) 继承了MFC的COleDropSource,并实现了其中的QueryContinueDrag(...)接口,
用来设置Drop标志(鼠标左键释放)。
(2) 继承了MFC的COleDataSource,并实现了其中的OnRenderGlobalData(...)接口,
用来延迟提供数据。
(3) 调用pcDataSource->DelayRenderData(CF_HDROP),设置数据格式。
(4) 调用pcDataSource->DoDragDrop(...),开始DragDrop。
(5) 在pcDropSource->QueryContinueDrag(...)返回DRAGDROP_S_DROP后,
在pcDataSource->OnRenderGlobalData(...)中提供实际数据。

我发现pcDataSource->OnRenderGlobalData(...)接口会被系统频繁调用,即使是在
我设置了Drop标志后,仍然会调用多次。而且好像并不是每次都需要将实际数据填
好,由于每次调用时传递的参数都一样,无法判断出哪一次才是真正要数据。在我的
系统上,我只要在第8次调用时将数据填好就行,可是在别的系统上却不对(不同的系
统次数不一样)。由于我的数据量有时会很大,不可能每次调用都提供实际数据。

请教:延迟提供数据的正确方法。谢谢!
...全文
141 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
nicotinism 2004-05-11
  • 打赏
  • 举报
回复
此问题已解决,感谢两位热心参与。
nicotinism 2004-05-10
  • 打赏
  • 举报
回复
to flyhigh(一不小心):
你的代码是DragDrop的立即模式,只适合于少量数据的传递。我的数据量会很大,因此需要延迟提供数据。
flyhigh 2004-05-10
  • 打赏
  • 举报
回复
用下面的代码:

void onbegindrag(...)
{
HGLOBAL hGblFiles;
COleDataSource datasource;
hGblFiles=MakeHDragFilesData();
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
datasource.CacheGlobalData( CF_FAVSOFTDRAGDATA, hGblFiles,&etc );
DROPEFFECT dropEff=datasource.DoDragDrop(DROPEFFECT_COPY ,NULL,NULL);
GlobalFree(hGblFiles);
}

HGLOBAL CSciView::MakeHDragFilesData()
{
HGLOBAL hGblFiles=NULL;
POSITION pos = m_filelstCtrl.GetFirstSelectedItemPosition();
CStringArray files;
int nFileListBufLen=0;
CString cdrompath=GetDocument()->m_CDROMPath;
while (pos)
{
int nItem = m_filelstCtrl.GetNextSelectedItem(pos);
CString filename=cdrompath+m_strPath+m_filelstCtrl.GetItemText(nItem,0);
files.Add(filename);
nFileListBufLen+=filename.GetLength()+1;
}
nFileListBufLen++;

hGblFiles= GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, sizeof(DROPFILES)+nFileListBufLen);
BYTE *szData=(BYTE*)GlobalLock(hGblFiles);
DROPFILES *pDropFiles=(DROPFILES*)szData;
pDropFiles->pFiles =sizeof(DROPFILES);
pDropFiles->pt.x=0;
pDropFiles->pt.y=0;
pDropFiles->fNC =FALSE;
pDropFiles->fWide =FALSE;
int offset=sizeof(DROPFILES);
for(int i=0;i<files.GetSize();i++)
{
CString filename=files.GetAt(i);
memcpy(szData+offset,(LPCTSTR)filename,filename.GetLength());
offset+=filename.GetLength()+1;
}
GlobalUnlock(hGblFiles);
return hGblFiles;
}
nicotinism 2004-05-10
  • 打赏
  • 举报
回复
nicotinism 2004-05-06
  • 打赏
  • 举报
回复
大侠,你的这段代码我省略了没贴(限于篇幅),实际上系统的每次调用不仅lpFormatEtc->cfFormat == CF_HDROP,其他的所有参数都相同。
aspnetwuxueyou 2004-05-06
  • 打赏
  • 举报
回复
// 只处理你想要的格式
if (lpFormatEtc->cfFormat == CF_HDROP )
{
// the pointer is null
if (! phGlobal)
GlobalAlloc()
else
{
*phGlobal = DealGetDropData()
return TRUE;
}

return FALSE;
}
nicotinism 2004-05-06
  • 打赏
  • 举报
回复
BOOL CMyOleDataSource::OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal)
{

if(!g_bDropGetData) return FALSE; // 左键释放标志


if(++g_nCount != 8) // ???????????????
{
return FALSE;
}

if(!*phGlobal)
{
if(*phGlobal = DealGetDropData())
{
return TRUE;
}
}
else //Never execute:
{
AfxMessageBox("*phGlobal != NULL");
}

return FALSE;
}
aspnetwuxueyou 2004-05-06
  • 打赏
  • 举报
回复
把你的OnRenderGlobalData paste出来,
我瞧瞧
内容概要:本文复现并深入探讨了一种基于价格弹性矩阵的居民峰谷分时电价激励策略,属于电力系统需求响应领域的关键技术研究。研究通过构建价格弹性矩阵精确刻画居民用户对不同时段电价变化的用电行为响应特性,结合优化算法设计科学合理的峰谷分时电价方案,有效引导用户在高峰时段减少用电、低谷时段增加用电,实现削峰填谷,提升电网运行稳定性与能源利用效率。文中配套提供了完整的Matlab代码实现,涵盖数据处理、模型构建、优化求解及结果可视化等模块,具有较强的可复现性与工程应用价值,适用于需求侧管理政策仿真与学术研究。; 适合人群:面向具备一定电力系统基础知识、能源经济学或需求响应研究背景的科研人员,以及从事相关课题的硕士、博士研究生;熟悉Matlab编程且关注智能电网优化的技术人员亦可从中获益。; 使用场景及目标:①用于居民侧用电行为建模与电价敏感性分析;②支撑峰谷电价政策的设计、仿真评估与优化调整;③作为高校教学中需求响应机制的算法实现案例与科研入门实践项目。; 阅读建议:建议读者结合Matlab代码逐模块解析其实现逻辑,重点掌握价格弹性矩阵的构造方法、目标函数与约束条件的数学建模过程,以及优化求解器的调用方式,同时可尝试引入其他智能优化算法进行对比实验,以深化对电价激励机制设计原理的理解与创新能力。

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧