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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.