From 5fe5bf04e8c1f58e4d5f10f3e61db4bf5bacb7f7 Mon Sep 17 00:00:00 2001 From: Shaojun Li Date: Tue, 3 May 2022 20:32:22 +0800 Subject: [PATCH] Add filters. --- WindowDebugger/ViewModels/ViewModel.cs | 140 +++++++++++++++----- WindowDebugger/Views/Pages/WindowsPage.xaml | 6 +- WindowDebugger/WindowDebugger.csproj | 4 + 3 files changed, 115 insertions(+), 35 deletions(-) diff --git a/WindowDebugger/ViewModels/ViewModel.cs b/WindowDebugger/ViewModels/ViewModel.cs index 7d20f89..e92a0a2 100644 --- a/WindowDebugger/ViewModels/ViewModel.cs +++ b/WindowDebugger/ViewModels/ViewModel.cs @@ -1,6 +1,8 @@ using Lsj.Util.Text; using Lsj.Util.Win32; +using Lsj.Util.Win32.BaseTypes; using Lsj.Util.Win32.Extensions; +using Lsj.Util.Win32.NativeUI; using Lsj.Util.WPF; using System; using System.Collections.ObjectModel; @@ -24,55 +26,127 @@ public ObservableCollection Windows get; } = new ObservableCollection(); + private WindowItem _currentWindow; + public WindowItem SelectedWindow { get => _currentWindow; set => SetField(ref _currentWindow, value, extraAction: () => { value?.RefreshItem(); value?.RefreshScreenShot(); }); } + + private bool _dwmIsCompositionEnabled; + + public bool DwmIsCompositionEnabled { get => _dwmIsCompositionEnabled; } + + private bool _includeNonVisibleWindows = false; + + public bool IncludeNonVisibleWindows { get => _includeNonVisibleWindows; set => SetField(ref _includeNonVisibleWindows, value, extraAction: RefreshWindowList); } + + private bool _includeNonTitledWindows = false; + + public bool IncludeNonTitledWindows { get => _includeNonTitledWindows; set => SetField(ref _includeNonTitledWindows, value, extraAction: RefreshWindowList); } + + private bool _includeChildWindows = false; + + public bool IncludeChildWindows { get => _includeChildWindows; set => SetField(ref _includeChildWindows, value, extraAction: RefreshWindowList); } + + private bool _includeMessageOnlyWindows = false; + + public bool IncludeMessageOnlyWindows { get => _includeMessageOnlyWindows; set => SetField(ref _includeMessageOnlyWindows, value, extraAction: RefreshWindowList); } + + private uint? _searchStringHexUintValue; + private uint? _searchStringUintValue; + public void RefreshWindowList() { Dwmapi.DwmIsCompositionEnabled(out var isEnabled); SetField(ref _dwmIsCompositionEnabled, isEnabled, propertyName: nameof(DwmIsCompositionEnabled)); - var windows = WindowExtensions.GetAllWindowHandle(); + if (!_searchText.IsNullOrEmpty()) + { + _searchStringHexUintValue = + uint.TryParse(_searchText, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out var uintHexVal) || + (_searchText.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase) && uint.TryParse(_searchText, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uintHexVal)) + ? uintHexVal + : null; + + _searchStringUintValue = uint.TryParse(_searchText, out var uintVal) ? uintVal : null; + } + else + { + _searchStringHexUintValue = null; + _searchStringUintValue = null; + } + + var windows = WindowExtensions.GetAllWindow(x => new WindowItem(x), WindowFilter, DescendantsFilter); Windows.Clear(); - foreach (var handle in windows) + foreach (var win in windows) + { + Windows.Add(win); + } + } + + private (bool includeSelf, bool includeDescendants, bool continueEnum) WindowFilter(HWND handle) + { + return (DescendantsFilter(handle).includeSelf, IncludeChildWindows, true); + } + + private (bool includeSelf, bool continueEnum) DescendantsFilter(HWND handle) + { + var win = new Win32Window(handle); + + if (!IncludeMessageOnlyWindows) { - var item = new WindowItem(handle); - if (!_searchText.IsNullOrEmpty()) + if (win.ParentWindowHandle == User32.HWND_MESSAGE) { - if ((item.Text?.IndexOf(_searchText, StringComparison.CurrentCultureIgnoreCase) > -1) - || (item.ProcessName?.IndexOf(_searchText, StringComparison.CurrentCultureIgnoreCase) > -1)) - { - Windows.Add(item); - } + return (false, true); + } + } - if (uint.TryParse(_searchText, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out var uintHexVal) || - (_searchText.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase) && uint.TryParse(_searchText, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uintHexVal))) - { - if (item.WindowHandle.SafeToUInt32() == uintHexVal || item.ProcessID == uintHexVal || item.ThreadID == uintHexVal - || item.OwnerWindowHandle.SafeToUInt32() == uintHexVal || item.ParentWindowHandle.SafeToUInt32() == uintHexVal) - { - Windows.Add(item); - } - } + if (!IncludeNonVisibleWindows) + { + if (!win.IsVisible) + { + return (false, true); + } + } + + var text = win.Text; + if (!IncludeNonTitledWindows) + { + if (text.IsNullOrEmpty()) + { + return (false, true); + } + } + + if (!_searchText.IsNullOrEmpty()) + { + if ((text.IndexOf(_searchText, StringComparison.CurrentCultureIgnoreCase) > -1) + || (win.ProcessName.IndexOf(_searchText, StringComparison.CurrentCultureIgnoreCase) > -1)) + { + return (true, true); + } - if (uint.TryParse(_searchText, out var uintVal)) + if (_searchStringHexUintValue is uint uintHexVal) + { + if (((IntPtr)handle).SafeToUInt32() == uintHexVal || win.ProcessID == uintHexVal || win.ThreadID == uintHexVal + || ((IntPtr)win.OwnerWindowHandle).SafeToUInt32() == uintHexVal || ((IntPtr)win.ParentWindowHandle).SafeToUInt32() == uintHexVal) { - if (item.WindowHandle.SafeToUInt32() == uintVal || item.ProcessID == uintVal || item.ThreadID == uintVal - || item.OwnerWindowHandle.SafeToUInt32() == uintVal || item.ParentWindowHandle.SafeToUInt32() == uintVal) - { - Windows.Add(item); - } + return (true, true); } } - else + + if (_searchStringUintValue is uint uintVal) { - Windows.Add(item); + if (((IntPtr)handle).SafeToUInt32() == uintVal || win.ProcessID == uintVal || win.ThreadID == uintVal + || ((IntPtr)win.OwnerWindowHandle).SafeToUInt32() == uintVal || ((IntPtr)win.ParentWindowHandle).SafeToUInt32() == uintVal) + { + return (true, true); + } } + + return (false, true); + } + else + { + return (true, true); } } - - private WindowItem _currentWindow; - public WindowItem SelectedWindow { get => _currentWindow; set => SetField(ref _currentWindow, value, extraAction: () => { value?.RefreshItem(); value?.RefreshScreenShot(); }); } - - private bool _dwmIsCompositionEnabled; - - public bool DwmIsCompositionEnabled { get => _dwmIsCompositionEnabled; } } } diff --git a/WindowDebugger/Views/Pages/WindowsPage.xaml b/WindowDebugger/Views/Pages/WindowsPage.xaml index f1f6445..c98de30 100644 --- a/WindowDebugger/Views/Pages/WindowsPage.xaml +++ b/WindowDebugger/Views/Pages/WindowsPage.xaml @@ -72,8 +72,10 @@ - - + + + + diff --git a/WindowDebugger/WindowDebugger.csproj b/WindowDebugger/WindowDebugger.csproj index 2eaae09..dd9d39d 100644 --- a/WindowDebugger/WindowDebugger.csproj +++ b/WindowDebugger/WindowDebugger.csproj @@ -11,6 +11,10 @@ true + + + +