这是个奇怪的问题,让我试着解释一下。我用支持拖放的 c++/MFC 编写了一个(基于对话框的)应用程序。
我在 Windows 7 上使用默认主题进行了以下测试。我的应用程序正在屏幕上运行。它不是顶部窗口(按其 z 顺序),或者换句话说,它被顶部的其他窗口遮挡了。
如果我开始从 Chrome 或 Firefox 网络浏览器中拖动一个链接或只是一个文本选择,首先拖到任务栏上我的应用程序图标中,该图标会闪烁并且我的应用程序会在屏幕上弹出(通过接收顶部的 z 顺序) 这样我就可以拖放到我的应用程序中。一切正常。
如果我从 IE 9(版本 9.0.8112,更新版本 9.0.12)执行相同的操作,当我首先将选定的文本或链接拖到我的应用程序的任务栏图标以使我的应用程序成为顶部窗口(在 z-订单),应用程序图标继续闪烁,但它永远不会像 Chrome 或 FF 那样显示在屏幕上,因此我不得不放弃拖放操作。
知道为什么 IE 会出现这种情况吗?是否有解决方法?
编辑:下面是关于我的评论的代码示例:
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;
}
最佳答案
作为防止对计算机进行未经授权的更改的沙盒的一部分,Internet Explorer 以比其他应用程序更低的 UIPI(用户界面特权隔离)完整性级别运行。因此,默认情况下它没有访问您的应用程序的权限,这更有可能以中等或高 UIPI 完整性级别运行(取决于它是否提升了 UAC)。闪烁的任务栏按钮意味着有东西试图将您的应用程序带到前台但没有这样做的权限(请参阅 SetForegroundWindow()
的文档了解更多详细信息)。 UIPI 不允许较低完整性进程将窗口消息发送到较高完整性进程,除非接收进程明确告诉 UIPI 允许它。 Chrome 和 FireFox 可能以与您的应用程序相同的完整性级别运行。为了支持 Internet Explorer 的拖放,请调用 ChangeWindowMessageFilter()
或 ChangeWindowMessageFilterEx()
让您的应用接收来自较低完整性进程的 WM_DROPFILES
、WM_COPYDATA
和 WM_COPYGLOBALDATA
(0x0049) 消息。
更新:看起来 Internet Explorer 在保护模式下运行时特别对拖放操作施加了额外的限制:
How to handle drag & drop from low integrity Internet Explorer
关于c++ - 从 IE 9 拖放到我的应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14470665/