qt 运行 as Administrator drop 无效为什么?

qt run as Administrator drop is invalid why?

qt 运行 as Administrator drop 无效, 我在 qt 中使用了 win32 api ChangeWindowMessageFilterEx 但不起作用, 我用的是 win32 api MFC 中的 ChangeWindowMessageFilterEx 可以正常工作。

当我 运行 作为管理员时,无法在 qt 中接收 WM_DROPFILES 消息。 这是在qt

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    DropTest w;
    w.show();

    CHANGEFILTERSTRUCT chfit1 = { sizeof(CHANGEFILTERSTRUCT) };
    CHANGEFILTERSTRUCT chfit2 = { sizeof(CHANGEFILTERSTRUCT) };
    CHANGEFILTERSTRUCT chfit3 = { sizeof(CHANGEFILTERSTRUCT) };
    HWND hwnd = (HWND)w.winId();;
    DragAcceptFiles(hwnd, TRUE);

    DropTest::ChangeWndMessageFilterOk(hwnd, WM_DROPFILES, MSGFLT_ALLOW, &chfit1);
    DropTest::ChangeWndMessageFilterOk(hwnd, WM_COPYDATA, MSGFLT_ALLOW, &chfit2);
    DropTest::ChangeWndMessageFilterOk(hwnd, 0x0049, MSGFLT_ALLOW, &chfit3);       // 0x0049 == WM_COPYGLOBALDATA


    //MyXcbEventFilter nativeEventFilterZ;
    //a.installNativeEventFilter(&nativeEventFilterZ);
    return a.exec();
}


BOOL DropTest::ChangeWndMessageFilterOk(HWND hWnd, UINT nMessage, DWORD dwAction, PCHANGEFILTERSTRUCT chfit)
{
    //typedef BOOL (WINAPI * ChangeWindowMessageFilterOkFn)(__in HWND hWnd, __in UINT message,  __in DWORD action, __inout_opt PCHANGEFILTERSTRUCT pChangeFilterStruct);
    typedef BOOL (WINAPI *ChangeWindowMessageFilterOkFn)(HWND, UINT, DWORD, PCHANGEFILTERSTRUCT);
    HMODULE hModUser32 = NULL;
    hModUser32 = LoadLibrary(L"user32.dll");
    if (hModUser32 == NULL) {
        return FALSE;
    }

    ChangeWindowMessageFilterOkFn pfnChangeWindowMessageFilter = (ChangeWindowMessageFilterOkFn) GetProcAddress(hModUser32, "ChangeWindowMessageFilterEx");
    if (pfnChangeWindowMessageFilter == NULL)
    {
        FreeLibrary(hModUser32);
        return FALSE;
    }

    FreeLibrary(hModUser32);
    BOOL ret = pfnChangeWindowMessageFilter(hWnd, nMessage, dwAction, chfit);
    QString strOut = QString("%1 ret = [%2] ExtStatus=[%3]\n").arg(__FUNCTION__, QString::number(ret), QString::number(chfit->ExtStatus));
    OutputDebugString(strOut.toStdWString().c_str());
    return ret;
}

我找到了季后赛, 使用 RevokeDragDrop 就可以了! 这是qt源码

void QWindowsWindow::setDropSiteEnabled(bool dropEnabled)
{
    if (isDropSiteEnabled() == dropEnabled)
        return;
    qCDebug(lcQpaMime) << __FUNCTION__ << window() << dropEnabled;
#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_DRAGANDDROP)
    if (dropEnabled) {
        Q_ASSERT(m_data.hwnd);
        m_dropTarget = new QWindowsOleDropTarget(window());
        RegisterDragDrop(m_data.hwnd, m_dropTarget);
        CoLockObjectExternal(m_dropTarget, true, true);
    } else {
        CoLockObjectExternal(m_dropTarget, false, true);
        m_dropTarget->Release();
        RevokeDragDrop(m_data.hwnd);
        m_dropTarget = 0;
    }
#endif // !QT_NO_CLIPBOARD && !QT_NO_DRAGANDDROP
}

我试过changewindowmessagefilter,无效,从qt源也没有发现异常,目前只需要管理员权限功能单独做一个程序,其他还没找到更好的解决方案