• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 332
  • Last Modified:

List taskbar child windows

Hi Experts,

I want to list all the processes that show a windows form in taskbar.

Here is my last coding:

public static List<CustomProcess> GetTaskbarWindowsList()
        {
            List<CustomProcess> list = new List<CustomProcess>();
            foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
            {
                if (!p.MainWindowHandle.Equals(IntPtr.Zero))
                {
                    if (p.MainWindowTitle != string.Empty)
                        list.Add(new CustomProcess(p.Handle, p.MainWindowTitle,p.MainModule.FileName));
                }
            }
            return list;
        }

It returns the main window of a process, but if an app has several sub windows I can't get them: I only get the main window (for example, I only get main  window of Outlook Express (1  result) ,but in taskbar I can see 2 other windows : inbox window, newMessage window).
How can I get those child windows ?
I try EnumChildWindows, but I get all objects in the form, not only the child window handle.

Thanks in advance for your help.
0
noulouk
Asked:
noulouk
  • 2
1 Solution
 
K VDatabase ConsultantCommented:
hi, i don't have enough resources to try this things.
i have a delphi code which can give u the idea as what it has used is APIs only.
so better you check for the code, and understand the usage of APIs.
0
 
K VDatabase ConsultantCommented:
hi, i don't have enough resources to try this things.
i have a delphi code which can give u the idea as what it has used is APIs only.
so better you check for the code, and understand the usage of APIs.
here is the answer from a gr8 X-pert, Ferruccio68....:

enumerating childwindows means this...
you start from the topmost parent and look for all children...
'a' is the parent, 'b' the child of 'a' and c is a child of 'b', but also a child of 'a'...
so you must add a check to prevent this double adding....

look how your code is modified...(it's all the unit, no addition to the form)...

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    TreeView1: TTreeView;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  sl: TStrings;  //object for the double hwnd check
implementation

{$R *.dfm}
type
  EnumClass = class
  public
    Treeview: TTreeview;
    ParentNode: TTreeNode;
  end;

function MainEnumProc(Hwnd, lParam: Longint): Boolean; stdcall;
var
  EC: EnumClass;
  ECChild: EnumClass;
  NewNode: TTreeNode;
  Buffer: PChar;
  RtnLen: Longint;
  NodeCaption, Caption, ClassName: string;
begin
  {Get the EnumClass Passed in}
 
  EC := ENumClass(lParam);
  {Allocate a buffer length}
  {Allocate a string buffer (PChar)}
  Buffer := StrAlloc(501);
  try
    {First get the caption/Text of the window were currently looking at}
    RtnLen := GetWindowText(Hwnd, Buffer, 500);
    Caption := Copy(Buffer, 1, RtnLen);
    {Now get the class name of the window were currently looking at}
    RtnLen := GetClassName(Hwnd, Buffer, 500);
    ClassName := Copy(Buffer, 1, RtnLen);
    {Set the caption of the new node}
    NodeCaption := Format('HWND: %d | ClassName: "%s" | Caption: "%s"', [HWND, ClassName, Caption]);
    {Creat the new node}
   
    if (SL.IndexOfObject(TObject(HWnd)) < 0) then begin // Test for duplicate handles
    SL.AddObject('found', TObject(HWnd));
    NewNode := EC.Treeview.Items.AddChild(EC.ParentNode, NodeCaption);
    {The following is for looking at children of this window
    this basically makes the function recursive}
    ECChild := EnumClass.Create;
    try
      ECChild.Treeview := EC.Treeview;
      ECChild.ParentNode := NewNode;
      {Call this function again :) }
      EnumChildWindows(Hwnd, @MainEnumProc, Longint(ECChild));
    finally
      ECChild.Free;
    end;
    end;
  finally
    {Free the buffer we created at the beginning of
    the procedure}
    StrDispose(Buffer);
  end;
  {Return True this will tell windows to
  carry on passing us the information}
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  EC: EnumClass;
  TN: TTreeNode;
  wnd: HWND;
begin
  sl := TStringlist.Create;
  { Get Window under cursor }Sleep(3000);
  wnd := WindowFromPoint(Mouse.CursorPos);

  {Stop the flockering}
  LockWindowUpdate(TreeView1.Handle);
  try
    {Clear all the items out of the treeview}
    TreeView1.Items.Clear;
    {Create a node which will be the parent}
    TN := TreeView1.Items.Add(nil, 'Window List');
    {Create our own EnumClass.  This will be used as the
    lParam of the EnumWindows Function and will contain
    a TreeView and Parent Node}
    EC := EnumClass.Create;
    try
      EC.Treeview := TreeView1;
      EC.ParentNode := TN;
      {Call the API with the ENumclass}
      if EnumChildWindows(wnd, @MainEnumProc, Longint(EC)) then
        TN.Expand(False);
    finally
      {Ensure we free the object when were done with it}
      EC.Free;
    end;
  finally
    LockWindowUpdate(0);
    sl.Free;
  end;
end;


end.

I get this from :
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_20845865.html?sfQueryTermInfo=1+childwindow+list+window
0
 
nouloukAuthor Commented:
Delphi is chineese for me, but I try to find how the code filters only windows and I can't get it.
Sorry.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now