whitespace forced changes (#6002)

This commit is contained in:
Clint Rutkas
2020-08-17 10:00:56 -07:00
committed by GitHub
parent 649e7e103d
commit d055ba1c3b
129 changed files with 14175 additions and 14175 deletions

View File

@@ -1,124 +1,124 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Class housing fuzzy matching methods
/// </summary>
public class FuzzyMatching
{
/// <summary>
/// Finds the best match (the one with the most
/// number of letters adjacent to each other) and
/// returns the index location of each of the letters
/// of the matches
/// </summary>
/// <param name="text">The text to search inside of</param>
/// <param name="searchText">the text to search for</param>
/// <returns>returns the index location of each of the letters of the matches</returns>
public static List<int> FindBestFuzzyMatch(string text, string searchText)
{
searchText = searchText.ToLower();
text = text.ToLower();
// Create a grid to march matches like
// eg.
// a b c a d e c f g
// a x x
// c x x
bool[,] matches = new bool[text.Length, searchText.Length];
for (int firstIndex = 0; firstIndex < text.Length; firstIndex++)
{
for (int secondIndex = 0; secondIndex < searchText.Length; secondIndex++)
{
matches[firstIndex, secondIndex] =
searchText[secondIndex] == text[firstIndex] ?
true :
false;
}
}
// use this table to get all the possible matches
List<List<int>> allMatches = GetAllMatchIndexes(matches);
// return the score that is the max
int maxScore = allMatches.Count > 0 ? CalculateScoreForMatches(allMatches[0]) : 0;
List<int> bestMatch = allMatches.Count > 0 ? allMatches[0] : new List<int>();
foreach (var match in allMatches)
{
int score = CalculateScoreForMatches(match);
if (score > maxScore)
{
bestMatch = match;
maxScore = score;
}
}
return bestMatch;
}
/// <summary>
/// Gets all the possible matches to the search string with in the text
/// </summary>
/// <param name="matches"> a table showing the matches as generated by
/// a two dimensional array with the first dimension the text and the second
/// one the search string and each cell marked as an intersection between the two</param>
/// <returns>a list of the possible combinations that match the search text</returns>
public static List<List<int>> GetAllMatchIndexes(bool[,] matches)
{
List<List<int>> results = new List<List<int>>();
for (int secondIndex = 0; secondIndex < matches.GetLength(1); secondIndex++)
{
for (int firstIndex = 0; firstIndex < matches.GetLength(0); firstIndex++)
{
if (secondIndex == 0 && matches[firstIndex, secondIndex])
{
results.Add(new List<int> { firstIndex });
}
else if (matches[firstIndex, secondIndex])
{
var tempList = results.Where(x => x.Count == secondIndex && x[x.Count - 1] < firstIndex).Select(x => x.ToList()).ToList();
foreach (var pathSofar in tempList)
{
pathSofar.Add(firstIndex);
}
results.AddRange(tempList);
}
}
results = results.Where(x => x.Count == secondIndex + 1).ToList();
}
return results.Where(x => x.Count == matches.GetLength(1)).ToList();
}
/// <summary>
/// Calculates the score for a string
/// </summary>
/// <param name="matches">the index of the matches</param>
/// <returns>an integer representing the score</returns>
public static int CalculateScoreForMatches(List<int> matches)
{
var score = 0;
for (int currentIndex = 1; currentIndex < matches.Count; currentIndex++)
{
var previousIndex = currentIndex - 1;
score -= matches[currentIndex] - matches[previousIndex];
}
return score == 0 ? -10000 : score;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Class housing fuzzy matching methods
/// </summary>
public class FuzzyMatching
{
/// <summary>
/// Finds the best match (the one with the most
/// number of letters adjacent to each other) and
/// returns the index location of each of the letters
/// of the matches
/// </summary>
/// <param name="text">The text to search inside of</param>
/// <param name="searchText">the text to search for</param>
/// <returns>returns the index location of each of the letters of the matches</returns>
public static List<int> FindBestFuzzyMatch(string text, string searchText)
{
searchText = searchText.ToLower();
text = text.ToLower();
// Create a grid to march matches like
// eg.
// a b c a d e c f g
// a x x
// c x x
bool[,] matches = new bool[text.Length, searchText.Length];
for (int firstIndex = 0; firstIndex < text.Length; firstIndex++)
{
for (int secondIndex = 0; secondIndex < searchText.Length; secondIndex++)
{
matches[firstIndex, secondIndex] =
searchText[secondIndex] == text[firstIndex] ?
true :
false;
}
}
// use this table to get all the possible matches
List<List<int>> allMatches = GetAllMatchIndexes(matches);
// return the score that is the max
int maxScore = allMatches.Count > 0 ? CalculateScoreForMatches(allMatches[0]) : 0;
List<int> bestMatch = allMatches.Count > 0 ? allMatches[0] : new List<int>();
foreach (var match in allMatches)
{
int score = CalculateScoreForMatches(match);
if (score > maxScore)
{
bestMatch = match;
maxScore = score;
}
}
return bestMatch;
}
/// <summary>
/// Gets all the possible matches to the search string with in the text
/// </summary>
/// <param name="matches"> a table showing the matches as generated by
/// a two dimensional array with the first dimension the text and the second
/// one the search string and each cell marked as an intersection between the two</param>
/// <returns>a list of the possible combinations that match the search text</returns>
public static List<List<int>> GetAllMatchIndexes(bool[,] matches)
{
List<List<int>> results = new List<List<int>>();
for (int secondIndex = 0; secondIndex < matches.GetLength(1); secondIndex++)
{
for (int firstIndex = 0; firstIndex < matches.GetLength(0); firstIndex++)
{
if (secondIndex == 0 && matches[firstIndex, secondIndex])
{
results.Add(new List<int> { firstIndex });
}
else if (matches[firstIndex, secondIndex])
{
var tempList = results.Where(x => x.Count == secondIndex && x[x.Count - 1] < firstIndex).Select(x => x.ToList()).ToList();
foreach (var pathSofar in tempList)
{
pathSofar.Add(firstIndex);
}
results.AddRange(tempList);
}
}
results = results.Where(x => x.Count == secondIndex + 1).ToList();
}
return results.Where(x => x.Count == matches.GetLength(1)).ToList();
}
/// <summary>
/// Calculates the score for a string
/// </summary>
/// <param name="matches">the index of the matches</param>
/// <returns>an integer representing the score</returns>
public static int CalculateScoreForMatches(List<int> matches)
{
var score = 0;
for (int currentIndex = 1; currentIndex < matches.Count; currentIndex++)
{
var previousIndex = currentIndex - 1;
score -= matches[currentIndex] - matches[previousIndex];
}
return score == 0 ? -10000 : score;
}
}
}

View File

@@ -1,58 +1,58 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Class containing methods to control the live preview
/// </summary>
internal class LivePreview
{
/// <summary>
/// Makes sure that a window is excluded from the live preview
/// </summary>
/// <param name="hwnd">handle to the window to exclude</param>
public static void SetWindowExclusionFromLivePreview(IntPtr hwnd)
{
int renderPolicy = (int)InteropAndHelpers.DwmNCRenderingPolicy.Enabled;
InteropAndHelpers.DwmSetWindowAttribute(
hwnd,
12,
ref renderPolicy,
sizeof(int));
}
/// <summary>
/// Activates the live preview
/// </summary>
/// <param name="targetWindow">the window to show by making all other windows transparent</param>
/// <param name="windowToSpare">the window which should not be transparent but is not the target window</param>
public static void ActivateLivePreview(IntPtr targetWindow, IntPtr windowToSpare)
{
InteropAndHelpers.DwmpActivateLivePreview(
true,
targetWindow,
windowToSpare,
InteropAndHelpers.LivePreviewTrigger.Superbar,
IntPtr.Zero);
}
/// <summary>
/// Deactivates the live preview
/// </summary>
public static void DeactivateLivePreview()
{
InteropAndHelpers.DwmpActivateLivePreview(
false,
IntPtr.Zero,
IntPtr.Zero,
InteropAndHelpers.LivePreviewTrigger.AltTab,
IntPtr.Zero);
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Class containing methods to control the live preview
/// </summary>
internal class LivePreview
{
/// <summary>
/// Makes sure that a window is excluded from the live preview
/// </summary>
/// <param name="hwnd">handle to the window to exclude</param>
public static void SetWindowExclusionFromLivePreview(IntPtr hwnd)
{
int renderPolicy = (int)InteropAndHelpers.DwmNCRenderingPolicy.Enabled;
InteropAndHelpers.DwmSetWindowAttribute(
hwnd,
12,
ref renderPolicy,
sizeof(int));
}
/// <summary>
/// Activates the live preview
/// </summary>
/// <param name="targetWindow">the window to show by making all other windows transparent</param>
/// <param name="windowToSpare">the window which should not be transparent but is not the target window</param>
public static void ActivateLivePreview(IntPtr targetWindow, IntPtr windowToSpare)
{
InteropAndHelpers.DwmpActivateLivePreview(
true,
targetWindow,
windowToSpare,
InteropAndHelpers.LivePreviewTrigger.Superbar,
IntPtr.Zero);
}
/// <summary>
/// Deactivates the live preview
/// </summary>
public static void DeactivateLivePreview()
{
InteropAndHelpers.DwmpActivateLivePreview(
false,
IntPtr.Zero,
IntPtr.Zero,
InteropAndHelpers.LivePreviewTrigger.AltTab,
IntPtr.Zero);
}
}
}

View File

@@ -1,106 +1,106 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Class that represents the state of the desktops windows
/// </summary>
internal class OpenWindows
{
/// <summary>
/// Delegate handler for open windows updates
/// </summary>
public delegate void OpenWindowsUpdateHandler(object sender, SearchController.SearchResultUpdateEventArgs e);
/// <summary>
/// Event raised when there is an update to the list of open windows
/// </summary>
public event OpenWindowsUpdateHandler OnOpenWindowsUpdate
{
add { }
remove { }
}
/// <summary>
/// List of all the open windows
/// </summary>
private readonly List<Window> windows = new List<Window>();
/// <summary>
/// An instance of the class OpenWindows
/// </summary>
private static OpenWindows instance;
/// <summary>
/// Gets the list of all open windows
/// </summary>
public List<Window> Windows
{
get { return new List<Window>(windows); }
}
/// <summary>
/// Gets an instance property of this class that makes sure that
/// the first instance gets created and that all the requests
/// end up at that one instance
/// </summary>
public static OpenWindows Instance
{
get
{
if (instance == null)
{
instance = new OpenWindows();
}
return instance;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="OpenWindows"/> class.
/// Private constructor to make sure there is never
/// more than one instance of this class
/// </summary>
private OpenWindows()
{
}
/// <summary>
/// Updates the list of open windows
/// </summary>
public void UpdateOpenWindowsList()
{
windows.Clear();
InteropAndHelpers.CallBackPtr callbackptr = new InteropAndHelpers.CallBackPtr(WindowEnumerationCallBack);
InteropAndHelpers.EnumWindows(callbackptr, 0);
}
/// <summary>
/// Call back method for window enumeration
/// </summary>
/// <param name="hwnd">The handle to the current window being enumerated</param>
/// <param name="lParam">Value being passed from the caller (we don't use this but might come in handy
/// in the future</param>
/// <returns>true to make sure to continue enumeration</returns>
public bool WindowEnumerationCallBack(IntPtr hwnd, IntPtr lParam)
{
Window newWindow = new Window(hwnd);
if (newWindow.IsWindow && newWindow.Visible && newWindow.IsOwner &&
(!newWindow.IsToolWindow || newWindow.IsAppWindow) && !newWindow.TaskListDeleted &&
newWindow.ClassName != "Windows.UI.Core.CoreWindow")
{
windows.Add(newWindow);
}
return true;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Class that represents the state of the desktops windows
/// </summary>
internal class OpenWindows
{
/// <summary>
/// Delegate handler for open windows updates
/// </summary>
public delegate void OpenWindowsUpdateHandler(object sender, SearchController.SearchResultUpdateEventArgs e);
/// <summary>
/// Event raised when there is an update to the list of open windows
/// </summary>
public event OpenWindowsUpdateHandler OnOpenWindowsUpdate
{
add { }
remove { }
}
/// <summary>
/// List of all the open windows
/// </summary>
private readonly List<Window> windows = new List<Window>();
/// <summary>
/// An instance of the class OpenWindows
/// </summary>
private static OpenWindows instance;
/// <summary>
/// Gets the list of all open windows
/// </summary>
public List<Window> Windows
{
get { return new List<Window>(windows); }
}
/// <summary>
/// Gets an instance property of this class that makes sure that
/// the first instance gets created and that all the requests
/// end up at that one instance
/// </summary>
public static OpenWindows Instance
{
get
{
if (instance == null)
{
instance = new OpenWindows();
}
return instance;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="OpenWindows"/> class.
/// Private constructor to make sure there is never
/// more than one instance of this class
/// </summary>
private OpenWindows()
{
}
/// <summary>
/// Updates the list of open windows
/// </summary>
public void UpdateOpenWindowsList()
{
windows.Clear();
InteropAndHelpers.CallBackPtr callbackptr = new InteropAndHelpers.CallBackPtr(WindowEnumerationCallBack);
InteropAndHelpers.EnumWindows(callbackptr, 0);
}
/// <summary>
/// Call back method for window enumeration
/// </summary>
/// <param name="hwnd">The handle to the current window being enumerated</param>
/// <param name="lParam">Value being passed from the caller (we don't use this but might come in handy
/// in the future</param>
/// <returns>true to make sure to continue enumeration</returns>
public bool WindowEnumerationCallBack(IntPtr hwnd, IntPtr lParam)
{
Window newWindow = new Window(hwnd);
if (newWindow.IsWindow && newWindow.Visible && newWindow.IsOwner &&
(!newWindow.IsToolWindow || newWindow.IsAppWindow) && !newWindow.TaskListDeleted &&
newWindow.ClassName != "Windows.UI.Core.CoreWindow")
{
windows.Add(newWindow);
}
return true;
}
}
}

View File

@@ -1,186 +1,186 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Responsible for searching and finding matches for the strings provided.
/// Essentially the UI independent model of the application
/// </summary>
internal class SearchController
{
/// <summary>
/// the current search text
/// </summary>
private string searchText;
/// <summary>
/// Open window search results
/// </summary
private List<SearchResult> searchMatches;
/// <summary>
/// Singleton pattern
/// </summary>
private static SearchController instance;
/// <summary>
/// Delegate handler for open windows updates
/// </summary>
public delegate void SearchResultUpdateHandler(object sender, SearchResultUpdateEventArgs e);
/// <summary>
/// Event raised when there is an update to the list of open windows
/// </summary>
public event SearchResultUpdateHandler OnSearchResultUpdate;
/// <summary>
/// Gets or sets the current search text
/// </summary>
public string SearchText
{
get
{
return searchText;
}
set
{
searchText = value.ToLower().Trim();
}
}
/// <summary>
/// Gets the open window search results
/// </summary>
public List<SearchResult> SearchMatches
{
get { return new List<SearchResult>(searchMatches).OrderByDescending(x => x.Score).ToList(); }
}
/// <summary>
/// Gets singleton Pattern
/// </summary>
public static SearchController Instance
{
get
{
if (instance == null)
{
instance = new SearchController();
}
return instance;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="SearchController"/> class.
/// Initializes the search controller object
/// </summary>
private SearchController()
{
searchText = string.Empty;
OpenWindows.Instance.OnOpenWindowsUpdate += OpenWindowsUpdateHandler;
}
/// <summary>
/// Event handler for when the search text has been updated
/// </summary>
public async Task UpdateSearchText(string searchText)
{
SearchText = searchText;
await SyncOpenWindowsWithModelAsync();
}
/// <summary>
/// Event handler called when the OpenWindows list changes
/// </summary>
/// <param name="sender">sending item</param>
/// <param name="e">event arg</param>
public async void OpenWindowsUpdateHandler(object sender, SearchResultUpdateEventArgs e)
{
await SyncOpenWindowsWithModelAsync();
}
/// <summary>
/// Syncs the open windows with the OpenWindows Model
/// </summary>
public async Task SyncOpenWindowsWithModelAsync()
{
System.Diagnostics.Debug.Print("Syncing WindowSearch result with OpenWindows Model");
List<Window> snapshotOfOpenWindows = OpenWindows.Instance.Windows;
if (SearchText == string.Empty)
{
searchMatches = new List<SearchResult>();
}
else
{
searchMatches = await FuzzySearchOpenWindowsAsync(snapshotOfOpenWindows);
}
OnSearchResultUpdate?.Invoke(this, new SearchResultUpdateEventArgs());
}
/// <summary>
/// Redirecting method for Fuzzy searching
/// </summary>
/// <param name="openWindows">what windows are open</param>
/// <returns>Returns search results</returns>
private Task<List<SearchResult>> FuzzySearchOpenWindowsAsync(List<Window> openWindows)
{
return Task.Run(
() =>
FuzzySearchOpenWindows(openWindows));
}
/// <summary>
/// Search method that matches the title of windows with the user search text
/// </summary>
/// <param name="openWindows">what windows are open</param>
/// <returns>Returns search results</returns>
private List<SearchResult> FuzzySearchOpenWindows(List<Window> openWindows)
{
List<SearchResult> result = new List<SearchResult>();
List<SearchString> searchStrings = new List<SearchString>();
searchStrings.Add(new SearchString(searchText, SearchResult.SearchType.Fuzzy));
foreach (var searchString in searchStrings)
{
foreach (var window in openWindows)
{
var titleMatch = FuzzyMatching.FindBestFuzzyMatch(window.Title, searchString.SearchText);
var processMatch = FuzzyMatching.FindBestFuzzyMatch(window.ProcessName, searchString.SearchText);
if ((titleMatch.Count != 0 || processMatch.Count != 0) &&
window.Title.Length != 0)
{
var temp = new SearchResult(window, titleMatch, processMatch, searchString.SearchType);
result.Add(temp);
}
}
}
System.Diagnostics.Debug.Print("Found " + result.Count + " windows that match the search text");
return result;
}
/// <summary>
/// Event args for a window list update event
/// </summary>
public class SearchResultUpdateEventArgs : EventArgs
{
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Responsible for searching and finding matches for the strings provided.
/// Essentially the UI independent model of the application
/// </summary>
internal class SearchController
{
/// <summary>
/// the current search text
/// </summary>
private string searchText;
/// <summary>
/// Open window search results
/// </summary
private List<SearchResult> searchMatches;
/// <summary>
/// Singleton pattern
/// </summary>
private static SearchController instance;
/// <summary>
/// Delegate handler for open windows updates
/// </summary>
public delegate void SearchResultUpdateHandler(object sender, SearchResultUpdateEventArgs e);
/// <summary>
/// Event raised when there is an update to the list of open windows
/// </summary>
public event SearchResultUpdateHandler OnSearchResultUpdate;
/// <summary>
/// Gets or sets the current search text
/// </summary>
public string SearchText
{
get
{
return searchText;
}
set
{
searchText = value.ToLower().Trim();
}
}
/// <summary>
/// Gets the open window search results
/// </summary>
public List<SearchResult> SearchMatches
{
get { return new List<SearchResult>(searchMatches).OrderByDescending(x => x.Score).ToList(); }
}
/// <summary>
/// Gets singleton Pattern
/// </summary>
public static SearchController Instance
{
get
{
if (instance == null)
{
instance = new SearchController();
}
return instance;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="SearchController"/> class.
/// Initializes the search controller object
/// </summary>
private SearchController()
{
searchText = string.Empty;
OpenWindows.Instance.OnOpenWindowsUpdate += OpenWindowsUpdateHandler;
}
/// <summary>
/// Event handler for when the search text has been updated
/// </summary>
public async Task UpdateSearchText(string searchText)
{
SearchText = searchText;
await SyncOpenWindowsWithModelAsync();
}
/// <summary>
/// Event handler called when the OpenWindows list changes
/// </summary>
/// <param name="sender">sending item</param>
/// <param name="e">event arg</param>
public async void OpenWindowsUpdateHandler(object sender, SearchResultUpdateEventArgs e)
{
await SyncOpenWindowsWithModelAsync();
}
/// <summary>
/// Syncs the open windows with the OpenWindows Model
/// </summary>
public async Task SyncOpenWindowsWithModelAsync()
{
System.Diagnostics.Debug.Print("Syncing WindowSearch result with OpenWindows Model");
List<Window> snapshotOfOpenWindows = OpenWindows.Instance.Windows;
if (SearchText == string.Empty)
{
searchMatches = new List<SearchResult>();
}
else
{
searchMatches = await FuzzySearchOpenWindowsAsync(snapshotOfOpenWindows);
}
OnSearchResultUpdate?.Invoke(this, new SearchResultUpdateEventArgs());
}
/// <summary>
/// Redirecting method for Fuzzy searching
/// </summary>
/// <param name="openWindows">what windows are open</param>
/// <returns>Returns search results</returns>
private Task<List<SearchResult>> FuzzySearchOpenWindowsAsync(List<Window> openWindows)
{
return Task.Run(
() =>
FuzzySearchOpenWindows(openWindows));
}
/// <summary>
/// Search method that matches the title of windows with the user search text
/// </summary>
/// <param name="openWindows">what windows are open</param>
/// <returns>Returns search results</returns>
private List<SearchResult> FuzzySearchOpenWindows(List<Window> openWindows)
{
List<SearchResult> result = new List<SearchResult>();
List<SearchString> searchStrings = new List<SearchString>();
searchStrings.Add(new SearchString(searchText, SearchResult.SearchType.Fuzzy));
foreach (var searchString in searchStrings)
{
foreach (var window in openWindows)
{
var titleMatch = FuzzyMatching.FindBestFuzzyMatch(window.Title, searchString.SearchText);
var processMatch = FuzzyMatching.FindBestFuzzyMatch(window.ProcessName, searchString.SearchText);
if ((titleMatch.Count != 0 || processMatch.Count != 0) &&
window.Title.Length != 0)
{
var temp = new SearchResult(window, titleMatch, processMatch, searchString.SearchType);
result.Add(temp);
}
}
}
System.Diagnostics.Debug.Print("Found " + result.Count + " windows that match the search text");
return result;
}
/// <summary>
/// Event args for a window list update event
/// </summary>
public class SearchResultUpdateEventArgs : EventArgs
{
}
}
}

View File

@@ -1,136 +1,136 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System.Collections.Generic;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Contains search result windows with each window including the reason why the result was included
/// </summary>
public class SearchResult
{
/// <summary>
/// Gets the actual window reference for the search result
/// </summary>
public Window Result
{
get;
private set;
}
/// <summary>
/// Gets the list of indexes of the matching characters for the search in the title window
/// </summary>
public List<int> SearchMatchesInTitle
{
get;
private set;
}
/// <summary>
/// Gets the list of indexes of the matching characters for the search in the
/// name of the process
/// </summary>
public List<int> SearchMatchesInProcessName
{
get;
private set;
}
/// <summary>
/// Gets the type of match (shortcut, fuzzy or nothing)
/// </summary>
public SearchType SearchResultMatchType
{
get;
private set;
}
/// <summary>
/// Gets a score indicating how well this matches what we are looking for
/// </summary>
public int Score
{
get;
private set;
}
/// <summary>
/// Gets the source of where the best score was found
/// </summary>
public TextType BestScoreSource
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="SearchResult"/> class.
/// Constructor
/// </summary>
public SearchResult(Window window, List<int> matchesInTitle, List<int> matchesInProcessName, SearchType matchType)
{
Result = window;
SearchMatchesInTitle = matchesInTitle;
SearchMatchesInProcessName = matchesInProcessName;
SearchResultMatchType = matchType;
CalculateScore();
}
/// <summary>
/// Calculates the score for how closely this window matches the search string
/// </summary>
/// <remarks>
/// Higher Score is better
/// </remarks>
private void CalculateScore()
{
if (FuzzyMatching.CalculateScoreForMatches(SearchMatchesInProcessName) >
FuzzyMatching.CalculateScoreForMatches(SearchMatchesInTitle))
{
Score = FuzzyMatching.CalculateScoreForMatches(SearchMatchesInProcessName);
BestScoreSource = TextType.ProcessName;
}
else
{
Score = FuzzyMatching.CalculateScoreForMatches(SearchMatchesInTitle);
BestScoreSource = TextType.WindowTitle;
}
}
/// <summary>
/// The type of text that a string represents
/// </summary>
public enum TextType
{
ProcessName,
WindowTitle,
}
/// <summary>
/// The type of search
/// </summary>
public enum SearchType
{
/// <summary>
/// the search string is empty, which means all open windows are
/// going to be returned
/// </summary>
Empty,
/// <summary>
/// Regular fuzzy match search
/// </summary>
Fuzzy,
/// <summary>
/// The user has entered text that has been matched to a shortcut
/// and the shortcut is now being searched
/// </summary>
Shortcut,
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System.Collections.Generic;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Contains search result windows with each window including the reason why the result was included
/// </summary>
public class SearchResult
{
/// <summary>
/// Gets the actual window reference for the search result
/// </summary>
public Window Result
{
get;
private set;
}
/// <summary>
/// Gets the list of indexes of the matching characters for the search in the title window
/// </summary>
public List<int> SearchMatchesInTitle
{
get;
private set;
}
/// <summary>
/// Gets the list of indexes of the matching characters for the search in the
/// name of the process
/// </summary>
public List<int> SearchMatchesInProcessName
{
get;
private set;
}
/// <summary>
/// Gets the type of match (shortcut, fuzzy or nothing)
/// </summary>
public SearchType SearchResultMatchType
{
get;
private set;
}
/// <summary>
/// Gets a score indicating how well this matches what we are looking for
/// </summary>
public int Score
{
get;
private set;
}
/// <summary>
/// Gets the source of where the best score was found
/// </summary>
public TextType BestScoreSource
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="SearchResult"/> class.
/// Constructor
/// </summary>
public SearchResult(Window window, List<int> matchesInTitle, List<int> matchesInProcessName, SearchType matchType)
{
Result = window;
SearchMatchesInTitle = matchesInTitle;
SearchMatchesInProcessName = matchesInProcessName;
SearchResultMatchType = matchType;
CalculateScore();
}
/// <summary>
/// Calculates the score for how closely this window matches the search string
/// </summary>
/// <remarks>
/// Higher Score is better
/// </remarks>
private void CalculateScore()
{
if (FuzzyMatching.CalculateScoreForMatches(SearchMatchesInProcessName) >
FuzzyMatching.CalculateScoreForMatches(SearchMatchesInTitle))
{
Score = FuzzyMatching.CalculateScoreForMatches(SearchMatchesInProcessName);
BestScoreSource = TextType.ProcessName;
}
else
{
Score = FuzzyMatching.CalculateScoreForMatches(SearchMatchesInTitle);
BestScoreSource = TextType.WindowTitle;
}
}
/// <summary>
/// The type of text that a string represents
/// </summary>
public enum TextType
{
ProcessName,
WindowTitle,
}
/// <summary>
/// The type of search
/// </summary>
public enum SearchType
{
/// <summary>
/// the search string is empty, which means all open windows are
/// going to be returned
/// </summary>
Empty,
/// <summary>
/// Regular fuzzy match search
/// </summary>
Fuzzy,
/// <summary>
/// The user has entered text that has been matched to a shortcut
/// and the shortcut is now being searched
/// </summary>
Shortcut,
}
}
}

View File

@@ -1,46 +1,46 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// A class to represent a search string
/// </summary>
/// <remarks>Class was added inorder to be able to attach various context data to
/// a search string</remarks>
internal class SearchString
{
/// <summary>
/// Gets where is the search string coming from (is it a shortcut
/// or direct string, etc...)
/// </summary>
public SearchResult.SearchType SearchType
{
get;
private set;
}
/// <summary>
/// Gets the actual text we are searching for
/// </summary>
public string SearchText
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="SearchString"/> class.
/// Constructor
/// </summary>
/// <param name="searchText">text from search</param>
/// <param name="searchType">type of search</param>
public SearchString(string searchText, SearchResult.SearchType searchType)
{
SearchText = searchText;
SearchType = searchType;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// A class to represent a search string
/// </summary>
/// <remarks>Class was added inorder to be able to attach various context data to
/// a search string</remarks>
internal class SearchString
{
/// <summary>
/// Gets where is the search string coming from (is it a shortcut
/// or direct string, etc...)
/// </summary>
public SearchResult.SearchType SearchType
{
get;
private set;
}
/// <summary>
/// Gets the actual text we are searching for
/// </summary>
public string SearchText
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="SearchString"/> class.
/// Constructor
/// </summary>
/// <param name="searchText">text from search</param>
/// <param name="searchType">type of search</param>
public SearchString(string searchText, SearchResult.SearchType searchType)
{
SearchText = searchText;
SearchType = searchType;
}
}
}

View File

@@ -1,402 +1,402 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Represents a specific open window
/// </summary>
public class Window
{
/// <summary>
/// Maximum size of a file name
/// </summary>
private const int MaximumFileNameLength = 1000;
/// <summary>
/// The list of owners of a window so that we don't have to
/// constantly query for the process owning a specific window
/// </summary>
private static readonly Dictionary<IntPtr, string> _handlesToProcessCache = new Dictionary<IntPtr, string>();
/// <summary>
/// The list of icons from process so that we don't have to keep
/// loading them from disk
/// </summary>
private static readonly Dictionary<uint, ImageSource> _processIdsToIconsCache = new Dictionary<uint, ImageSource>();
/// <summary>
/// The handle to the window
/// </summary>
private readonly IntPtr hwnd;
/// <summary>
/// Gets the title of the window (the string displayed at the top of the window)
/// </summary>
public string Title
{
get
{
int sizeOfTitle = InteropAndHelpers.GetWindowTextLength(hwnd);
if (sizeOfTitle++ > 0)
{
StringBuilder titleBuffer = new StringBuilder(sizeOfTitle);
InteropAndHelpers.GetWindowText(hwnd, titleBuffer, sizeOfTitle);
return titleBuffer.ToString();
}
else
{
return string.Empty;
}
}
}
/// <summary>
/// Gets the handle to the window
/// </summary>
public IntPtr Hwnd
{
get { return hwnd; }
}
public uint ProcessID { get; set; }
/// <summary>
/// Gets returns the name of the process
/// </summary>
public string ProcessName
{
get
{
lock (_handlesToProcessCache)
{
if (_handlesToProcessCache.Count > 7000)
{
Debug.Print("Clearing Process Cache because it's size is " + _handlesToProcessCache.Count);
_handlesToProcessCache.Clear();
}
if (!_handlesToProcessCache.ContainsKey(Hwnd))
{
var processName = GetProcessNameFromWindowHandle(Hwnd);
if (processName.Length != 0)
{
_handlesToProcessCache.Add(
Hwnd,
processName.ToString().Split('\\').Reverse().ToArray()[0]);
}
else
{
_handlesToProcessCache.Add(Hwnd, string.Empty);
}
}
if (_handlesToProcessCache[hwnd].ToLower() == "applicationframehost.exe")
{
new Task(() =>
{
InteropAndHelpers.CallBackPtr callbackptr = new InteropAndHelpers.CallBackPtr((IntPtr hwnd, IntPtr lParam) =>
{
var childProcessId = GetProcessIDFromWindowHandle(hwnd);
if (childProcessId != ProcessID)
{
_handlesToProcessCache[Hwnd] = GetProcessNameFromWindowHandle(hwnd);
return false;
}
else
{
return true;
}
});
InteropAndHelpers.EnumChildWindows(Hwnd, callbackptr, 0);
}).Start();
}
return _handlesToProcessCache[hwnd];
}
}
}
/// <summary>
/// Gets returns the name of the class for the window represented
/// </summary>
public string ClassName
{
get
{
StringBuilder windowClassName = new StringBuilder(300);
InteropAndHelpers.GetClassName(Hwnd, windowClassName, windowClassName.MaxCapacity);
return windowClassName.ToString();
}
}
/// <summary>
/// Gets represents the Window Icon for the specified window
/// </summary>
public ImageSource WindowIcon
{
get
{
lock (_processIdsToIconsCache)
{
InteropAndHelpers.GetWindowThreadProcessId(Hwnd, out uint processId);
if (!_processIdsToIconsCache.ContainsKey(processId))
{
try
{
Process process = Process.GetProcessById((int)processId);
Icon tempIcon = Icon.ExtractAssociatedIcon(process.Modules[0].FileName);
_processIdsToIconsCache.Add(processId, Imaging.CreateBitmapSourceFromHIcon(
tempIcon.Handle,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()));
}
catch
{
BitmapImage failedImage = new BitmapImage(new Uri(@"Images\failedIcon.jpg", UriKind.Relative));
_processIdsToIconsCache.Add(processId, failedImage);
}
}
return _processIdsToIconsCache[processId];
}
}
}
/// <summary>
/// Gets a value indicating whether is the window visible (might return false if it is a hidden IE tab)
/// </summary>
public bool Visible
{
get
{
return InteropAndHelpers.IsWindowVisible(Hwnd);
}
}
/// <summary>
/// Gets a value indicating whether determines whether the specified window handle identifies an existing window.
/// </summary>
public bool IsWindow
{
get
{
return InteropAndHelpers.IsWindow(Hwnd);
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether is the window GWL_EX_STYLE is a toolwindow
/// </summary>
public bool IsToolWindow
{
get
{
return (InteropAndHelpers.GetWindowLong(Hwnd, InteropAndHelpers.GWL_EXSTYLE) &
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_TOOLWINDOW) ==
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_TOOLWINDOW;
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether the window GWL_EX_STYLE is an appwindow
/// </summary>
public bool IsAppWindow
{
get
{
return (InteropAndHelpers.GetWindowLong(Hwnd, InteropAndHelpers.GWL_EXSTYLE) &
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_APPWINDOW) ==
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_APPWINDOW;
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether the window has ITaskList_Deleted property
/// </summary>
public bool TaskListDeleted
{
get
{
return InteropAndHelpers.GetProp(Hwnd, "ITaskList_Deleted") != IntPtr.Zero;
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether the app is a cloaked UWP app
/// </summary>
public bool IsUWPCloaked
{
get
{
return IsWindowCloaked() && ClassName == "ApplicationFrameWindow";
}
}
/// <summary>
/// Gets a value indicating whether determines whether the specified windows is the owner
/// </summary>
public bool IsOwner
{
get
{
return InteropAndHelpers.GetWindow(Hwnd, InteropAndHelpers.GetWindowCmd.GW_OWNER) != null;
}
}
/// <summary>
/// Gets a value indicating whether is the window cloaked. To detect UWP apps in background or win32 apps running in another virtual desktop
/// </summary>
public bool IsWindowCloaked()
{
int isCloaked = 0;
const int DWMWA_CLOAKED = 14;
InteropAndHelpers.DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, out isCloaked, sizeof(int));
return isCloaked != 0;
}
/// <summary>
/// Gets a value indicating whether returns true if the window is minimized
/// </summary>
public bool Minimized
{
get
{
return GetWindowSizeState() == WindowSizeState.Minimized;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="Window"/> class.
/// Initializes a new Window representation
/// </summary>
/// <param name="hwnd">the handle to the window we are representing</param>
public Window(IntPtr hwnd)
{
// TODO: Add verification as to whether the window handle is valid
this.hwnd = hwnd;
}
/// <summary>
/// Highlights a window to help the user identify the window that has been selected
/// </summary>
public void HighlightWindow()
{
throw new NotImplementedException();
}
/// <summary>
/// Switches desktop focus to the window
/// </summary>
public void SwitchToWindow()
{
// The following block is necessary because
// 1) There is a weird flashing behavior when trying
// to use ShowWindow for switching tabs in IE
// 2) SetForegroundWindow fails on minimized windows
if (ProcessName.ToLower().Equals("iexplore.exe") || !Minimized)
{
InteropAndHelpers.SetForegroundWindow(Hwnd);
}
else
{
InteropAndHelpers.ShowWindow(Hwnd, InteropAndHelpers.ShowWindowCommands.Restore);
}
InteropAndHelpers.FlashWindow(Hwnd, true);
}
/// <summary>
/// Converts the window name to string along with the process name
/// </summary>
/// <returns>The title of the window</returns>
public override string ToString()
{
return Title + " (" + ProcessName.ToUpper() + ")";
}
/// <summary>
/// Returns what the window size is
/// </summary>
/// <returns>The state (minimized, maximized, etc..) of the window</returns>
public WindowSizeState GetWindowSizeState()
{
InteropAndHelpers.GetWindowPlacement(Hwnd, out InteropAndHelpers.WINDOWPLACEMENT placement);
switch (placement.ShowCmd)
{
case InteropAndHelpers.ShowWindowCommands.Normal:
return WindowSizeState.Normal;
case InteropAndHelpers.ShowWindowCommands.Minimize:
case InteropAndHelpers.ShowWindowCommands.ShowMinimized:
return WindowSizeState.Minimized;
case InteropAndHelpers.ShowWindowCommands.Maximize: // No need for ShowMaximized here since its also of value 3
return WindowSizeState.Maximized;
default:
// throw new Exception("Don't know how to handle window state = " + placement.ShowCmd);
return WindowSizeState.Unknown;
}
}
/// <summary>
/// Enum to simplify the state of the window
/// </summary>
public enum WindowSizeState
{
Normal,
Minimized,
Maximized,
Unknown,
}
/// <summary>
/// Gets the name of the process using the window handle
/// </summary>
/// <param name="hwnd">The handle to the window</param>
/// <returns>A string representing the process name or an empty string if the function fails</returns>
private string GetProcessNameFromWindowHandle(IntPtr hwnd)
{
uint processId = GetProcessIDFromWindowHandle(hwnd);
ProcessID = processId;
IntPtr processHandle = InteropAndHelpers.OpenProcess(InteropAndHelpers.ProcessAccessFlags.AllAccess, true, (int)processId);
StringBuilder processName = new StringBuilder(MaximumFileNameLength);
if (InteropAndHelpers.GetProcessImageFileName(processHandle, processName, MaximumFileNameLength) != 0)
{
return processName.ToString().Split('\\').Reverse().ToArray()[0];
}
else
{
return string.Empty;
}
}
/// <summary>
/// Gets the process ID for the Window handle
/// </summary>
/// <param name="hwnd">The handle to the window</param>
/// <returns>The process ID</returns>
private uint GetProcessIDFromWindowHandle(IntPtr hwnd)
{
InteropAndHelpers.GetWindowThreadProcessId(hwnd, out uint processId);
return processId;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Microsoft.Plugin.WindowWalker.Components
{
/// <summary>
/// Represents a specific open window
/// </summary>
public class Window
{
/// <summary>
/// Maximum size of a file name
/// </summary>
private const int MaximumFileNameLength = 1000;
/// <summary>
/// The list of owners of a window so that we don't have to
/// constantly query for the process owning a specific window
/// </summary>
private static readonly Dictionary<IntPtr, string> _handlesToProcessCache = new Dictionary<IntPtr, string>();
/// <summary>
/// The list of icons from process so that we don't have to keep
/// loading them from disk
/// </summary>
private static readonly Dictionary<uint, ImageSource> _processIdsToIconsCache = new Dictionary<uint, ImageSource>();
/// <summary>
/// The handle to the window
/// </summary>
private readonly IntPtr hwnd;
/// <summary>
/// Gets the title of the window (the string displayed at the top of the window)
/// </summary>
public string Title
{
get
{
int sizeOfTitle = InteropAndHelpers.GetWindowTextLength(hwnd);
if (sizeOfTitle++ > 0)
{
StringBuilder titleBuffer = new StringBuilder(sizeOfTitle);
InteropAndHelpers.GetWindowText(hwnd, titleBuffer, sizeOfTitle);
return titleBuffer.ToString();
}
else
{
return string.Empty;
}
}
}
/// <summary>
/// Gets the handle to the window
/// </summary>
public IntPtr Hwnd
{
get { return hwnd; }
}
public uint ProcessID { get; set; }
/// <summary>
/// Gets returns the name of the process
/// </summary>
public string ProcessName
{
get
{
lock (_handlesToProcessCache)
{
if (_handlesToProcessCache.Count > 7000)
{
Debug.Print("Clearing Process Cache because it's size is " + _handlesToProcessCache.Count);
_handlesToProcessCache.Clear();
}
if (!_handlesToProcessCache.ContainsKey(Hwnd))
{
var processName = GetProcessNameFromWindowHandle(Hwnd);
if (processName.Length != 0)
{
_handlesToProcessCache.Add(
Hwnd,
processName.ToString().Split('\\').Reverse().ToArray()[0]);
}
else
{
_handlesToProcessCache.Add(Hwnd, string.Empty);
}
}
if (_handlesToProcessCache[hwnd].ToLower() == "applicationframehost.exe")
{
new Task(() =>
{
InteropAndHelpers.CallBackPtr callbackptr = new InteropAndHelpers.CallBackPtr((IntPtr hwnd, IntPtr lParam) =>
{
var childProcessId = GetProcessIDFromWindowHandle(hwnd);
if (childProcessId != ProcessID)
{
_handlesToProcessCache[Hwnd] = GetProcessNameFromWindowHandle(hwnd);
return false;
}
else
{
return true;
}
});
InteropAndHelpers.EnumChildWindows(Hwnd, callbackptr, 0);
}).Start();
}
return _handlesToProcessCache[hwnd];
}
}
}
/// <summary>
/// Gets returns the name of the class for the window represented
/// </summary>
public string ClassName
{
get
{
StringBuilder windowClassName = new StringBuilder(300);
InteropAndHelpers.GetClassName(Hwnd, windowClassName, windowClassName.MaxCapacity);
return windowClassName.ToString();
}
}
/// <summary>
/// Gets represents the Window Icon for the specified window
/// </summary>
public ImageSource WindowIcon
{
get
{
lock (_processIdsToIconsCache)
{
InteropAndHelpers.GetWindowThreadProcessId(Hwnd, out uint processId);
if (!_processIdsToIconsCache.ContainsKey(processId))
{
try
{
Process process = Process.GetProcessById((int)processId);
Icon tempIcon = Icon.ExtractAssociatedIcon(process.Modules[0].FileName);
_processIdsToIconsCache.Add(processId, Imaging.CreateBitmapSourceFromHIcon(
tempIcon.Handle,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()));
}
catch
{
BitmapImage failedImage = new BitmapImage(new Uri(@"Images\failedIcon.jpg", UriKind.Relative));
_processIdsToIconsCache.Add(processId, failedImage);
}
}
return _processIdsToIconsCache[processId];
}
}
}
/// <summary>
/// Gets a value indicating whether is the window visible (might return false if it is a hidden IE tab)
/// </summary>
public bool Visible
{
get
{
return InteropAndHelpers.IsWindowVisible(Hwnd);
}
}
/// <summary>
/// Gets a value indicating whether determines whether the specified window handle identifies an existing window.
/// </summary>
public bool IsWindow
{
get
{
return InteropAndHelpers.IsWindow(Hwnd);
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether is the window GWL_EX_STYLE is a toolwindow
/// </summary>
public bool IsToolWindow
{
get
{
return (InteropAndHelpers.GetWindowLong(Hwnd, InteropAndHelpers.GWL_EXSTYLE) &
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_TOOLWINDOW) ==
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_TOOLWINDOW;
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether the window GWL_EX_STYLE is an appwindow
/// </summary>
public bool IsAppWindow
{
get
{
return (InteropAndHelpers.GetWindowLong(Hwnd, InteropAndHelpers.GWL_EXSTYLE) &
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_APPWINDOW) ==
(uint)InteropAndHelpers.ExtendedWindowStyles.WS_EX_APPWINDOW;
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether the window has ITaskList_Deleted property
/// </summary>
public bool TaskListDeleted
{
get
{
return InteropAndHelpers.GetProp(Hwnd, "ITaskList_Deleted") != IntPtr.Zero;
}
}
/// <summary>
/// Gets a value indicating whether get a value indicating whether the app is a cloaked UWP app
/// </summary>
public bool IsUWPCloaked
{
get
{
return IsWindowCloaked() && ClassName == "ApplicationFrameWindow";
}
}
/// <summary>
/// Gets a value indicating whether determines whether the specified windows is the owner
/// </summary>
public bool IsOwner
{
get
{
return InteropAndHelpers.GetWindow(Hwnd, InteropAndHelpers.GetWindowCmd.GW_OWNER) != null;
}
}
/// <summary>
/// Gets a value indicating whether is the window cloaked. To detect UWP apps in background or win32 apps running in another virtual desktop
/// </summary>
public bool IsWindowCloaked()
{
int isCloaked = 0;
const int DWMWA_CLOAKED = 14;
InteropAndHelpers.DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, out isCloaked, sizeof(int));
return isCloaked != 0;
}
/// <summary>
/// Gets a value indicating whether returns true if the window is minimized
/// </summary>
public bool Minimized
{
get
{
return GetWindowSizeState() == WindowSizeState.Minimized;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="Window"/> class.
/// Initializes a new Window representation
/// </summary>
/// <param name="hwnd">the handle to the window we are representing</param>
public Window(IntPtr hwnd)
{
// TODO: Add verification as to whether the window handle is valid
this.hwnd = hwnd;
}
/// <summary>
/// Highlights a window to help the user identify the window that has been selected
/// </summary>
public void HighlightWindow()
{
throw new NotImplementedException();
}
/// <summary>
/// Switches desktop focus to the window
/// </summary>
public void SwitchToWindow()
{
// The following block is necessary because
// 1) There is a weird flashing behavior when trying
// to use ShowWindow for switching tabs in IE
// 2) SetForegroundWindow fails on minimized windows
if (ProcessName.ToLower().Equals("iexplore.exe") || !Minimized)
{
InteropAndHelpers.SetForegroundWindow(Hwnd);
}
else
{
InteropAndHelpers.ShowWindow(Hwnd, InteropAndHelpers.ShowWindowCommands.Restore);
}
InteropAndHelpers.FlashWindow(Hwnd, true);
}
/// <summary>
/// Converts the window name to string along with the process name
/// </summary>
/// <returns>The title of the window</returns>
public override string ToString()
{
return Title + " (" + ProcessName.ToUpper() + ")";
}
/// <summary>
/// Returns what the window size is
/// </summary>
/// <returns>The state (minimized, maximized, etc..) of the window</returns>
public WindowSizeState GetWindowSizeState()
{
InteropAndHelpers.GetWindowPlacement(Hwnd, out InteropAndHelpers.WINDOWPLACEMENT placement);
switch (placement.ShowCmd)
{
case InteropAndHelpers.ShowWindowCommands.Normal:
return WindowSizeState.Normal;
case InteropAndHelpers.ShowWindowCommands.Minimize:
case InteropAndHelpers.ShowWindowCommands.ShowMinimized:
return WindowSizeState.Minimized;
case InteropAndHelpers.ShowWindowCommands.Maximize: // No need for ShowMaximized here since its also of value 3
return WindowSizeState.Maximized;
default:
// throw new Exception("Don't know how to handle window state = " + placement.ShowCmd);
return WindowSizeState.Unknown;
}
}
/// <summary>
/// Enum to simplify the state of the window
/// </summary>
public enum WindowSizeState
{
Normal,
Minimized,
Maximized,
Unknown,
}
/// <summary>
/// Gets the name of the process using the window handle
/// </summary>
/// <param name="hwnd">The handle to the window</param>
/// <returns>A string representing the process name or an empty string if the function fails</returns>
private string GetProcessNameFromWindowHandle(IntPtr hwnd)
{
uint processId = GetProcessIDFromWindowHandle(hwnd);
ProcessID = processId;
IntPtr processHandle = InteropAndHelpers.OpenProcess(InteropAndHelpers.ProcessAccessFlags.AllAccess, true, (int)processId);
StringBuilder processName = new StringBuilder(MaximumFileNameLength);
if (InteropAndHelpers.GetProcessImageFileName(processHandle, processName, MaximumFileNameLength) != 0)
{
return processName.ToString().Split('\\').Reverse().ToArray()[0];
}
else
{
return string.Empty;
}
}
/// <summary>
/// Gets the process ID for the Window handle
/// </summary>
/// <param name="hwnd">The handle to the window</param>
/// <returns>The process ID</returns>
private uint GetProcessIDFromWindowHandle(IntPtr hwnd)
{
InteropAndHelpers.GetWindowThreadProcessId(hwnd, out uint processId);
return processId;
}
}
}

View File

@@ -1,31 +1,31 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.Plugin.WindowWalker.Components
{
internal class WindowResult : Window
{
/// <summary>
/// Number of letters in between constant for when
/// the result hasn't been set yet
/// </summary>
public const int NoResult = -1;
/// <summary>
/// Gets or sets properties that signify how many characters (including spaces)
/// were found when matching the results
/// </summary>
public int LettersInBetweenScore { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="WindowResult"/> class.
/// Constructor for WindowResult
/// </summary>
public WindowResult(Window window)
: base(window.Hwnd)
{
LettersInBetweenScore = NoResult;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.Plugin.WindowWalker.Components
{
internal class WindowResult : Window
{
/// <summary>
/// Number of letters in between constant for when
/// the result hasn't been set yet
/// </summary>
public const int NoResult = -1;
/// <summary>
/// Gets or sets properties that signify how many characters (including spaces)
/// were found when matching the results
/// </summary>
public int LettersInBetweenScore { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="WindowResult"/> class.
/// Constructor for WindowResult
/// </summary>
public WindowResult(Window window)
: base(window.Hwnd)
{
LettersInBetweenScore = NoResult;
}
}
}