我用WTL 开发界面程序,实现将IE的链结拖动(不是文件拖动)的主程序窗体,从面获取IE链结地址。(就像FLASHGET 等一些下载工具都有这功能,不过他们都不用WTL开发)。请哪位大侠指点实现此功能,谢谢。

解决方案 »

  1.   

    参考:
    http://www.vckbase.com/document/viewdoc/?id=258
      

  2.   

    请各位帮帮忙呀,本人开发的程序,不用的MFC了,不知该怎做呀。
      

  3.   

    这个跟用不用 WTL 无关。 首先你的程序需要实现 IDropTarget 接口,
    然后向系统注册拖拽的窗口句柄,RegisterDragDrop(...)
    当有拖拽Data 进入到你的窗口时调用 DragEnter 方法,你可以查询 拖拽Data 所支持的数据格式,
    对于IE链结拖动,他的 格式名称是 UniformResourceLocator, 下面的代码是取url 的过程: 
    p 就是链结urlDragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
    {
    IEnumFORMATETC* p=NULL;
    pDataObject->EnumFormatEtc(DATADIR_GET,&p);
    FORMATETC pFormat[20];
    ZeroMemory(&(pFormat[0]),20*sizeof(FORMATETC));
    ULONG uFetched=0;
    p->Next(20,&(pFormat[0]),&uFetched);
    TCHAR szFormatName[MAX_PATH];
    for(int i=0;i<uFetched;i++)
    {

    GetClipboardFormatName(pFormat[i].cfFormat,szFormatName,MAX_PATH);
    if(StrCmp(szFormatName,"UniformResourceLocator")==0)
    {
    FORMATETC urlFe={pFormat[i].cfFormat,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
    STGMEDIUM stg;
    if(FAILED(pDataObject->GetData(&urlFe,&stg)))
    {
    MessageBox(NULL,"Uniform Resource Locator Get Data Failure!","Get Data",MB_OK); }
    else
    {
    switch(stg.tymed)
    {
    case TYMED_HGLOBAL:
    {
    char* p=(char*)GlobalLock(stg.hGlobal);
    MessageBox(NULL,p,"URL",MB_OK);
    if(stg.pUnkForRelease==NULL)
    {
    GlobalFree(stg.hGlobal);
    }
    }
    break;
    default:
    }
    ReleaseStgMedium(&stg);
    }
    }
    }
    }
      

  4.   

    请问怎样实现IDropTarget 接口,怎样注册我的拖拽的窗口句柄。
    谢谢!
      

  5.   

    如果使用WTL使用这段代码
    class CShowInfoWnd : 
             public CScrollWindowImpl<CShowInfoWnd>,
    public IDropTargetImpl<CShowInfoWnd>
    {
             BEGIN_MSG_MAP(CShowInfoWnd)
    MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
    CHAIN_MSG_MAP(IDropTargetImpl<CShowInfoWnd>)
    CHAIN_MSG_MAP(CScrollWindowImpl<CShowInfoWnd>)
    MESSAGE_HANDLER(WM_SIZE,OnSize)
    END_MSG_MAP()
           HRESULT OnDrop (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    if(!IsDragToSameWnd())
    {
    string yourLinker;
    GetTextData(m_yourLinker,pDataObject);
    }
    return S_OK;
    }
    };
    //IDropTarget&frac12;&Oacute;&iquest;&Uacute;&Ecirc;&micro;&Agrave;&yacute;,&cedil;&Atilde;&Ecirc;&micro;&Agrave;&yacute;&Oacute;&Eacute;&acute;°&iquest;&Uacute;&para;&Ocirc;&Iuml;ó&frac14;&Igrave;&sup3;&ETH;,&sup2;&raquo;&raquo;á&Oacute;&Eacute;&frac12;&Oacute;&iquest;&Uacute;&micro;&Auml;Release&Ecirc;&Iacute;·&Aring;&cedil;&Atilde;&para;&Ocirc;&Iuml;ó,&acute;°&iquest;&Uacute;&Iuml;&ucirc;&Atilde;&eth;&Ecirc;±IDropTarget&sup2;&raquo;&iquest;&Eacute;&Oacute;&Atilde;
    template <class T>
    class ATL_NO_VTABLE IDropTargetImpl :
    public IDropTarget,
    public CMessageMap
    {
    public:
    BEGIN_MSG_MAP(IDropTargetImpl)
    MESSAGE_HANDLER(WM_CREATE,OnCreate)
    MESSAGE_HANDLER(WM_DESTROY,OnDestory)
    END_MSG_MAP() LRESULT OnCreate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
    T* pT = static_cast<T*>(this);
    IDropTarget *pDropTarget;
    QueryInterface(IID_IDropTarget,(void **)&pDropTarget);
    CoLockObjectExternal(pDropTarget, TRUE, FALSE); //&Euml;&oslash;&para;¨&cedil;&Atilde;&para;&Ocirc;&Iuml;ó&Ecirc;&sup1;&Euml;ü&Ograve;&raquo;&Ouml;±&Ocirc;&Uacute;&Auml;&Uacute;&acute;&aelig;&Ouml;&ETH;
    RegisterDragDrop(pT->m_hWnd, pDropTarget); //&Ecirc;&sup1;&cedil;&Atilde;&acute;°&iquest;&Uacute;&iquest;&Eacute;&Ograve;&Ocirc;&frac12;&Oacute;&Ecirc;&Otilde;&Iacute;&ETH;&para;&macr;
    bHandled=FALSE;
    return S_OK;
    }
    LRESULT OnDestory(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
    T* pT = static_cast<T*>(this);
    RevokeDragDrop(pT->m_hWnd); //&Egrave;&iexcl;&Iuml;&ucirc;&acute;°&iquest;&Uacute;&iquest;&Eacute;&Ograve;&Ocirc;&frac12;&Oacute;&Ecirc;&Otilde;&Iacute;&ETH;&para;&macr;&micro;&Auml;&Auml;&Uuml;&Aacute;&brvbar;
    IDropTarget *pDropTarget;
    QueryInterface(IID_IDropTarget,(void **)&pDropTarget);
    HRESULT hr=CoLockObjectExternal(pDropTarget, FALSE, TRUE); //&Egrave;&iexcl;&Iuml;&ucirc;&para;&Ocirc;&Iuml;ó&Euml;&oslash;&para;¨
    bHandled=FALSE;
    return S_OK;
    } //IUnknown implementation
    HRESULT __stdcall QueryInterface (REFIID iid, void ** ppvObject)
    {
    if(iid == IID_IDropTarget || iid == IID_IUnknown)
    {
    AddRef();
    *ppvObject = this;
    return S_OK;
    }
    else
    {
    *ppvObject = 0;
    return E_NOINTERFACE;
    }
    }
    ULONG __stdcall AddRef (void){return 1;}
    ULONG __stdcall Release (void){return 1;}
    //&raquo;&Oslash;&micro;÷&ordm;&macr;&Ecirc;&yacute;
    //pdwEffect &Ecirc;&ocirc;&ETH;&Ocirc;&Euml;&micro;&Atilde;÷
    // DROPEFFECT_NONE = &Icirc;&THORN;&Iacute;&ETH;&para;&macr;&Oacute;&ETH;&ETH;§&ETH;&Ocirc;
    // DROPEFFECT_COPY = &Icirc;&ordf;&iquest;&frac12;±&acute;&Ntilde;ù&Ecirc;&frac12;&micro;&Auml;&Iacute;&ETH;&para;&macr;
    // DROPEFFECT_MOVE = &Icirc;&ordf;&Ograve;&AElig;&para;&macr;&Ntilde;ù&Ecirc;&frac12;&micro;&Auml;&Iacute;&ETH;&para;&macr;
    // &micro;±&Iacute;&ETH;&para;&macr;&frac12;&oslash;&Egrave;&euml;&cedil;&Atilde;&acute;°&iquest;&Uacute;&Ecirc;±(&Ecirc;&yacute;&frac34;&Yacute;&Iacute;&ETH;&para;&macr;&frac12;&oslash;&acute;°&iquest;&Uacute;&Ecirc;±,&Aring;&ETH;&para;&Iuml;&acute;°&iquest;&Uacute;&Ecirc;&Ccedil;·&ntilde;&Ouml;§&sup3;&Ouml;&cedil;&Atilde;&Ecirc;&yacute;&frac34;&Yacute;,&Egrave;&ccedil;&sup1;&ucirc;&sup2;&raquo;&Ouml;§&sup3;&Ouml;&Eacute;è&Ouml;&Atilde;*pdwEffect=DROPEFFECT_NONE)
    HRESULT OnDragEnter(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
    {
    return S_OK;
    }
    HRESULT OnDragOver (DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    return S_OK;
    }
    HRESULT OnDragLeave()
    {
    return S_OK;
    }
    HRESULT OnDrop (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    return S_OK;
    }
    // IDropTarget implementation
    HRESULT __stdcall DragEnter (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    T* pT = static_cast<T*>(this);
    return pT->OnDragEnter(pDataObject, grfKeyState, pt,  pdwEffect);
    }
    HRESULT __stdcall DragOver (DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    T* pT = static_cast<T*>(this);
    return pT->OnDragOver (grfKeyState, pt, pdwEffect);
    }
    HRESULT __stdcall DragLeave (void)
    {
    T* pT = static_cast<T*>(this);
    pT->OnDragLeave ();
    return S_OK;
    }
    HRESULT __stdcall Drop (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    T* pT = static_cast<T*>(this);
    return pT->OnDrop (pDataObject,grfKeyState, pt, pdwEffect);
    }
    //&cedil;¨&Ouml;ú·&frac12;·¨
    public:
    DWORD DropEffect(DWORD grfKeyState, POINTL pt, DWORD dwAllowed)
    {
    DWORD dwEffect = 0;
    // 1. check "pt" -> do we allow a drop at the specified coordinates?
    // 2. work out that the drop-effect should be based on grfKeyState
    if(grfKeyState & MK_CONTROL)
    {
    dwEffect = dwAllowed & DROPEFFECT_COPY;
    }
    else if(grfKeyState & MK_SHIFT)
    {
    dwEffect = dwAllowed & DROPEFFECT_MOVE;
    } // 3. no key-modifiers were specified (or drop effect not allowed), so
    //    base the effect on those allowed by the dropsource
    if(dwEffect == 0)
    {
    if(dwAllowed & DROPEFFECT_COPY) dwEffect = DROPEFFECT_COPY;
    if(dwAllowed & DROPEFFECT_MOVE) dwEffect = DROPEFFECT_MOVE;
    }
    return dwEffect;
    }
    // QueryDataObject private helper routine
    BOOL QueryDataObject(FORMATETC &fmtetc,IDataObject *pDataObject)
    {
    return pDataObject->QueryGetData(&fmtetc) == S_OK ? TRUE : FALSE;
    }
    BOOL GetTextData(string &text,IDataObject *pDataObject)
    {
    FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; //CF_TEXT&cedil;&ntilde;&Ecirc;&frac12;
    STGMEDIUM stgmed;
    BOOL isRight=FALSE;
    if(pDataObject->QueryGetData(&fmtetc) == S_OK)
    {
    if(pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
    {
    LPVOID data = GlobalLock(stgmed.hGlobal);
    text=(char *)data;
    GlobalUnlock(stgmed.hGlobal);
    ReleaseStgMedium(&stgmed);// release the data using the COM API
    isRight=TRUE;
    }
    }
    return isRight;
    }
    };
      

  6.   

    请问怎样注册对象,实现IDropTarget。谢谢
      

  7.   

    不用注册对象,直接使用就行了,
    1.由于托动目标和窗口对应,所以在你要接收托动的窗口增加托动目标的支持
    public IDropTargetImpl<CShowInfoWnd>
    2.在该窗口的消息处理映射宏中增加
    CHAIN_MSG_MAP(IDropTargetImpl<CShowInfoWnd>)
    由IDropTargetImpl自动完成托动目标的初始化和释放操作,也就是你说的注册不不是(这不要你作)
    3.增加托动消息处理函数,由IDropTargetImpl中回调,当有信息托动到该窗口时自动回调到它这个虚函数
    HRESULT OnDrop (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
    {
    if(!IsDragToSameWnd()) //判断是否托动源和目标是同一个窗口
    {
    string yourLinker; //如果托动的是连接,那你的连接放在这个字符串中
    GetTextData(m_yourLinker,pDataObject); //这是IDropTargetImpl支持,它获取剪切板为文本类型的信息
    }
    return S_OK;
    }
    就这样就完成你的要求了
    IDropTargetImpl在上面的文章中以有了你拷贝下来就可以了中间的;&Iacute些是在拷贝时中文的乱码问题不要求可以了
      

  8.   

    对了,注册是在WM_CREATE中进行的,注销是在WM_DESTORY中进行的
      

  9.   

    谢谢!但我还是不知怎么用 RegisterDragDrop() 函数,能否再指点一下。
      

  10.   

    MSDN中
    WINOLEAPI RegisterDragDrop(
      HWND hwnd,  //Handle to a window that can accept drops
      IDropTarget * pDropTarget //Pointer to object that is to be target of drop
    );
    hwnd [in] Handle to a window that can be a target for an OLE drag-and-drop operation. pDropTarget [in] Pointer to the IDropTarget interface on the object that is to be the target of a drag-and-drop operation in a specified window. This interface is used to communicate OLE drag-and-drop information for that window. 
      

  11.   

    我就是不知怎么得到IDropTarget * pDropTarget 这具对像了,请您 多多指点,跪谢!
      

  12.   

    我是让框架接受拖拽,其它部分与上面一样,可是就是框架就是不接受
    class CMainFrame :  public CFrameWindowImpl<CMainFrame>,
    public IDropTargetImpl<CMainFrame>,
    public CUpdateUI<CMainFrame>,
    public CMessageFilter, 
    public CIdleHandler
      

  13.   

    你增加
    CHAIN_MSG_MAP(IDropTargetImpl<CMainFrame>)没有
    还是就是你的
    WM_CREATE 中的消息处理函数中Handle 要为FALSE
    或放到CHAIN_MSG_MAP(IDropTargetImpl<CMainFrame>)的第行
      

  14.   

    IDropTarget 是一个接口,从IDropTargetImpl<CMainFrame>继承那到IDropTarget接口的对象就是窗口类本身(CMainFrame )
      

  15.   

    大哥,我都照做了,可还是不行,应该是我哪里错了。我贴出代码一部份,能帮我看看么。谢谢!pragma once
    #include "DropTarget.h"   //DropTarget.hb 是你贴出的内容
    class CMainFrame :  public CFrameWindowImpl<CMainFrame>,
    public IDropTargetImpl<CMainFrame>,
    public CUpdateUI<CMainFrame>,
    public CMessageFilter, 
    public CIdleHandler
    {
    public:
    DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME) CTuotuTestView m_view;
    CCommandBarCtrl m_CmdBar; virtual BOOL PreTranslateMessage(MSG* pMsg);
    virtual BOOL OnIdle();
    BEGIN_UPDATE_UI_MAP(CMainFrame)
    UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
    UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
    END_UPDATE_UI_MAP() BEGIN_MSG_MAP(CMainFrame)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
    COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
    COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
    COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
    COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
    MESSAGE_HANDLER(WM_DROPFILES, OnDropFiles)
    CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
    CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
    CHAIN_MSG_MAP(IDropTargetImpl<CMainFrame>)
    END_MSG_MAP()
     
    HRESULT OnDrop (IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
    {
    //if(!IsDragToSameWnd())
    {
    string yourLinker;
    GetTextData(yourLinker,pDataObject);
    //GetTextData(yourLinker,pDataObject);
    ::MessageBox(NULL,yourLinker.c_str(),"",0);
    }
    return S_OK;
    }         LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
             {
                  ......
         RegisterDragDrop(m_hWnd,this);
         return 0;
             }       .....
    }
      

  16.   

    1.在_tWinMain 内加入hRes=::OleInitialize(NULL);不然会出错
    2.
    BEGIN_MSG_MAP(CMainFrame)
    CHAIN_MSG_MAP(IDropTargetImpl<CMainFrame>)发在第一行
             ...
    END_MSG_MAP()

    LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
             {
                  ...
                  bHandled=FALSE;
         return 0;
             }3.你的OnCreate中RegisterDragDrop(m_hWnd,this);不要
    LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
             {
                  ......
         return 0;
             }
      

  17.   

    在tWinMain 最后加::OleUninitialize();
    int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
    {
    HRESULT hRes = ::CoInitialize(NULL);
    hRes=::OleInitialize(NULL);
             .........
             .........
    ::CoUninitialize();
    ::OleUninitialize();
    return nRet;
    }