• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dapplo / Dapplo.Windows / 22326814353

23 Feb 2026 10:05PM UTC coverage: 32.819% (-0.03%) from 32.847%
22326814353

push

github

Lakritzator
Improving the message result passing

617 of 2002 branches covered (30.82%)

Branch coverage included in aggregate %.

1 of 2 new or added lines in 2 files covered. (50.0%)

3 existing lines in 2 files now uncovered.

1702 of 5064 relevant lines covered (33.61%)

30.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.55
/src/Dapplo.Windows/Desktop/InteropWindowQuery.cs
1
// Copyright (c) Dapplo and contributors. All rights reserved.
2
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
using System;
4
using System.Collections.Concurrent;
5
using System.Collections.Generic;
6
using System.Diagnostics;
7
using System.Linq;
8
using Dapplo.Windows.App;
9
using Dapplo.Windows.User32;
10
using Dapplo.Windows.User32.Enums;
11

12
namespace Dapplo.Windows.Desktop;
13

14
/// <summary>
15
///     Query for native windows
16
/// </summary>
17
public static class InteropWindowQuery
18
{
19
    /// <summary>
20
    ///     Window classes which can be ignored
21
    /// </summary>
22
    public static ConcurrentBag<string> IgnoreClasses { get; } = new ConcurrentBag<string>(new[] {"Progman", "Button", "Dwm"}); //"MS-SDIa"
80✔
23

24
    /// <summary>
25
    ///     Get the window with which the user is currently working
26
    /// </summary>
27
    /// <returns>IInteropWindow</returns>
28
    public static IInteropWindow GetForegroundWindow()
29
    {
30
        return InteropWindowFactory.CreateFor(User32Api.GetForegroundWindow());
×
31
    }
32

33
    /// <summary>
34
    ///     Gets the Desktop window
35
    /// </summary>
36
    /// <returns>IInteropWindow for the desktop window</returns>
37
    public static IInteropWindow GetDesktopWindow()
38
    {
39
        return InteropWindowFactory.CreateFor(User32Api.GetDesktopWindow());
2✔
40
    }
41

42
    /// <summary>
43
    ///     Find windows belonging to the same process (thread) as the process ID.
44
    /// </summary>
45
    /// <param name="processId">int with process Id</param>
46
    /// <returns>IEnumerable with IInteropWindow</returns>
47
    public static IEnumerable<IInteropWindow> GetWindowsForProcess(int processId)
48
    {
49
        using (var process = Process.GetProcessById(processId))
×
50
        {
51
            foreach (ProcessThread thread in process.Threads)
×
52
            {
53
                var handles = User32Api.EnumThreadWindows(thread.Id);
×
54
                thread.Dispose();
×
55
                foreach (var handle in handles)
×
56
                {
57
                    yield return InteropWindowFactory.CreateFor(handle);
×
58
                }
59
            }
60
        }
×
61
    }
×
62

63
    /// <summary>
64
    ///     Iterate the Top level windows, from top to bottom
65
    /// </summary>
66
    /// <param name="ignoreKnownClasses">true to ignore windows with certain known classes</param>
67
    /// <returns>IEnumerable with all the top level windows</returns>
68
    public static IEnumerable<IInteropWindow> GetTopLevelWindows(bool ignoreKnownClasses = true)
69
    {
70
        return GetTopWindows().Where(possibleTopLevel => possibleTopLevel.IsTopLevel(ignoreKnownClasses));
81✔
71
    }
72

73
    /// <summary>
74
    ///     Iterate the windows, from top to bottom
75
    /// </summary>
76
    /// <param name="parent">InteropWindow as the parent, to iterate over the children, or null for all</param>
77
    /// <returns>IEnumerable with all the top level windows</returns>
78
    public static IEnumerable<IInteropWindow> GetTopWindows(IInteropWindow parent = null)
79
    {
80
        // TODO: Guard against looping
81
        var windowPtr = parent == null ? User32Api.GetTopWindow(IntPtr.Zero) : User32Api.GetWindow(parent.Handle, GetWindowCommands.GW_CHILD);
3!
82
        do
83
        {
84
            yield return InteropWindowFactory.CreateFor(windowPtr);
88✔
85
            windowPtr = User32Api.GetWindow(windowPtr, GetWindowCommands.GW_HWNDNEXT);
86✔
86
        } while (windowPtr != IntPtr.Zero);
86✔
87
    }
1✔
88

89
    /// <summary>
90
    /// Check the Classname of the IInteropWindow against a list of know classes which can be ignored.
91
    /// </summary>
92
    /// <param name="interopWindow">IInteropWindow</param>
93
    /// <returns>bool</returns>
94
    public static bool CanIgnoreClass(this IInteropWindow interopWindow)
95
    {
96
        return IgnoreClasses.Contains(interopWindow.GetClassname());
79✔
97
    }
98

99
    /// <summary>
100
    /// Is the specified window a visible popup
101
    /// </summary>
102
    /// <param name="interopWindow">IInteropWindow</param>
103
    /// <param name="ignoreKnowClasses">true (default) to ignore some known internal windows classes</param>
104
    /// <returns>true if the IInteropWindow is a popup</returns>
105
    public static bool IsPopup(this IInteropWindow interopWindow, bool ignoreKnowClasses = true)
106
    {
107
        if (ignoreKnowClasses && interopWindow.CanIgnoreClass())
×
108
        {
109
            return false;
×
110
        }
111

112
        // Windows without size
113
        if (interopWindow.GetInfo().Bounds.IsEmpty)
×
114
        {
115
            return false;
×
116
        }
117

118
        // Windows without parent
119
        if (interopWindow.GetParent() != IntPtr.Zero)
×
120
        {
121
            return false;
×
122
        }
123

124
        // Get the info for the style & extended style
125
        var windowInfo = interopWindow.GetInfo();
×
126
        var windowStyle = windowInfo.Style;
×
127
        if ((windowStyle & WindowStyleFlags.WS_POPUP) == 0)
×
128
        {
129
            return false;
×
130
        }
131
        var exWindowStyle = windowInfo.ExtendedStyle;
×
132
        // Skip everything which is not rendered "normally"
133
        if (!interopWindow.IsWin8App() && (exWindowStyle & ExtendedWindowStyleFlags.WS_EX_NOREDIRECTIONBITMAP) != 0)
×
134
        {
135
            return false;
×
136
        }
137
        // A Windows 10 App which runs in the background, has a HWnd but is not visible.
138
        if (interopWindow.IsBackgroundWin10App())
×
139
        {
140
            return false;
×
141
        }
142
        // Skip preview windows, like the one from Firefox
143
        if ((windowStyle & WindowStyleFlags.WS_VISIBLE) == 0)
×
144
        {
145
            return false;
×
146
        }
147
        return !interopWindow.IsMinimized();
×
148
    }
149

150
    /// <summary>
151
    ///     Check if the window is a top level window.
152
    ///     This method will retrieve all information, and fill it to the interopWindow, it needs to make the decision.
153
    /// </summary>
154
    /// <param name="interopWindow">InteropWindow</param>
155
    /// <param name="ignoreKnowClasses">true (default) to ignore classes from the IgnoreClasses list</param>
156
    /// <returns>bool</returns>
157
    public static bool IsTopLevel(this IInteropWindow interopWindow, bool ignoreKnowClasses = true)
158
    {
159
        if (ignoreKnowClasses && interopWindow.CanIgnoreClass())
79✔
160
        {
161
            return false;
2✔
162
        }
163

164
        var info = interopWindow.GetInfo();
77✔
165
        // Windows without size
166
        if (info.Bounds.IsEmpty)
77✔
167
        {
168
            return false;
51✔
169
        }
170

171
        // Ignore windows with a parent
172
        if (interopWindow.GetParent() != IntPtr.Zero)
26!
173
        {
UNCOV
174
            return false;
×
175
        }
176

177
        var exWindowStyle = info.ExtendedStyle;
26✔
178
        if ((exWindowStyle & ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW) != 0)
26✔
179
        {
180
            return false;
5✔
181
        }
182

183
        // Skip everything which is not rendered "normally"
184
        if (!interopWindow.IsWin8App() && (exWindowStyle & ExtendedWindowStyleFlags.WS_EX_NOREDIRECTIONBITMAP) != 0)
21✔
185
        {
186
            return false;
1✔
187
        }
188

189
        // A Windows 10 App which runs in the background, has a HWnd but is not visible.
190
        if (interopWindow.IsBackgroundWin10App())
20!
191
        {
192
            return false;
×
193
        }
194

195
        // Skip preview windows, windows without WS_VISIBLE, like the one from Firefox
196
        if ((info.Style & WindowStyleFlags.WS_VISIBLE) == 0)
20✔
197
        {
198
            return false;
19✔
199
        }
200

201
        // Ignore windows without title
202
        if (interopWindow.GetCaption().Length == 0)
1!
203
        {
204
            return false;
×
205
        }
206
        return !interopWindow.IsMinimized();
1✔
207
    }
208
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc