最近项目中用到了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();
}
//---------------------------------------------------------------------------

 

分类:

技术点:

相关文章: