![]() |
Windows 7 Standby/Hibernate Phänomen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe da ein Frage zu Windows 7 RTM & Delphi 2009. Und zwar habe ich zum Test ein kleines Programm anghängt. Dieses Programm loggt die WM_POWERBROADCAST Messages. Nun zu dem Pänomen: Starte ich die "Standby_Test.exe" zwei mal und drücke bei einem auf den Button fährt das System in den Standby. Wenn der PC wieder zurück kommt zeigt sich folgendes: Das Programm welches der Auslöser für den Standby war bekommt die Meldung PBT_APMSUSPEND nicht! :wall: Das zweite Programm jedoch schon! :wiejetzt: Fährt man über Windows->Start->Ruhezustand den PC runter bekommen beide Programme die Meldung! Bei XP bekommen auch alle beide die Meldung. Meine Frage ist nun - ist das ein Windows 7 Bug oder ist das so gewollt? Wie kann man das "Reparieren"? |
Re: Windows 7 Standby/Hibernate Phänomen
Was passiert wenn du die Exe kopierst so das unterschiedliche Exe-Namen vorliegen?
|
Re: Windows 7 Standby/Hibernate Phänomen
einfache Lösung wäre, wenn dein programm sich selber nochmal startet, mit einem Parameter.
wenn es beim Start diesen Parameter erkennt, dann schickt es Windows den Standby-Befehl und beendet sich danach wieder dann schickt ja quasi ein "anderes" Programm den Befehl an Windows und dein Programm sollte das Ereignis mitbekommen. |
Re: Windows 7 Standby/Hibernate Phänomen
Also ich finde das schon logisch. Warum sollte das Programm selber benachrichtigt werden, dass es selber gerade den Standby-Modus ausgelöst hat? Das weiss das Programm ja eh. Die Meldung bekommt man also nur wenn die Auslösung von außen passierte. Ich empfinde das eigentlich nicht als Fehler sondern als logisches Design.
|
Re: Windows 7 Standby/Hibernate Phänomen
Zitat:
Wenn nun das Hauptprogramm den Standby auslöst bekommt das Plugin keine Meldung da es zu dem Programm-Thread/Window gehört. So bin ich ja drauf gekommen das da was anders ist. Wie könnte das dann bei einem Plugin gelöst werden? |
Re: Windows 7 Standby/Hibernate Phänomen
Dann muß das Programm seinen Plugins dieses eben selber mitteilen.
|
Re: Windows 7 Standby/Hibernate Phänomen
Es ist ja gar kein Akt, die entsprechende Message in die passende Queue zu stellen.
|
Re: Windows 7 Standby/Hibernate Phänomen
Leider habe ich auf die Software die mein Plugin ladet keinen Einfluß.
Daher frage ich ob es da einen Weg herum gibt? Vielleicht eigenen eigenen unabhängigen Thread erzeugen? |
Re: Windows 7 Standby/Hibernate Phänomen
Und wenn Du ein eigenes zusätzliches Toplevel-Window registrierst bekommt das die Messages auch nicht? (mit AllocateHwnd)
|
Re: Windows 7 Standby/Hibernate Phänomen
Das mit AllocateHwnd habe ich schon ausprobiert. Doch auch da kommt die "ich gehe in Standby" Message auch nicht an.
Werde es einmal mit einen eigenen Thread versuchen. |
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. |
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:
ein Fenster un schickt der DummyApp das THandle fHWnd.
protected
procedure WndMethod(var Msg: TMessage); virtual; fHWnd := AllocateHWnd(WndMethod); Nun das Ergebnis: DummyApp:
Code:
Client:
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
Code:
Na? Fällt es jemanden auf?
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 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: |
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. |
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:
Also wenn meine DummyApp eine PowerMessage bekommt wird einfach per:
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;
Delphi-Quellcode:
Ein Thread erzeugt der per Postmessage die Nachricht weiterleitet und sich dann selber gleich wieder beendet.
TSendMessageThread.Create(TempClientHandles[i],MyMessage.WParam);
DummyApp:
Code:
Client:
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
Code:
Die Nachricht kommt trotzdem erst nach dem Standby beim Client an.
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 :wall: |
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:
Wird so aufgerufen:
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;
Delphi-Quellcode:
Der Client schickt per Sendmessage seinen Callbackpointer:
TSendMessageThread.Create(Clients[i],4);
//wobei: Clients: Array of Pointer;
Delphi-Quellcode:
die so bei der DummyApp empfangen und gespeichert wird:
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;
Delphi-Quellcode:
Clients[High(Clients)] := Pointer(MyMessage.WParam);
|
Re: Windows 7 Standby/Hibernate Phänomen
Registrier Dein Fenster mal mit Hilfe von
![]() |
Re: Windows 7 Standby/Hibernate Phänomen
Danke!
Habe es einmal so versucht:
Delphi-Quellcode:
Jedoch auch keine Meldung zu meinem Fenster das ich mit AllocateHWnd mache :(
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; Hast du vielleicht einen Tipp wo du das gefunden hast? |
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:
Das Fenster wird auch braf als Child von Shell_TrayWnd erzeugt.
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'); 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?? |
Re: Windows 7 Standby/Hibernate Phänomen
** gelöscht, war doch nicht so :oops:
|
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 17:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz