Nico du Boulot Ответов: 0

Qt: qabstractnativeeventfilter с qt::framelesswindowhint


Привет,

Я использую Qt для Windows.
Я хотел бы иметь окно с системным меню и динамическим бескаркасным флагом. Без бескаркасного флага окно должно иметь системное меню с несколькими дополнительными записями; пользователь может свободно переключать бескаркасный флаг по требованию (например, нажав кнопку), и окно должно регулироваться.

Я нашел решение для системного меню Windows, используя Win32 API и собственный фильтр событий. Проблема заключается в том, что при установке собственного фильтра событий установка флага Framless приводит к сбою приложения (переполнение стека).

Я привел минимальный пример. Я делаю что-то не так? Спасибо за любую подсказку.

Вот этот код:

графический интерфейс.ч
#ifndef GUI_H
#define GUI_H

#include <QWidget>

namespace Ui {
class gui;
}

class gui : public QWidget
{
    Q_OBJECT

public:
    explicit gui(QWidget *parent = 0);
    ~gui();

private:
    //Ui::gui *ui;
};

#endif // GUI_H


gui.cpp
#include "gui.h"
//#include "ui_gui.h"

#include <qt_windows.h>
#include <QAbstractNativeEventFilter>
#include <QDebug>
#include <QMessageBox>
#include <QAbstractEventDispatcher>


#define MENUITEM_ABOUT 4324
gui *wnd = NULL;   // For the global EventFilter

class GlobalEventFilter : public QAbstractNativeEventFilter
{
    virtual bool nativeEventFilter(const QByteArray & /*eventType*/, void * message, long * /*result*/)
    {
        MSG *msg = (MSG*)message;

        if (wnd && msg->hwnd == (HWND) wnd->winId())
        {
            if(msg->message == WM_SYSCOMMAND)
            {
                if(msg->wParam == MENUITEM_ABOUT)
                {
                    qDebug() << "ABOUT";
                    //wnd->emitSignalAbout();
                    return true;
                }
            }
        }

        return false;
    }
} globalEventFilter;


gui::gui(QWidget *parent) :
    QWidget(parent)
//    ,ui(new Ui::gui)
{
    wnd = this;

    HMENU hMenu = ::GetSystemMenu((HWND) winId(), false);
    ::AppendMenu(hMenu, MF_SEPARATOR, 1, L"Separator");
    ::AppendMenu(hMenu, MF_STRING, MENUITEM_ABOUT, L"About");
    QAbstractEventDispatcher::instance(0)->installNativeEventFilter(&globalEventFilter);

    QAbstractEventDispatcher::instance(0)->removeNativeEventFilter(&globalEventFilter);
    setWindowFlag(Qt::FramelessWindowHint, true);
    QAbstractEventDispatcher::instance(0)->installNativeEventFilter(&globalEventFilter);

    //ui->setupUi(this);
}

gui::~gui()
{
    //delete ui;
}


Что я уже пробовал:

If I remove either the setWindowFlag, or the installNativeEventFilter calls, all works fine. With both of them, I get the stack overflow crash. If I move the setWindowFlag at the beginning of the function, it does not crash for some reason; if I toggle the flag later though, it crashes.

0 Ответов