/// <summary> /// Query the windows /// </summary> /// <param name="callback">A callback that's called when a new window is found. This way the functionality is the same as before</param> /// <param name="windowPtrSet">A set of current window ptrs</param> public void QueryProcessesWithWindows(Action <ProcessDetails> callback, HashSet <long> windowPtrSet) { var ptrList = new List <IntPtr>(); Native.EnumWindows_CallBackProc del = (hwnd, lParam) => GetMainWindowForProcess_EnumWindows(ptrList, hwnd, lParam); Native.EnumWindows(del, 0); Native.EnumWindows(del, 1); foreach (var ptr in ptrList) { if (Native.GetWindowRect(ptr, out Native.Rect rect)) { if (((Rectangle)rect).IsEmpty) { continue; } //check if we already have this window in the list so we can avoid calling //GetWindowThreadProcessId(its costly) if (windowPtrSet.Contains(ptr.ToInt64())) { continue; } uint processId; Native.GetWindowThreadProcessId(ptr, out processId); callback(new ProcessDetails(Process.GetProcessById((int)processId), ptr) { Manageable = true }); } } }