您的位置:首页 > 其它

DragSource Lib for BCB使用说明

2007-05-06 11:48 417 查看
如果你想让你的软件可以象WinRAR/WinZip一样支持把文件拖曳到资源管理器里, 或者把图片, 文字拖出到Word里,以增强用户体验, 偶的DragSource Lib 是你很好的选择(怎么有点象广告词?).

在你的线程(注意不是进程)使用DragSource Lib函数之前,都要先调用OleInitialize初始化OLE.

函数:
TDropResult DoDragDrop(char *szText,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE);
开始拖出文本
szText 指向一个以NULL结尾的字符串
dwOKEffect 支持哪些操作(默认支持拷贝和移动),可以是以下几种值的组合:
DROPEFFECT_NONE 什么都不支持
DROPEFFECT_COPY 支持拷贝
DROPEFFECT_MOVE 支持移动
DROPEFFECT_LINK 支持链接
DROPEFFECT_SCROLL 表示拖放目标窗口正在/将要滚动
返回值: 拖动结果(TDropResult::Result)和最终拖动类型(TDropResult::Effect)

TDropResult DoDragDropURL(char *URL,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK);
开始拖出网址URL
URL 网页地址,一个以NULL结尾的字符串.
dwOKEffect 同上, 默认支持(默认支持拷贝,移动,链接)
返回值: 同上

TDropResult DoDragDrop(wchar_t *wszText,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE); //Drag Unicode Text
开始拖出Unicode文本
wszText 以NULL结尾的宽字符串.
dwOKEffect 同上, 默认支持(默认支持拷贝,移动)
返回值: 同上

TDropResult DoDragDrop(HBITMAP hBitmap,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE); //Drag Bitmap
开始拖出BMP图片
hBitmap HBITMAP类型,你应该知道是什么.
dwOKEffect 同上, 默认支持(默认支持拷贝,移动)
返回值: 同上

TDropResult DoDragDrop(const THDROP_Files &files,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK);
开始拖出文件
files THDROP_Files类型, 存放要被拖出的文件名
dwOKEffect 同上, 默认支持(默认支持拷贝,移动,链接)
返回值: 同上

TDropResult DoDragDrop(FORMATETC *fmtetc, STGMEDIUM *stgmeds,UINT count=1,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE);
用于同时拖出多种格式,比如拖到资源管理器里表现为文件拖动,拖到Word里表现为文字
fmtetc FORMATETC数组(定义查MSDN),指出每个数据的格式类型
stgmeds STGMEDIUM数组(定义查MSDN),存储数据指针
count 格式种类数,也就是FORMATETC数组和STGMEDIUM数组的大小.
dwOKEffect 同上.
返回值: 同上

TDropResult DoDragDrop(CLIPFORMAT ctFormat,DWORD tymed,void *hStorage,
DWORD dwOKEffect=DROPEFFECT_COPY|DROPEFFECT_MOVE);
拖出一个自定义格式数据
ctFormat CLIPFORMAT(还得查MSDN),CLIPFORMAT常用于表示剪切板里的数据类型.
tymed 存储媒介类型,是在内存里的还是文件里的? 也可以查MSDN(关键字:TYMED)
hStorage 存储媒介指针,实际上它是STGMEDIUM里的hGlobal/hBitmap/lpszFileName...项,注意调用后hStorage里的数据将被自动释放
dwOKEffect 同上.
返回值: 同上

HANDLE MemToHandle (void *pMem, int nSize);
生成适用于DoDragDrop(CLIPFORMAT ctFormat,DWORD tymed,void *hStorage,dwOKEffect)中hGlobal(hStorage)的内存数据.

类:
TDataObject
IDataObject的实现,主要成员函数:
void Add(FORMATETC *fmtetc, STGMEDIUM *stgmeds, UINT count); 添加多个数据类型,参考DoDragDrop的定义
void Add(CLIPFORMAT ctFormat,DWORD tymed,void *hStorage); 添加一个数据类型,参考DoDragDrop的定义
size_t size(); 类型种类数
bool empty(); 是否为空
void Clear(); 清空数据
void ClearAndRelease(); 清空并释放数据

TDropSource
IDropSource的实现

TDataObject和TDropSource用于和WINAPI DoDragDrop合作.

THDROP_Files
文件列表类,继承自std::vector<std::string>,用于DoDragDrop(const THDROP_Files &files,dwOKEffect)函数,主要成员函数:
void *Create_HDROP() const; 根据文件列表生成HDROP数据类型(这可以偶花了一下午时间摸索出来的,偶在MSDN里没查到相关资料,好在比较简单)

例:
BCB6里新建一工程:

Form1的OnCreate和OnDestroy分别调用OleInitialize(NULL)和OleUninitialize().
Form1->OnMouseDown:
{
Tag=1; // Tag=1用来表示鼠标已按下
}
Form1->OnMouseUp:
{
Tag=0; // Tag=0用来表示鼠标已松开
}
Form1->OnMouseMove:
{
if(Tag)
{
DoDragDrop("Hello EveryOne!");
Tag=0;
}
}
编译执行,按住Form1(不是标题栏,是客户区)拖动鼠标到WordPad里试试.

然后把
DoDragDrop("Hello EveryOne!");
改成:
DoDragDropURL("http://www.csdn.net");
再拖到IE里试试

再改成
Graphics::TBitmap *bmp=new Graphics::TBitmap;
bmp->Width = Form1->ClientWidth;
bmp->Height = Form1->ClientHeight;
Form1->PaintTo(bmp->Canvas,0,0);
DoDragDrop(bmp->Handle);
delete bmp;
再拖动到WordPad里试试?

再改一把:
THDROP_Files files;
files.push_back(Application->ExeName.c_str());
files.push_back(ChangeFileExt(Application->ExeName,".cpp").c_str());
DoDragDrop(files,DROPEFFECT_COPY);
这次请拖到桌面上试试,是不是多了什么? :)

最后再试一个复杂点的(同时支持多种格式):
TDataObject DataObject;
TDropSource DropSource;

THDROP_Files files;
files.push_back(Application->ExeName.c_str());
files.push_back(ChangeFileExt(Application->ExeName,".cpp").c_str());

DataObject.Add(CF_TEXT,TYMED_HGLOBAL,MemToHandle("Hahahaha",8));
DataObject.Add(CF_HDROP,TYMED_HGLOBAL,files.Create_HDROP());

DWORD dwEffect;
DoDragDrop(&DataObject, &DropSource, DROPEFFECT_COPY , &dwEffect);

DataObject.ClearAndRelease(); //帮我们把MemToHandle和files.Create_HDROP()生成的内存给清理掉

这次要用Word试了, WordPad有时会先处理我们拖进去的文件, 晕~~. 试完Word再试桌面:)

如有更多细节问题或BUG请在Blog上留言.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: