Das Herunterfahren abfangen...



Das Herunterfahren abfangen...

Beitrag, 20.02.2005 22:25: Hallo Profaner...
Ich habe folgendes Problem:
Auf den Versuch Windows herunterzufahren muss ein Programm von mir entsprechend reagieren.
Ich weiss, das Windows beim Herunterfahren die Message WM_QUERYENDSESSION an jedes Programm sendet und auf eine positive Rückmeldung wartet. Wie kann ich diese Message mit Profan abfangen und entsprechend behandeln? Hat jemand eine Idee???
Profan 7.5 => Windows2000/XP


Frank Abbing, 20.02.2005 22:36: Hallo Andeas,
mit XProfan könntest du das sicher über ein Subclassing realisieren
Aber auch mit niedrigeren Profanversion sollte das möglich sein. Auf meiner Webpage findest du die kleine Freeware "Message.dll". Damit kannst du jede Message empfangen. In jedem Fenster und ab Profan 5.


David Strutz, 21.02.2005 00:42: Sagen wir mal so - es wäre auch sinnvoll wenn Roland diese "ok-killme" nicht generell sendet - sondern vielleicht die Abhandlung dessen einer XProfan-Proc überlässt.
Salve, iF


Beitrag, 21.02.2005 08:38: Hallo IF...
Das sehe ich genauso, leider hilft mir das jetzt nicht weiter. Gibt es keine API die Messages abfängt und eine beliebige Rückmeldung an Windows sendet?...
Ich habe hier mal einen Quellcode in Delphi - habe leider zu wenig Ahnung um den komplett zu verstehen und umzusetzen.
Kann jemand [...] was anfangen?
@Frank: Ich habe leider keine Idee, wie mir deine DLL da weiterhelfen kann. Was kann die alles?


Subclassing...

Beitrag, 21.02.2005 20:38: Hallo...
OK, ich glaube den Quelltext habe ich jetzt verstanden:
An Offset GWL_WNDPROC des Fensters befindet sich die Adresse einer Prozedur. Diese Prozedur ist dafür zuständig Messages, die an das Fenster gesendet werden, zu verarbeiten.
Um Messages, die an das Fenster gendet werden, nicht zuerst von dieser Prozedur behandeln zu lassen, setzt man einfach mit SetWindowlong den Wert bei GWL_WNDPROC auf die Adresse einer anderen Prozedur und merkt sich die Adresse der alten Prozedur. In meinem Fall müsste diese Prozedur bei der ankommenden Message WM_QUERYENDSESSION eigentlich nur den Wert 0 zurückgeben - oder 1 wenn das System heruntergefahren werden soll. Alle anderen Messages müssten dann mit CallWindowProc innerhalb dieser Prozedur auf die gemerkte, alte Adresse umgeleitet werden.
Mit Profan, jedenfalls mit Version 7.5, komme ich - soweit ich weiss - nicht an eine Adresse einer in meinem Programm stehenden Prozedur.
Wenn ich aber ein DLL hätte, könnte ich die Adresse einer dort stehenden Prozedur mit GetProcAddress herausfinden und diese für das SubClassing verwenden.

Habe ich jetzt totalen Mist verzapft oder stimmt das in etwa so???
~?~


Frank Abbing, 21.02.2005 20:49: Hi,
ziemlicher Mist, ja.
Denke daran, Profan ist und bleibt eine Interpretersprache.
Du hast meine Dll, die listet dir jede Message auf. Ob du so das Herunterfahren abfangen kannst, weiss ich nicht. Das musst du selber harausfinden, ich hab' momentan einfach viel zuwenig Zeit...


Beitrag, 21.02.2005 21:20: Macht nichts, Frank - gibt ja auch noch andere.
Es klappt - so wie ich das möchte - mit deiner DLL leider nicht.
An alle anderen: Kann mir als unwissendem sonsteiner mal erklären, was Subclassing genau ist? Was genau ist ziemlicher Mist an meinen Überlegungen???
Ziel der Sache ist in etwa ein Verhalten wie es Notepad zeigt:
Wenn Windows heruntergefahren wird und eine Datei gerade bearbeitet, aber noch nicht abgespeichert wurde, gibt Notepad eine Messagebox aus. Wenn hier 'abbrechen' gedrückt wird, wird das System nicht heruntergefahren.


Cb, 21.02.2005 21:21: Hi, Andreas!
Direkt weiterhelfen kann ich Dir leider nicht, aber schau Dir das mal näher an:
[...]
Ist ein ziemlich geniales Programm mit ein paar dll's, die allerdings mit ResourceHacker nicht zu öffnen sind (ASM-Dll's?). Vielleicht hast Du da 'ne Möglichkeit dazu - oder Frank, falls er mal weniger Überfluss an Arbeit hat?
Gruss, Christian


Beitrag, 21.02.2005 23:23: Hallo Christian...
Das Programm werde ich mir auf jeden Fall ansehen - leider wird es mir bei meinem Problem nicht helfen.
Windows sendet beim Herunterfahren die Message WM_QUERYENDSESION an jedes Toplevelfenster. Jedes Fenster gibt, bedingt durch seine Klasse (wenn ich das richtig verstehe), eine Wert (entweder 1 oder 0) an Windows zurück. 1=Windows darf heruntergefahren werden 0=Windows darf nicht heruntergefahren werden. Erst wenn alle Fenster eine 1 zurückliefern, wird Windows beendet und die Message WM_ENDSESSION an jedes Toplevelfenster gesendet => siehe Notepad.

Die Message WM_QUERYENDSESION kann ich unter bestimmten Bedingungen auch mit Profan empfangen => vorausgesetzt ich arbeite mit Windows98, da dort das Herunterfahren etwas anders abläuft als unter WindowsNT.
Da mein Programm - wohl bedingt durch das, was ich als Fensterklasse verstehe - aber sofort nach dem Empfang der Message gekillt wird, bringt mir das nichts.
Ich muss also irgendwie an die "Klasse" meines Hauptfensters ran, um dort etwas zu verändern.
Mit Profan alleine geht das wohl nicht - jedenfalls nicht mit 7.5, denn dazu brauche ich die Adresse einer Art "Ersatzprozedur".
Meine Frage: Kann ich mit XProfan Subclassing realisieren? Gibt es eine Möglichkeit Subclassing über externe DLL's zu regeln? Habe ich den Begriff Subclassing überhaupt richtig verstanden???


Frank Abbing, 22.02.2005 00:00: Hi,
Subclassing ist das Einfügen eines eigenen Codes in die Windows-Message Prozedur. Wird eine Message ausgelöst, dann wird diese eigene Routine angesprungen, bevor in der Windows-Message Prozedur die ankommende Message weiter bearbeitet wird. Dieser eigene Code kann jetzt Messages verändern, entfernen oder selber welche erzeugen. Du könntest hier also deine gewünschte Message einfach löschen oder entsprechend darauf reagieren. Etwa so:
[code:1:e342c7b311]Proc NewWindowCallBack
Parameters wnd&,msg&,wparam&,lparam&
If msg&=~WM_QUERYENDSESION
Return 0
Endif
RETURN ~CallWindowProc(OldWindowCallBack&,wnd&,msg&,wparam&,lparam&)
EndProc[/code:1:e342c7b311]
Schau doch mal bei Andreas Miethe vorbei. Der hat schon einige XProfancodes erstellt, die Profans Windowsprozedur subclassen. Ich selber pflege das immer nur in eine Dll verpackt mit Assembler zu machen.
@Christian: Vielleicht sind die Dll's gepackt?


Cb, 22.02.2005 00:12: [quote:7658e6b148="Frank Abbing"]@Christian: Vielleicht sind die Dll's gepackt?[/quote:7658e6b148]
ResourceHacker zeigt nur ein leeres Feld, keinerlei Einträge.
Ich habe dann mal mit einem speziellen Editor (eigentlich ein Plugin vom Total Commander) hineingeschaut:
FILE CHARACTERISTICS :
File is executable (i.e. no unresolved external references)
COFF line numbers have been removed
COFF symbol table entries for local symbols have been removed
Machine based on 32-bit-word architecture
File is a DLL
Ach was - das Prog. ist Freeware. Ich schick' Euch mal die dll's einfach mit. Vielleicht könnt Ihr ja was damit anfangen.
Gruss, Christian

Winspector_DLL.zip


Frank Abbing, 22.02.2005 07:26: Gerade gefunden: [...]
Andreas hat sowas schon geschrieben


Beitrag, 22.02.2005 12:57: Nochmals besten Dank, Frank. Das zeigt mir eigentlich schon, dass ich die Sache richtig verstanden habe.
Ich werde mich mal auf Andreas' Homepage umsehen. Bislang kenne ich nur die Möglichkeit, mit SetWindowLong die Adresse der neuen Prozedur zu übergeben, vielleicht komme ich da noch auf neue Ideen.


Beitrag, 22.02.2005 15:42: Hallo Frank...
Dein Tipp war goldrichtig und hat mir fast alle meiner Fragen auf einmal beantwortet .
Kann man Subclassing auch mit externen DLL's realisieren, oder muss die Prozedur innerhalb meines Programms stehen?


Frank Abbing, 22.02.2005 17:36: Hi,
nein, eine externe Dll geht natürlich auch. Siehe Message.dll


Besten Dank und grosse Bitte...

Beitrag, 22.02.2005 20:03: Da habe ich wirklich eine ganze Menge dazugelernt . Leider zeigt mir das aber auch, dass ich mit meiner jetzigen Profanversion auf keinen Fall weiterkomme.

Ich habe jetzt folgende grosse Bitte an jeden von euch:
Ich brauche für eines meiner Shareware Programme eine mit UPX komprimierte XProfan EXE als Freeware. Dieses Programm soll mittels Subclassing die Message WM_QUERRYENDSESSIN abfangen und, wenn diese Message aufgetreten ist, Windows mit dem Profanbefehl ExitWindows 4 herunterfahren. Das von der EXE erzeugte Fenster muss unsichtbar sein. Ob das Programm in der Taskleiste erscheint, ist egal (Übergangslösung, bis ich XProfan habe).
Das hört sich vielleicht ziemlich kompliziert an, in Wirklichkeit sind das aber nur ein paar Zeilen Quelltext. Fast alles, was man zu diesem Programm braucht - sogar den grössten Teil des Quelltextes (nämlich das Subclassing der Message WM_QUERRYENDSESSION) - findet man eigentlich schon auf der XProfan Homepage von Andreas Miethe. Das ganze dürfte also nur eine Arbeit von ein paar Minuten sein.
Ich weiss, dass das eine sehr grosse Bitte ist, und ich wäre auch nicht böse, wenn mir diesen Wunsch niemand erfüllen würde - aber riesig freuen würde ich mich schon.


David Strutz, 22.02.2005 20:47: Nein eigendlich keine grosse bitte - Du holst Dir einfach die neuste XProfan-Shareware ausm Downloadbereich und proggst was Du brauchst. Das Compilieren inne Exe wird sicherlich jemand für Dich übernehmen.
Salve, iF


Frank Abbing, 22.02.2005 20:49: Hi,
mach den Code nach deinen Vorstellungen fertig und schicke ihn mir ruhig zu. Ich kompiliere ihn für dich und schicke dir die Exe zurück.
Noch besser wäre es, du legst dir XProfan zu...


Michael D., 22.02.2005 23:21: Hallo,
meint ihr so etwa?
[code:1:5431acf58c]Def CallWindowProc(5) !"USER32.DLL","CallWindowProcA" ' lpPrevWndFunc&,hwnd&,MSG&,wParam&,lParam&
Def SetWindowLong(3) !"USER32.DLL","SetWindowLongA" ' hwnd&,nIndex&,dwNewLong&
Def &GWL_WNDPROC -4
Def &WM_QUERYENDSESSION $0011
Def &WM_CANCELMODE $001F
Declare gHW&,lpPrevWndProc&
Proc NewWindowProc
Parameters hw&,uMsg&,wParam&,lParam&
Declare Ant&
Case (uMsg& = &WM_QUERYENDSESSION): ExitWindows 4
Return CallWindowProc(lpPrevWndProc&,hw&,uMsg&,wParam&,lParam&)
EndProc
Proc Hook
gHW& = %hwnd
lpPrevWndProc& = SetWindowLong(gHW&,&GWL_WNDPROC,ProcAddr("NewWindowProc",4))
EndProc
Window Add(%maxX,10),100-25,25
ShowWindow(%HWnd,0)
Hook
While 1
WaitInput
EndWhile
End[/code:1:5431acf58c]
Hab das mal mit Profan2Cpp & UPX auf 76kB gedrückt: [...]
Vielleicht isses ja brauchbar.
Gruss
Michael...


Beitrag, 23.02.2005 17:51: Hallo Michael...
Denk dir einen Schönen Titel für das Fenster aus und kompiliere das zur EXE - das müsste es sein! Zum Testen des Programms kanns du einfach Notepad starten, einen kleinen Text eingeben und nicht speichern. Wenn du dann das Programm startest und Windows danach herunterfahren lässt, soll Windows ohne Nachfrage beendet werden.
@IF...
Mein Rechner ist mit Profanversionen bis zum Stehkragen gefüllt - laufend gibt es Probleme die richtige Hilfe zu starten. Deshalb ziehe ich mir jetzt nicht die Sharewareversion - aber demnächst die Vollversion.
Vielen Dank an alle für ihre Hilfe!


David Strutz, 23.02.2005 18:05: Für solcherlei Probleme gibs doch aba den XPSE.
Naja und die Hilfe... da braucht man doch eigendlich imma nur die Neueste.
Salve, iF


Beitrag, 23.02.2005 20:16: Hallo Michael...
Au bion ich blöd! Hab den Link ganz übersehen - Programm ist ja schon fertig! Werds morgen gleich testen!!!


Beitrag, 24.02.2005 09:48: Hallo Michael...
Das Programm funktioniert hervorragend und ist haargenau und bis aufs I-Tüpfelchen genau das was ich haben wollte! ~pressmee~
...Vielleicht hilft es ja noch irgendeinem weiter, wenn ich jetzt mal genauer auf die Unterschiede beim Herunterfahren von Windows eingehe:
Windows95/98/ME=>
Es wird an jedes Toplevelfenster die Message WM_QUERYENDSESSION gesendet. Erst wenn alle Fenster eine 1 zurückgeliefert haben, wird die Message WM_ENDSESSION an die Fenster geschickt, die alle laufenden Programme beendet. Liefert ein Fenster als Antwort auf WM_QUERYENDSESSION 0 zurück, wird die Message WM_ENDSESSION nicht abgeschickt.
WindowsNT/2000/XP=>
Es wird an jedes Toplevelfenster die Message WM_QUERYENDSESSION geschickt. Jedes Fenster, das eine 1 zurückliefert, erhält dann die Message WM_ENDSESSION , was dazu führt, dass das betreffende Programm beendet wird. Liefert ein Fenster auf WM_QUERYENDSESSION 0 zurück, wird der ganze Prozess abgebrochen und es wird an die nachfolgenden Fenster weder die Message WM_QUERYENDSESSION noch die Message WM_ENDSESSION gesendet.
Welches Fenster zuerst die Message WM_QUERYENDSESSION bekommt, hängt davon ab, wann der dazugehörige Prozess gestartet wurde (meiner Meining nach eine extrem unideale Variante des Shutdowns).


Dies ist die Offlinevariante vom Thread [Das Herunterfahren abfangen...].

Valid CSS!

©2006 XProfan.Com