Skip to content

Commit

Permalink
Add filters.
Browse files Browse the repository at this point in the history
  • Loading branch information
kkwpsv committed May 3, 2022
1 parent 13ddd01 commit 5fe5bf0
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 35 deletions.
140 changes: 107 additions & 33 deletions WindowDebugger/ViewModels/ViewModel.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -24,55 +26,127 @@ public ObservableCollection<WindowItem> Windows
get;
} = new ObservableCollection<WindowItem>();

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; }
}
}
6 changes: 4 additions & 2 deletions WindowDebugger/Views/Pages/WindowsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@
</Style>
</StackPanel.Resources>
<TextBlock Text="Filter Options:" />
<CheckBox Content="Visible windows only" />
<CheckBox Content="Titled windows only" />
<CheckBox Content="Include non-visible windows" IsChecked="{Binding IncludeNonVisibleWindows}"/>
<CheckBox Content="Include non-titled windows" IsChecked="{Binding IncludeNonTitledWindows}"/>
<CheckBox Content="Include child windows" IsChecked="{Binding IncludeChildWindows}"/>
<CheckBox Content="Include message-only windows" IsChecked="{Binding IncludeMessageOnlyWindows}"/>
</StackPanel>
</Expander>

Expand Down
4 changes: 4 additions & 0 deletions WindowDebugger/WindowDebugger.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<SupportedPlatform Include="Windows" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Lsj.Util.JSON" Version="6.0.0" />
<PackageReference Include="Lsj.Util.Win32" Version="6.2.1" />
Expand Down

0 comments on commit 5fe5bf0

Please sign in to comment.