c++ - 自定义窗口框架在 qt 构建中表现不同(ANGLE 与 OpenGL)

标签 c++ qt winapi opengl qt-quick

我的任务是为 QtQuick 创建一个窗口,可以像普通窗口一样使用它,但具有自定义框架外观(不是默认的系统装饰)。我想实现类似于 Visual Studio 窗口或类似的效果。

允许我实现该目标的代码如下所示:

main.cpp

#include <QtQuick/qquickpainteditem.h>
#include <qapplication.h>
#include <qqmlengine.h>
#include <QtQuick/qquickwindow.h>

class frameLess :
    public QQuickWindow
{
public:
    frameLess(QWindow *parent = 0) :QQuickWindow(parent) { }

    bool nativeEvent(const QByteArray& eventType, void* message, long* result)
    {
        MSG *msg = static_cast<MSG *>(message);

        switch (msg->message)
        {
        case WM_SHOWWINDOW:
            // after that call Qt considers window as frameless
            setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
            // that call force the Windows to serve users mouse events like in standard window
            SetWindowLongPtr(msg->hwnd, GWL_STYLE, WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
            return false;

        case WM_NCCALCSIZE:
            // prevent the Windows from painting the frame
            *result = 0;
            return true;

        default:
            break;
        }

        return false;
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterType<frameLess>("fb", 1, 0, "FrameLess");

    QQmlEngine engine;
    QQmlComponent *component = new QQmlComponent(&engine);

    QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));

    component->loadUrl(QUrl("qrc:////main.qml"));

    if (!component->isReady())
    {
        qWarning("%s", qPrintable(component->errorString()));
        return -1;
    }

    QObject *topLevel = component->create();
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);

    QSurfaceFormat surfaceFormat = window->requestedFormat();
    window->setFormat(surfaceFormat);
    window->show();

    return app.exec();
}

ma​​in.qml

import fb 1.0
import QtQuick 2.2
import QtQuick.Controls 1.1

FrameLess {
    color:"lightgray"
    Rectangle {
        width: 45
        height: 45
        color: "green"
        anchors {
            top: parent.top
            left: parent.left
        }

        MouseArea {
            anchors.fill: parent
            hoverEnabled: true;
            onEntered: parent.color="red"
            onExited: parent.color="green"
        }
    }
}

因此,应该会出现左上角带有绿色矩形的无框窗口。此外,当鼠标悬停时,该矩形应该变为红色。

当我使用基于 ANGLE 的 Qt 构建构建它时,一切都按预期工作。

Window which is expected

但是,我的团队正在使用基于 OpenGL 的 Qt 构建。问题是,当我的代码链接到此类 Qt 版本时,绘画区域会按窗口框架的大小移动:

Window with shifted painting area

更重要的是,只有绘画区域被移动。例如,鼠标命中框位于适当的位置。因此,命中框和场景项目坐标是不同步的。 (MouseArea 的交互区域与其填充的 Rectangle 位于不同的位置)

Window with shifted painting area and hovered rectangle hitbox

我的期望是使用不同的 Qt 构建应该不会影响最终的应用程序。

我的问题是为什么使用基于 OpenGL 的 Qt 构建会影响窗口外观,以及我如何可移植地(跨 Windows Qt 构建)实现预期的行为。

我使用的构建是:

  • 适用于 32 位 Windows 的 Qt 5.3.1(VS 2013、OpenGL、557 MB)
  • Windows 32 位 Qt 5.3.1(VS 2013,559 MB)

我正在使用 Windows 8.1 进行测试

更新: Qt 5.4.0 好像修复了这个bug

最佳答案

这是一个 Qt 错误。请照原样报告。您无需在代码中执行任何特殊操作即可使其正常运行。

关于c++ - 自定义窗口框架在 qt 构建中表现不同(ANGLE 与 OpenGL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24994033/

相关文章:

c# - 从不使用标签控件的对话框中获取文本?

C++风格: Stroustrup' s placement of pointer asterisks

c++ - 将 char** 转换为 char[x][x]

c++ - 在 OpenGL 中渲染火焰

c++ - QNetworkAccessManager上传到本地FTP服务器

c++ - QFutureWatcher 不调用连接槽

c++ - MFC 应用程序 DialogBased 使用 propertyPage,CDialog 的 DoModal() 不打开任何对话框

android - gradle experimental 通过 srcDir srcFile 指令包含文件目录

c++ - 如何使中心区域调整到 QDockWidgets 位置

c++ - 子类按钮不会在每次重复单击时生成动画