Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Custom Window Border
Qt 6.11 is out! See what's new in the release blog

Custom Window Border

Scheduled Pinned Locked Moved Unsolved General and Desktop
windowsqmainwindowpaintevent
2 Posts 2 Posters 2.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dot97
    wrote on last edited by
    #1

    Hello,

    I currently try to create a QMainWindow with an custom window border on Windows. My current code is:

    bool MainWindow::nativeEvent(const QByteArray &eventType,
        void *msg, long *result) {
        auto win_msg = static_cast<MSG*>(msg);
        auto message = win_msg->message;
        auto wParam = win_msg->wParam;
        auto lParam = win_msg->lParam;
    
        if (message == WM_CREATE)
            int i = 0;
    
        if (message == WM_CREATE || message == WM_ACTIVATE
            || message == WM_NCCALCSIZE || message == WM_NCHITTEST) {
            auto forward = true;
            auto win_result = (LRESULT)0;
            auto hwnd = (HWND)winId();
            auto dwm_enabled = (BOOL)FALSE;
            auto hr = DwmIsCompositionEnabled(&dwm_enabled);
            if (SUCCEEDED(hr)) {
                forward = !DwmDefWindowProc(hwnd, message,
                    wParam, lParam, &win_result);
    
                switch (message) {
                case WM_CREATE: {
                    RECT rcClient;
                    GetWindowRect(hwnd, &rcClient);
    
                    // Inform application of the frame change.
                    SetWindowPos(hwnd, NULL,
                        rcClient.left, rcClient.top,
                        rcClient.right - rcClient.left,
                        rcClient.bottom - rcClient.top,
                        SWP_FRAMECHANGED);
    
                    forward = true;
                    win_result = 0;
                    break;
                }
                case WM_ACTIVATE: {
                    MARGINS margins;
    
                    margins.cxLeftWidth = 0;
                    margins.cxRightWidth = 0;
                    margins.cyBottomHeight = 0;
                    margins.cyTopHeight = 0;
    
                    hr = DwmExtendFrameIntoClientArea(hwnd, &margins);
    
                    if (!SUCCEEDED(hr))
                    {
                        // Handle error.
                    }
    
                    forward = true;
                    win_result = 0;
                    break;
                }
                case WM_NCCALCSIZE: {
                    if (wParam == TRUE) {
                        NCCALCSIZE_PARAMS *params =
                            reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
                        params->rgrc[0].left = params->rgrc[0].left + 5;
                        params->rgrc[0].top = params->rgrc[0].top + 0;
                        params->rgrc[0].right = params->rgrc[0].right - 5;
                        params->rgrc[0].bottom = params->rgrc[0].bottom - 5;
                        forward = false;
                        win_result = 0;
                    }
                    break;
                }
                case WM_NCHITTEST: {
                    if (win_result == 0) {
                        auto mouse_pos = POINT{ LOWORD(lParam), HIWORD(lParam) };
                        RECT window_rect;
                        GetWindowRect(hwnd, &window_rect);
                        RECT frame_rect = { 0 };
                        AdjustWindowRectEx(&frame_rect,
                            WS_OVERLAPPEDWINDOW & ~WS_CAPTION, FALSE, NULL);
                        auto row = (USHORT)1;
                        auto col = (USHORT)1;
                        auto resize_border = false;
                        if (mouse_pos.y >= window_rect.top
                            && mouse_pos.y < window_rect.top + 30) {
                            resize_border =
                                (mouse_pos.y < (window_rect.top - frame_rect.top));
                            row = 0;
                        }
                        else
                            if (mouse_pos.y < window_rect.bottom
                                && mouse_pos.y >= window_rect.bottom)
                                row = 2;
                        if (mouse_pos.x >= window_rect.left
                            && mouse_pos.x < window_rect.left)
                            col = 0;
                        else
                            if (mouse_pos.x < window_rect.right
                                && mouse_pos.x >= window_rect.right)
                                col = 2;
    
                        LRESULT result_map[3][3] = {
                            { HTTOPLEFT, resize_border ? HTTOP : HTCAPTION, HTTOPRIGHT },
                            { HTLEFT, HTNOWHERE, HTRIGHT },
                            { HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT },
                        };
    
                        win_result = result_map[row][col];
                        if (win_result != HTNOWHERE)
                            forward = false;
                    }
                    break;
                }
                }
            }
    
            if (!forward) {
                *result = win_result;
                return true;
            }
        }
    
        return QWidget::nativeEvent(eventType, msg, result);
    }
    
    void MainWindow::paintEvent(QPaintEvent *event) {
        QPainter p(this);
        p.setPen(Qt::NoPen);
    
        p.setBrush(QBrush(QColor("#bbdefb")));
        p.drawRect(0, 0, geometry().width(), geometry().height());
    
        p.setBrush(QBrush(QColor("#2196f3")));
        p.drawRect(0, 0, geometry().width(), 30);
    
        QMainWindow::paintEvent(event);
    }
    

    The problem is, them main winow then looks like this:
    0_1488728775996_mainwindow.png

    So it seems, that the sizes of the drawing area are not calculated correctly given the customizations I made.
    Does anybody know a solution to this?

    Regards

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      Hi, and welcome. The image upload function on our forum is broken, the uploaded images might be visible to you, but they aren't to anyone else. See this thread for a workaround.

      1 Reply Last reply
      1

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved