这是一个奇怪的问题,让我试着解释一下。我在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;
}
答案 0 :(得分:7)
作为防止对计算机进行未经授权更改的沙盒的一部分,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