Get windows windows windows using a pen or pid

I have a handle and pid of the main process / window.
I want the children of the process / window to be only visual windows with a title.

To achieve what I want, I used the following:

[DllImport("user32.dll")] private static extern int EnumWindows(EnumWindowsProc ewp, int lParam);
[DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")] private static extern bool IsWindowVisible(int hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetWindowText(int hWnd, StringBuilder title, int size);


public delegate bool EnumWindowsProc(int hWnd, int lParam); //Delegate used for EnumWindows() callback function.


public void GetChildren()
{
    //Declare a callback delegate for EnumWindows() API call.
    EnumWindowsProc ewp = new EnumWindowsProc(EvalWindow);
    //Enumerate all Windows.
    EnumWindows(ewp, 0);
}

//EnumWindows CALLBACK function
private bool EvalWindow(int hWnd, int lParam)
{
    //Get the ThreadProcessId of the Window.
    IntPtr handle = (IntPtr)hWnd;
    uint currentThreadPid;
    GetWindowThreadProcessId(handle, out currentThreadPid);

    //Check if the Window is children of the current Window (if it is, it will have the same pid).
    if (currentThreadPid != _threadPid)
        return true;

    //Check if Window is Visible or not.
    if (!IsWindowVisible(hWnd))
        return true;

    //Get the Window Title.
    StringBuilder title = new StringBuilder(256);
    GetWindowText(hWnd, title, 256);

    //Check if Window has Title.
    if (title.Length == 0)
        return true;

    //Add new Window to the _childrenhWnd.
    _childrenhWnd.Add(handle);

    return true;
}

where _threadPidis the pid of the parent.

It works great, but I feel that there is a better way to do this, rather than looking at all open windows and filtering them.

I'm right? how can i make it better?

I saw something about EnumChildWindows, but I could achieve the same.

EDIT:

RaymondChen, , , "":
 1. - - .
 2. Paint.NET (f5, f6, f7, f8),   - .
, ( ), .

2:

:

[DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
[DllImport("user32.dll")] private static extern bool IsWindowVisible(int hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetWindowText(int hWnd, StringBuilder title, int size);


delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);


public void GetChildren()
{
   foreach (ProcessThread processThread in _process.Threads)
   {
       EnumThreadWindows(processThread.Id,
        (hWnd, lParam) => 
        {
            //Check if Window is Visible or not.
            if (!IsWindowVisible((int)hWnd))
                return true;

            //Get the Window Title.
            StringBuilder title = new StringBuilder(256);
            GetWindowText((int)hWnd, title, 256);

            //Check if Window has Title.
            if (title.Length == 0)
                return true;

            _childrenhWnd.Add(hWnd);

            return true;
        }, IntPtr.Zero);
   }
}

GetWindowLongPtr, , , .

+4
1

, , EnumWindows() . , , , , . , Paint.NET. winapi .

. , Process.Threads. EnumThreadWindows(). GetWindowLongPtr() GWLP_HWNDPARENT , , .

+3

Source: https://habr.com/ru/post/1530025/


All Articles