Click here to Skip to main content
15,890,512 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am using Qt for Windows.
I would like to have a window with a system menu and a dynamic Frameless flag. Without the Frameless flag, the window should have a system menu with a few additional entries; the user is free to toggle the Frameless flag on demand (e.g. by clicking a button), and the window should adjust.

I found a solution for the Windows system menu, using the Win32 API and a native event filter. The problem is that, when I install a native event filter, setting the Framless flag crashes the application (stack overflow).

I made a minimal example. Am I doing something wrong? Thank you for any hint.

Here is the code:

gui.h
C++
#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
C++
#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;
}


What I have tried:

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.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900