最近项目中用到了OLE 拖拽功能
和BCB 一个Form的Drag 不同的是,只有实现了OLE 拖拽才能,从其他程序拖拽数据到Form
下面的代码实现了,同HTML网页拖拽到Form时,Form获得HTML数据
其核心思想是,
1,要实现 COM的 IDropTarget 接口
2,RegisterDragDrop(handle,this); 注册窗口的拖拽
3,窗口类构造 OleInitialize(NULL);
4,窗口类析构时 OleUninitialize();
5,在下面的代码中,我将IDropTarget 接口封装为类TOleDragAndDrop
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include <OLEIDL.h> #include <SysUtils.hpp> #include <ObjIdl.h> //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; /*实现IDropTarget COM接口*/ class TOleDragAndDrop : public TObject, public IDropTarget, public IUnknown { private: HANDLE d_handle;//注册的窗体句柄 volatile LONG d_ref; //引用计数器 public: //构造是注册OLEDragDrop TOleDragAndDrop(HANDLE handle) { d_ref = 0; d_handle = handle; RegisterDragDrop(handle,this); } //必须虚函数,以调用父类的析构 __fastcall ~TOleDragAndDrop() { RevokeDragDrop(d_handle); //调用父类的析构 } //实现COM要求的QueryInterface HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject) { HRESULT result=S_OK; if (GetInterface(iid,ppvObject)) result=S_OK; else result=E_NOINTERFACE; return result; } //实现COM要求的引用计数器 ULONG STDMETHODCALLTYPE AddRef(void) { ULONG result = InterlockedDecrement(&d_ref); return result; } //实现COM要求的释放接口 ULONG STDMETHODCALLTYPE Release(void) { ULONG result = InterlockedDecrement(&d_ref); return result; } //实现IDropTarget 中的DragOver HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt,DWORD *pdwEffect) { //ShowMessage("drag over"); return S_OK; } //实现IDropTarget 中的DragEnter HRESULT STDMETHODCALLTYPE DragEnter(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt,DWORD * pdwEffect) { //ShowMessage("drag enter"); return S_OK; } //实现IDropTarget 中的DragLeave HRESULT STDMETHODCALLTYPE DragLeave(void) { //ShowMessage("drag leave"); return S_OK; } //实现IDropTarget 中的Drop HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj,DWORD grfKeyState, POINTL pt,DWORD __RPC_FAR *pdwEffect) { AnsiString retStr; FORMATETC format; int cf_html = RegisterClipboardFormat("HTML Format"); FORMATETC cFmt = {(CLIPFORMAT) CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; cFmt.cfFormat = cf_html; STGMEDIUM stgMedium; pDataObj->GetData(&cFmt, &stgMedium); if(stgMedium.tymed == TYMED_HGLOBAL) { char* html = (char*)GlobalLock(stgMedium.hGlobal); ShowMessage(Utf8ToAnsi(html)); //剩下的就是把<img>。。。</img> 通过XML解析出来 } return S_OK; } }; //--------------------------------------------------------------------------- static TOleDragAndDrop* d_poledragDrop = NULL; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OleInitialize(NULL); d_poledragDrop = new TOleDragAndDrop(Memo1->Handle); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { delete d_poledragDrop; d_poledragDrop = NULL; OleUninitialize(); } //---------------------------------------------------------------------------