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

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

#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

Решение

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

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

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

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

5

Другие решения

Других решений пока нет ...

По вопросам рекламы [email protected]