Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Windows 7 Standby/Hibernate Phänomen (https://www.delphipraxis.net/142639-windows-7-standby-hibernate-phaenomen.html)

schwa226 4. Nov 2009 10:54

Re: Windows 7 Standby/Hibernate Phänomen
 
Ein paar Versuche später:

Habe nun einen eigenen Thread erzeugt dre sich mit AllocateHwnd ein Fenster Handle holt.
Doch auch dieser bekommt die Meldung nicht da der Thread ja zu meinem Programm dazu gehört.

Kann man einen Thread erzeugen, der nicht in Verbindung zu meinem Programm steht?

Oder sowas wie einen "virtuellen" Process der mit meiner Anwendung nicht gekoppelt ist?

Habe auch schon Versucht es über einen Service zu lösen. Dieser Service schickt mir was wenn er eine PowerMessage bekommt.
Geht fast unter XP aber unter Windows 7 wieder gar nicht.

Eine eigene (extra) exe will ich mir am liebsten sparen. Ich weis das dass warscheinlich am einfachsten wäre. Den eine eigene exe bekommt ja die Messages und die kann es dann per PostMessage an meine Anwendung weiterleiten. Möchte aber wie gesagt sowas vermeiden dass ein extra Programm benötigt wird.

schwa226 20. Nov 2009 19:22

Re: Windows 7 Standby/Hibernate Phänomen
 
Update hierzu:

Ich habe mir nun eine DummyApp gemacht die einfach die WM_POWERBROADCAST überwacht.
Wenn diese eine Nachricht bekommt schickt sie diese per SendMessage weiter zu einem Client.
Der Client erzeugt mit:

Delphi-Quellcode:
protected
    procedure WndMethod(var Msg: TMessage); virtual;


fHWnd := AllocateHWnd(WndMethod);
ein Fenster un schickt der DummyApp das THandle fHWnd.

Nun das Ergebnis:
DummyApp:
Code:
19:58:31 Client: Add 263828 to list
19:59:16 WMPowerBroadcast: WM_POWERBROADCAST message, WParm: 4
19:59:16 WMPowerBroadcast: try to send message to client 1: 263828
20:01:41 WMPowerBroadcast: WM_POWERBROADCAST message, WParm: 18
20:01:41 WMPowerBroadcast: try to send message to client 1: 263828
20:01:41 WMPowerBroadcast: WM_POWERBROADCAST message, WParm: 7
20:01:41 WMPowerBroadcast: try to send message to client 1: 263828
Client:
Code:
20:01:41 WndMethod: PowerMessage received: WParam: 4
20:01:41 WndMethod: PBT_APMSUSPEND
20:01:41 WndMethod: PowerMessage received: WParam: 18
20:01:41 WndMethod: PBT_APMRESUMEAUTOMATIC
20:01:41 WndMethod: PowerMessage received: WParam: 7
20:01:41 WndMethod: PBT_APMRESUMEAUTOMATIC
Na? Fällt es jemanden auf?

Die Meldung PBT_APMSUSPEND wurde um 19:59:16 empfangen und sofort weitergeschickt.
Jedoch ist sie beim Client erst um 20:01:41 angekommen. :gruebel:
Also nachdem der PC wieder aus dem Standby zurück gekommen ist.

Habe es auch schon mit PostMessage versucht, aber da ist es genau so!

Hilfe!! :wall:

himitsu 20. Nov 2009 19:40

Re: Windows 7 Standby/Hibernate Phänomen
 
SendMessage müßte eigentlich sofort ankommen, denn dieses kehrt erst zurück, nachdem die Nachricht beim Clienten verarbeitet wurde. :gruebel:

PostMessage wird nur an die Wartschlange angehängt und dann verarbeitet, wenn die App dazu kommt.

schwa226 20. Nov 2009 21:03

Re: Windows 7 Standby/Hibernate Phänomen
 
Kann es noch daran liegen, dass ich in der Procedure (die in der DummyApp) die WM_POWERBROADCAST Message erhält auch das Sendmessage ausführe?
Währe es besser Sendmessage erst nach einem kurzen Delay auszuführen?
Also die DummyApp Message Procedure durchlaufen lassen und z.B. Timer mit z.B. 100ms starten.
Wenn der Timer auslößt dann erst die Sendmessage zum Client.

Weiß aber nicht wie ich dann den Resume abfangen soll. Da kommen ja zwei Meldungen fast zur gleichen Zeit.

EDIT:
Habe jetzt folgendes probiert:
Delphi-Quellcode:
type
  TSendMessageThread = class(TThread)
    private
      fWParam : Cardinal;
      fHWnd: HWND;
    protected
      procedure Execute; override;
    public
      constructor Create(hWnd : HWND; WParam: Cardinal); virtual;
  end;

procedure TSendMessageThread.Execute;
begin
  PostMessage(fHWnd, PowerMessage, fWParam,0);
  Terminate;
end;

constructor TSendMessageThread.Create(hWnd : HWND; WParam: Cardinal);
begin
inherited Create(True);
  fWParam := WParam;
  fHWnd := hWnd;
  Resume;
end;
Also wenn meine DummyApp eine PowerMessage bekommt wird einfach per:
Delphi-Quellcode:
TSendMessageThread.Create(TempClientHandles[i],MyMessage.WParam);
Ein Thread erzeugt der per Postmessage die Nachricht weiterleitet und sich dann selber gleich wieder beendet.

DummyApp:
Code:
22:30:15 Client: Add 919140 to list
22:30:45 WMPowerBroadcast: WM_POWERBROADCAST message, WParm: 4
22:30:45 WMPowerBroadcast: try to send message to client 1: 919140
22:30:45 WMPowerBroadcast: message got sent to client 1: 919140
22:34:12 WMPowerBroadcast: WM_POWERBROADCAST message, WParm: 18
22:34:12 WMPowerBroadcast: try to send message to client 1: 919140
22:34:12 WMPowerBroadcast: message got sent to client 1: 919140
22:34:12 WMPowerBroadcast: WM_POWERBROADCAST message, WParm: 7
22:34:13 WMPowerBroadcast: try to send message to client 1: 919140
22:34:14 WMPowerBroadcast: message got sent to client 1: 919140
Client:
Code:
22:34:14 WndMethod: PowerMessage received: WParam: 4
22:34:14 WndMethod: PBT_APMSUSPEND
22:34:14 WndMethod: PowerMessage received: WParam: 18
22:34:14 WndMethod: PBT_APMRESUMEAUTOMATIC
22:34:14 WndMethod: PowerMessage received: WParam: 7
22:34:14 WndMethod: PBT_APMRESUMEAUTOMATIC
Die Nachricht kommt trotzdem erst nach dem Standby beim Client an.
:wall:

schwa226 21. Nov 2009 10:08

Re: Windows 7 Standby/Hibernate Phänomen
 
Ich versuche gerade noch das ganze über eine Callback zu machen.

Hab aber so meine Probleme damit!

DummyApp:
Delphi-Quellcode:
type
  TPowerMessageCallback = procedure (WParam:Cardinal);

procedure TSendMessageThread.Execute;
var
  PowerMessageCallback : TPowerMessageCallback;
begin
  @PowerMessageCallback := fcb;
  PowerMessageCallback(fWParam);
  Terminate;
end;

constructor TSendMessageThread.Create(cb : Pointer; WParam: Cardinal);
begin
inherited Create(True);
  fWParam := WParam;
  fcb := cb;
  Resume;
end;
Wird so aufgerufen:
Delphi-Quellcode:
TSendMessageThread.Create(Clients[i],4);

//wobei:
Clients: Array of Pointer;
Der Client schickt per Sendmessage seinen Callbackpointer:
Delphi-Quellcode:
  TMyClass = class(TComponent)
  public
     constructor Create(AOwner: TComponent); override;
       { create hidden window here: store handle in fHWnd}
     destructor Destroy; override;
       { free hidden window here }
     procedure PowerMessageCallback(WParam:Cardinal);
end;

SendMessage(FindWindow('TFormTestApp',nil),ClientRegister,Int64(@TMyClass.PowerMessageCallback),0);

procedure TMyClass.PowerMessageCallback(WParam:Cardinal);
begin
  //do wcallback work
end;
die so bei der DummyApp empfangen und gespeichert wird:
Delphi-Quellcode:
Clients[High(Clients)] := Pointer(MyMessage.WParam);

Fridolin Walther 21. Nov 2009 16:45

Re: Windows 7 Standby/Hibernate Phänomen
 
Registrier Dein Fenster mal mit Hilfe von MSDN-Library durchsuchenRegisterPowerSettingNotification für den Empfang von PBT_POWERSETTINGCHANGE Nachrichten. Auch wenn dies laut Dokumentation keinen Einfluss auf die Zustellung der von Dir gewünschten Nachricht haben sollte, haben doch einige Leute mit dem selben Problem reported, daß die Meldungen dann an kamen für Events, die von ihrer Anwendung selbst ausgelöst wurden. Versuch ists alle mal wert :).

schwa226 21. Nov 2009 18:37

Re: Windows 7 Standby/Hibernate Phänomen
 
Danke!

Habe es einmal so versucht:

Delphi-Quellcode:
procedure RegisterPowerSettingNotification(hRecipient : hwnd; PowerSettingGuid: PGuid; Flags: byte);stdcall;external 'user32.dll';


Procedure RegisterForPowerNotifications(hwnd: hwnd);
Const

  GUID_POWERSCHEME_PERSONALITY: TGUID =     '{245d8541-3943-4422-b025-13A784F679B7}';
  GUID_MIN_POWER_SAVINGS: TGUID =           '{8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c}';
  GUID_MAX_POWER_SAVINGS: TGUID =           '{a1841308-3541-4fab-bc81-f71556f20b4a}';
  GUID_TYPICAL_POWER_SAVINGS: TGUID =       '{381b4222-f694-41f0-9685-ff5bb260df2e}';
  GUID_ACDC_POWER_SOURCE: TGUID =           '{5d3e9a59-e9D5-4b00-a6bd-ff34ff516548}';
  GUID_BATTERY_PERCENTAGE_REMAINING: TGUID = '{a7ad8041-b45a-4cae-87a3-eecbb468a9e1}';
  GUID_IDLE_BACKGROUND_TASK: TGUID =        '{515c31d8-f734-163d-a0fd-11a08c91e8f1}';
  GUID_SYSTEM_AWAYMODE: TGUID =             '{98a7f580-01f7-48aa-9c0f-44352c29e5C0}';
  GUID_MONITOR_POWER_ON: TGUID =            '{02731015-4510-4526-99e6-e5a17ebd1aea}';

Var
  DEVICE_NOTIFY_WINDOW_HANDLE: Byte;
Begin
  DEVICE_NOTIFY_WINDOW_HANDLE := 0;

  RegisterPowerSettingNotification(hwnd,
    @GUID_POWERSCHEME_PERSONALITY,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_MIN_POWER_SAVINGS,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_MAX_POWER_SAVINGS,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_TYPICAL_POWER_SAVINGS,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_ACDC_POWER_SOURCE,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_BATTERY_PERCENTAGE_REMAINING,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_IDLE_BACKGROUND_TASK,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_SYSTEM_AWAYMODE,
    DEVICE_NOTIFY_WINDOW_HANDLE);

  RegisterPowerSettingNotification(hwnd,
    @GUID_MONITOR_POWER_ON,
    DEVICE_NOTIFY_WINDOW_HANDLE);
End;
Jedoch auch keine Meldung zu meinem Fenster das ich mit AllocateHWnd mache :(

Hast du vielleicht einen Tipp wo du das gefunden hast?

schwa226 9. Dez 2009 18:38

Re: Windows 7 Standby/Hibernate Phänomen
 
Da ich das Problem noch immer nicht gelößt habe mus ich hier nocheinmal nachfragen!

Ich erzeuge nun so ein Window das auch WM_POWERBROADCAST Messages erhält:

Delphi-Quellcode:
        hWindowParent := FindWindow('Shell_TrayWnd',nil);

            if hWindowParent <> 0 then
            begin

              //create window for powerbroadcasts:
              zeromemory(@wa, sizeof(wa)); // <--<<
              with wa do begin
                lpszClassName := 'My_Power_Broadcast';
                lpfnWndProc  := @uMain.PowerBroadcastWndProc;
                Style        := CS_VREDRAW or CS_HREDRAW;
                hInstance    := GetCurrentProcessID;//hMain;
                hIcon        := 0;//LoadIcon(0, IDI_APPLICATION);
                hCursor      := 0;//LoadCursor(0, IDC_ARROW);
                hbrBackground := (COLOR_WINDOW + 1);
                lpszMenuName := nil;
                cbClsExtra   := 0;
                cbWndExtra   := 0;
              end;

              if (Windows.RegisterClass(wa) = 0) then
                WriteLog('Error RegisterClass')
              else
              begin


                  hWindowChild := CreateWindowEx(WS_EX_TOPMOST Or WS_EX_TOOLWINDOW,
                    'My_Power_Broadcast',
                    '',
                    WS_POPUP, // <--<<
                    0, 0,
                    0, 0, // <--<<
                    hWindowParent,
                    0,
                    GetCurrentProcessID,
                    nil);

                  if hWindowChild = 0 then
                    WriteLog('Error CreateWindowEx: hWindowChild')
                  else
                    WriteLog('Info CreateWindowEx: hWindowChild ok');
              end;

            end
            else
               WriteLog('Error FindWindow: Shell_TrayWnd');
Das Fenster wird auch braf als Child von Shell_TrayWnd erzeugt.

Nun habe ich mit Winspy gesehen, dass die Message PBT_APMSUSPEND zwar beim Fenster Shell_TrayWnd ankommt, jedoch nicht bei meinem!
Die Messages: PBT_APMRESUMESTANDBY & PBT_APMRESUMEAUTOMATIC kommen jedoch auch bei meinem Fenster an.

Warum bekomme ich die Meldung nicht das er in den Standby geht??

Kann ich einen Messagehook auf Shell_TrayWnd machen? Habe glaube einmal gelesen zu haben das so ein Hook aber nicht so gut ist...

Jemand einen Tipp??

Wal 29. Dez 2009 10:53

Re: Windows 7 Standby/Hibernate Phänomen
 
** gelöscht, war doch nicht so :oops:

netpilots 26. Jun 2014 10:40

AW: Windows 7 Standby/Hibernate Phänomen
 
Hier wurden die diversen Events gut beschrieben. Konnte daraus was bauen welches was macht wenn der Computer aus dem Tiefschlaf geweckt wird.
Nun würde mich interessieren ob es was gibt um den Zeitpunkt zu erkennen wenn der Benutzer den Computer aus dem gesperrten Zustand holt.
Gemeint ist der Zustand wo man auf sein Benutzerlogo klickt. Das geht mit oder ohne Passwort, je nach Einstellung.
In den gesperrten Zustand kommt man durch Tastendruck "Fenster" und "L".


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:57 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz