Autor |
Beitrag |
FinalFantasy
      
Beiträge: 127
Windows XP
Delphi 5 Professional, Visual Studio 7 .NET (C#)
|
Verfasst: Di 20.09.05 15:46
Hi,
Ich bin auf der Suche nach allen Fenstern auf meinem Desktop. FindWindow liefert mir aber Tausende von Handles die zu irgendwelchen Sachen gehören... Jetzt bin ich schonmal auf die Idee gekommen, alle Fenster die Parentfenster haben oder bei denen length(caption) = 0 zutrifft, auszufiltern. Das hat meine Liste schonmal deutlich minimiert, aber ich finde immernoch sehr viele Handles, die offensichtlich nicht zu einem richtigem Fenster gehören.
So, wie kann ich jetzt die Fenster rausfiltern, die wirklich ein Fenster sind (also eigentlich alles, was auch bei Alt+Tab auftaucht, nicht mehr und nicht weniger), und zusätzlich müsste ich noch rausfinden, ob die Fenster auf Always on Top gesetzt sind....
Hat jemand eine Idee, wie man das machen kann/könnte?
Achja, und das Fenster meiner Applikation sollte unsichtbar sein (also auch nicht in der Taskleiste auftauchen), die Visible-Property des Forms scheint Delphi aber nicht sonderlich zu interessieren, und im OnCreate kann ich ja Hide() noch nicht aufrufen, weil das Fenster ja noch gar nicht existiert....
|
|
matze
      
Beiträge: 4613
Erhaltene Danke: 24
XP home, prof
Delphi 2009 Prof,
|
Verfasst: Di 20.09.05 15:57
Wenn du 2 Fragen hast, dann stell bitte jede Frage in einem seperaten Topic.
_________________ In the beginning was the word.
And the word was content-type: text/plain.
|
|
FinalFantasy 
      
Beiträge: 127
Windows XP
Delphi 5 Professional, Visual Studio 7 .NET (C#)
|
Verfasst: Di 20.09.05 16:20
Ja, sorry.
EnumWindows scheint genau das zu sein, was ich Suche.
Allerdings krieg ich bei dem Aufruf der Funktion den Fehler "Variable erforderlich":
Delphi-Quelltext 1:
| EnumWindows(@EnumWinProc, 0); |
EnumWinProc sieht dabei so aus:
Delphi-Quelltext 1:
| function TfrmOnTopControl.EnumWinProc(Wnd: THandle; LParam: LongInt): Boolean; stdcall; |
Ist also eine Memberfunktion der Klasse.
Bekomme aber den selben Fehler, wenn ich es als Funktion deklariere.
Das ganze stammt von hier: www.delphi-forum.de/...ighlight=enumwindows
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Di 20.09.05 19:20
nimm ENUMDESKTOPWINDOWS, damit kriegst du alle top-level windows.
die enumwindowsproc darf übrigens kein mitglied einer klasse sein.
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Di 20.09.05 19:26
EnumWindows liestet auch nur Top-Level-Fenster auf, aber nicht jedes Top-Level-Fenster ist auch automatisch in der Taskleiste bzw im Alt-Tab-Fenster.
EnumDesktopWindows ist was ganz andres - hier werden die Fenster eines bestimmten Desktops aufgelistet, wobei ein "Desktop" hier ein absolut andere Bedeutung als im üblichen Sprachgebrauch hat, hier ist ein Desktop nämlich ein Security-Objekt - ein Teil einer WindowStation.
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Di 20.09.05 19:31
Motzi hat folgendes geschrieben: |
EnumDesktopWindows ist was ganz andres... |
ok, und was würdest du vorschlagen ? ich habe das mal so gemacht:
Delphi-Quelltext 1: 2: 3: 4:
| style:=getwindowlong(wnd,GWL_STYLE); if (style and WS_VISIBLE) <> 0 then if (style and WS_SYSMENU) <> 0 then |
das liefert ganz brauchbare ergebnise, aber es entspricht nicht genau dem resultat der taskbar.
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Di 20.09.05 20:08
Mit GetWindowLong() bist du schon am richtigen Weg, allerdings solltest du statt GWL_STYLE GWL_EXSTYLE nehmen und auf WS_EX_APPWINDOW testen...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Di 20.09.05 21:21
das funktioniert nicht wirklich.
nimm z.b. den VLC mediaplayer (0.8.2) , der hat folgende Styles:
Quelltext 1: 2: 3: 4: 5:
| WS_OVERLAPPEDWINDOW WS_VISIBLE WS_CLIPSIBLINGS WS_CLIPCHILDREN WS_OVERLAPPED |
Extended:
Quelltext 1: 2: 3: 4:
| WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR WS_EX_WINDOWEDGE |
von WS_EX_APPWINDOW keine spur, trotzdem ists in der taskleiste drin ^^
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
FinalFantasy 
      
Beiträge: 127
Windows XP
Delphi 5 Professional, Visual Studio 7 .NET (C#)
|
Verfasst: Mi 21.09.05 08:43
Habs jetzt EnumWindows zum laufen gebracht... allerdings findet EnumWindows auch viel zu viele Fenster, ähnlich wie FindWindow...
GetWindowsLong findet dagegen kein einziges Fenster mit der WS_VISIBLE-Eigenschaft, aber da sind definitiv welche da!!
Mit WS_EX_APPWINDOW wird mein Feierabendcountdown gefunden (der hat zwar ein Fenster, ist aber ins Systemtray minimiert), Outlook und die MSDN werden gefunden... Opera, Delphi, Delphi-Hilfe und sich selbst findet es damit jedoch auch nicht....
Was für ein gefummel...
[EDIT]:
Sorry, war mein Fehler... die Flags von GWL_STYLE sind nicht in GWL_EXSTYLE enthalten.... logisch, dass kein Fenster WS_VISIBLE hat, wenn ich GetWindowLong mit GWL_EXSTYLE aufrufe...
Ich hole mir jetzt beide Styles, weil ich gesehen hab, dass im Ex-Style die TopMost Eigenschaft drin steckt... (womit eine weitere Frage beantwortet wäre)
WS_VISIBLE liefert (wenn man es richtig macht  ) doch ganz brauchbare Ergebnisse, da ich ja nur die Fenster haben will, die man auch sehen kann *gg*
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Do 22.09.05 14:17
Ok, du hast recht, nicht jedes Fenster das in der Taskbar ist hat WS_EX_APPWINDOW gesetzt, aber jedes Fenster das WS_EX_APPWINDOW gesetzt hat, ist auch in der Taskbar!
Weiters - jedes Fenster, das WS_EX_TOOLWINDOW gesetzt hat ist nicht in der Taskbar.
Ich hab mal einen bisschen Code von mir zusammengesucht und mal das zusammengeklickt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74:
| function GetWindowText(wnd: Hwnd): String; var dwResult: DWord; pBuffer: PChar; begin SetLastError(0); if SendMessageTimeOut(wnd, WM_GETTEXTLENGTH, 0, 0, SMTO_NORMAL, 750, dwResult) = 0 then begin if GetLastError = ERROR_TIMEOUT then Result := '<SendMessage timed out>' else Result := '<SendMessage failed>'; Exit; end; Inc(dwResult);
pBuffer := GetMemory(dwResult); try if SendMessageTimeOut(wnd, WM_GETTEXT, dwResult, Integer(pBuffer), SMTO_NORMAL, 750, dwResult) = 0 then begin if GetLastError = ERROR_TIMEOUT then Result := '<SendMessage timed out>' else Result := '<SendMessage failed>'; end else Result := String(pBuffer); finally FreeMemory(pBuffer); end; end;
function GetClassName(wnd: Hwnd): String; var szBuffer: array [0..255] of Char; iCount: Integer; begin ZeroMemory(@szBuffer, SizeOf(szBuffer)); iCount := Windows.GetClassName(wnd, szBuffer, SizeOf(szBuffer)); if wnd = GetDesktopWindow then StrPCopy(@szBuffer[iCount], 'Desktop');
Result := String(szBuffer); end;
function enumProc(wnd: Hwnd; Listbox: TListBox): Boolean; stdcall; var dwStyle: DWord; bAdd: Boolean; begin Result := true; if IsWindowVisible(wnd) then begin bAdd := True; dwStyle := GetWindowLong(wnd, GWL_STYLE); bAdd := bAdd and (dwStyle and WS_POPUP = WS_POPUP);
dwStyle := GetWindowLong(wnd, GWL_EXSTYLE); bAdd := bAdd or (dwStyle and WS_EX_APPWINDOW = WS_EX_APPWINDOW); bAdd := bAdd and not (dwStyle and WS_EX_TOOLWINDOW = WS_EX_TOOLWINDOW);
if bAdd then Listbox.Items.Add('0x' + IntToHex(wnd, 8) + ' - ' + GetClassName(wnd) + ' - ' + GetWindowText(wnd)); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin EnumWindows(@enumProc, Integer(ListBox1)); end; |
Das funktioniert schon ganz gut, man muss es aber noch ein bisschen verfeinern, bei mir findet er alle Fenster bis auf den Firefox.
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
|