How to get notified programmatically when the system (Windows Laptop) goes to sleep/hibernation using Qt C++?

374 Views Asked by At

I have a Qt application that is built on Windows (Laptop). I am using a Windows 11 pro system, I need to get a notification/message when the system goes into sleep/hibernation.

I have used the below code in my application.

#include <QAbstractNativeEventFilter>
#include <QAbstractEventDispatcher>
#include <QDebug>
#include <windows.h>

class MyEventFilter : public QAbstractNativeEventFilter {
public:
   virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long*) Q_DECL_OVERRIDE {
     MSG* msg = static_cast< MSG* >( message );

     if (msg->message == WM_POWERBROADCAST) {
       switch (msg->wParam) {
         case PBT_APMPOWERSTATUSCHANGE:
           qDebug() << ("PBT_APMPOWERSTATUSCHANGE  received\n");
           break;
         case PBT_APMRESUMEAUTOMATIC:
           qDebug() << ("PBT_APMRESUMEAUTOMATIC  received\n");
           break;
         case PBT_APMRESUMESUSPEND:
           qDebug() << ("PBT_APMRESUMESUSPEND  received\n");
           break;
         case PBT_APMSUSPEND:
           qDebug() << ("PBT_APMSUSPEND  received\n");
           break;
       }
     }
     return false;
   }
};

But, I am not receiving the PBT_APMSUSPEND event message when my system goes to sleep/hibernation. (i.e either when I close the laptop manually or click on the sleep option in the power menu) Am I missing something? RegisterSuspendResumeNotification function, can it be used? If so how?

Thanks

Update

The above code works well on the Windows Desktop system but not on the Laptop system.

Update 2

There is no issue with the system and the code will also work smoothly. Only the sleep mode scenario is slightly weird. When the system is put on sleep mode overnight, in the morning when turned on the system actually starts from the bootup, so in this scenario, the PBT_APMSUSPEND is received.

1

There are 1 best solutions below

18
Strive Sun On

I tested in my another computer(Windows 11). When the system goes to sleep, I received PBT_APMSUSPEND, PBT_APMRESUMESUSPEND, PBT_APMRESUMEAUTOMATIC event. But PBT_APMPOWERSTATUSCHANGE not be received.

I suspect you haven't put the computer into sleep in a reasonable way.

Try to click Sleep icon as the screenshot showed below.

enter image description here

This is a minimal example, works on WIN10 and WIN11

class MyEventFilter : public QAbstractNativeEventFilter {
 public:
   virtual bool nativeEventFilter(const QByteArray& eventType, void* message,
                                 long*) Q_DECL_OVERRIDE {
    MSG* msg = static_cast<MSG*>(message);

    if (msg->message == WM_POWERBROADCAST) {
      switch (msg->wParam) {
        case PBT_APMPOWERSTATUSCHANGE:
          qDebug() << ("PBT_APMPOWERSTATUSCHANGE  received\n");
          break;
        case PBT_APMRESUMEAUTOMATIC:
          qDebug() << ("PBT_APMRESUMEAUTOMATIC  received\n");
          break;
        case PBT_APMRESUMESUSPEND:
          qDebug() << ("PBT_APMRESUMESUSPEND  received\n");
          break;
        case PBT_APMSUSPEND:
          qDebug() << ("PBT_APMSUSPEND  received\n");
          break;
      }
    }
    return false;
  }
};

int main() {
  int argc = 1;
  char* argv = new char[MAX_PATH];
  QApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
  QApplication app(argc, &argv);

  QMainWindow main_window;
  main_window.setFixedSize(200, 100);
  main_window.show();

  QAbstractEventDispatcher::instance()->installNativeEventFilter(
      new MyEventFilter);

  app.exec();
  return 0;
}

Update:

I notice you said only the PBT_APMPOWERSTATUSCHANGE is received when I plug in/unplug to power and the other three are not working.

This is by design.

From PBT_APMPOWERSTATUSCHANGE,

Notifies applications of a change in the power status of the computer, such as a switch from battery power to A/C. The system also broadcasts this event when remaining battery power slips below the threshold specified by the user or if the battery power changes by a specified percentage.

The computer go to sleep does not change the battery status.