Entwickler-Ecke

Windows API - Taskbar-Einträge


Xion - So 04.02.07 14:17
Titel: Taskbar-Einträge
Hi

ich will mir eine eigene Taskbar bauen. An sich kein Problem, ein Problem hab ich aber doch. Wie kann ich die Anwendungen herausfinden, die in der Taskbar sind (ggf. auch die im Tray). Das Problem ist, dass ich nicht genau herausbekomm, welche denn in der Taskbar sind, denn z.B. hat Delphi mehrere Handles, aber nur einen Eintrag in der Taskbar. müsste ja irgendwie über EnumWindows gehen.

thx

Xion

//EDIT: hab hier ne Quelle in Visual Basic, aber irgendwie ist die auch nicht besser als das normale EnumWindows http://www.vbarchiv.net/archiv/tipp_1147.html


jaenicke - So 04.02.07 14:37

user profile iconXion hat folgendes geschrieben:
//EDIT: hab hier ne Quelle in Visual Basic, aber irgendwie ist die auch nicht besser als das normale EnumWindows

In dem VB-Quelltext macht genau das Filtern ja ew_fenster, das sollte so funktionieren. Sieht zumindest richtig aus.


Xion - So 04.02.07 14:45

hmm, geht aber irgendwie nicht


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
function EnumWinProc(Wnd: THandle; LParam: LongInt): Boolean; stdcall;
var
  i1,i2: DWord;
  d1,d2: String;
begin
  Result:=True;

  If (IsWindowVisible(Wnd)) And (GetParent(Wnd) = 0Then
   begin
    // erweiterte Optionen abrufen
    i1 := GetWindowLong(Wnd, GWL_EXSTYLE);
    // nochmals Elternfenster prüfen:
    i2 := GetWindow(Wnd, GW_OWNER);
    // Prüfen, ob:
    // - Kein ToolWindow und kein Childfenster oder
    // - Anwendungsfenster und Childfenster
    If (((i1 And WS_EX_TOOLWINDOW) = 0And (i2 = 0)) Or ((i1 And WS_EX_APPWINDOW) And (i2 <> 0)) Then
      // Titel / Klasse auslesen
      GetWindowInfo(Wnd, d1, d2);

    d1:=d1; //Breakpoint um Ergebnis zu checken
   end;
end;


=> [Fehler] UTaskbar.pas(33): E2015 Operator ist auf diesen Operandentyp nicht anwendbar


Xion - So 04.02.07 14:59

ok, habs jetzt


Delphi-Quelltext
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:
function EnumWinProc(Wnd: THandle; LParam: LongInt): Boolean; stdcall;
var
  i1,i2: DWord;
  d1,d2: array [0..255of Char;
begin
  Result:=True;

  If (IsWindowVisible(Wnd)) And (GetParent(Wnd) = 0Then
   begin
    // erweiterte Optionen abrufen
    i1 := GetWindowLong(Wnd, GWL_EXSTYLE);
    // nochmals Elternfenster prüfen:
    i2 := GetWindow(Wnd, GW_OWNER);
    // Prüfen, ob:
    // - Kein ToolWindow und kein Childfenster oder
    // - Anwendungsfenster und Childfenster
    If (((i1 And WS_EX_TOOLWINDOW) = 0And (i2 = 0)) Or (((i1 And WS_EX_APPWINDOW)=0And (i2 <> 0)) Then
      begin
        // Informationen holen
        GetWindowText( Wnd, d1, 1024);
        GetClassName (Wnd, d2, 1024);
      end;
    ShowMessage(String(d1));
   end;


end;


nur kommen die meisten Einträge doppelt als Meldung...jemand ne Ahnung woran das liegt. Man könnte sie zur Not auch filtern...

Thx

Xion


Billi Berserker - Mi 28.02.07 14:03

Eine Taskbar über EnumWindows zu bauen ist nicht wirklich optimal. Jedesmal alle Fenster durchgehen und testen ob sich da etwas ändert ist etwas arg umständlich und auch langsam.
Die ideale implentierung geht über Shell Hooks
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/shellproc.asp
Damit braucht du nur noch die HSHELL_WINDOWACTIVATED, HSHELL_WINDOWCREATED, HSHELL_WINDOWDESTROYED Nachrichten auswerten :)

Falls du es doch über EnumWindow machen willst dann probier es so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    if (GetWindowLong(Wnd, GWL_STYLE) and WS_SYSMENU <> 0and
       ((IsWindowVisible(Wnd) or IsIconic(wnd)) and
       ((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0or
       (GetWindowLong(Wnd, GWL_HWNDPARENT) = GetDesktopWindow)) and
       (GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0))  then
    begin
      ...
    end;


Xion - Mi 28.02.07 16:09

thx :)

der Code funzt super ohne der letzten Bedingung
(GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0)
mit dieser Zeile findet er z.B. Miranda nicht

die Shell Hooks hab ich mir angeguckt, ist mir aber zu aufwendig (mit EnumWindows gehts zur Zeit gut, das Prog ist nur für mich und allzu viel Zeit hab ich momentan auch nicht ;) )

Danke

Xion


Billi Berserker - Mi 28.02.07 17:15

user profile iconXion hat folgendes geschrieben:
(GetWindowLong(Wnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0)
mit dieser Zeile findet er z.B. Miranda nicht

Dann hast du bei Miranda eingestellt das es als Style Toolwindow hat. Aber ein Toolwindow sollte soweit ich weiß generell nicht in der Taskbar angezeigt werden (im Fall von Miranda dann nur noch als Tray Icon). Also bei Miranda einfach ausstellen :)


Xion - Do 01.03.07 14:37

ja, aber...hab z.B. auch eigene Progs die nicht in der Taskbar erscheinen, aber die will ich trozdem in meiner Liste haben. Vielleicht sollte ich es umformulieren: ich will alle sichtbaren Fenster, aber z.B. bei Delphi nur "Delphi" und nicht die einzelnen Unterfenster

thx

Xion