Drag-and-drop from IE 9 into my application

2020-07-22 19:53发布

It's kind of weird issue, let me try to explain. I wrote a (dialog based) app in c++/MFC that supports drag-n-dropping.

I do the following test on Windows 7 with default themes. My app is running on the screen. It is not a top window (in its z-order) or in other words it's obscured by other windows on top of it.

If I begin dragging a link or just a text selection from the Chrome or Firefox web browser, first into my app's icon on the taskbar, the icon flashes and my app pops up on the screen (by receiving the top z-order) so I can then drag-and-drop into my app. Everything works fine.

If I do the same from IE 9 (version 9.0.8112, update versions 9.0.12) when I drag selected text or a link first to the taskbar icon of my app to make my app become top window (in z-order), the app icon continues flashing but it never gets shown on the screen like it happens with Chrome or FF, so as a result I have to abandon my drag-and-drop.

Any idea why is it happening like that with IE and if there's a way to fix it?

EDIT: Here's the code sample in regards to my comments below:

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;
}

1条回答
太酷不给撩
2楼-- · 2020-07-22 20:15

As part of its sandboxing to prevent unauthorized changes to the machine, Internet Explorer runs in a lower UIPI (User Interface Privilege Isolation) integrity level than other apps do. As such, it does not have permission to access your app by default, which is more likely to be running in a medium or high UIPI integrity level (depending on whether it is UAC elevated or not). The flashing taskbar button means that something is trying to bring your app to the foreground but does not have permission to do so (see the documentation of SetForegroundWindow() for more details). UIPI does not allow a lower-integrity process to send window messages to a higher-integrity process unless the receiving process explicitally tells UIPI to allow it. Chrome and FireFox are likely running in the same integrity level as your app. In order to support drag-and-drop from Internet Explorer, call ChangeWindowMessageFilter() or ChangeWindowMessageFilterEx() to let your app receive WM_DROPFILES, WM_COPYDATA, and WM_COPYGLOBALDATA (0x0049) messages from lower-integrity processes.

Update: It looks like Internet Explorer in particular imposes additional restrictions on drag&drop operations when it is running in Protected Mode:

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

查看更多
登录 后发表回答