【问题标题】:Drag-and-drop from IE 9 into my application从 IE 9 拖放到我的应用程序中
【发布时间】:2013-01-23 00:45:20
【问题描述】:

这是一个奇怪的问题,让我试着解释一下。我在支持拖放的 c++/MFC 中编写了一个(基于对话框的)应用程序。

我在 Windows 7 上使用默认主题进行以下测试。我的应用程序正在屏幕上运行。它不是顶部窗口(按其 z 顺序),或者换句话说,它被其顶部的其他窗口遮挡。

如果我开始从 Chrome 或 Firefox 网络浏览器中拖动链接或仅选择文本,首先进入任务栏上我的应用程序图标,该图标会闪烁并且我的应用程序会在屏幕上弹出(通过接收顶部 z-order ) 所以我可以拖放到我的应用程序中。一切正常。

如果我在 IE 9(版本 9.0.8112,更新版本 9.0.12)中执行相同操作,则首先将选定的文本或链接拖到我的应用程序的任务栏图标以使我的应用程序成为顶部窗口(在 z- order),应用程序图标继续闪烁,但它从未像 Chrome 或 FF 那样显示在屏幕上,因此我不得不放弃我的拖放操作。

知道为什么 IE 会出现这种情况吗?是否有办法修复它?

编辑:下面是关于我的 cmets 的代码示例:

HRESULT __stdcall DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
{
    //IDropTarget::DragEnter
    m_fAllowDrop = QueryDataObject(pDataObject);

    if(m_fAllowDrop)
    {
        //SUCCESS
        // get the dropeffect based on keyboard state
    }
    else
    {
        //FAILURE
        *pdwEffect = DROPEFFECT_NONE;
    }

    return S_OK;
}

BOOL QueryDataObject(IDataObject* pDataObject, int* pnOutDataType)
{
    static FORMATETC fmtetc_file = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
    static FORMATETC fmtetc_txt = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};

    BOOL bRes = FALSE;
    HRESULT hr;

    //See if our data type
    hr = pDataObject->QueryGetData(&fmtetc_file);
    if(hr == S_OK)
    {
        bRes = TRUE;
    }

    //In my case hr is E_FAIL or 0x80004005

    hr = pDataObject->QueryGetData(&fmtetc_txt);
    if(hr == S_OK)
    {
        bRes = TRUE;
    }

    //In my case hr is E_FAIL or 0x80004005

    return bRes;
}

【问题讨论】:

    标签: c++ internet-explorer winapi user-interface drag-and-drop


    【解决方案1】:

    作为其沙盒的一部分,以防止对计算机进行未经授权的更改,Internet Explorer 以比其他应用程序更低的 UIPI(用户界面特权隔离)完整性级别运行。因此,默认情况下它没有访问您的应用程序的权限,这更有可能以中等或高 UIPI 完整性级别运行(取决于它是否提升了 UAC)。闪烁的任务栏按钮意味着有东西试图将您的应用程序带到前台但没有这样做的权限(有关更多详细信息,请参阅SetForegroundWindow() 的文档)。 UIPI 不允许低完整性进程向高完整性进程发送窗口消息,除非接收进程明确告诉 UIPI 允许。 Chrome 和 FireFox 可能运行在与您的应用相同的完整性级别。为了支持从 Internet Explorer 拖放,请调用 ChangeWindowMessageFilter()ChangeWindowMessageFilterEx() 以让您的应用接收来自低完整性进程的 WM_DROPFILESWM_COPYDATAWM_COPYGLOBALDATA (0x0049) 消息。

    更新:看起来 Internet Explorer 在保护模式下运行时对拖放操作施加了额外的限制:

    How to handle drag & drop from low integrity Internet Explorer

    Understanding and Working in Protected Mode Internet Explorer - Allowing Drag and Drop Operations in your Application

    【讨论】:

    • 感谢您的信息。我现在可以将文件拖到我的应用程序中,尽管“放置”部分似乎不起作用。出于某种原因,当我从 IE 拖动文本时,从处理 QueryDataObject 调用的 IDataObject::QueryGetData 返回 0x80004005E_FAIL
    • 您查询的是IDataObject实际支持的数据格式吗?
    • 我用代码更新了我的原始帖子。如果您查看QueryDataObject 方法,我在CF_HDROPCF_UNICODETEXT 两种情况下得到的HRESULTE_FAIL。我不知道为什么? PS。请注意,上面的代码适用于 Chrome 和 FF。 PS2。仅供参考,我正在拖动文本选择。
    • 你试过CF_TEXTCFSTR_INETURL了吗?除了TYMED_HGLOBAL,您是否尝试过使用其他TYMED 值?您是否尝试过使用IDataObject::EnumFormatEtc() 找出IDataObject 中实际可用的格式以及QueryGetData() 可用的格式?仅仅因为某些东西适用于 Chrome/FF 并不能保证它适用于 IE。毕竟,它们是独立的应用程序。它们不必使用完全相同的格式。
    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 2011-05-28
    • 2013-09-17
    • 1970-01-01
    相关资源
    最近更新 更多