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
Forum Update on Monday, May 27th 2025

Custom Window Border

Scheduled Pinned Locked Moved Unsolved General and Desktop
windowsqmainwindowpaintevent
2 Posts 2 Posters 2.0k Views
  • 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 5 Mar 2017, 15:49 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 5 Mar 2017, 19:17 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

      2/2

      5 Mar 2017, 19:17

      • Login

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