![]() |
PowerButton-Event von Windows abfangen und auswerten
Hallo,
ich will bei einer Maschine mit einem Industrie-PC (Emb. Win XP) verhindern, dass dieser herunterfährt, wenn man den Netzschalter (auf der Front) drückt. Bisher habe ich herausgefunden, dass das Event WM_POWERBROADCAST heißt und nur an die Top-Level-Anwendungen verschickt wird, weshalb ich bei meinem Programm einen global hook installieren muss. Dafür habe ich dieses Tutorial verwendet: ![]() In meiner .exe wird im FormCreate InstallHook aufgerufen sowie in FormDestroy UninstallHook, die beide aus der .dll vom Tutorial stammen:
Delphi-Quellcode:
Kompiliere ich dann beides zusammen und drücke den Netzschalter, passiert nichts.
library KeyboardHook;
uses Windows, Messages; var HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0; function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin sleep(10); end; end; end; function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin Result := False; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; end; function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(HookHandle); HookHandle := 0; end; exports InstallHook, UninstallHook; end. Wenn ich einen zusätzlichen Button mache, der WM_POWERBROADCAST sendet
Delphi-Quellcode:
passiert auch nichts.
SendMessage(HWNC_BROADCAST,WM_POWERBROADCAST,0,0)
Wo liegt mein Fehler? Oder muss man einen anderen Weg nehmen? Gruß |
Re: PowerButton-Event von Windows abfangen und auswerten
Was soll auch passieren? In deiner KeyboardHookProc machst du ja nichts. Und ob ein KeyboardHook der passende Hook ist, weiß ich nicht. Der Powerknopf am Gehäuse gehört ja nicht zur Tastatur. Und warum ist dein Fenster kein Toplevel Fenster, wenn es eine Form hat?
Davon mal abgesehen, was machst du, wenn der Netzschalter zum ausschalten benutzt wird oder wenn das Netzkabel gezogen wird? Das Auschalten wirst du nicht verhindern können. |
Re: PowerButton-Event von Windows abfangen und auswerten
Liste der Anhänge anzeigen (Anzahl: 1)
Darf der PC nur unter bestimmten Umständen nicht über den Power-Knopf heruntergefahren werden oder gilt das immer? für das zweite ließe sich das auch über Windows regeln ...
Systemsteuerung -> Energieoptionen -> Erweitert -> "Beim Drücken des Netzschalters am Computer" Wobei du das Ausschalten mit "lang drücken" nicht verhindern kannst außer das BIOS lässt da irgendwelche Optionen zu. Edit: und falls du es wirklich über die Message im eigenen Programm machen willst dann eher so:
Delphi-Quellcode:
procedure WMPowerBroadcast(var Msg : TWMPower); message WM_POWERBROADCAST;
. . . procedure TForm1.WMPowerBroadcast(var Msg: TWMPower); begin Msg.Result := BROADCAST_QUERY_DENY; end; |
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
Zitat:
Zitat:
|
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
Unsere Anwendung läuft Fullscreen ohne Taskleiste. Die Powertaste haben wir in Windows abgestellt ("Nichts machen") möchten aber die Nachricht dass die Taste gedrückt wurde selbst auswerten und einen eigenen Abfragedialog anzeigen. Edit: und falls du es wirklich über die Message im eigenen Programm machen willst dann eher so:
Delphi-Quellcode:
Der Student wird morgen gleich "weiterforschen".
procedure WMPowerBroadcast(var Msg : TWMPower); message WM_POWERBROADCAST;
. . . procedure TForm1.WMPowerBroadcast(var Msg: TWMPower); begin Msg.Result := BROADCAST_QUERY_DENY; end; Danke und Gruß |
Re: PowerButton-Event von Windows abfangen und auswerten
Lies Dir meinen Beitrag durch; dann brauchst Du keinen Dialog im Vordergrund (sofern Du Zugriff auf die Registry hast).
|
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
Zitat:
Zitat:
Es ist ein Maschinensteuerungs-PC. In meinem vorherigen Posting habe ich etwas mehr dazu geschrieben. Danke und Gruß |
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
Gruß P.S. Diese Anforderung zum Handling ist speziell, wie gesagt es ist eine Maschinensteuerung. Doch das auswerten der Windows-Message beim Drücken des Power-Knopfes sollte doch eine normale Programmiersache sein, oder? |
Re: PowerButton-Event von Windows abfangen und auswerten
Du kannst auch diese Einstellung wieder zurücksetzen und dann das OnCloseQuery-Event auswerten. Zum Beispiel standardmäßig False (glaub ich) zurückgeben, und dem User einen Dialog präsentieren. Wenn er das dann doch möchte, kannst du das Herunterfahren wieder anstoßen ;)
P.S.: imho sollte das Teil ein Top-Level-Fenster sein, auch ohne Titelleiste und Border - top-level schließt vor allem die ganzen kleinen dinger (buttons, edits, usw.) aus... |
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
|
Re: PowerButton-Event von Windows abfangen und auswerten
Wenn die Powertaste abgestellt wurde, dann wird doch auch keine WM_POWERBROADCAST-Botschaft verschickt, da dann ja nichts passiert.
WM_POWERBROADCAST ist nur eine Reaktion auf das Drücken des Tasters oder auf irgendwas, welches den PC z.B. runterfahren will ... diese Nachricht hat also nix mit der Taste selber zu tun. Das drücken des Gehäuse-Power-Knöpfchens dürfte eher irgendeinen Interupt auslösen und an den kommt man wohl nur über einen Treiber? :gruebel: |
Re: PowerButton-Event von Windows abfangen und auswerten
...oder man fragt den Embedded Controller direkt ab - das Byte ist aber bei jedem PC/Notebook an einer anderen Stelle, denn es gibt keine Normung.
|
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
|
Re: PowerButton-Event von Windows abfangen und auswerten
Zitat:
Darauf habe ich einen Test-Button der die Message sendet. Darauf reagiert meine Prozedur
Delphi-Quellcode:
wenn ich den Test-Button im Programm drücke, aber nicht wenn ich den PowerButton drücke und auch nicht, wenn ich den "Ausschalten"-Button drücke, der auf Start > Computer ausschalten... erscheint (wie weiter oben jmd schrieb).
procedure WMPowerBroadcast(var Msg:TWMPower);
message WM_POWERBROADCAST; procedure TForm1.WMPowerBroadcast(var Msg:TWMPower); begin Msg.Result:=BROADCAST_QUERY_DENY; ShowMessage('procedure TForm1.WMPowerBroadcast(var Msg:TWMPower);'); end; Eine andere Empfangs-Prozedur, die ich in meiner Nachforschung entdeckt habe ist:
Delphi-Quellcode:
Diese wird beim manuellen senden der Message gar nicht erst aufgerufen. Verwende ich WndProc falsch oder überschreibe ich sie nicht richtig?
procedure wndproc(var msg:Tmessage);
begin inherited; if msg.msg = WM_POWERBROADCAST then begin ShowMessage('procedure wndproc(var msg:Tmessage);'); msg.result:=BROADCAST_QUER_DENY; end; end; Zitat:
Wie weiter oben in diesem Post genauer beschrieben, reagiert das Programm aber auch nicht, wenn ich auf "Ausschalten" gehen und somit, laut deiner Aussage, das WM_POWERBROADCAST-Event auslöse. Zitat:
Zitat:
Es gibt eine Message, laut meinen Recherchen-Quellen ist es WM_POWERBROADCAST, was auch schon in einem älteren Thread im Forum (erfolgreich?) in einem ähnlichen Zusammenhang verwendet wurde. edit: Dieser Thread ist es: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:52 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