Click here to Skip to main content
15,441,629 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello!
I see 4 windows on the monitor (for example), but EnumWindows gives me more than a dozen - some incomprehensible windows that are not on the screen at all. They names are something like "Microsoft Text Input Application, Microsoft Store, etc"
IsVisible returns true, IsIconic returns false, GetWindowsRect return some rect with non-zero width and heights. So, how I can filter them ?? For now all what I can do - to get image with PrintWindow and to see it is totally black, but this way looks like a gag not solution :)

My task is simple - to get screenshot for all windows on the screen one by one, but it is not very good for me to get additional 10 black rectangles.


To be more informative: OS - Windows10

What I have tried:

class OpenWindowsGetter
{
    [DllImport("USER32.DLL")]
    static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
    [DllImport("USER32.DLL")]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    [DllImport("USER32.DLL")]
    static extern int GetWindowTextLength(IntPtr hWnd);
    [DllImport("USER32.DLL")]
    static extern bool IsWindowVisible(IntPtr hWnd);
    [DllImport("USER32.DLL")]
    static extern IntPtr GetShellWindow();
    [DllImport("User32.dll")]
    static extern bool IsIconic(IntPtr hwnd);

    delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
        /// <summary>Returns a dictionary that contains the handle and title of all opened windows.</summary>
        /// <returns>A dictionary that contains the handle and title of all opened windows.</returns>
        public static IDictionary<IntPtr, string> GetOpenWindows()
        {
            IntPtr lShellWindow = GetShellWindow();
            Dictionary<IntPtr, string> lWindows = new Dictionary<IntPtr, string>();

            EnumWindows(delegate (IntPtr hWnd, int lParam)
            {
                if (hWnd == lShellWindow) return true;
                if (!IsWindowVisible(hWnd)) return true;
                if (IsIconic(hWnd)) return true;

                int lLength = GetWindowTextLength(hWnd);
                if (lLength == 0) return true;

                StringBuilder lBuilder = new StringBuilder(lLength);
                GetWindowText(hWnd, lBuilder, lLength + 1);

                lWindows[hWnd] = lBuilder.ToString();
                return true;

            }, 0);

            return lWindows;
        }
}


And to see a result with combobox WindsCB:

private void button1_Click(object sender, EventArgs e)
{
    WindsCB.Items.Clear();
    IDictionary<IntPtr, string> winds = OpenWindowsGetter.GetOpenWindows();
    foreach (var item in winds) WindsCB.Items.Add(item);
}
Posted
Updated 23-May-21 23:07pm
v3
Comments
BillWoodruff 25-May-21 10:57am    
for the "black rectangles" you describe: is there any common feature you can isolate (size ?) that would let you exclude them ?
Михаил Солодков 25-May-21 15:31pm     CRLF
Size is not common for this rectangles :\ For now I get an image and check if it is totally black ( 0-0-0 in RGB ). Well, and if GetWindowText returns "Microsoft Text Input Application" - I pass it without checking :)) But all this looks like workaround not solution.
BillWoodruff 26-May-21 2:21am    
Wish I could be more helpful !

1 solution

 
Share this answer
 
Comments
Михаил Солодков 24-May-21 5:11am     CRLF
I tried it, but the result is exactly the same. I used EnumDesktopWindows(0, delegate (IntPtr hWnd, int lParam) {..}, 0). May be I miss something? May be not zero as desktop handle, but what else? THanks!
Richard MacCutchan 24-May-21 5:27am     CRLF
I do not think there is much you can do. The system itself uses its own Windows for various purposes so you will always get them returned. You can only work on the information provided from the Window's handle. And the remarks section for the IsWindowVisible function (winuser.h) - Win32 apps | Microsoft Docs[^] function states:
The visibility state of a window is indicated by the WS_VISIBLE style bit. When WS_VISIBLE is set, the window is displayed and subsequent drawing into it is displayed as long as the window has the WS_VISIBLE style.Any drawing to a window with the WS_VISIBLE style will not be displayed if the window is obscured by other windows or is clipped by its parent window.
Михаил Солодков 24-May-21 6:12am     CRLF
About your remarks - do not know why, but with winapi's PrintWindow I get an image from obscured windows w\o problems. public static Bitmap WindImage(IntPtr hwnd) { GetWindowRect(hwnd, out RECT rect); Bitmap image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top); using (var graphics = Graphics.FromImage(image)) { var hdcBitmap = graphics.GetHdc(); PrintWindow(hwnd, hdcBitmap, 0); graphics.ReleaseHdc(hdcBitmap); } return image; } So my problem not in "I can not get what I want", but "I get too much!!!" LOL :))) thanks for your answers anyway!
BillWoodruff 26-May-21 2:20am    
+5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900