Delphi-PRAXiS

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 + D' - Taste austricksen (https://www.delphipraxis.net/104628-windows-d-taste-austricksen.html)

SittingDuck 7. Dez 2007 17:52


'Windows + D' - Taste austricksen
 
Moin Moin ...

Klar ... das soll man nicht ... ich weiss. Gehört sich auch nicht !
Kann man oft im Internet nachlesen ... 'Win + D' heisst 'Win + D'
und mehr nicht. Wiederspenstige Fenster sind 'böse' ! :twisted:
Das einfach mal Vorweg ...

OK, trotzdem wurde dieses 'resistente Fensterverhalten' schon
von vielen Anwendern, als Feature für den Launcher gewünscht.

Gut, ich habe viel gelesen und da sowieso ein winziger Timer
im Launcher läuft, hatte ich folgende Idee nach umfangreicher
Analyse mit 'XSpy'.
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var s: array[0..255] of char;
begin
   GetClassName(GetForeGroundWindow, s, 255);
   if s = 'WorkerW' then Application.BringToFront;
end;
Peter Below hat irgendwo mal geschrieben, das 'Win + D' die anderen
Fenster nicht minimiert, sondern der Desktop wird einfach als 'TopMost'
Fenster nach vorne geholt. Das stimmt und der Code von oben funktioniert
demnach auch, weil nach dem drücken von 'Win + D' ein Fenster mit dem
ClassName 'WorkerW' aktiv ist. Das ist auch der Grund, warum die anderen
Fenster nie eine Minimized-Message 'hören' konnten.

Ich tue jetzt mal so, als wüsste ich hier wovon ich rede ... aber es war
niemand überraschter als ich, als die zwei Zeilen von oben wirklich liefen.
Unter Windows XP. Davor (Win9x etc.) hieß die ClassName nämlich 'WorkerA'.
Gut, das könnte man noch abfragen, aber obwohl die ClassName unter Vista
auch 'WorkerW' heisst, läuft der Code von oben dort leider nicht. Vista macht
da irgendwas anders und damit kommen ich zu meiner Frage.

Zum einen glaube ich nicht, das die zwei Zeilen von oben schon ausreichen,
weil XSpy mir ganz viele 'WorkerW'-ClassNames gezeigt hat. Demnach wäre es
denkbar das die Routine öfter als gewünscht den Launcher nach vorne holt,
wobei mir das jedoch in den letzten Tagen nicht aufgefallen ist ...
Dieses 'WorkerW'-ClassName-Ding hat laut 'XSpy' einen Parent mit dem Namen
'#32764 (Desktop)'. Sinnvoll bekomme ich das nicht 'verwurstet', zumal
ich auf diesem Gebiet gerade erst die ersten Erfahrungen mache. :stupid:

Wer kann die zwei Zeilen sinnvoll ergänzen bzw. hat eine Idee warum das
unter Vista nicht läuft. Ich könnte generell etwas mehr 'Licht' in diesem
Thema gebrauchen. :idea:

Aus der Dunkelheit grüßt ...

DeddyH 7. Dez 2007 18:38

Re: 'Windows + D' - Taste austricksen
 
Vielleicht bin ich auf dem Holzweg, aber wäre es nicht besser, wenn Du einen Tastaturhook installierst und auf diese Tastenkombination reagierst, anstatt mit einem Timer das oberste Fenster zu ermitteln?

SittingDuck 7. Dez 2007 20:28

Re: 'Windows + D' - Taste austricksen
 
Tach nochmal ...

@DeddyH: Nein, nein ... auf dem Holzweg bist Du nicht ...
Aber einen TataturHook verpackt in eine *.dll-Datei ist
sicherlich um einiges aufwendiger als diese simple Abfrage.

Sie läuft ja auch erstaunlicherweise recht gut, bis auf
meine noch offene Vista-Frage und meine Vermutung, das
bei mehreren von XSpy gefundenen 'WorkerW'-ClassNames
eine noch vielleicht etwas 'eindeutigere' Abfrage
nötig ist. Stichwort: '32769 (Desktop)'-Parent (s.o.)

Da erhoffe ich mir ja einen hilfreichen Hinweis von
dem ein oder anderen 'Win-API-Freak', da das Internet
an der Stelle doch leider etwas schweigsam ist.

Ich vermute mal Folgendes: XSpy hat mir 4 'WorkerW'-
Dinger angezeigt und unter XP ist die erste ClassName
(die mit der Parent: '32769 (Desktop)') per Zufall die
Richtige. Unter Vista leider nicht.

Deshalb meine Frage so gut ich sie mit meinem jetzigen
Wissensstand überhaupt stellen kann: Wie kann ich die
'WorkerW'-Abfrage (was ist das überhaupt ?) von oben
eindeutiger machen, vielleicht in dem ich eine Parent-
Abfrage vorweg schicke ?

Ich hoffe mal, dass trotz der etwas 'schwammigen' Frage-
stellung, irgendwann die richtigen Leute das hier lesen.
Danke schonmal im Vorraus ...

DGL-luke 7. Dez 2007 20:43

Re: 'Windows + D' - Taste austricksen
 
Wegen der Eingrenzung: Du könntest per MSDN-Library durchsuchenEnumChildWindows alle Child-Windows des Desktop-Fenster (Handle=0) auflisten und dann per GetClassName nochmal prüfen.

SittingDuck 10. Dez 2007 10:22

Re: 'Windows + D' - Taste austricksen
 
So ... ich nochmal ...

@DGL-luke: Hm ... irgendwie komme ich hier nicht weiter. EnumChildWindows könnte, wenn ich das richtig verstehe auch mehrere 'WorkerW'-ClassNames enthalten. Ich müsste aber gezielt die ClassName finden, welche als Parent den '32769 (Desktop)' hat. Vielleicht habe ich hier aber auch einen Denkfehler ...

Ich beschreibe einfach nochmal in möglichst einfachen Worten was ich gemacht habe und welche Idee ich verfolge: Wenn ich XSpy starte und dann 'Win + D' drücke, dann meldet mir XSpy, das ein Fenster(?) aktiv ist mit dem ClassName 'WorkerW'. Cool, dachte ich mir. Dann frage ich einfach in meiner Timer-Routine ab, wann das der Fall ist und bringe kurz dannach mein Launcher-Fenster nach vorne.

Nun gibt es aber laut XSpy mehrere 'WorkerW'-ClassNames. Bei meinem System mindestens 4, starte ich den Internet Explorer dann gerne auch noch mehr. Die GetClassName-Abfrage läuft, aber wahrscheinlich nur per Zufall, weil die zuerst gefundene ClassName halt gerade die richtige ist. Das würde erklären, warum es unter XP läuft, aber unter Vista leider nicht.

Wie kann ich meine GetClassName-Abfrage präziser machen, wenn ich als einzigen Hinweis von XSpy den Parent '32769 (Desktop)' habe. In einem ähnlichen Thread hier hat ein anderer DP'ler mal mit seinen Worten versucht das Problem einzugrenzen. Ich denke mal vom Prinzip her versuchen wir beide das gleiche. Leider ist dieser andere Thread auch noch unbeantwortet, wobei ich mir denke, das diese Routine ein Klassiker für die CodeLib wäre.

Nun ja ... danke erstmal fürs Nachvollziehen und ggf. für Eure Ideen ...

himitsu 10. Dez 2007 13:55

Re: 'Windows + D' - Taste austricksen
 
ist bei dir "Active Desktop" aktiviert?

wenn ja, dann ist der Desktop eigentlich ein InternetExplorerFenster,
was beim Standarddektop nicht der Fall ist.

jetzt kann sich das entweder im Vista geändert haben
und wenn es dort so geblieben ist, dann könnte auf dem getesteten Vista einfach nur kein "Active Desktop" aktivert sein.

SittingDuck 14. Dez 2007 13:02

Re: 'Windows + D' - Taste austricksen
 
Moin Moin ...

Ok, jetzt läuft es mit folgender Routine sowohl unter Win98 bis Vista.
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var s: array[0..255] of char;
begin
   GetClassName(GetForeGroundWindow, s, 255);
   if Assigned(AnsiStrPos(s, 'Worker')) then BringAppToFront;
end;
Das Problem war der Befehl 'Application.BringToFront' welcher unter Vista scheinbar nicht immer zuverlässig läuft. Warum das so ist, das entzieht sich meiner Kenntnis. Ich habe etwas experimentiert und heraus gefunden, das man über den Befehl 'AttachThreadInput' z.B. hier zum gewünschten Ziel kommt. Die Routine wurde geringfügig erweitert um 'WorkerA' und auch 'WorkerW' ClassNames zu finden.

Ein 'Active Desktop' hat aus meiner Sicht keinen Einfluss auf die Funktion dieser Timer-Routine und eine Überschneidung mit anderen 'WorkerW'-ClassNames ist mir bisher nicht aufgefallen. Aus meiner Sicht ist dieser Thread beendet. Vielleicht haben die Moderatoren der Code-Lib ja Interesse an dem Ergebnis.

Danke nochmal für Eure Mithilfe ...

Luckie 14. Dez 2007 13:11

Re: 'Windows + D' - Taste austricksen
 
Zitat:

Zitat von SittingDuck
Das Problem war der Befehl 'Application.BringToFront' welcher unter Vista scheinbar nicht immer zuverlässig läuft. Warum das so ist, das entzieht sich meiner Kenntnis.

Weil Microsoft verhindern wollte, dass sich ein Fenster so einfach in den Vordergrund bringt bzw. drängelt. Es soll dem Benutzer überlassen bleiben, wann er mit welchem Fenster arbeiten will.

SittingDuck 14. Dez 2007 14:39

Re: 'Windows + D' - Taste austricksen
 
Trotz vorsichtig formulierter Einleitung in diesen Thread ist jetzt doch der warnende Zeigefinger gekommen. :zwinker:
Natürlich ging es hier nur um eine theoretische Möglichkeit. Aber Luckie hat Recht ... ein einfaches
Delphi-Quellcode:
SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
macht genau das Gleiche und ist darüber hinaus noch 'politisch Korrekt'.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:22 Uhr.

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