Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-39268

Windows: rendering issues when customizing window frame with native event filters

    XMLWordPrintable

Details

    • Bug
    • Resolution: Out of scope
    • Not Evaluated
    • None
    • 5.2.1, 5.3.0
    • QPA: Windows
    • None
    • qt-opensource-windows-x86-msvc2013-5.3.0
      qt-opensource-windows-x86-msvc2010-5.2.1

    Description

      Source:

      C++
      #include "mainwindow.h"
      
      #ifdef Q_OS_WIN
      #include <Windows.h>
      #include <WinUser.h>
      #include <windowsx.h>
      #include <Dwmapi.h>
      #include <gdiplus.h>
      #include <GdiPlusColor.h>
      #pragma comment (lib,"Dwmapi.lib")
      #endif //Q_OS_WIN
      
      MainWindow::MainWindow(QWidget *parent)
          : QWidget(parent)
      {
          setStyleSheet("background-color: rgb(83, 83, 83);");
          resize(250,200);
      }
      
      void MainWindow::showEvent(QShowEvent *event)
      {
          QWidget::showEvent(event);
      #ifdef Q_OS_WIN
          window_borderless();
      #endif
      }
      
      #ifdef Q_OS_WIN
      void MainWindow::window_borderless()
      {
          if (isVisible())
          {
              window_shadow();
      
              SetWindowPos(reinterpret_cast<HWND>(winId()), 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
          }
      }
      
      void MainWindow::window_shadow()
      {
          const MARGINS shadow = { 1, 1, 1, 1 };
          DwmExtendFrameIntoClientArea(reinterpret_cast<HWND>(winId()), &shadow);
      }
      
      bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
      {
          MSG *msg = static_cast<MSG *>(message);
          switch (msg->message)
          {
          case WM_NCCALCSIZE:
          {
              //this kills the window frame and title bar we added with
              //WS_THICKFRAME and WS_CAPTION
              *result = 0;
              return true;
              break;
          }
          case WM_NCHITTEST:
          {
              *result = 0;
      
              const LONG border_width = 8; //in pixels
              RECT winrect;
              GetWindowRect(reinterpret_cast<HWND>(winId()), &winrect);
      
              long x = GET_X_LPARAM(msg->lParam);
              long y = GET_Y_LPARAM(msg->lParam);
      
              bool resizeWidth = minimumWidth() != maximumWidth();
              bool resizeHeight = minimumHeight() != maximumHeight();
      
              if(resizeWidth)
              {
                  //left border
                  if (x >= winrect.left && x < winrect.left + border_width)
                  {
                      *result = HTLEFT;
                  }
                  //right border
                  if (x < winrect.right && x >= winrect.right - border_width)
                  {
                      *result = HTRIGHT;
                  }
              }
              if(resizeHeight)
              {
                  //bottom border
                  if (y < winrect.bottom && y >= winrect.bottom - border_width)
                  {
                      *result = HTBOTTOM;
                  }
                  //top border
                  if (y >= winrect.top && y < winrect.top + border_width)
                  {
                      *result = HTTOP;
                  }
              }
              if(resizeWidth && resizeHeight)
              {
                  //bottom left corner
                  if (x >= winrect.left && x < winrect.left + border_width &&
                          y < winrect.bottom && y >= winrect.bottom - border_width)
                  {
                      *result = HTBOTTOMLEFT;
                  }
                  //bottom right corner
                  if (x < winrect.right && x >= winrect.right - border_width &&
                          y < winrect.bottom && y >= winrect.bottom - border_width)
                  {
                      *result = HTBOTTOMRIGHT;
                  }
                  //top left corner
                  if (x >= winrect.left && x < winrect.left + border_width &&
                          y >= winrect.top && y < winrect.top + border_width)
                  {
                      *result = HTTOPLEFT;
                  }
                  //top right corner
                  if (x < winrect.right && x >= winrect.right - border_width &&
                          y >= winrect.top && y < winrect.top + border_width)
                  {
                      *result = HTTOPRIGHT;
                  }
              }
      
              //TODO: allow move?
              if(*result==0)
                  *result = HTCAPTION ;
      
              return true;
              break;
          } //end case WM_NCHITTEST
          }
      
          return QWidget::nativeEvent(eventType, message, result);
      }
      #endif //Q_OS_WIN
      
      

      Run:

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              kleint Friedemann Kleint
              flucheng fenglc
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes