Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Frameless windows window while still using window manager



  • I am trying to make my QML window become borderless on windows while still using the native window manager to support platform features like aero. I found "a stackoverflow answer":http://stackoverflow.com/a/17713810/2282732 which explains how to do it with win api and tried to use it in Qt.

    @#ifndef FRAMELESSWINDOW_H
    #define FRAMELESSWINDOW_H

    #include <QQuickWindow>
    #include <QDebug>
    #include <Windows.h>
    #include <windowsx.h>

    class FramelessWindow : public QQuickWindow {
    public:
    FramelessWindow(QQuickWindow *parent = 0) : QQuickWindow(parent) {
    hwnd = (HWND) this->winId();

        //setFlags(flags() | Qt::FramelessWindowHint);
    
        LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
        lStyle = (WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
        SetWindowLong(hwnd, GWL_STYLE, lStyle);
    
        LONG lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
        SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
    }
    

    private:
    HWND hwnd;

    long NCHITTEST(LPARAM &lparam) {
        const LONG border_width = 8; //in pixels
        RECT winrect;
        GetWindowRect(hwnd, &winrect);
        long x = GET_X_LPARAM(lparam);
        long y = GET_Y_LPARAM(lparam);
    
        //bottom left corner
        if (x >= winrect.left && x < winrect.left + border_width &&
            y < winrect.bottom && y >= winrect.bottom - border_width)
        {
            return HTBOTTOMLEFT;
        }
        //bottom right corner
        if (x < winrect.right && x >= winrect.right - border_width &&
            y < winrect.bottom && y >= winrect.bottom - border_width)
        {
            return HTBOTTOMRIGHT;
        }
        //top left corner
        if (x >= winrect.left && x < winrect.left + border_width &&
            y >= winrect.top && y < winrect.top + border_width)
        {
            return HTTOPLEFT;
        }
        //top right corner
        if (x < winrect.right && x >= winrect.right - border_width &&
            y >= winrect.top && y < winrect.top + border_width)
        {
            return HTTOPRIGHT;
        }
        //left border
        if (x >= winrect.left && x < winrect.left + border_width)
        {
            return HTLEFT;
        }
        //right border
        if (x < winrect.right && x >= winrect.right - border_width)
        {
            return HTRIGHT;
        }
        //bottom border
        if (y < winrect.bottom && y >= winrect.bottom - border_width)
        {
            return HTBOTTOM;
        }
        //top border
        if (y >= winrect.top && y < winrect.top + border_width)
        {
            return HTTOP;
        }
    
        return HTCAPTION;
    }
    
    bool nativeEvent(const QByteArray &eventType, void *message, long *result) {
        MSG* msg = (MSG*) message;
        switch(msg->message) {
        case WM_NCCALCSIZE:
            *result = 0;
            return true;
            break;
        case WM_NCHITTEST:
            *result = NCHITTEST(msg->lParam);
            return true;
        }
        return false;
    }
    

    };

    #endif // FRAMELESSWINDOW_H
    @

    However in general it works but the window has a margin of 8 + 8 px on the right (the windows frame is 8 px thick) and a margin of about 30px on the top (titlebar + bottom border height) which is client aera but gets ignored by Qt.

    Screenshot:
    !http://i.imgur.com/qoGOPfa.png?1(The squares should be on the edges)!

    When I add the Qt::FramelessWindowHint flag the margins disappear and everything is fine until I minimize and restore the window or maximize it (then the margins appear again).

    Can somebody help me with this please?


Log in to reply