Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt::nativeEvent calls

Tags:

c++

qt

I am working on a Windows 8 x64 laptop. Developing with Qt5. I have some difficulties to handle non-client area color (especially the color frame). I did not find some easy-to-use functions or processes to do that. I found that the DWM message to handle for the title bar color is WM_DWMCOLORIZATIONCOLORCHANGED and I would like to modify its wParam variable to set a new color.

For now I am trying to extend the frame into the client area, using the QtWin::extendFrameIntoClientArea function in an implementation of the nativeEvent function. as it follows:

bool SkyFlies::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
  Q_UNUSED(result);
  Q_UNUSED(eventType);

  MSG *msg = static_cast<MSG*>(message);
  if(msg->message == WM_ACTIVATE)
  {
     const QMargins marge(-1, -1, -1, -1);
     QtWin::extendFrameIntoClientArea(this, marge);
  }
  return false;
}

My question is the following: In the piece of code where I would like to call the preceding function,

SkyFlies::SkyFlies()
{
  ...
  this->nativeEvent();
  ...
}

I would like to know how to fill the function parameters. I know it sounds a bit foolish, but I quite stuck.

Thanks!

Here is an update:

errors like LNK2019 unresolved external symbol... really suck!!!

As I googled my concerns, I found a pretty code to customize the window frame. I used it in my code and after fixing compiler errors, I got a LNK 2019 error for the DwmExtendFrameIntoClientArea function here is the code: the header file-

#include <QtWidgets>

#ifdef Q_OS_WIN

#include <Windows.h>
#include <WinUser.h>
#include <windowsx.h>
#include <dwmapi.h>
#include <minmax.h>
#include <gdiplus.h>
#include <gdipluscolor.h>

#endif

class SkyFlies : public QMainWindow
{
    Q_OBJECT

    ...

    void showEvent(QShowEvent *event);  // Manage window borders
    void windowBorderless();    // Show a borderless window for Windows system
    void windowShadow();    // Set shadow border effect

    ...
};

The implementation file-

// Manage window borders
void SkyFlies::showEvent(QShowEvent *event)
{
    QWidget::showEvent(event);

#ifdef Q_OS_WIN

    this->windowBorderless();

#endif
}

#ifdef Q_OS_WIN

void SkyFlies::windowBorderless()
{
    if(this->isVisible())
    {
        SetWindowLongPtr((HWND)winId(), GWL_STYLE, WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
        this->windowShadow();
        SetWindowPos((HWND)winId(), 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
    }
}

void SkyFlies::windowShadow()
{
    const MARGINS shadow={1, 1, 1, 1};
    HRESULT hr = S_OK;
    hr = DwmExtendFrameIntoClientArea((HWND)winId(), &shadow);
}

#endif

Please, how can I resolve the LNK2019 issue? I tried to run QMake without any success. Here is my .pro file:

QT += widgets

SOURCES += \
    main.cpp \
    SkyFlies.cpp

HEADERS += \
    SkyFlies.h \
    SkyWord.h

The SkyWord file is empty. Thanks

As another update, I just read the last answer, I fixed the linker issue few hours ago by adding

#pragma comment (lib,"Dwmapi.lib")

in the header file. In definitive, I got a window extended through the title bar. Now I'm struggling to find a way to change the color of the title bar. But I don't see any satisfactory solution. I thought that I could handle the WM_DWMCOLORIZATIONCHANGED message but no.

And the MSDN example about custom title bar(http://msdn.microsoft.com/en-us/library/bb688195%28VS.85%29.aspx#appendixb) do not talk about changing colors. But maybe there are things to do with the WM_NCPAINT message.

like image 330
Patrik Avatar asked Dec 26 '22 02:12

Patrik


2 Answers

First: you don't need to call nativeEvent method directly. It is a callback that is called by Qt. You may override it.

Second. There are known bugs in Qt5 with processing nativeEvent. So be careful with it. But, as I know, there are problemd only with native child widgets.

Third. Solution: create your own QAbstractNativeEventFilter. Hint, how to use it (because it is not well-documented):

QAbstractEventDispatcher::instance()->installNativeEventFilter(yourFilter);

class MyEventFilter
    : public QAbstractNativeEventFilter
{
public:
    virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
    {
        MSG *msg = static_cast< MSG * >( message );
        // TODO: filter out or modify msg struct here
        // ...
        return false;
    }
};
like image 133
Dmitry Sazonov Avatar answered Jan 04 '23 03:01

Dmitry Sazonov


After looking for a solution to my problem, I finally find this solution. It is a very good way to build borderless windows using Qt that looks the way many softwares looks today just like (Adobe softwares or MS Office). Thanks for you support.

like image 43
Patrik Avatar answered Jan 04 '23 05:01

Patrik