On 2020-05-06 11:09, Julius Bullinger wrote:
Usually, sending a WM_QUIT message to a QApplication triggers the
QCoreApplication::aboutToQuit() signal, e.g. when ending the
application via Windows's Task Manager, or using "taskkill /PID <pid>".
We discovered that no aboutToQuit() signal is emitted when a
QApplication without windows receives a WM_QUIT:
#include <QApplication>
#include <QDebug>
#include <QWidget>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QApplication::connect(&app, &QApplication::aboutToQuit, []() {
qDebug() << "QApplication::aboutToQuit";
});
// Commenting those lines will not trigger aboutToQuit() when
// the application is closed via Task Manager:
QWidget w;
w.show();
return app.exec();
}
Our application supports a text-only variant, where the GUI is
disabled. We're basically doing it like that, and wondered why our
shutdown code was not called when the application was quit via the
Task Manager.
Is there anything that needs to be done to get consistent behavior?
Hi, when running apps on Windows without a window, you'll be missing out
on a lot of inter-process stuff like WM_QUIT (that's why it's common for
windowless apps to create a hidden, non-interactive window just to be
able to receive all those WM_XXX). So no aboutToQuit() will be emitted
for you when you skip creating that widget window.
But there's an API for windowless apps where you can receive a control
signal, e.g. Ctrl-C was pressed or someone (like the Task Manager) is
shutting down the app, more here:
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler
and the callback:
https://docs.microsoft.com/en-us/windows/console/handlerroutine
There's no support for that API in Qt but it's pretty easy to use.
Here's an example, I created a vanilla Qt console app, and changed
main.cpp to this:
-----------------------------------------
#include <QCoreApplication>
#include <windows.h>
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
case CTRL_CLOSE_EVENT:
::OutputDebugStringA("Ctrl-Close event"); // catch taskkill or
Task Manager End task
return TRUE;
default:
return FALSE;
}
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
SetConsoleCtrlHandler(CtrlHandler, TRUE);
return app.exec();
}
-----------------------------------------
Note: I'm using OutputDebugString and DbgView.exe to view the output,
qDebug() output has a tendency to disappear when you test with "End
task" from TaskManager.
Note 2: this API is very flakey if you try it from a GUI-built .exe, for
Qt apps I mean built with "QT += core gui etc" in the .pro file, and use
of QApplication in main.cpp. Instead you need to build your app like a
Qt console app, "QT -= gui" and CONFIG += console, and use
QCoreApplication in main.cpp, like in my example above.
Rgrds Henry
_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest