Почему ChangeWindowMessageFilter вызывает сбой Qt?

0

Почему происходит сбой следующей программы?

#include <QApplication>

#include <windows.h>
#include <QFrame>


uint MSGFLT_ADD = 1;
uint WM_COPYGLOBALDATA = 0x0049;

int main(int argc, char *argv[])
{
    BOOL (*ChangeWindowMessageFilter)(UINT,DWORD) = NULL;

    HINSTANCE hDLL = LoadLibraryA("User32.dll");               // Handle to DLL
    if (hDLL != NULL){
        ChangeWindowMessageFilter = (BOOL (*)(UINT,DWORD))GetProcAddress(hDLL, "ChangeWindowMessageFilter");
    }

    if (ChangeWindowMessageFilter != NULL){
        if (!(*ChangeWindowMessageFilter)(WM_DROPFILES, MSGFLT_ADD)){
            printf("Failed to add exception for WM_DROPFILES\n");
        }
        if (!(*ChangeWindowMessageFilter)(WM_COPYDATA, MSGFLT_ADD)){
            printf("Failed to add exception for WM_COPYDATA");
        }
        if (!(*ChangeWindowMessageFilter)(WM_COPYGLOBALDATA, MSGFLT_ADD)){
            printf("Failed to add exception for WM_COPYGLOBALDATA");
        }
        printf("Added filters\n");
        fflush(0);
    }
    if (hDLL != NULL){
        FreeLibrary(hDLL);
    }

    QApplication a(argc, argv);
    QFrame w; //debug crashes here
    w.show();

    return a.exec();
}

QFrame::QFrame(QWidget* parent, Qt::WindowFlags f)
    : QWidget(*new QFramePrivate, parent, f) //on this line in particular
{
    Q_D(QFrame);
    d->init();
}

РЕДАКТИРОВАТЬ:

if (!(*ChangeWindowMessageFilter)(WM_COPYDATA, MSGFLT_ADD)){ //if i disable this everything works
    printf("Failed to add exception for WM_COPYDATA");
}
  • 0
    Ваш выход установлен на 64 или 32 бита?
  • 0
    это хороший вопрос, это 32 бит. возможно я загружаю 64-битную версию?
Показать ещё 3 комментария
Теги:
qt
dynamic-loading

1 ответ

5
Лучший ответ
   BOOL (*ChangeWindowMessageFilter)(UINT,DWORD) = NULL;

Объявление указателя функции неверно. Функции Winapi всегда __stdcall. Ваш компилятор, без сомнения, использует значение по умолчанию, __cdecl. Дисбаланс стека, который вы получаете при выполнении вызова через указатель функции, может иметь много побочных эффектов. Если вы используете MSVC++ и запустите сборку Debug, вы всегда получите немедленную диагностику. Fix:

   BOOL (WINAPI * ChangeWindowMessageFilter)(UINT,DWORD) = NULL;

Fwiw, если это предназначено для включения drag + drop в повышенную программу, тогда просто удалите все это, это не сработает. D + D основан на COM, он не использует сообщения.

  • 0
    Ах, спасибо. Он предназначен для включения DnD (и не работает, хаха). Есть ли обходной путь для его включения?
  • 3
    Google "uiaccess = true"

Ещё вопросы

Сообщество Overcoder
Наверх
Меню