Seite 1 von 3

Liste "echter" Fenster

Verfasst: 28.10.2005 13:39
von Kiffi
Hallo,

mit dem Spy++ (oder auch EnumAllWindows) kann man sich eine Liste der
aktuell im System verfügbaren Fenster anschauen. Hierbei wird aber alles
aufgelistet, was über ein Fenster-Handle verfügt. Ich benötige allerdings nur
eine Liste der "echten" Fenster, sprich: Alle Fenster, die sich in die Taskleiste
einklinken und auf Knopfdruck in den Vordergrund gebracht werden können.

Meine Frage: An welchen eindeutigen Merkmalen erkennt man solche
Fenster?

Danke im voraus & Grüße ... Kiffi

Verfasst: 28.10.2005 14:01
von IcedCoffee
sie haben eine Größe
GetWindowRect
aber da gibt es einen bug in der structure
aus
structure RECT
left.l
top.l
right.l
bottom.l
endstructure
MUST du das machen
structure RECT
XXX.l
left.l
top.l
right.l
bottom.l
endstructure
weil die ersten 4 byte nicht beschrieben werden ka warum

ps: ich bin mir aber nciht sicher ob es so ist ales ob alle fenster eine Größe haben

Verfasst: 28.10.2005 14:20
von Kiffi
> sie haben eine Größe

äh, ja, das ist aber kein eindeutiges Merkmal für ein "echtes" Fenster.

Beispiel: Fenster A hat eine Toolbar. Die Toolbar wird in Spy++ auch mit
aufgelistet. Und die Toolbar hat nun mal auch eine Grösse.

Danke & Grüße ... Kiffi

Verfasst: 28.10.2005 14:35
von ts-soft
Ich weiß nicht, ob Sie wußten:

Code: Alles auswählen

EnumChildWindows_(#Null, lpEnumFunc, lParam)
oder

Code: Alles auswählen

EnumWindows_(lpEnumFunc, lParam)
liefert nur Hauptfenster, ich denke, aber dieses meinste nicht :freak:

Verfasst: 28.10.2005 14:49
von Kiffi
> Ich weiß nicht, ob Sie wußten: [...]

ja, ich bin doch kein Dummie ;-)

folgenden Code habe ich mir schon zusammenklauen können:

Code: Alles auswählen

Structure Window
  Childs.l
  Rekursion.l
  
  ;Window
  Handle.l
  Process.l
  Name.s
  Class.s
EndStructure

#BufferSize = 2048

NewList Window.Window()
 
Procedure.s GetClassName(Handle.l)
  Class.s = Space(#BufferSize)
  GetClassName_(Handle, @Class, Len(Class))
  ProcedureReturn Left(Class, Len(Class))
EndProcedure

Procedure.s GetTitle(Handle)
  Name.s = Space(#BufferSize)
  GetWindowText_(Handle, @Name, Len(Name))
  ProcedureReturn Left(Name, Len(Name))
EndProcedure

Procedure EnumProc(Handle.l, lParam.l)
  AddElement(Window())
  
  Window()\Handle = Handle
  Window()\Process = 0
  GetWindowThreadProcessId_(Handle, @Window()\Process)
  Window()\Name = GetTitle(Handle)
  Window()\Class = GetClassName(Handle)
  
  If lParam
    *tmp.Window = lParam
    *tmp\Childs + 1
    Window()\Rekursion = *tmp\Rekursion + 1
  Else
    Window()\Rekursion = 0
  EndIf
  
  ; EnumChildWindows_(Handle, @EnumProc(), @Window())
  
  ProcedureReturn #True
  
EndProcedure

Procedure EnumAllWindows()
  Protected TmpL.l
  ClearList(Window())
  TmpL = EnumWindows_(@EnumProc(), 0)
EndProcedure

;-

EnumAllWindows()

ForEach Window()
  
  If EindeutigesMerkmalFuerEchteFensterDasIchAllerdingsNichtKenne
    Debug Window()\Handle
  EndIf

Next
Grüße ... Kiffi

Verfasst: 28.10.2005 14:59
von Franky
Wie wär´s mit "IsWindowVisible"? gibt allerdings auch fenster, die trotzdem net in der Taskleiste stehen, is die frage, ob du die auch willst. Desweiteren musst du noch das Fenster beachten, auf dem die Desktopicons liegen (weiß jetzt nicht, wie es heißt, musst eben nachschauen).

Ist allerdings auch ein bisschen gefrickelt

Oder du suchst die Taskbar und testest ein Bisschen rum, wo die "Knöpfe" für die Fenster liegen.

Verfasst: 28.10.2005 15:12
von sim0n
Wenn du alle Fenster auflisten willst, die sich in die Startleiste einklinken, warum holst du dir dann nicht mit

Code: Alles auswählen

tWnd = FindWindow_("Shell_TrayWnd", "")
das Handle des Startleiste und durchsucht dann einfach mit

Code: Alles auswählen

bWnd = GetWindow_(tWnd, #GW_CHILD)
alle Child-Fenster?

Wenn sie nicht "Start" als Text haben, müssten es normalerweise die Fenster sein, die du suchst (denke ich zumindest...)

Verfasst: 28.10.2005 15:31
von edel
Vielleicht so ?

Code: Alles auswählen

Procedure ListWindows(hwnd, Param)
  
  If GetWindowLong_(hwnd,#GWL_EXSTYLE) ! #WS_EX_TOOLWINDOW And GetWindowLong_(hwnd,#GWL_STYLE) & #WS_VISIBLE
    s.s = Space(250) 
    GetWindowText_(hwnd,s,250) 
    Debug s
  EndIf
  
  ProcedureReturn #True
EndProcedure 

parent = FindWindow_("ToolbarWindow32","Ausgeführte Anwendungen")
EnumChildWindows_(parent,@ListWindows(),0)

Verfasst: 04.10.2007 18:46
von Scarabol
Hat sich nach dieser kleinen Denkpause, vielleicht noch was vernünfitges ergeben?

Gruß
Scarabol

Verfasst: 05.10.2007 11:15
von Tafkadasom2k5
Ich habe keine Ahnung, ob das funktioniert, aber ein Versuch ist es wert- habe Kiffis Code mal umgeschrieben, aber habe keinen Compiler zur Hand. Ist- wie gesagt, nur ein armer Versuch ;)

Code: Alles auswählen

;Originalcode von Kiffi
;modifiziert am 05.10.2007 von Tafkadasom2k5
;Kein Compiler zur Hand, von daher bitte überprüfen ;)

;Flags, die unter Umständen beim GetWindowPlacement herauskommen könnten
#SW_HIDE            = 0
#SW_SHOWNORMAL      = 1
#SW_NORMAL          = 1
#SW_SHOWMINIMIZED   = 2
#SW_SHOWMAXIMIZED   = 3
#SW_MAXIMIZE        = 3
#SW_SHOWNOACTIVATE  = 4
#SW_SHOW            = 5
#SW_MINIMIZE        = 6
#SW_SHOWMINNOACTIVE = 7
#SW_SHOWNA          = 8
#SW_RESTORE         = 9
#SW_SHOWDEFAULT     = 10
#SW_FORCEMINIMIZE   = 11
#SW_MAX             = 11

;Indiz für ein Nachrichtenfenster
#HWND_MESSAGE = 4294967293


;Zusätzliche Strukturen, sofern noch nicht definiert
Structure RECT
   left.l 
   top.l 
   right.l 
   bottom.l 
EndStructure

Structure POINT
    x.l 
    y.l 
EndStructure

Structure WINDOWPLACEMENT
   length.l
   flags.l 
   showCmd.l 
   ptMinPosition.point 
   ptMaxPosition.point 
   rcNormalPosition.rect
EndStructure

Structure Window
  Childs.l
  Rekursion.l
 
  ;Window
  Handle.l
  Process.l
  Name.s
  Class.s
  WinAttributes.WINDOWPLACEMENT ;Bauen wir noch zusätzlich rein.
EndStructure

#BufferSize = 2048

NewList Window.Window()
 
Procedure.s GetClassName(Handle.l)
  Class.s = Space(#BufferSize)
  GetClassName_(Handle, @Class, Len(Class))
  ProcedureReturn Left(Class, Len(Class))
EndProcedure

Procedure.s GetTitle(Handle)
  Name.s = Space(#BufferSize)
  GetWindowText_(Handle, @Name, Len(Name))
  ProcedureReturn Left(Name, Len(Name))
EndProcedure

;Hinzugefügte Prozedur zum Ermitteln, ob Fenster existent. Notfalls mal mt den Flags herumprobieren.
Procedure.l IsVisibleWindow(myWindow.Window)
   showCommand.l = myWindow\WinAttributes\showCmd
   If showCommand <> #SW_HIDE And showCommand =  #SW_SHOWMAXIMIZED Or showCommand =  #SW_MAXIMIZE Or showCommand =  #SW_SHOWMINIMIZED Or showCommand =  #SW_MINIMIZE And GetParent(Handle) <> #HWND_MESSAGE
      ProcedureReturn #True
   Else
      ProcedureReturn #False
   EndIf
EndProcedure
   
Procedure EnumProc(Handle.l, lParam.l)
  AddElement(Window())
 
  Window()\Handle = Handle
  Window()\Process = 0
  GetWindowThreadProcessId_(Handle, @Window()\Process)
  Window()\Name = GetTitle(Handle)
  Window()\Class = GetClassName(Handle)
  
  ;Windowattribute zusätzlich hinzufügen
  Window()\WinAttributes\lenght = SizeOf(WINDOWPLACEMENT)
  GetWindowPlacement_(Handle, @Window()\WinAttributes)
 
  If lParam
    *tmp.Window = lParam
    *tmp\Childs + 1
    Window()\Rekursion = *tmp\Rekursion + 1
  Else
    Window()\Rekursion = 0
  EndIf
 
  ; EnumChildWindows_(Handle, @EnumProc(), @Window())
 
  ProcedureReturn #True
 
EndProcedure

Procedure EnumAllWindows()
  Protected TmpL.l
  ClearList(Window())
  TmpL = EnumWindows_(@EnumProc(), 0)
EndProcedure

;-
lCounter.l
EnumAllWindows()

ForEach Window()
 
  If IsVisibleWindow(Window())
    Debug "--------------"
    Debug Window()\Handle
    Debug Window()\Name
    Debug Window()\Class
    Debug "--------------"
  EndIf

Next
Gr33tz
Tafkadasom2k5

Edit:
Merke gerade, dass sich keine Strukturen an Funktionen übergeben lassen. Stimmt ja. (versuche nur gerade zumindest die Syntax über die PB4-Demo zu richten :oops: ) *schnell nach ner Lösung such*