Skip to content
  • 0 Votes
    2 Posts
    376 Views
    bibasmallB

    I have found out that this problem is mainly related to WinAPI + framelessness, not to Qt. I didn't manage to find any working WinAPI solution, for example, I've tried this one: melak47's solution. So I've chosen Qt way. This approach is not as concise as I expected from the WinAPI approach, but it works.
    Here is a code snippet describing only the necessary parts.

    .hpp

    class FramelessWindow : public QQuickWindow { Q_OBJECT QML_ELEMENT Q_PROPERTY(bool isMaximized READ isMaximized NOTIFY isMaximizedChanged) signals: void isMaximizedChanged(); public: FramelessWindow() noexcept; Q_INVOKABLE void showNormal() noexcept; Q_INVOKABLE void showMaximized() noexcept; bool isMaximized() const noexcept; private: bool eventFilter(QObject* watched, QEvent* event) override; bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override; QRect restoredGeometry_; bool isMaximized_; };

    .cpp

    FramelessWindow::FramelessWindow() noexcept : isMaximized_ { false } { setFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMaximizeButtonHint); installEventFilter(this); SetWindowLongPtr((HWND)winId(), GWL_STYLE, WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX); } void FramelessWindow::showNormal() noexcept { setGeometry(restoredGeometry_); isMaximized_ = false; emit isMaximizedChanged(); } void FramelessWindow::showMaximized() noexcept { restoredGeometry_ = geometry(); setGeometry(screen()->availableGeometry()); isMaximized_ = true; emit isMaximizedChanged(); } bool FramelessWindow::isMaximized() const noexcept { return isMaximized_; } bool FramelessWindow::eventFilter(QObject* watched, QEvent* event) { QPoint cursorPos = QCursor::pos(); qreal dpr = devicePixelRatio(); QRect draggingArea = geometry(); draggingArea.setHeight(32 * dpr); draggingArea.setY(draggingArea.y() + dpr * ResizeBorderWidth); if (draggingArea.contains(cursorPos)) { if (event->type() == QEvent::MouseButtonPress) { if (isMaximized_) { restoredGeometry_.moveTo({ QCursor::pos().x() - restoredGeometry_.width() / 2, QCursor::pos().y() - 10 }); showNormal(); } startSystemMove(); return true; } else if (isResizable_ && event->type() == QEvent::MouseButtonDblClick) { if (draggingArea.contains(cursorPos)) { if (isMaximized_) { showNormal(); } else { showMaximized(); } return true; } } else if (event->type() == QEvent::WindowStateChange && QWindow::visibility() == QWindow::Maximized) { setGeometry(screen()->availableGeometry()); isMaximized_ = true; emit isMaximizedChanged(); return true; } } return QQuickWindow::eventFilter(watched, event); } bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) { if (auto* msg = static_cast<MSG*>(message); msg->message == WM_NCCALCSIZE) { NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam); if (params.rgrc[0].top != 0) { --params.rgrc[0].top; } *result = 0; return true; } return QQuickWindow::nativeEvent(eventType, message, result); }
  • 0 Votes
    3 Posts
    344 Views
    bibasmallB

    The problem was that every child widget of the native widnow got it's own window descriptor (HWND), so, for example, if I hit the menubar, in nativeEvent I saw that the message had a different descriptor than the main window had.
    This is what solved my problem:

    QApplication a(argc, argv); a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); //... CEventFilter e{ &w }; a.installNativeEventFilter(&e);
  • 0 Votes
    10 Posts
    1k Views
    artwawA

    @JoeCFD No, I refuse to. I tried once, perfectly healthy code that I maintained for 3 years on MingW didn't even want to compile (it was Qt only, no external libs), I refused to waste my time on Microsoft shenanigans.

    Anyway, I got it to work. I was missing one thing in MinGW. For the record:

    to use WinAPI with MinGW (I do it via Msys2) two packages are needed (I was missing the latter): msys2-w32api-headers and msys2-w32api-runtime. .pro file in the end looks like I was expecting: LIBS += -LC:/msys64/usr/lib/w32api/ -liphlpapi LIBS += -LC:/msys64/usr/lib/w32api/ -lws2_32 INCLUDEPATH += C:/msys64/usr/include/w32api DEPENDPATH += C:/msys64/usr/lib/w32api

    Thank you everyone who contributed, thanks to your input I was able to trace and find my error. As always, your help is much appreciated.

  • 0 Votes
    3 Posts
    624 Views
    aha_1980A

    Hi @CybeX,

    and to add to @JKSH: you probably want to use GetFinalPathNameByHandleW as this is the UNICODE version.

    Regards

  • 0 Votes
    3 Posts
    528 Views
    Q

    @Chris-Kawa
    wow, so simple :)
    and so fast answer!! woooow
    Thank you very much!
    Its works!

    void MainWindow::onStatusChanged(PVOID p) { qDebug() << "void *p address" << p; SERVICE_NOTIFY_2A* temp_pNotifyBuffer = static_cast<SERVICE_NOTIFY_2A*>(p); //MainWindow* ptr_mainWindow = static_cast<MainWindow*>(p); //qDebug() << ptr_mainWindow->m_test_string; qDebug() << temp_pNotifyBuffer->pContext; qDebug() << static_cast<MainWindow*>(temp_pNotifyBuffer->pContext)->m_test_string; }

    Service man opened
    pcontext address 0x8ff6a0
    void *p address 0x8ff6bc
    0x8ff6a0
    "look it"

    I was misled that in Visual studio the example with "direct" transformation worked. And I went the wrong way ..

  • 0 Votes
    3 Posts
    746 Views
    T

    I know that I can use QDialog to create Window instead of WinApi. But I think this example is very easy, so I think there is another way...

  • 0 Votes
    1 Posts
    1k Views
    No one has replied
  • 0 Votes
    3 Posts
    366 Views
    aarelovichA

    Maybe I expressed myself incorrectly. By native I meant that uses the WinMain function as an entry point, for example. Something like the code in the link I've poste.

    But If you can provide some example code on HOW I can use Qt and the win32 APi and Direct X 11, I'd appreaciate it. I have not been able to find ANYTHING online.

    Just a simple open a window and draw a circle or something will do. I want to know how con configure the .pro so that it will find all the appropriate libraries and the code will compile.

  • 0 Votes
    3 Posts
    1k Views
    P

    @kshegunov said in App crushes when Qt core calls WinAPI's "DispatchMessage" function:

    This address is rather suspicious. Please tell me you don't have global QWidgets?

    No, I have only a dll with function

    extern "C" CORE_SHARED_API QMainWindow * svCreateMainWindow() { return new MainWindow; }

    (CORE_SHARED_API is __declspec(dllexport))

    @kshegunov said in App crushes when Qt core calls WinAPI's "DispatchMessage" function:

    Btw, 0xc0000409 is stack overflow, so be on the lookout for endless recursion.

    As I said, QWindowsGuiEventDispatcher::processEvents() is called twice, and I believe those calls are on the same stack level (crush happens in the second call).

  • 0 Votes
    3 Posts
    3k Views
    A

    Thanks, SGaist.
    QtSingleApplicaiton is an alternative solution to singleton , I will make a try.

  • 0 Votes
    17 Posts
    7k Views
    RIVOPICOR

    @Chris-Kawa Thanks a lot your answer solve my dude thanks a lot. The system of resources of Qt is awesome and more easy to use so it's better. Anyways i was trying to understand more about windows api and with these explications i understand now thanks.

  • 0 Votes
    6 Posts
    3k Views
    kshegunovK

    @Thynome
    Hi,
    Well, you're stuck with C when working with the WinApi. It sucks, I know, but you need to transfer the context (the object) through a global variable. You can look here for some inspiration - WindowsCtrlDispatcher::instance is the context that's transferred to the VOID WINAPI ServiceMain(DWORD, LPTSTR *) function. I hope that helps.

    Kind regards.

  • 0 Votes
    19 Posts
    5k Views
    kshegunovK

    @SGaist said:

    Indeed, but I wouldn't be surprised if that changed at some point :D

    Perhaps, perhaps. Although, judging from the time it took MS to introduce the x64 compiler, if it were to change, it'd take decades. And since it hasn't changed for over 30 years, I really doubt that it ever will. :D