Einzelnen Beitrag anzeigen

Benutzerbild von ULIK
ULIK

Registriert seit: 25. Sep 2006
Ort: Regensburg
416 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: WM_POWERBROADCAST wie verwenden?

  Alt 31. Okt 2019, 09:20
Hier mal eine etwas komplettere Unit
Delphi-Quellcode:
{-----------------------------------------------------------------------------
  Name:          uPowerManagement
  Author:        UK

  Description:
    Hilfsunit, die die Funktionen zum Registrieren der WM_POWERBROADCAST
    Messages bereitstellt (ab Win 8 nötig): dadurch empfängt diese BroadcastMessages
    für Suspend und Resume

    Aufruf erfolgt dann z.b. im FormCreate/Destroy mit dem Form-Handle, das die
    Message verarbeiten soll:


    procedure TForm1.FormCreate(Sender: TObject);
    begin
      RegisterPowermanagement(Handle);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      UnregisterPowermanagement;
    end;

  History:
    2019-10-30  UK  Unit created.
-----------------------------------------------------------------------------}


unit uPowerManagement;

interface

uses
  Winapi.Windows,
  System.SysUtils;

procedure RegisterPowermanagement(AMainForm: HWND);
procedure UnregisterPowermanagement;

implementation

var
  hLibrary: THandle = 0;
  hNotification: HPOWERNOTIFY = nil;

  RegisterSuspendResumeNotification: function(hRecipient: THandle; flags: DWORD): HPOWERNOTIFY; stdcall = nil;
  UnRegisterSuspendResumeNotification: function(hNotification: HPOWERNOTIFY): Bool; stdcall = nil;

{-----------------------------------------------------------------------------
  Procedure:  goIsWindows8OrHigher
  Author:      UK
  Description: Erkennung Windowsversion  (nur eine Möglichkeit)
  Arguments:
  Result:      Boolean
  Exceptions:  -
-----------------------------------------------------------------------------}


function goIsWindows8OrHigher: Boolean;
begin
  Result := ((Win32MajorVersion = 6) and (Win32MinorVersion >= 2)) or
             (Win32MajorVersion > 6);
end;
{-----------------------------------------------------------------------------
  Procedure:  RegisterPowermanagement
  Author:      UK
  Description:
  Arguments:  AMainForm : HWND - Fensterhandle Anwendung
  Result:      None
  Exceptions:  -
-----------------------------------------------------------------------------}


procedure RegisterPowermanagement(AMainForm: HWND);
begin
  if goIsWindows8OrHigher then // Erkennen, daß man unter Windows 8 und höher ist.
  begin
    if Assigned(RegisterSuspendResumeNotification) then
    begin
      hNotification := RegisterSuspendResumeNotification(AMainForm, DEVICE_NOTIFY_WINDOW_HANDLE);
      if hNotification <> nil then
        // Logging: SiUnit.LogString(lvDebug, 'Info', 'Powermanagement successfully registered')
      else
        ;// Logging: LogLastOSError('RegisterSuspendResumeNotification');
    end
    else
      ;// Logging: SiUnit.LogWarning('RegisterSuspendResumeNotification not registered');
  end;
end;

{-----------------------------------------------------------------------------
  Procedure:  UnregisterPowermanagement
  Author:      UK
  Description:
  Arguments:
  Result:      None
  Exceptions:  -
-----------------------------------------------------------------------------}


procedure UnregisterPowermanagement;
begin
  if goIsWindows8OrHigher then
  begin
    if Assigned(UnRegisterSuspendResumeNotification) then
    begin
      if (hNotification <> nil) then
      begin
        if UnRegisterSuspendResumeNotification(hNotification) then
          // Logging: SiUnit.LogString(lvDebug, 'Info', 'Powermanagement successfully unregistered')
        else
          // Logging: SiUnit.LogError('Failed to unregister notification: ' + LastWin32Error);
      end
      else
        // Logging: SiUnit.LogWarning('UnRegisterSuspendResumeNotification: no notification registered');
    end
    else
      // Logging: SiUnit.LogWarning('UnRegisterSuspendResumeNotification not registered');
  end;
end;

initialization

  hLibrary := LoadLibrary('user32.dll');
  if hLibrary <> 0 then
  begin
    RegisterSuspendResumeNotification := GetProcAddress(hLibrary, 'RegisterSuspendResumeNotification');
    UnRegisterSuspendResumeNotification := GetProcAddress(hLibrary, 'UnregisterSuspendResumeNotification');
  end;

finalization

  FreeLibrary(hLibrary);

end.
Ob man dafür jetzt einen QP Request schreiben sollte, bin ich mir nicht sicher. Es ist halt schon eine sehr spezielle Situation, daß man auf Suspend/Resume reagieren muß. Wenn dann sollte das jedenfalls in Winapi.Windows rein (da gibt's bereits ähnliche Deklarationen für das Powermanagement).
Aber das Ganze hier unter einem Vorbehalt: damit funktioniert es bei mir. Ob das aber nun wirklich der korrekte Weg ist, auf Suspend / Resume zu reagieren bin ich mir auch nicht 100% sicher. Dazu kenn ich mich zu wenig in dem Zeug aus.
Vieleicht können hier ja noch die Experten was beisteuern.

Geändert von ULIK (31. Okt 2019 um 09:42 Uhr) Grund: Korrektur kleiner Fehler
  Mit Zitat antworten Zitat