├── .build ├── MSBuild.Community.Tasks.dll └── MSBuild.Community.Tasks.targets ├── .gitignore ├── ChocolateyPackages ├── .gitignore ├── switcheroo.install │ ├── switcheroo.install.nuspec │ └── tools │ │ └── chocolateyInstall.ps1 ├── switcheroo.portable │ ├── switcheroo.portable.nuspec │ └── tools │ │ ├── chocolateyInstall.ps1 │ │ └── switcheroo.exe.gui └── switcheroo │ ├── switcheroo.nuspec │ └── tools │ └── chocolateyInstall.ps1 ├── Core.UnitTests ├── ContainsMatcherTest.cs ├── Core.UnitTests.csproj ├── IndividualCharactersMatcherTests.cs ├── Properties │ └── AssemblyInfo.cs ├── StartsWithMatcherTests.cs ├── XamlHighlighterTests.cs └── packages.config ├── Core ├── AppWindow.cs ├── Core.csproj ├── FilterResult.cs ├── IWindowText.cs ├── KeyboardHelper.cs ├── Matchers │ ├── ContainsMatcher.cs │ ├── IMatcher.cs │ ├── IndividualCharactersMatcher.cs │ ├── MatchResult.cs │ ├── SignificantCharactersMatcher.cs │ ├── StartsWithMatcher.cs │ └── StringPart.cs ├── Properties │ └── AssemblyInfo.cs ├── WinApi.cs ├── WindowFilterer.cs ├── WindowFinder.cs ├── WindowIconFinder.cs └── XamlHighlighter.cs ├── Installer ├── Build.xml ├── InnoSetup │ ├── Default.isl │ ├── ISCC.exe │ ├── ISCmplr.dll │ ├── ISPP.dll │ ├── ISPPBuiltins.iss │ ├── Setup.e32 │ ├── SetupLdr.e32 │ ├── WizModernImage-IS.bmp │ ├── WizModernImage.bmp │ ├── WizModernSmallImage-IS.bmp │ ├── WizModernSmallImage.bmp │ ├── islzma.dll │ ├── islzma32.exe │ ├── islzma64.exe │ └── license.txt └── Installer.iss ├── LICENSE.txt ├── ManagedWinapi ├── AccessibleObjectListener.cs ├── ApiHelper.cs ├── ClipboardNotifier.cs ├── CodepointRange.cs ├── Contents │ ├── AccessibleWindowParser.cs │ ├── ContentParserRegistry.cs │ ├── ListParser.cs │ ├── TextFieldParser.cs │ ├── WindowContent.cs │ └── WindowContentParser.cs ├── Crosshair.Designer.cs ├── Crosshair.cs ├── Crosshair.resx ├── EventDispatchingNativeWindow.cs ├── ExtendedFileInfo.cs ├── Hook.cs ├── Hotkey.cs ├── InputBlocker.cs ├── JournalHook.cs ├── KeyboardKey.cs ├── LockKeyResetter.cs ├── LowLevelHook.cs ├── MachineIdentifiers.cs ├── ManagedWinapi.csproj ├── ManagedWinapiNativeHelper.dll ├── Mixer.cs ├── MixerControl.cs ├── MixerLine.cs ├── PInvokeTypes.cs ├── PrivilegedActions.cs ├── ProcessMemoryChunk.cs ├── Properties │ └── AssemblyInfo.cs ├── SendKeysEscaper.cs ├── ShortcutBox.Designer.cs ├── ShortcutBox.cs ├── ShortcutBox.resx ├── SystemAccessibleObject.cs ├── SystemListBox.cs ├── SystemListView.cs ├── SystemTreeView.cs ├── SystemWindow.cs ├── crosshair.cur └── crosshair.ico ├── Switcheroo.sln ├── Switcheroo ├── AboutWindow.xaml ├── AboutWindow.xaml.cs ├── AltTabHook.cs ├── App.xaml ├── App.xaml.cs ├── AppWindowViewModel.cs ├── AutoStart.cs ├── BoolToWhateverConverter.cs ├── FormattedTextAttribute.cs ├── HotKey.cs ├── IconToBitmapConverter.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── OptionsWindow.xaml ├── OptionsWindow.xaml.cs ├── PortableSettingsProvider.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Switcheroo.csproj ├── Theme.cs ├── WindowCloser.cs ├── WindowHandleToCachedIconConverter.cs ├── WindowHandleToIconConverter.cs ├── app.config ├── icon.ico └── packages.config ├── changelog.md ├── logo.png ├── readme.md └── screenshot.png /.build/MSBuild.Community.Tasks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/.build/MSBuild.Community.Tasks.dll -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | .vs 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | x64/ 15 | build/ 16 | bld/ 17 | [Bb]in/ 18 | [Oo]bj/ 19 | 20 | # MSTest test Results 21 | [Tt]est[Rr]esult*/ 22 | [Bb]uild[Ll]og.* 23 | 24 | #NUNIT 25 | *.VisualState.xml 26 | TestResult.xml 27 | 28 | *_i.c 29 | *_p.c 30 | *_i.h 31 | *.ilk 32 | *.meta 33 | *.obj 34 | *.pch 35 | *.pdb 36 | *.pgc 37 | *.pgd 38 | *.rsp 39 | *.sbr 40 | *.tlb 41 | *.tli 42 | *.tlh 43 | *.tmp 44 | *.tmp_proj 45 | *.log 46 | *.vspscc 47 | *.vssscc 48 | .builds 49 | *.pidb 50 | *.svclog 51 | *.scc 52 | 53 | # Chutzpah Test files 54 | _Chutzpah* 55 | 56 | # Visual C++ cache files 57 | ipch/ 58 | *.aps 59 | *.ncb 60 | *.opensdf 61 | *.sdf 62 | *.cachefile 63 | 64 | # Visual Studio profiler 65 | *.psess 66 | *.vsp 67 | *.vspx 68 | 69 | # TFS 2012 Local Workspace 70 | $tf/ 71 | 72 | # Guidance Automation Toolkit 73 | *.gpState 74 | 75 | # ReSharper is a .NET coding add-in 76 | _ReSharper*/ 77 | *.[Rr]e[Ss]harper 78 | *.DotSettings.user 79 | 80 | # JustCode is a .NET coding addin-in 81 | .JustCode 82 | 83 | # TeamCity is a build add-in 84 | _TeamCity* 85 | 86 | # DotCover is a Code Coverage Tool 87 | *.dotCover 88 | 89 | # NCrunch 90 | *.ncrunch* 91 | _NCrunch_* 92 | .*crunch*.local.xml 93 | 94 | # MightyMoose 95 | *.mm.* 96 | AutoTest.Net/ 97 | 98 | # Installshield output folder 99 | [Ee]xpress/ 100 | 101 | # DocProject is a documentation generator add-in 102 | DocProject/buildhelp/ 103 | DocProject/Help/*.HxT 104 | DocProject/Help/*.HxC 105 | DocProject/Help/*.hhc 106 | DocProject/Help/*.hhk 107 | DocProject/Help/*.hhp 108 | DocProject/Help/Html2 109 | DocProject/Help/html 110 | 111 | # Click-Once directory 112 | publish/ 113 | 114 | # Publish Web Output 115 | *.[Pp]ublish.xml 116 | *.azurePubxml 117 | 118 | # NuGet Packages Directory 119 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 120 | packages/* 121 | ## TODO: If the tool you use requires repositories.config, also uncomment the next line 122 | #!packages/repositories.config 123 | 124 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 125 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 126 | !packages/build/ 127 | 128 | # Windows Azure Build Output 129 | csx/ 130 | *.build.csdef 131 | 132 | # Windows Store app package directory 133 | AppPackages/ 134 | 135 | # Others 136 | sql/ 137 | *.Cache 138 | ClientBin/ 139 | [Ss]tyle[Cc]op.* 140 | ~$* 141 | *~ 142 | *.dbmdl 143 | *.dbproj.schemaview 144 | *.pfx 145 | *.publishsettings 146 | node_modules/ 147 | 148 | # RIA/Silverlight projects 149 | Generated_Code/ 150 | 151 | # Backup & report files from converting an old project file to a newer 152 | # Visual Studio version. Backup files are not needed, because we have git ;-) 153 | _UpgradeReport_Files/ 154 | Backup*/ 155 | UpgradeLog*.XML 156 | UpgradeLog*.htm 157 | 158 | # SQL Server files 159 | App_Data/*.mdf 160 | App_Data/*.ldf 161 | 162 | # Business Intelligence projects 163 | *.rdl.data 164 | *.bim.layout 165 | *.bim_*.settings 166 | 167 | # Microsoft Fakes 168 | FakesAssemblies/ 169 | 170 | # ========================= 171 | # Windows detritus 172 | # ========================= 173 | 174 | # Windows image file caches 175 | Thumbs.db 176 | ehthumbs.db 177 | 178 | # Folder config file 179 | Desktop.ini 180 | 181 | # Recycle Bin used on file shares 182 | $RECYCLE.BIN/ 183 | 184 | Installer/Output 185 | -------------------------------------------------------------------------------- /ChocolateyPackages/.gitignore: -------------------------------------------------------------------------------- 1 | *.nupkg 2 | -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo.install/switcheroo.install.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | switcheroo.install 5 | Switcheroo (Install) 6 | 0.9.2.111 7 | Regin Larsen, James Sulak 8 | Regin Larsen 9 | An alternative alt-tab task switcher 10 | Switcheroo is for anyone who spends more time using a keyboard than a mouse. Instead of alt-tabbing through a (long) list of open windows, Switcheroo allows you to quickly switch to any window by typing in just a few characters of its title. 11 | http://www.switcheroo.io 12 | switcheroo 13 | GNU GPL 3 14 | http://www.switcheroo.io/ 15 | false 16 | https://cdn.rawgit.com/kvakulo/Switcheroo/8ff2eaaee6092b05e00b21f78745c1d2d834e0ae/logo.png 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo.install/tools/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | $packageName = 'switcheroo.install' 2 | $installerType = 'EXE' 3 | $url = 'https://github.com/kvakulo/Switcheroo/releases/download/v0.9.2/switcheroo-setup.exe' 4 | $silentArgs = '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART' 5 | $validExitCodes = @(0) 6 | 7 | Install-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url" "$url64" -validExitCodes $validExitCodes -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo.portable/switcheroo.portable.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | switcheroo.portable 5 | Switcheroo (Portable) 6 | 0.9.2.111 7 | Regin Larsen, James Sulak 8 | Regin Larsen 9 | An alternative alt-tab task switcher 10 | Switcheroo is for anyone who spends more time using a keyboard than a mouse. Instead of alt-tabbing through a (long) list of open windows, Switcheroo allows you to quickly switch to any window by typing in just a few characters of its title. 11 | http://www.switcheroo.io 12 | switcheroo 13 | GNU GPL 3 14 | http://www.switcheroo.io/ 15 | false 16 | https://cdn.rawgit.com/kvakulo/Switcheroo/8ff2eaaee6092b05e00b21f78745c1d2d834e0ae/logo.png 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo.portable/tools/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | $packageName = 'switcheroo.portable' 2 | $url = 'https://github.com/kvakulo/Switcheroo/releases/download/v0.9.2/switcheroo-portable.zip' 3 | 4 | Install-ChocolateyZipPackage "switcheroo" "$url" "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo.portable/tools/switcheroo.exe.gui: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/ChocolateyPackages/switcheroo.portable/tools/switcheroo.exe.gui -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo/switcheroo.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | switcheroo 5 | Switcheroo 6 | 0.9.2.111 7 | Regin Larsen, James Sulak 8 | Regin Larsen 9 | An alternative alt-tab task switcher 10 | Switcheroo is for anyone who spends more time using a keyboard than a mouse. Instead of alt-tabbing through a (long) list of open windows, Switcheroo allows you to quickly switch to any window by typing in just a few characters of its title. 11 | http://www.switcheroo.io 12 | switcheroo 13 | GNU GPL 3 14 | http://www.switcheroo.io/ 15 | false 16 | https://cdn.rawgit.com/kvakulo/Switcheroo/8ff2eaaee6092b05e00b21f78745c1d2d834e0ae/logo.png 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ChocolateyPackages/switcheroo/tools/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | #Install-VirtualPackage 'switcheroo.portable' 'switcheroo.install' -------------------------------------------------------------------------------- /Core.UnitTests/ContainsMatcherTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Switcheroo.Core.Matchers; 3 | 4 | namespace Switcheroo.Core.UnitTests 5 | { 6 | [TestFixture] 7 | public class ContainsMatcherTests 8 | { 9 | [Test] 10 | public void Evaluate_InputNull_ReturnsNonMatchingResult() 11 | { 12 | var result = Evaluate(null, "google"); 13 | Assert.That(result.Matched, Is.False); 14 | } 15 | 16 | [Test] 17 | public void Evaluate_InputNull_ReturnsNonStringParts() 18 | { 19 | var result = Evaluate(null, "google"); 20 | Assert.That(result.StringParts.Count, Is.EqualTo(0)); 21 | } 22 | 23 | [Test] 24 | public void Evaluate_PatternNull_ReturnsNonMatchingResult() 25 | { 26 | var result = Evaluate("google chrome", null); 27 | Assert.That(result.Matched, Is.False); 28 | } 29 | 30 | [Test] 31 | public void Evaluate_InputDoesNotContainPattern_ScoreIsZero() 32 | { 33 | var result = Evaluate("google", "chrome"); 34 | Assert.That(result.Score, Is.EqualTo(0)); 35 | } 36 | 37 | [Test] 38 | public void Evaluate_InputDoesNotContainPattern_OneStringPart() 39 | { 40 | var result = Evaluate("google", "chrome"); 41 | Assert.That(result.StringParts.Count, Is.EqualTo(1)); 42 | Assert.That(result.StringParts[0].Value, Is.EqualTo("google")); 43 | Assert.That(result.StringParts[0].IsMatch, Is.False); 44 | } 45 | 46 | [Test] 47 | public void Evaluate_InputContainsPattern_ScoreIsTwo() 48 | { 49 | var result = Evaluate("google chrome", "chrome"); 50 | Assert.That(result.Score, Is.EqualTo(2)); 51 | } 52 | 53 | [Test] 54 | public void Evaluate_InputContainsPattern_ResultMatches() 55 | { 56 | var result = Evaluate("google chrome", "chrome"); 57 | Assert.That(result.Matched, Is.True); 58 | } 59 | 60 | [Test] 61 | public void Evaluate_InputContainsPattern_TwoStringParts() 62 | { 63 | var result = Evaluate("google chrome", "chrome"); 64 | Assert.That(result.StringParts.Count, Is.EqualTo(2)); 65 | } 66 | 67 | [Test] 68 | public void Evaluate_InputContainsPattern_StringPartsAreCorrect() 69 | { 70 | var result = Evaluate("google chrome", "chrome"); 71 | Assert.That(result.StringParts[0].Value, Is.EqualTo("google ")); 72 | Assert.That(result.StringParts[0].IsMatch, Is.False); 73 | Assert.That(result.StringParts[1].Value, Is.EqualTo("chrome")); 74 | Assert.That(result.StringParts[1].IsMatch, Is.True); 75 | } 76 | 77 | [Test] 78 | public void Evaluate_InputContainsPatternInBeginning_StringPartsAreCorrect() 79 | { 80 | var result = Evaluate("google chrome", "google"); 81 | Assert.That(result.StringParts.Count, Is.EqualTo(2)); 82 | Assert.That(result.StringParts[0].Value, Is.EqualTo("google")); 83 | Assert.That(result.StringParts[0].IsMatch, Is.True); 84 | Assert.That(result.StringParts[1].Value, Is.EqualTo(" chrome")); 85 | Assert.That(result.StringParts[1].IsMatch, Is.False); 86 | } 87 | 88 | [Test] 89 | public void Evaluate_InputContainsPatternInMiddle_StringPartsAreCorrect() 90 | { 91 | var result = Evaluate("google chrome v28", "chrome"); 92 | Assert.That(result.StringParts[0].Value, Is.EqualTo("google ")); 93 | Assert.That(result.StringParts[0].IsMatch, Is.False); 94 | Assert.That(result.StringParts[1].Value, Is.EqualTo("chrome")); 95 | Assert.That(result.StringParts[1].IsMatch, Is.True); 96 | Assert.That(result.StringParts[2].Value, Is.EqualTo(" v28")); 97 | Assert.That(result.StringParts[2].IsMatch, Is.False); 98 | } 99 | 100 | [Test] 101 | public void Evaluate_IgnoresCasing_ReturnsMatchingResult() 102 | { 103 | var result = Evaluate("Google Chrome", "chrome"); 104 | Assert.That(result.Matched, Is.True); 105 | } 106 | 107 | private static MatchResult Evaluate(string input, string pattern) 108 | { 109 | var containsMatcher = new ContainsMatcher(); 110 | return containsMatcher.Evaluate(input, pattern); 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /Core.UnitTests/Core.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CDB9C567-6CFA-4A52-AD14-7DDF82880281} 8 | Library 9 | Properties 10 | Switcheroo.Core.UnitTests 11 | Switcheroo.Core.UnitTests 12 | v4.5 13 | 512 14 | ..\ 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {b846514d-25be-4274-972a-0e6e74dd0f8b} 54 | Core 55 | 56 | 57 | 58 | 59 | 60 | 61 | 68 | -------------------------------------------------------------------------------- /Core.UnitTests/IndividualCharactersMatcherTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Switcheroo.Core.Matchers; 3 | 4 | namespace Switcheroo.Core.UnitTests 5 | { 6 | [TestFixture] 7 | public class IndividualCharactersMatcherTests 8 | { 9 | [Test] 10 | public void Evaluate_InputNull_ReturnsNonMatchingResult() 11 | { 12 | var result = Evaluate(null, "crm"); 13 | Assert.That(result.Matched, Is.False); 14 | } 15 | 16 | [Test] 17 | public void Evaluate_InputNull_ReturnsNoStringParts() 18 | { 19 | var result = Evaluate(null, "crm"); 20 | Assert.That(result.StringParts.Count, Is.EqualTo(0)); 21 | } 22 | 23 | [Test] 24 | public void Evaluate_PatternNull_ReturnsNonMatchingResult() 25 | { 26 | var result = Evaluate("chrome", null); 27 | Assert.That(result.Matched, Is.False); 28 | } 29 | 30 | [Test] 31 | public void Evaluate_PatternNull_ReturnsOneNonMatchingStringPart() 32 | { 33 | var result = Evaluate("chrome", null); 34 | Assert.That(result.StringParts.Count, Is.EqualTo(1)); 35 | Assert.That(result.StringParts[0].Value, Is.EqualTo("chrome")); 36 | } 37 | 38 | [Test] 39 | public void Evaluate_InputContainsCharacter_ReturnsMatchingResult() 40 | { 41 | var result = Evaluate("chrome", "r"); 42 | Assert.That(result.Matched, Is.True); 43 | } 44 | 45 | [Test] 46 | public void Evaluate_InputContainsCharacter_ReturnsCorrectScore() 47 | { 48 | var result = Evaluate("chrome", "r"); 49 | Assert.That(result.Score, Is.EqualTo(1)); 50 | } 51 | 52 | [Test] 53 | public void Evaluate_InputContainsCharacter_ReturnsThreeStringParts() 54 | { 55 | var result = Evaluate("chrome", "r"); 56 | Assert.That(result.StringParts.Count, Is.EqualTo(3)); 57 | Assert.That(result.StringParts[0].Value, Is.EqualTo("ch")); 58 | Assert.That(result.StringParts[1].Value, Is.EqualTo("r")); 59 | Assert.That(result.StringParts[2].Value, Is.EqualTo("ome")); 60 | } 61 | 62 | [Test] 63 | public void Evaluate_InputContainsTwoCharacters_ReturnsFourStringParts() 64 | { 65 | var result = Evaluate("chrome", "re"); 66 | Assert.That(result.StringParts.Count, Is.EqualTo(4)); 67 | Assert.That(result.StringParts[0].Value, Is.EqualTo("ch")); 68 | Assert.That(result.StringParts[1].Value, Is.EqualTo("r")); 69 | Assert.That(result.StringParts[2].Value, Is.EqualTo("om")); 70 | Assert.That(result.StringParts[3].Value, Is.EqualTo("e")); 71 | } 72 | 73 | [Test] 74 | public void Evaluate_InputContainsTwoCharacters2_ReturnsFourStringParts() 75 | { 76 | var result = Evaluate("chrome", "ce"); 77 | Assert.That(result.StringParts.Count, Is.EqualTo(3)); 78 | Assert.That(result.StringParts[0].Value, Is.EqualTo("c")); 79 | Assert.That(result.StringParts[1].Value, Is.EqualTo("hrom")); 80 | Assert.That(result.StringParts[2].Value, Is.EqualTo("e")); 81 | } 82 | 83 | private static MatchResult Evaluate(string input, string pattern) 84 | { 85 | return new IndividualCharactersMatcher().Evaluate(input, pattern); 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /Core.UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | 9 | [assembly: AssemblyTitle("Core.UnitTests")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("Core.UnitTests")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | 22 | [assembly: ComVisible(false)] 23 | 24 | // The following GUID is for the ID of the typelib if this project is exposed to COM 25 | 26 | [assembly: Guid("d2a8e791-8e3e-4925-b0ee-330e14428359")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | // You can specify all the values or you can default the Build and Revision Numbers 36 | // by using the '*' as shown below: 37 | // [assembly: AssemblyVersion("1.0.*")] 38 | 39 | [assembly: AssemblyVersion("1.0.0.0")] 40 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /Core.UnitTests/StartsWithMatcherTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NUnit.Framework; 3 | using Switcheroo.Core.Matchers; 4 | 5 | namespace Switcheroo.Core.UnitTests 6 | { 7 | [TestFixture] 8 | public class StartsWithMatcherTests 9 | { 10 | [Test] 11 | public void Evaluate_InputStartsWithPattern_ResultIsMatched() 12 | { 13 | var input = "google chrome"; 14 | var pattern = "google"; 15 | 16 | var result = Evaluate(input, pattern); 17 | 18 | Assert.That(result.Matched, Is.True); 19 | } 20 | 21 | [Test] 22 | public void Evaluate_InputStartsWithPattern_ScoreIsFour() 23 | { 24 | var input = "google chrome"; 25 | var pattern = "google"; 26 | 27 | var result = Evaluate(input, pattern); 28 | 29 | Assert.That(result.Score, Is.EqualTo(4)); 30 | } 31 | 32 | [Test] 33 | public void Evaluate_InputStartsWithPattern_FirstStringPartIsMatch() 34 | { 35 | var input = "google chrome"; 36 | var pattern = "google"; 37 | 38 | var result = Evaluate(input, pattern); 39 | 40 | Assert.That(result.StringParts.First().Value, Is.EqualTo("google")); 41 | Assert.That(result.StringParts.First().IsMatch, Is.True); 42 | } 43 | 44 | [Test] 45 | public void Evaluate_InputStartsWithPattern_SecondStringPartIsNotMatch() 46 | { 47 | var input = "google chrome"; 48 | var pattern = "google"; 49 | 50 | var result = Evaluate(input, pattern); 51 | 52 | Assert.That(result.StringParts.ToList()[1].Value, Is.EqualTo(" chrome")); 53 | Assert.That(result.StringParts.ToList()[1].IsMatch, Is.False); 54 | } 55 | 56 | [Test] 57 | public void Evaluate_NullInput_ReturnsNotMatchingResult() 58 | { 59 | var result = Evaluate(null, "google"); 60 | Assert.That(result.Matched, Is.False); 61 | } 62 | 63 | [Test] 64 | public void Evaluate_NullPattern_ReturnsNotMatchingResult() 65 | { 66 | var result = Evaluate("google chrome", null); 67 | Assert.That(result.Matched, Is.False); 68 | } 69 | 70 | [Test] 71 | public void Evaluate_NullPattern_ReturnsOneNonMatchingStringPart() 72 | { 73 | var result = Evaluate("google chrome", null); 74 | Assert.That(result.StringParts.Count(), Is.EqualTo(1)); 75 | Assert.That(result.StringParts.First().Value, Is.EqualTo("google chrome")); 76 | Assert.That(result.StringParts.First().IsMatch, Is.False); 77 | } 78 | 79 | [Test] 80 | public void Evaluate_InputContainsPattern_ReturnsNotMatchingResult() 81 | { 82 | var result = Evaluate("google chrome", "chrome"); 83 | Assert.That(result.Matched, Is.False); 84 | } 85 | 86 | [Test] 87 | public void Evaluate_InputContainsPattern_ReturnsOneNonMatchingStringPart() 88 | { 89 | var result = Evaluate("google chrome", "chrome"); 90 | Assert.That(result.StringParts.Count(), Is.EqualTo(1)); 91 | Assert.That(result.StringParts.First().Value, Is.EqualTo("google chrome")); 92 | Assert.That(result.StringParts.First().IsMatch, Is.False); 93 | } 94 | 95 | [Test] 96 | public void Evaluate_InputStartsWithPattern_CasingIsNotChanged() 97 | { 98 | var result = Evaluate("Google Chrome", "google"); 99 | Assert.That(result.StringParts[0].Value, Is.EqualTo("Google")); 100 | Assert.That(result.StringParts[1].Value, Is.EqualTo(" Chrome")); 101 | } 102 | 103 | private static MatchResult Evaluate(string input, string pattern) 104 | { 105 | var matcher = new StartsWithMatcher(); 106 | return matcher.Evaluate(input, pattern); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /Core.UnitTests/XamlHighlighterTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Switcheroo.Core.Matchers; 3 | 4 | namespace Switcheroo.Core.UnitTests 5 | { 6 | [TestFixture] 7 | public class XamlHighlighterTests 8 | { 9 | [Test] 10 | public void DoesItWork() 11 | { 12 | var input = new StringPart("test > test-1", true); 13 | var output = new XamlHighlighter().Highlight(new[] {input, new StringPart("test"),}); 14 | Assert.That(output, Is.EqualTo("test > test-1test")); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Core.UnitTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Core/Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B846514D-25BE-4274-972A-0E6E74DD0F8B} 8 | Library 9 | Properties 10 | Switcheroo.Core 11 | Switcheroo.Core 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | {fbd3ec1e-47e2-4d2d-81c9-d6506125a09a} 69 | ManagedWinapi 70 | 71 | 72 | 73 | 80 | -------------------------------------------------------------------------------- /Core/FilterResult.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Collections.Generic; 22 | using Switcheroo.Core.Matchers; 23 | 24 | namespace Switcheroo.Core 25 | { 26 | public class FilterResult where T : IWindowText 27 | { 28 | public T AppWindow { get; set; } 29 | public IList WindowTitleMatchResults { get; set; } 30 | public IList ProcessTitleMatchResults { get; set; } 31 | } 32 | } -------------------------------------------------------------------------------- /Core/IWindowText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Switcheroo.Core 8 | { 9 | public interface IWindowText 10 | { 11 | string WindowTitle { get; } 12 | string ProcessTitle { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /Core/KeyboardHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.Diagnostics; 23 | using System.Text; 24 | using System.Windows.Forms; 25 | 26 | namespace Switcheroo.Core 27 | { 28 | // Convert a keycode to the relevant display character 29 | // http://stackoverflow.com/a/375047/198065 30 | public class KeyboardHelper 31 | { 32 | public static string CodeToString(uint virtualKey) 33 | { 34 | uint procId; 35 | var thread = WinApi.GetWindowThreadProcessId(Process.GetCurrentProcess().MainWindowHandle, out procId); 36 | var hkl = WinApi.GetKeyboardLayout(thread); 37 | 38 | if (hkl == IntPtr.Zero) 39 | { 40 | return string.Empty; 41 | } 42 | 43 | var keyStates = new Keys[256]; 44 | if (!WinApi.GetKeyboardState(keyStates)) 45 | { 46 | return string.Empty; 47 | } 48 | 49 | var scanCode = WinApi.MapVirtualKeyEx(virtualKey, WinApi.MapVirtualKeyMapTypes.MAPVK_VK_TO_CHAR, hkl); 50 | 51 | var sb = new StringBuilder(10); 52 | var rc = WinApi.ToUnicodeEx(virtualKey, scanCode, new Keys[0], sb, sb.Capacity, 0, hkl); 53 | return sb.ToString(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Core/Matchers/ContainsMatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace Switcheroo.Core.Matchers 4 | { 5 | public class ContainsMatcher : IMatcher 6 | { 7 | public MatchResult Evaluate(string input, string pattern) 8 | { 9 | if (input == null || pattern == null) 10 | { 11 | return NonMatchResult(input); 12 | } 13 | 14 | var match = Regex.Match(input, "(.*)(" + Regex.Escape(pattern) + ")(.*)", RegexOptions.IgnoreCase); 15 | 16 | if (!match.Success) 17 | { 18 | return NonMatchResult(input); 19 | } 20 | 21 | var matchResult = new MatchResult(); 22 | if (match.Groups[1].Length > 0) 23 | { 24 | matchResult.StringParts.Add(new StringPart(match.Groups[1].Value)); 25 | } 26 | 27 | if (match.Groups[2].Length > 0) 28 | { 29 | matchResult.StringParts.Add(new StringPart(match.Groups[2].Value, true)); 30 | } 31 | 32 | if (match.Groups[3].Length > 0) 33 | { 34 | matchResult.StringParts.Add(new StringPart(match.Groups[3].Value)); 35 | } 36 | 37 | matchResult.Matched = true; 38 | matchResult.Score = 2; 39 | 40 | return matchResult; 41 | } 42 | 43 | private static MatchResult NonMatchResult(string input) 44 | { 45 | var matchResult = new MatchResult(); 46 | if (input != null) 47 | { 48 | matchResult.StringParts.Add(new StringPart(input)); 49 | } 50 | return matchResult; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Core/Matchers/IMatcher.cs: -------------------------------------------------------------------------------- 1 | namespace Switcheroo.Core.Matchers 2 | { 3 | public interface IMatcher 4 | { 5 | MatchResult Evaluate(string input, string pattern); 6 | } 7 | } -------------------------------------------------------------------------------- /Core/Matchers/IndividualCharactersMatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace Switcheroo.Core.Matchers 4 | { 5 | public class IndividualCharactersMatcher : IMatcher 6 | { 7 | public MatchResult Evaluate(string input, string pattern) 8 | { 9 | if (input == null || pattern == null) 10 | { 11 | return NonMatchResult(input); 12 | } 13 | 14 | var regexPattern = BuildRegexPattern(pattern); 15 | 16 | var match = Regex.Match(input, regexPattern, RegexOptions.IgnoreCase); 17 | 18 | if (!match.Success) 19 | { 20 | return NonMatchResult(input); 21 | } 22 | 23 | var matchResult = new MatchResult(); 24 | for (var groupIndex = 1; groupIndex < match.Groups.Count; groupIndex++) 25 | { 26 | var group = match.Groups[groupIndex]; 27 | if (group.Value.Length > 0) 28 | { 29 | matchResult.StringParts.Add(new StringPart(group.Value, groupIndex%2 == 0)); 30 | } 31 | } 32 | 33 | matchResult.Matched = true; 34 | matchResult.Score = 1; 35 | 36 | return matchResult; 37 | } 38 | 39 | private static string BuildRegexPattern(string pattern) 40 | { 41 | var regexPattern = ""; 42 | char? previousChar = null; 43 | foreach (var p in pattern) 44 | { 45 | if (previousChar != null) 46 | { 47 | regexPattern += string.Format("([^{0}]*?)({1})", Regex.Escape(previousChar + ""), 48 | Regex.Escape(p + "")); 49 | } 50 | else 51 | { 52 | regexPattern += string.Format("(.*?)({0})", Regex.Escape(p + "")); 53 | } 54 | previousChar = p; 55 | } 56 | return regexPattern + "(.*)"; 57 | } 58 | 59 | private static MatchResult NonMatchResult(string input) 60 | { 61 | var matchResult = new MatchResult(); 62 | if (input != null) 63 | { 64 | matchResult.StringParts.Add(new StringPart(input)); 65 | } 66 | return matchResult; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /Core/Matchers/MatchResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Switcheroo.Core.Matchers 4 | { 5 | public class MatchResult 6 | { 7 | public bool Matched { get; set; } 8 | public int Score { get; set; } 9 | public IList StringParts { get; set; } 10 | 11 | public MatchResult() 12 | { 13 | StringParts = new List(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Core/Matchers/SignificantCharactersMatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace Switcheroo.Core.Matchers 5 | { 6 | public class SignificantCharactersMatcher : IMatcher 7 | { 8 | public MatchResult Evaluate(string input, string pattern) 9 | { 10 | if (input == null || pattern == null) 11 | { 12 | return NonMatchResult(input); 13 | } 14 | 15 | var regexPattern = BuildRegexPattern(pattern); 16 | 17 | var match = Regex.Match(input, regexPattern); 18 | 19 | if (!match.Success) 20 | { 21 | return NonMatchResult(input); 22 | } 23 | 24 | var matchResult = new MatchResult(); 25 | 26 | var beforeMatch = input.Substring(0, match.Index); 27 | matchResult.StringParts.Add(new StringPart(beforeMatch)); 28 | 29 | for (var groupIndex = 1; groupIndex < match.Groups.Count; groupIndex++) 30 | { 31 | var group = match.Groups[groupIndex]; 32 | if (group.Value.Length > 0) 33 | { 34 | matchResult.StringParts.Add(new StringPart(group.Value, groupIndex%2 == 0)); 35 | } 36 | } 37 | 38 | var afterMatch = input.Substring(match.Index + match.Length); 39 | matchResult.StringParts.Add(new StringPart(afterMatch)); 40 | 41 | matchResult.Matched = true; 42 | matchResult.Score = 2; 43 | 44 | return matchResult; 45 | } 46 | 47 | private static string BuildRegexPattern(string pattern) 48 | { 49 | var regexPattern = ""; 50 | foreach (var p in pattern) 51 | { 52 | var lowerP = Char.ToLowerInvariant(p); 53 | var upperP = Char.ToUpperInvariant(p); 54 | regexPattern += string.Format(@"([^\p{{Lu}}\s]*?\s?)(\b{0}|{1})", Regex.Escape(lowerP + ""), 55 | Regex.Escape(upperP + "")); 56 | } 57 | return regexPattern; 58 | } 59 | 60 | private static MatchResult NonMatchResult(string input) 61 | { 62 | var matchResult = new MatchResult(); 63 | if (input != null) 64 | { 65 | matchResult.StringParts.Add(new StringPart(input)); 66 | } 67 | return matchResult; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Core/Matchers/StartsWithMatcher.cs: -------------------------------------------------------------------------------- 1 | namespace Switcheroo.Core.Matchers 2 | { 3 | public class StartsWithMatcher : IMatcher 4 | { 5 | public MatchResult Evaluate(string input, string pattern) 6 | { 7 | var matchResult = new MatchResult(); 8 | 9 | if (input == null) 10 | { 11 | return matchResult; 12 | } 13 | 14 | if (pattern == null) 15 | { 16 | matchResult.StringParts.Add(new StringPart(input)); 17 | return matchResult; 18 | } 19 | 20 | if (!InputStartsWithPattern(input, pattern)) 21 | { 22 | matchResult.StringParts.Add(new StringPart(input)); 23 | return matchResult; 24 | } 25 | 26 | var matchedPart = input.Substring(0, pattern.Length); 27 | var restOfInput = input.Substring(pattern.Length); 28 | 29 | matchResult.Matched = true; 30 | matchResult.Score = 4; 31 | matchResult.StringParts.Add(new StringPart(matchedPart, true)); 32 | matchResult.StringParts.Add(new StringPart(restOfInput, false)); 33 | 34 | return matchResult; 35 | } 36 | 37 | private static bool InputStartsWithPattern(string input, string pattern) 38 | { 39 | return input.ToLowerInvariant().StartsWith(pattern.ToLowerInvariant()); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Core/Matchers/StringPart.cs: -------------------------------------------------------------------------------- 1 | namespace Switcheroo.Core.Matchers 2 | { 3 | public class StringPart 4 | { 5 | public string Value { get; set; } 6 | public bool IsMatch { get; set; } 7 | 8 | public StringPart() 9 | { 10 | } 11 | 12 | public StringPart(string value, bool isMatch = false) 13 | { 14 | Value = value; 15 | IsMatch = isMatch; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("Switcheroo.Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Switcheroo.Core")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | 25 | [assembly: Guid("4af06758-f037-4f41-ae72-7fa3e8137183")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | 38 | [assembly: AssemblyVersion("0.0.0.0")] 39 | [assembly: AssemblyFileVersion("0.0.0.0")] -------------------------------------------------------------------------------- /Core/WindowFilterer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | using Switcheroo.Core.Matchers; 24 | 25 | namespace Switcheroo.Core 26 | { 27 | public class WindowFilterer 28 | { 29 | public IEnumerable> Filter(WindowFilterContext context, string query) where T : IWindowText 30 | { 31 | var filterText = query; 32 | string processFilterText = null; 33 | 34 | var queryParts = query.Split(new [] {'.'}, 2); 35 | 36 | if (queryParts.Length == 2) 37 | { 38 | processFilterText = queryParts[0]; 39 | if (processFilterText.Length == 0) 40 | { 41 | processFilterText = context.ForegroundWindowProcessTitle; 42 | } 43 | 44 | filterText = queryParts[1]; 45 | } 46 | 47 | return context.Windows 48 | .Select( 49 | w => 50 | new 51 | { 52 | Window = w, 53 | ResultsTitle = Score(w.WindowTitle, filterText), 54 | ResultsProcessTitle = Score(w.ProcessTitle, processFilterText ?? filterText) 55 | }) 56 | .Where(r => 57 | { 58 | if (processFilterText == null) 59 | { 60 | return r.ResultsTitle.Any(wt => wt.Matched) || r.ResultsProcessTitle.Any(pt => pt.Matched); 61 | } 62 | return r.ResultsTitle.Any(wt => wt.Matched) && r.ResultsProcessTitle.Any(pt => pt.Matched); 63 | }) 64 | .OrderByDescending(r => r.ResultsTitle.Sum(wt => wt.Score) + r.ResultsProcessTitle.Sum(pt => pt.Score)) 65 | .Select( 66 | r => 67 | new FilterResult 68 | { 69 | AppWindow = r.Window, 70 | WindowTitleMatchResults = r.ResultsTitle, 71 | ProcessTitleMatchResults = r.ResultsProcessTitle 72 | }); 73 | } 74 | 75 | private static List Score(string title, string filterText) 76 | { 77 | var startsWithMatcher = new StartsWithMatcher(); 78 | var containsMatcher = new ContainsMatcher(); 79 | var significantCharactersMatcher = new SignificantCharactersMatcher(); 80 | var individualCharactersMatcher = new IndividualCharactersMatcher(); 81 | 82 | var results = new List 83 | { 84 | startsWithMatcher.Evaluate(title, filterText), 85 | significantCharactersMatcher.Evaluate(title, filterText), 86 | containsMatcher.Evaluate(title, filterText), 87 | individualCharactersMatcher.Evaluate(title, filterText) 88 | }; 89 | 90 | return results; 91 | } 92 | } 93 | 94 | public class WindowFilterContext where T : IWindowText 95 | { 96 | public string ForegroundWindowProcessTitle { get; set; } 97 | public IEnumerable Windows { get; set; } 98 | } 99 | } -------------------------------------------------------------------------------- /Core/WindowFinder.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | 24 | namespace Switcheroo.Core 25 | { 26 | public class WindowFinder 27 | { 28 | public List GetWindows() 29 | { 30 | return AppWindow.AllToplevelWindows 31 | .Where(a => a.IsAltTabWindow()) 32 | .ToList(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Core/WindowIconFinder.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.ComponentModel; 23 | using System.Drawing; 24 | 25 | namespace Switcheroo.Core 26 | { 27 | public enum WindowIconSize 28 | { 29 | Small, 30 | Large 31 | } 32 | 33 | public class WindowIconFinder 34 | { 35 | public Icon Find(AppWindow window, WindowIconSize size) 36 | { 37 | Icon icon = null; 38 | try 39 | { 40 | // http://msdn.microsoft.com/en-us/library/windows/desktop/ms632625(v=vs.85).aspx 41 | IntPtr response; 42 | var outvalue = WinApi.SendMessageTimeout(window.HWnd, 0x007F, 43 | size == WindowIconSize.Small ? new IntPtr(2) : new IntPtr(1), 44 | IntPtr.Zero, WinApi.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 100, out response); 45 | 46 | if (outvalue == IntPtr.Zero || response == IntPtr.Zero) 47 | { 48 | response = WinApi.GetClassLongPtr(window.HWnd, 49 | size == WindowIconSize.Small 50 | ? WinApi.ClassLongFlags.GCLP_HICONSM 51 | : WinApi.ClassLongFlags.GCLP_HICON); 52 | } 53 | 54 | if (response != IntPtr.Zero) 55 | { 56 | icon = Icon.FromHandle(response); 57 | } 58 | else 59 | { 60 | var executablePath = window.ExecutablePath; 61 | icon = Icon.ExtractAssociatedIcon(executablePath); 62 | } 63 | } 64 | catch (Win32Exception) 65 | { 66 | // Could not extract icon 67 | } 68 | return icon; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Core/XamlHighlighter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | using System.Xml.Linq; 24 | using Switcheroo.Core.Matchers; 25 | 26 | namespace Switcheroo.Core 27 | { 28 | public class XamlHighlighter 29 | { 30 | public string Highlight(IEnumerable stringParts) 31 | { 32 | if (stringParts == null) return string.Empty; 33 | 34 | var xDocument = new XDocument(new XElement("Root")); 35 | foreach (var stringPart in stringParts) 36 | { 37 | if (stringPart.IsMatch) 38 | { 39 | xDocument.Root.Add(new XElement("Bold", stringPart.Value)); 40 | } 41 | else 42 | { 43 | xDocument.Root.Add(new XText(stringPart.Value)); 44 | } 45 | } 46 | return string.Join("", xDocument.Root.Nodes().Select(x => x.ToString()).ToArray()); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Installer/Build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\.. 5 | $(SolutionDir)\.build 6 | Rebuild 7 | Release 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Installer/InnoSetup/ISCC.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/ISCC.exe -------------------------------------------------------------------------------- /Installer/InnoSetup/ISCmplr.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/ISCmplr.dll -------------------------------------------------------------------------------- /Installer/InnoSetup/ISPP.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/ISPP.dll -------------------------------------------------------------------------------- /Installer/InnoSetup/Setup.e32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/Setup.e32 -------------------------------------------------------------------------------- /Installer/InnoSetup/SetupLdr.e32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/SetupLdr.e32 -------------------------------------------------------------------------------- /Installer/InnoSetup/WizModernImage-IS.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/WizModernImage-IS.bmp -------------------------------------------------------------------------------- /Installer/InnoSetup/WizModernImage.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/WizModernImage.bmp -------------------------------------------------------------------------------- /Installer/InnoSetup/WizModernSmallImage-IS.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/WizModernSmallImage-IS.bmp -------------------------------------------------------------------------------- /Installer/InnoSetup/WizModernSmallImage.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/WizModernSmallImage.bmp -------------------------------------------------------------------------------- /Installer/InnoSetup/islzma.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/islzma.dll -------------------------------------------------------------------------------- /Installer/InnoSetup/islzma32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/islzma32.exe -------------------------------------------------------------------------------- /Installer/InnoSetup/islzma64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Installer/InnoSetup/islzma64.exe -------------------------------------------------------------------------------- /Installer/InnoSetup/license.txt: -------------------------------------------------------------------------------- 1 | Inno Setup License 2 | ================== 3 | 4 | Except where otherwise noted, all of the documentation and software included 5 | in the Inno Setup package is copyrighted by Jordan Russell. 6 | 7 | Copyright (C) 1997-2013 Jordan Russell. All rights reserved. 8 | Portions Copyright (C) 2000-2013 Martijn Laan. All rights reserved. 9 | 10 | This software is provided "as-is," without any express or implied warranty. 11 | In no event shall the author be held liable for any damages arising from the 12 | use of this software. 13 | 14 | Permission is granted to anyone to use this software for any purpose, 15 | including commercial applications, and to alter and redistribute it, 16 | provided that the following conditions are met: 17 | 18 | 1. All redistributions of source code files must retain all copyright 19 | notices that are currently in place, and this list of conditions without 20 | modification. 21 | 22 | 2. All redistributions in binary form must retain all occurrences of the 23 | above copyright notice and web site addresses that are currently in 24 | place (for example, in the About boxes). 25 | 26 | 3. The origin of this software must not be misrepresented; you must not 27 | claim that you wrote the original software. If you use this software to 28 | distribute a product, an acknowledgment in the product documentation 29 | would be appreciated but is not required. 30 | 31 | 4. Modified versions in source or binary form must be plainly marked as 32 | such, and must not be misrepresented as being the original software. 33 | 34 | 35 | Jordan Russell 36 | jr-2010 AT jrsoftware.org 37 | http://www.jrsoftware.org/ 38 | -------------------------------------------------------------------------------- /Installer/Installer.iss: -------------------------------------------------------------------------------- 1 | #define MyAppName "Switcheroo" 2 | #define MyAppPublisher "Regin Larsen" 3 | #define MyAppURL "http://www.switcheroo.io" 4 | #define MyAppExeName "switcheroo.exe" 5 | #define MyAppPath SourcePath + "ProgramFiles" 6 | #define MyAppVer = GetFileVersion(MyAppPath + "\switcheroo.exe") 7 | 8 | [Setup] 9 | AppId={{A5AF4C34-70A7-4D3B-BA18-E49C0AEEA5E6} 10 | AppMutex=DBDE24E4-91F6-11DF-B495-C536DFD72085-switcheroo 11 | AppName={#MyAppName} 12 | AppVerName={#MyAppName} v{#MyAppVer} 13 | AppPublisher={#MyAppPublisher} 14 | AppPublisherURL={#MyAppURL} 15 | AppSupportURL={#MyAppURL} 16 | AppUpdatesURL={#MyAppURL} 17 | DefaultDirName={pf}\{#MyAppName} 18 | DefaultGroupName={#MyAppName} 19 | OutputBaseFilename=switcheroo-setup 20 | Compression=lzma 21 | SolidCompression=yes 22 | 23 | [Languages] 24 | Name: english; MessagesFile: compiler:Default.isl 25 | 26 | [InstallDelete] 27 | Type: files; Name: "{commonstartup}\{#MyAppName}.lnk" 28 | 29 | [Tasks] 30 | Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked 31 | Name: startupfolder; Description: Startup with Windows 32 | 33 | [Files] 34 | Source: {#MyAppPath}\switcheroo.exe; DestDir: {app}; Flags: ignoreversion 35 | Source: {#MyAppPath}\*.dll; DestDir: {app}; Flags: ignoreversion 36 | Source: {#MyAppPath}\switcheroo.exe.config; DestDir: {app}; Flags: ignoreversion 37 | Source: {#MyAppPath}\LICENSE.txt; DestDir: {app}; Flags: ignoreversion 38 | 39 | [Icons] 40 | Name: {group}\{#MyAppName}; Filename: {app}\{#MyAppExeName} 41 | Name: {group}\{cm:UninstallProgram,{#MyAppName}}; Filename: {uninstallexe} 42 | Name: {userdesktop}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: desktopicon 43 | Name: {userstartup}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: startupfolder 44 | 45 | [Run] 46 | Filename: {app}\{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppName}}; Flags: nowait postinstall skipifsilent 47 | 48 | [Code] 49 | const 50 | 51 | // The following was stolen from the Witty Twitter installer. 52 | // http://code.google.com/p/wittytwitter/source/browse/trunk/Witty/Installer/Installer.iss 53 | 54 | dotnetRedistURL = 'http://www.microsoft.com/en-us/download/details.aspx?id=30653'; 55 | dotnetRegKey = 'SOFTWARE\Microsoft\Net Framework Setup\NDP\v4.0'; 56 | version = '4.5'; 57 | 58 | function InitializeSetup(): Boolean; 59 | var 60 | ErrorCode: Integer; 61 | NetFrameWorkInstalled : Boolean; 62 | InstallDotNetResponse : Boolean; 63 | begin 64 | NetFrameWorkInstalled := RegKeyExists(HKLM,dotnetRegKey); 65 | if NetFrameWorkInstalled =true then 66 | begin 67 | Result := true; 68 | end 69 | else 70 | begin 71 | InstallDotNetResponse := MsgBox('This setup requires version ' + version + ' of the .NET Framework. Please download and install the .NET Framework and run this setup again. Do you want to download the framework now?',mbConfirmation,MB_YESNO)= idYes; 72 | if InstallDotNetResponse =false then 73 | begin 74 | Result:=false; 75 | end 76 | else 77 | begin 78 | Result:=false; 79 | ShellExec('open',dotnetRedistURL,'','',SW_SHOWNORMAL,ewNoWait,ErrorCode); 80 | end; 81 | end; 82 | end; 83 | -------------------------------------------------------------------------------- /ManagedWinapi/ApiHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Text; 23 | using System.ComponentModel; 24 | using System.Runtime.InteropServices; 25 | 26 | namespace ManagedWinapi 27 | { 28 | /// 29 | /// Helper class that contains static methods useful for API programming. This 30 | /// class is not exposed to the user. 31 | /// 32 | internal class ApiHelper 33 | { 34 | /// 35 | /// Throw a if the supplied (return) value is zero. 36 | /// This exception uses the last Win32 error code as error message. 37 | /// 38 | /// The return value to test. 39 | internal static int FailIfZero(int returnValue) 40 | { 41 | if (returnValue == 0) 42 | { 43 | throw new Win32Exception(Marshal.GetLastWin32Error()); 44 | } 45 | return returnValue; 46 | } 47 | 48 | /// 49 | /// Throw a if the supplied (return) value is zero. 50 | /// This exception uses the last Win32 error code as error message. 51 | /// 52 | /// The return value to test. 53 | internal static IntPtr FailIfZero(IntPtr returnValue) 54 | { 55 | if (returnValue == IntPtr.Zero) 56 | { 57 | throw new Win32Exception(Marshal.GetLastWin32Error()); 58 | } 59 | return returnValue; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ManagedWinapi/ClipboardNotifier.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.ComponentModel; 22 | using System.Collections.Generic; 23 | using System.Diagnostics; 24 | using System.Text; 25 | using ManagedWinapi.Windows; 26 | using System.Runtime.InteropServices; 27 | using Microsoft.Win32; 28 | 29 | namespace ManagedWinapi 30 | { 31 | /// 32 | /// Specifies a component that monitors the system clipboard for changes. 33 | /// 34 | [DefaultEvent("ClipboardChanged")] 35 | public class ClipboardNotifier : Component 36 | { 37 | 38 | /// 39 | /// Occurs when the clipboard contents have changed. 40 | /// 41 | public event EventHandler ClipboardChanged; 42 | 43 | private readonly IntPtr hWnd; 44 | private IntPtr nextHWnd; 45 | private readonly EventDispatchingNativeWindow ednw; 46 | 47 | private static Boolean instantiated = false; 48 | 49 | /// 50 | /// Creates a new clipboard notifier. 51 | /// 52 | /// The container. 53 | public ClipboardNotifier(IContainer container) 54 | : this() 55 | { 56 | container.Add(this); 57 | } 58 | 59 | /// 60 | /// Creates a new clipboard notifier. 61 | /// 62 | public ClipboardNotifier() 63 | { 64 | if (instantiated) 65 | { 66 | // use new windows if more than one instance is used. 67 | System.Diagnostics.Debug.WriteLine("WARNING: More than one ClipboardNotifier used!"); 68 | ednw = new EventDispatchingNativeWindow(); 69 | } 70 | else 71 | { 72 | ednw = EventDispatchingNativeWindow.Instance; 73 | instantiated = true; 74 | } 75 | ednw.EventHandler += clipboardEventHandler; 76 | hWnd = ednw.Handle; 77 | nextHWnd = SetClipboardViewer(hWnd); 78 | } 79 | 80 | /// 81 | /// Frees resources. 82 | /// 83 | protected override void Dispose(bool disposing) 84 | { 85 | ChangeClipboardChain(hWnd, nextHWnd); 86 | ednw.EventHandler -= clipboardEventHandler; 87 | base.Dispose(disposing); 88 | } 89 | 90 | void clipboardEventHandler(ref System.Windows.Forms.Message m, ref bool handled) 91 | { 92 | if (handled) return; 93 | if (m.Msg == WM_DRAWCLIPBOARD) 94 | { 95 | // notify me 96 | if (ClipboardChanged != null) 97 | ClipboardChanged(this, EventArgs.Empty); 98 | // pass on message 99 | SendMessage(nextHWnd, m.Msg, m.WParam, m.LParam); 100 | handled = true; 101 | } 102 | else if (m.Msg == WM_CHANGECBCHAIN) 103 | { 104 | if (m.WParam == nextHWnd) 105 | { 106 | nextHWnd = m.LParam; 107 | } 108 | else 109 | { 110 | SendMessage(nextHWnd, m.Msg, m.WParam, m.LParam); 111 | } 112 | } 113 | } 114 | 115 | #region PInvoke Declarations 116 | 117 | [DllImport("User32.dll", CharSet = CharSet.Auto)] 118 | private static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); 119 | 120 | [DllImport("user32.dll")] 121 | private static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); 122 | 123 | [DllImport("user32.dll", CharSet = CharSet.Auto)] 124 | private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); 125 | 126 | private static readonly int 127 | WM_DRAWCLIPBOARD = 0x0308, 128 | WM_CHANGECBCHAIN = 0x030D; 129 | 130 | #endregion 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /ManagedWinapi/Contents/ContentParserRegistry.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace ManagedWinapi.Windows.Contents 24 | { 25 | internal class ContentParserRegistry 26 | { 27 | static ContentParserRegistry instance = null; 28 | 29 | public static ContentParserRegistry Instance 30 | { 31 | get 32 | { 33 | if (instance == null) 34 | instance = new ContentParserRegistry(); 35 | return instance; 36 | } 37 | } 38 | 39 | List parsers = new List(); 40 | 41 | private ContentParserRegistry() 42 | { 43 | parsers.Add(new ComboBoxParser()); 44 | parsers.Add(new ListBoxParser()); 45 | parsers.Add(new TextFieldParser(true)); 46 | parsers.Add(new ListViewParser()); 47 | parsers.Add(new TreeViewParser()); 48 | parsers.Add(new AccessibleWindowParser()); 49 | parsers.Add(new TextFieldParser(false)); 50 | } 51 | 52 | public WindowContentParser GetParser(SystemWindow sw) 53 | { 54 | foreach(WindowContentParser p in parsers) { 55 | if (p.CanParseContent(sw)) 56 | return p; 57 | } 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ManagedWinapi/Contents/TextFieldParser.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace ManagedWinapi.Windows.Contents 24 | { 25 | 26 | /// 27 | /// The content of a text box. 28 | /// 29 | public class TextContent : WindowContent 30 | { 31 | readonly string text; 32 | readonly bool password; 33 | readonly bool strict; 34 | 35 | internal TextContent(string text, bool password, bool strict) 36 | { 37 | this.text = text; 38 | this.password = password; 39 | this.strict = strict; 40 | } 41 | 42 | /// 43 | public string ComponentType 44 | { 45 | get { return strict ? "TextBox" : "Text"; } 46 | } 47 | 48 | /// 49 | public string ShortDescription 50 | { 51 | get 52 | { 53 | string s = strict ? " " : ""; 54 | if (text.IndexOf("\n") != -1) 55 | return "" + s; 56 | else if (password) 57 | return text + " " + s; 58 | else 59 | return text + s; 60 | } 61 | } 62 | 63 | /// 64 | public string LongDescription 65 | { 66 | get 67 | { 68 | if (password) 69 | return text + " "; 70 | else 71 | return text; 72 | } 73 | } 74 | 75 | /// 76 | public Dictionary PropertyList 77 | { 78 | get 79 | { 80 | Dictionary result = new Dictionary(); 81 | result.Add("Password", password ? "True" : "False"); 82 | result.Add("MultiLine", text.IndexOf('\n') != -1 ? "True" : "False"); 83 | result.Add("Text", text); 84 | return result; 85 | } 86 | } 87 | } 88 | 89 | class TextFieldParser : WindowContentParser 90 | { 91 | readonly bool strict; 92 | 93 | public TextFieldParser(bool strict) 94 | { 95 | this.strict = strict; 96 | } 97 | 98 | internal override bool CanParseContent(SystemWindow sw) 99 | { 100 | if (strict) 101 | { 102 | uint EM_GETLINECOUNT = 0xBA; 103 | return sw.SendGetMessage(EM_GETLINECOUNT) != 0; 104 | } 105 | else 106 | { 107 | return sw.Title != ""; 108 | } 109 | } 110 | 111 | internal override WindowContent ParseContent(SystemWindow sw) 112 | { 113 | return new TextContent(sw.Title, sw.PasswordCharacter != 0, strict); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /ManagedWinapi/Contents/WindowContent.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace ManagedWinapi.Windows.Contents 24 | { 25 | /// 26 | /// An abstract representation of the content of a window or control. 27 | /// 28 | public interface WindowContent 29 | { 30 | /// 31 | /// A short description of the type of this window. 32 | /// 33 | string ComponentType { get;} 34 | 35 | /// 36 | /// A short description of this content. 37 | /// 38 | string ShortDescription { get;} 39 | 40 | /// 41 | /// The full description of this content. 42 | /// 43 | string LongDescription { get;} 44 | 45 | /// 46 | /// A list of properties of this content. 47 | /// 48 | Dictionary PropertyList { get;} 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ManagedWinapi/Contents/WindowContentParser.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | 22 | namespace ManagedWinapi.Windows.Contents 23 | { 24 | internal abstract class WindowContentParser 25 | { 26 | internal abstract bool CanParseContent(SystemWindow sw); 27 | internal abstract WindowContent ParseContent(SystemWindow sw); 28 | 29 | internal static WindowContent Parse(SystemWindow sw) 30 | { 31 | WindowContentParser parser = ContentParserRegistry.Instance.GetParser(sw); 32 | if (parser == null) return null; 33 | return parser.ParseContent(sw); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ManagedWinapi/Crosshair.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ManagedWinapi 2 | { 3 | partial class Crosshair 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.dragger = new System.Windows.Forms.PictureBox(); 32 | ((System.ComponentModel.ISupportInitialize)(this.dragger)).BeginInit(); 33 | this.SuspendLayout(); 34 | // 35 | // dragger 36 | // 37 | this.dragger.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; 38 | this.dragger.Cursor = System.Windows.Forms.Cursors.Cross; 39 | this.dragger.Dock = System.Windows.Forms.DockStyle.Fill; 40 | this.dragger.Location = new System.Drawing.Point(0, 0); 41 | this.dragger.Name = "dragger"; 42 | this.dragger.Size = new System.Drawing.Size(36, 36); 43 | this.dragger.TabIndex = 0; 44 | this.dragger.TabStop = false; 45 | this.dragger.MouseDown += new System.Windows.Forms.MouseEventHandler(this.dragger_MouseDown); 46 | this.dragger.MouseMove += new System.Windows.Forms.MouseEventHandler(this.dragger_MouseMove); 47 | this.dragger.MouseUp += new System.Windows.Forms.MouseEventHandler(this.dragger_MouseUp); 48 | // 49 | // Crosshair 50 | // 51 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 52 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 53 | this.Controls.Add(this.dragger); 54 | this.Name = "Crosshair"; 55 | this.Size = new System.Drawing.Size(36, 36); 56 | ((System.ComponentModel.ISupportInitialize)(this.dragger)).EndInit(); 57 | this.ResumeLayout(false); 58 | 59 | } 60 | 61 | #endregion 62 | 63 | private System.Windows.Forms.PictureBox dragger; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ManagedWinapi/Crosshair.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | using System.Runtime.InteropServices; 9 | 10 | namespace ManagedWinapi 11 | { 12 | /// 13 | /// This component displays a crosshair icon that can be dragged to any point 14 | /// on screen. This is useful to select other programs by dragging the crosshair 15 | /// to a program window. 16 | /// 17 | [DefaultEvent("CrosshairDragged")] 18 | public partial class Crosshair : UserControl 19 | { 20 | Image myImage; 21 | Cursor myCursor; 22 | 23 | /// 24 | /// Occurs when the user finished dragging the crosshair. Use 25 | /// to detect the cursor position. 26 | /// 27 | public event EventHandler CrosshairDragged; 28 | 29 | /// 30 | /// Occurs while the user drags the crosshair. Use 31 | /// to detect the cursor position. 32 | /// 33 | public event EventHandler CrosshairDragging; 34 | 35 | /// 36 | /// Creates a new crosshair control. 37 | /// 38 | public Crosshair() 39 | { 40 | InitializeComponent(); 41 | myImage = new Bitmap(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("ManagedWinapi.crosshair.ico")); 42 | myCursor = new Cursor(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("ManagedWinapi.crosshair.ico")); 43 | dragger.Image = myImage; 44 | } 45 | 46 | private void dragger_MouseDown(object sender, MouseEventArgs e) 47 | { 48 | dragger.Image = null; 49 | dragger.Cursor = myCursor; 50 | } 51 | 52 | private void dragger_MouseUp(object sender, MouseEventArgs e) 53 | { 54 | dragger.Image = myImage; 55 | dragger.Cursor = Cursors.Cross; 56 | if (CrosshairDragged != null) 57 | { 58 | CrosshairDragged(this, new EventArgs()); 59 | } 60 | } 61 | 62 | private void dragger_MouseMove(object sender, MouseEventArgs e) 63 | { 64 | if (dragger.Cursor == myCursor) 65 | { 66 | if (CrosshairDragging != null) 67 | { 68 | CrosshairDragging(this, new EventArgs()); 69 | } 70 | } 71 | } 72 | 73 | /// 74 | /// When a window is hidden, the .NET framework releases mouse capture. 75 | /// If you hide your window while the crosshair is dragged, invoke 76 | /// this method afterwards to restore mouse capture. 77 | /// 78 | public void RestoreMouseCapture() 79 | { 80 | dragger.Capture = true; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ManagedWinapi/Crosshair.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ManagedWinapi/EventDispatchingNativeWindow.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Text; 23 | using System.Windows.Forms; 24 | 25 | namespace ManagedWinapi.Windows 26 | { 27 | 28 | /// 29 | /// Called by an EventDispatchingNativeWindow when a window message is received 30 | /// 31 | /// The message to handle. 32 | /// Whether the event has already been handled. If this value is true, the handler 33 | /// should return immediately. It may set the value to true to indicate that no others 34 | /// should handle it. If the event is not handled by any handler, it is passed to the 35 | /// default WindowProc. 36 | public delegate void WndProcEventHandler(ref Message m, ref bool handled); 37 | 38 | /// 39 | /// A Win32 native window that delegates window messages to handlers. So several 40 | /// components can use the same native window to save "USER resources". This class 41 | /// is useful when writing your own components. 42 | /// 43 | public class EventDispatchingNativeWindow : NativeWindow 44 | { 45 | 46 | private static Object myLock = new Object(); 47 | private static EventDispatchingNativeWindow _instance; 48 | 49 | /// 50 | /// A global instance which can be used by components that do not need 51 | /// their own window. 52 | /// 53 | public static EventDispatchingNativeWindow Instance 54 | { 55 | get 56 | { 57 | lock (myLock) 58 | { 59 | if (_instance == null) 60 | _instance = new EventDispatchingNativeWindow(); 61 | return _instance; 62 | } 63 | } 64 | } 65 | 66 | /// 67 | /// Attach your event handlers here. 68 | /// 69 | public event WndProcEventHandler EventHandler; 70 | 71 | /// 72 | /// Create your own event dispatching window. 73 | /// 74 | public EventDispatchingNativeWindow() 75 | { 76 | CreateHandle(new CreateParams()); 77 | } 78 | 79 | /// 80 | /// Parse messages passed to this window and send them to the event handlers. 81 | /// 82 | /// A System.Windows.Forms.Message that is associated with the 83 | /// current Windows message. 84 | protected override void WndProc(ref Message m) 85 | { 86 | bool handled = false; 87 | if (EventHandler != null) 88 | EventHandler(ref m, ref handled); 89 | if (!handled) 90 | base.WndProc(ref m); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ManagedWinapi/InputBlocker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ManagedWinapi 5 | { 6 | /// 7 | /// Blocks keyboard and mouse input until this object is disposed. 8 | /// Unlike , you cannot detect when the systems 9 | /// removes the block (which happens when the user presses CTRL+ALT+DEL), 10 | /// but it works on Windows Vista as well. 11 | /// 12 | public class InputBlocker : IDisposable 13 | { 14 | bool needUnblock; 15 | 16 | /// 17 | /// Blocks keyboard and mouse input until this object is disposed. 18 | /// 19 | public InputBlocker() 20 | { 21 | needUnblock = BlockInput(true); 22 | } 23 | 24 | /// 25 | /// Unblocks keyboard and mouse input. 26 | /// 27 | public void Dispose() 28 | { 29 | if (needUnblock) BlockInput(false); 30 | needUnblock = false; 31 | } 32 | 33 | #region PInvoke Declarations 34 | [DllImport("user32.dll")] 35 | static extern bool BlockInput(bool fBlockIt); 36 | #endregion 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ManagedWinapi/KeyboardKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Windows.Forms; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace ManagedWinapi 7 | { 8 | /// 9 | /// This class contains utility methods related to keys on the keyboard. 10 | /// 11 | public class KeyboardKey 12 | { 13 | readonly Keys key; 14 | readonly bool extended; 15 | 16 | /// 17 | /// Initializes a new instance of this class for a given key. 18 | /// 19 | /// 20 | public KeyboardKey(Keys key) 21 | { 22 | this.key = key; 23 | switch (key) 24 | { 25 | case Keys.Insert: 26 | case Keys.Delete: 27 | case Keys.PageUp: 28 | case Keys.PageDown: 29 | case Keys.Home: 30 | case Keys.End: 31 | case Keys.Up: 32 | case Keys.Down: 33 | case Keys.Left: 34 | case Keys.Right: 35 | this.extended = true; 36 | break; 37 | default: 38 | this.extended = false; 39 | break; 40 | } 41 | } 42 | 43 | /// 44 | /// The state of this key, as seen by this application. 45 | /// 46 | public short State { get { return GetKeyState((short)key); } } 47 | 48 | /// 49 | /// The global state of this key. 50 | /// 51 | public short AsyncState { get { return GetAsyncKeyState((short)key); } } 52 | 53 | /// 54 | /// Press this key and release it. 55 | /// 56 | public void PressAndRelease() 57 | { 58 | Press(); 59 | Release(); 60 | } 61 | 62 | /// 63 | /// Press this key. 64 | /// 65 | public void Press() 66 | { 67 | keybd_event((byte)key, (byte)MapVirtualKey((int)key, 0), extended ? (uint)0x1 : 0x0, UIntPtr.Zero); 68 | } 69 | 70 | /// 71 | /// Release this key. 72 | /// 73 | public void Release() 74 | { 75 | keybd_event((byte)key, (byte)MapVirtualKey((int)key, 0), extended ? (uint)0x3 : 0x2, UIntPtr.Zero); 76 | } 77 | 78 | /// 79 | /// Determine the name of a key in the current keyboard layout. 80 | /// 81 | /// The key's name 82 | public string KeyName 83 | { 84 | get 85 | { 86 | StringBuilder sb = new StringBuilder(512); 87 | int scancode = MapVirtualKey((int)key, 0); 88 | if (extended) 89 | scancode += 0x100; 90 | GetKeyNameText(scancode << 16, sb, sb.Capacity); 91 | if (sb.Length == 0) 92 | { 93 | switch (key) 94 | { 95 | case Keys.BrowserBack: 96 | sb.Append("Back"); 97 | break; 98 | case Keys.BrowserForward: 99 | sb.Append("Forward"); 100 | break; 101 | case (Keys)19: 102 | sb.Append("Break"); 103 | break; 104 | case Keys.Apps: 105 | sb.Append("ContextMenu"); 106 | break; 107 | case Keys.LWin: 108 | case Keys.RWin: 109 | sb.Append("Windows"); 110 | break; 111 | case Keys.PrintScreen: 112 | sb.Append("PrintScreen"); 113 | break; 114 | } 115 | } 116 | return sb.ToString(); 117 | } 118 | } 119 | 120 | /// 121 | /// Inject a keyboard event into the event loop, as if the user performed 122 | /// it with his keyboard. 123 | /// 124 | public static void InjectKeyboardEvent(Keys key, byte scanCode, uint flags, UIntPtr extraInfo) 125 | { 126 | keybd_event((byte)key, scanCode, flags, extraInfo); 127 | } 128 | 129 | /// 130 | /// Inject a mouse event into the event loop, as if the user performed 131 | /// it with his mouse. 132 | /// 133 | public static void InjectMouseEvent(uint flags, uint dx, uint dy, uint data, UIntPtr extraInfo) 134 | { 135 | mouse_event(flags, dx, dy, data, extraInfo); 136 | } 137 | 138 | #region PInvoke Declarations 139 | 140 | [DllImport("user32.dll")] 141 | private static extern short GetKeyState(short nVirtKey); 142 | 143 | [DllImport("user32.dll")] 144 | private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, 145 | UIntPtr dwExtraInfo); 146 | 147 | [DllImport("user32.dll")] 148 | static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, 149 | UIntPtr dwExtraInfo); 150 | 151 | [DllImport("user32.dll")] 152 | static extern int GetKeyNameText(int lParam, [Out] StringBuilder lpString, 153 | int nSize); 154 | 155 | [DllImport("user32.dll")] 156 | static extern int MapVirtualKey(int uCode, int uMapType); 157 | 158 | [DllImport("user32.dll")] 159 | static extern short GetAsyncKeyState(int vKey); 160 | #endregion 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /ManagedWinapi/LockKeyResetter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Text; 23 | using System.Windows.Forms; 24 | using System.Runtime.InteropServices; 25 | 26 | namespace ManagedWinapi 27 | { 28 | /// 29 | /// Utility class that can be used to create key events with all current 30 | /// locking keys (like Caps Lock) disabled. Other modifier keys (like Ctrl or Shift) 31 | /// are also ignored if they are currently pressed on the "real" keyboard. 32 | /// 33 | /// 34 | /// 35 | /// using (new LockKeysResetter()) { 36 | /// SendKeys.Send("Hello"); 37 | /// } 38 | /// 39 | /// 40 | public class LockKeyResetter :IDisposable 41 | { 42 | static readonly Keys[] MODIFIER_KEYS = { 43 | Keys.RShiftKey, Keys.LShiftKey, Keys.ShiftKey, 44 | Keys.RMenu, Keys.LMenu, Keys.Menu, 45 | Keys.RControlKey, Keys.LControlKey, Keys.LMenu, 46 | Keys.RWin, Keys.LWin, Keys.CapsLock 47 | }; 48 | 49 | bool capslock; 50 | bool[] simpleModifiers = new bool[MODIFIER_KEYS.Length]; 51 | 52 | /// 53 | /// Reset all modifier keys and remember in this object which modifier keys 54 | /// have been set. 55 | /// 56 | public LockKeyResetter() 57 | { 58 | for (int i = 0; i < MODIFIER_KEYS.Length; i++) 59 | { 60 | KeyboardKey k = new KeyboardKey(MODIFIER_KEYS[i]); 61 | short dummy = k.AsyncState; // reset remembered status 62 | if (k.AsyncState != 0) 63 | { 64 | simpleModifiers[i] = true; 65 | k.Release(); 66 | } 67 | } 68 | KeyboardKey capslockKey = new KeyboardKey(Keys.CapsLock); 69 | int capslockstate = capslockKey.State; 70 | capslock = ((capslockstate & 0x01) == 0x01); 71 | if (capslock) 72 | { 73 | // press caps lock 74 | capslockKey.PressAndRelease(); 75 | Application.DoEvents(); 76 | if ((capslockKey.State & 0x01) == 0x01) 77 | { 78 | // press shift 79 | new KeyboardKey(Keys.ShiftKey).PressAndRelease(); 80 | } 81 | Application.DoEvents(); 82 | if ((capslockKey.State & 0x01) == 0x01) 83 | { 84 | throw new Exception("Cannot disable caps lock."); 85 | } 86 | } 87 | } 88 | 89 | /// 90 | /// Set all modifier keys that have been set before. Since this class implements 91 | /// , you can use the using 92 | /// keyword in C# to automatically set modifier keys when you have finished. 93 | /// 94 | public void Dispose() 95 | { 96 | if (capslock) { 97 | // press caps lock 98 | KeyboardKey capslockKey = new KeyboardKey(Keys.CapsLock); 99 | capslockKey.PressAndRelease(); 100 | Application.DoEvents(); 101 | if ((capslockKey.State & 0x01) != 0x01) 102 | throw new Exception("Cannot enable caps lock."); 103 | } 104 | for (int i = MODIFIER_KEYS.Length-1; i >= 0; i--) 105 | { 106 | if (simpleModifiers[i]) 107 | { 108 | new KeyboardKey(MODIFIER_KEYS[i]).Press(); 109 | } 110 | } 111 | } 112 | 113 | /// 114 | /// Convenience method to send keys with all modifiers disabled. 115 | /// 116 | /// The keys to send 117 | public static void Send(String keys) 118 | { 119 | using (new LockKeyResetter()) 120 | { 121 | SendKeys.Send(keys); 122 | } 123 | } 124 | 125 | /// 126 | /// Convenience method to send keys and wait for them (like 127 | /// SendKeys.SendWait) with all modifiers disabled. 128 | /// 129 | /// 130 | public static void SendWait(String keys) 131 | { 132 | using (new LockKeyResetter()) 133 | { 134 | SendKeys.SendWait(keys); 135 | } 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /ManagedWinapi/ManagedWinapi.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A} 9 | Library 10 | Properties 11 | ManagedWinapi 12 | ManagedWinapi 13 | 14 | 15 | 16 | 17 | 3.5 18 | v4.5 19 | 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | bin\Debug\ManagedWinapi.XML 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | bin\Release\ 38 | TRACE 39 | prompt 40 | 4 41 | bin\Release\ManagedWinapi.XML 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Component 56 | 57 | 58 | 59 | 60 | 61 | Component 62 | 63 | 64 | 65 | Component 66 | 67 | 68 | 69 | Component 70 | 71 | 72 | 73 | 74 | Component 75 | 76 | 77 | ShortcutBox.cs 78 | 79 | 80 | 81 | 82 | 83 | Component 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | UserControl 92 | 93 | 94 | Crosshair.cs 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | Component 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | Designer 116 | Crosshair.cs 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | Designer 126 | ShortcutBox.cs 127 | 128 | 129 | 130 | 131 | PreserveNewest 132 | 133 | 134 | 135 | 142 | -------------------------------------------------------------------------------- /ManagedWinapi/ManagedWinapiNativeHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/ManagedWinapi/ManagedWinapiNativeHelper.dll -------------------------------------------------------------------------------- /ManagedWinapi/PInvokeTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Drawing; 5 | using System.Runtime.InteropServices; 6 | 7 | // from www.pinvoke.net 8 | namespace ManagedWinapi.Windows 9 | { 10 | 11 | /// 12 | /// Wrapper around the Winapi POINT type. 13 | /// 14 | [StructLayout(LayoutKind.Sequential)] 15 | public struct POINT 16 | { 17 | /// 18 | /// The X Coordinate. 19 | /// 20 | public int X; 21 | 22 | /// 23 | /// The Y Coordinate. 24 | /// 25 | public int Y; 26 | 27 | /// 28 | /// Creates a new POINT. 29 | /// 30 | /// 31 | /// 32 | public POINT(int x, int y) 33 | { 34 | this.X = x; 35 | this.Y = y; 36 | } 37 | 38 | /// 39 | /// Implicit cast. 40 | /// 41 | /// 42 | public static implicit operator System.Drawing.Point(POINT p) 43 | { 44 | return new System.Drawing.Point(p.X, p.Y); 45 | } 46 | 47 | /// 48 | /// Implicit cast. 49 | /// 50 | /// 51 | public static implicit operator POINT(System.Drawing.Point p) 52 | { 53 | return new POINT(p.X, p.Y); 54 | } 55 | } 56 | 57 | /// 58 | /// Wrapper around the Winapi RECT type. 59 | /// 60 | [Serializable, StructLayout(LayoutKind.Sequential)] 61 | public struct RECT 62 | { 63 | /// 64 | /// LEFT 65 | /// 66 | public int Left; 67 | 68 | /// 69 | /// TOP 70 | /// 71 | public int Top; 72 | 73 | /// 74 | /// RIGHT 75 | /// 76 | public int Right; 77 | 78 | /// 79 | /// BOTTOM 80 | /// 81 | public int Bottom; 82 | 83 | /// 84 | /// Creates a new RECT. 85 | /// 86 | public RECT(int left_, int top_, int right_, int bottom_) 87 | { 88 | Left = left_; 89 | Top = top_; 90 | Right = right_; 91 | Bottom = bottom_; 92 | } 93 | 94 | /// 95 | /// HEIGHT 96 | /// 97 | public int Height { get { return Bottom - Top; } } 98 | 99 | /// 100 | /// WIDTH 101 | /// 102 | public int Width { get { return Right - Left; } } 103 | 104 | /// 105 | /// SIZE 106 | /// 107 | public Size Size { get { return new Size(Width, Height); } } 108 | 109 | /// 110 | /// LOCATION 111 | /// 112 | public Point Location { get { return new Point(Left, Top); } } 113 | 114 | // Handy method for converting to a System.Drawing.Rectangle 115 | /// 116 | /// Convert RECT to a Rectangle. 117 | /// 118 | public Rectangle ToRectangle() 119 | { return Rectangle.FromLTRB(Left, Top, Right, Bottom); } 120 | 121 | /// 122 | /// Convert Rectangle to a RECT 123 | /// 124 | public static RECT FromRectangle(Rectangle rectangle) 125 | { 126 | return new RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom); 127 | } 128 | 129 | /// 130 | /// Returns the hash code for this instance. 131 | /// 132 | public override int GetHashCode() 133 | { 134 | return Left ^ ((Top << 13) | (Top >> 0x13)) 135 | ^ ((Width << 0x1a) | (Width >> 6)) 136 | ^ ((Height << 7) | (Height >> 0x19)); 137 | } 138 | 139 | #region Operator overloads 140 | 141 | /// 142 | /// Implicit Cast. 143 | /// 144 | public static implicit operator Rectangle(RECT rect) 145 | { 146 | return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); 147 | } 148 | 149 | /// 150 | /// Implicit Cast. 151 | /// 152 | public static implicit operator RECT(Rectangle rect) 153 | { 154 | return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom); 155 | } 156 | 157 | #endregion 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /ManagedWinapi/PrivilegedActions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace ManagedWinapi 7 | { 8 | /// 9 | /// Collection of miscellaneous actions that cannot be performed as 10 | /// a non-administrative user, like shutdown or setting the system time. 11 | /// 12 | public static class PrivilegedActions 13 | { 14 | /// 15 | /// Shutdown the system. 16 | /// 17 | public static void ShutDown(ShutdownAction action) 18 | { 19 | ShutDown(action, ShutdownForceMode.NoForce); 20 | } 21 | 22 | /// 23 | /// Shutdown the system. 24 | /// 25 | public static void ShutDown(ShutdownAction action, ShutdownForceMode forceMode) 26 | { 27 | ApiHelper.FailIfZero(ExitWindowsEx((uint)action | (uint)forceMode, SHTDN_REASON_FLAG_PLANNED)); 28 | } 29 | 30 | /// 31 | /// Get or set the system time in the local timezone. 32 | /// 33 | public static DateTime LocalTime 34 | { 35 | get 36 | { 37 | SYSTEMTIME st = new SYSTEMTIME(); 38 | ApiHelper.FailIfZero(GetLocalTime(ref st)); 39 | return st.ToDateTime(); 40 | } 41 | 42 | set 43 | { 44 | SYSTEMTIME st = new SYSTEMTIME(value); 45 | // Set it twice due to possible daylight savings change 46 | ApiHelper.FailIfZero(SetLocalTime(ref st)); 47 | ApiHelper.FailIfZero(SetLocalTime(ref st)); 48 | } 49 | } 50 | 51 | /// 52 | /// Get or set the system time, in UTC. 53 | /// 54 | public static DateTime SystemTime 55 | { 56 | get 57 | { 58 | SYSTEMTIME st = new SYSTEMTIME(); 59 | ApiHelper.FailIfZero(GetSystemTime(ref st)); 60 | return st.ToDateTime(); 61 | } 62 | 63 | set 64 | { 65 | SYSTEMTIME st = new SYSTEMTIME(value); 66 | ApiHelper.FailIfZero(SetLocalTime(ref st)); 67 | } 68 | } 69 | 70 | /// 71 | /// Actions that can be performed at shutdown. 72 | /// 73 | public enum ShutdownAction : uint 74 | { 75 | /// 76 | /// Log off the currently logged-on user. 77 | /// 78 | LogOff = 0x00, 79 | 80 | /// 81 | /// Shut down the system. 82 | /// 83 | ShutDown = 0x01, 84 | 85 | /// 86 | /// Reboot the system. 87 | /// 88 | Reboot = 0x02, 89 | 90 | /// 91 | /// Shut down the system and power it off. 92 | /// 93 | PowerOff = 0x08, 94 | 95 | /// 96 | /// Reboot the system and restart applications that are running 97 | /// now and support this feature. 98 | /// 99 | RestartApps = 0x40, 100 | } 101 | 102 | /// 103 | /// Whether shutdown should be forced if an application cancels it 104 | /// or is hung. 105 | /// 106 | public enum ShutdownForceMode : uint 107 | { 108 | /// 109 | /// Do not force shutdown, applications can cancel it. 110 | /// 111 | NoForce = 0x00, 112 | 113 | /// 114 | /// Force shutdown, even if application cancels it or is hung. 115 | /// 116 | Force = 0x04, 117 | 118 | /// 119 | /// Force shutdown if application is hung, but not if it cancels it. 120 | /// 121 | ForceIfHung = 0x10 122 | } 123 | 124 | #region PInvoke Declarations 125 | 126 | [DllImport("user32.dll", SetLastError = true)] 127 | static extern int ExitWindowsEx(uint uFlags, uint dwReason); 128 | 129 | const uint SHTDN_REASON_FLAG_PLANNED = 0x80000000; 130 | 131 | struct SYSTEMTIME 132 | { 133 | internal ushort wYear, wMonth, wDayOfWeek, wDay, 134 | wHour, wMinute, wSecond, wMilliseconds; 135 | 136 | internal SYSTEMTIME(DateTime time) 137 | { 138 | wYear = (ushort)time.Year; 139 | wMonth = (ushort)time.Month; 140 | wDayOfWeek = (ushort)time.DayOfWeek; 141 | wDay = (ushort)time.Day; 142 | wHour = (ushort)time.Hour; 143 | wMinute = (ushort)time.Minute; 144 | wSecond = (ushort)time.Second; 145 | wMilliseconds = (ushort)time.Millisecond; 146 | } 147 | 148 | internal DateTime ToDateTime() 149 | { 150 | return new DateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds); 151 | } 152 | } 153 | 154 | [DllImport("kernel32.dll", SetLastError = true)] 155 | static extern int GetSystemTime(ref SYSTEMTIME lpSystemTime); 156 | 157 | [DllImport("kernel32.dll", SetLastError = true)] 158 | static extern int SetSystemTime(ref SYSTEMTIME lpSystemTime); 159 | 160 | [DllImport("kernel32.dll", SetLastError = true)] 161 | static extern int GetLocalTime(ref SYSTEMTIME lpSystemTime); 162 | 163 | [DllImport("kernel32.dll", SetLastError = true)] 164 | static extern int SetLocalTime(ref SYSTEMTIME lpSystemTime); 165 | 166 | #endregion 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /ManagedWinapi/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ManagedWinapi")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ManagedWinapi")] 13 | [assembly: AssemblyCopyright("Copyright © 2005, 2006, 2007, 2008 Michael Schierl")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ae6cf5e3-0fe3-4222-aaac-b4a98b42aeb5")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("0.3")] 35 | [assembly: AssemblyFileVersion("0.3")] 36 | -------------------------------------------------------------------------------- /ManagedWinapi/SendKeysEscaper.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/ManagedWinapi/SendKeysEscaper.cs -------------------------------------------------------------------------------- /ManagedWinapi/SystemListBox.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Text; 22 | using System.Runtime.InteropServices; 23 | 24 | namespace ManagedWinapi.Windows 25 | { 26 | /// 27 | /// Any list box, including those from other applications. 28 | /// 29 | public class SystemListBox 30 | { 31 | /// 32 | /// Get a SystemListBox reference from a SystemWindow (which is a list box) 33 | /// 34 | public static SystemListBox FromSystemWindow(SystemWindow sw) 35 | { 36 | if (sw.SendGetMessage(LB_GETCOUNT) == 0) return null; 37 | return new SystemListBox(sw); 38 | } 39 | 40 | private SystemWindow sw; 41 | 42 | private SystemListBox(SystemWindow sw) 43 | { 44 | this.sw = sw; 45 | } 46 | 47 | /// 48 | /// The SystemWindow instance that represents this list box. 49 | /// 50 | public SystemWindow SystemWindow 51 | { 52 | get { return sw; } 53 | } 54 | 55 | /// 56 | /// The number of elements in this list box. 57 | /// 58 | public int Count 59 | { 60 | get 61 | { 62 | return sw.SendGetMessage(LB_GETCOUNT); 63 | } 64 | } 65 | 66 | /// 67 | /// The index of the selected element in this list box. 68 | /// 69 | public int SelectedIndex 70 | { 71 | get 72 | { 73 | return sw.SendGetMessage(LB_GETCURSEL); 74 | } 75 | } 76 | 77 | /// 78 | /// The selected element in this list box. 79 | /// 80 | public string SelectedItem 81 | { 82 | get 83 | { 84 | int idx = SelectedIndex; 85 | if (idx == -1) return null; 86 | return this[idx]; 87 | } 88 | } 89 | 90 | /// 91 | /// Get an element of this list box by index. 92 | /// 93 | public string this[int index] 94 | { 95 | get 96 | { 97 | if (index < 0 || index >= Count) 98 | { 99 | throw new ArgumentException("Argument out of range"); 100 | } 101 | int length = sw.SendGetMessage(LB_GETTEXTLEN, (uint)index); 102 | StringBuilder sb = new StringBuilder(length); 103 | SystemWindow.SendMessage(new HandleRef(this, sw.HWnd), LB_GETTEXT, new IntPtr(index), sb); 104 | return sb.ToString(); 105 | 106 | } 107 | } 108 | 109 | #region PInvoke Declarations 110 | 111 | private static readonly uint LB_GETTEXT = 0x189, 112 | LB_GETTEXTLEN = 0x18A, 113 | // LB_GETSEL = 0x187, 114 | LB_GETCURSEL = 0x188, 115 | // LB_GETSELCOUNT = 0x190, 116 | // LB_GETSELITEMS = 0x191, 117 | LB_GETCOUNT = 0x18B; 118 | #endregion 119 | } 120 | 121 | /// 122 | /// Any combo box, including those from other applications. 123 | /// 124 | public class SystemComboBox 125 | { 126 | /// 127 | /// Get a SystemComboBox reference from a SystemWindow (which is a combo box) 128 | /// 129 | public static SystemComboBox FromSystemWindow(SystemWindow sw) 130 | { 131 | if (sw.SendGetMessage(CB_GETCOUNT) == 0) return null; 132 | return new SystemComboBox(sw); 133 | } 134 | 135 | SystemWindow sw; 136 | 137 | private SystemComboBox(SystemWindow sw) 138 | { 139 | this.sw = sw; 140 | } 141 | 142 | /// 143 | /// The SystemWindow instance that represents this combo box. 144 | /// 145 | public SystemWindow SystemWindow 146 | { 147 | get { return sw; } 148 | } 149 | 150 | /// 151 | /// The number of elements in this combo box. 152 | /// 153 | public int Count 154 | { 155 | get 156 | { 157 | return sw.SendGetMessage(CB_GETCOUNT); 158 | } 159 | } 160 | 161 | /// 162 | /// Gets an element by index. 163 | /// 164 | public string this[int index] 165 | { 166 | get 167 | { 168 | if (index < 0 || index >= Count) 169 | { 170 | throw new ArgumentException("Argument out of range"); 171 | } 172 | int length = sw.SendGetMessage(CB_GETLBTEXTLEN, (uint)index); 173 | StringBuilder sb = new StringBuilder(length); 174 | SystemWindow.SendMessage(new HandleRef(this, sw.HWnd), CB_GETLBTEXT, new IntPtr(index), sb); 175 | return sb.ToString(); 176 | 177 | } 178 | } 179 | 180 | #region PInvoke Declarations 181 | 182 | private static readonly uint CB_GETCOUNT = 0x146, 183 | CB_GETLBTEXT = 0x148, 184 | CB_GETLBTEXTLEN = 0x149; 185 | 186 | #endregion 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /ManagedWinapi/SystemTreeView.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ManagedWinapi - A collection of .NET components that wrap PInvoke calls to 3 | * access native API by managed code. http://mwinapi.sourceforge.net/ 4 | * Copyright (C) 2006 Michael Schierl 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; see the file COPYING. if not, visit 17 | * http://www.gnu.org/licenses/lgpl.html or write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Text; 23 | using System.Windows.Forms; 24 | using System.Runtime.InteropServices; 25 | using System.Drawing; 26 | 27 | namespace ManagedWinapi.Windows 28 | { 29 | /// 30 | /// Any tree view, including those from other applications. 31 | /// 32 | public class SystemTreeView 33 | { 34 | /// 35 | /// Get a SystemTreeView reference from a SystemWindow (which is a tree view) 36 | /// 37 | public static SystemTreeView FromSystemWindow(SystemWindow sw) 38 | { 39 | if (sw.SendGetMessage(TVM_GETCOUNT) == 0) return null; 40 | return new SystemTreeView(sw); 41 | } 42 | 43 | internal readonly SystemWindow sw; 44 | 45 | private SystemTreeView(SystemWindow sw) 46 | { 47 | this.sw = sw; 48 | } 49 | 50 | /// 51 | /// The number of items (icons) in this tree view. 52 | /// 53 | public int Count 54 | { 55 | get 56 | { 57 | return sw.SendGetMessage(TVM_GETCOUNT); 58 | } 59 | } 60 | 61 | /// 62 | /// The root items of this tree view. 63 | /// 64 | public SystemTreeViewItem[] Roots 65 | { 66 | get 67 | { 68 | return FindSubItems(sw, IntPtr.Zero); 69 | } 70 | } 71 | 72 | internal static SystemTreeViewItem[] FindSubItems(SystemWindow sw, IntPtr hParent) 73 | { 74 | List result = new List(); 75 | IntPtr hChild; 76 | HandleRef hr = new HandleRef(sw, sw.HWnd); 77 | if (hParent == IntPtr.Zero) 78 | { 79 | hChild = SystemWindow.SendMessage(hr, TVM_GETNEXTITEM, new IntPtr(TVGN_ROOT), IntPtr.Zero); 80 | } 81 | else 82 | { 83 | hChild = SystemWindow.SendMessage(hr, TVM_GETNEXTITEM, new IntPtr(TVGN_CHILD), hParent); 84 | } 85 | while (hChild != IntPtr.Zero) 86 | { 87 | result.Add(new SystemTreeViewItem(sw, hChild)); 88 | hChild = SystemWindow.SendMessage(hr, TVM_GETNEXTITEM, new IntPtr(TVGN_NEXT), hChild); 89 | } 90 | return result.ToArray(); 91 | } 92 | 93 | 94 | #region PInvoke Declarations 95 | 96 | private static readonly uint TVM_GETCOUNT = 0x1100 + 5, 97 | TVM_GETNEXTITEM = 0x1100 + 10, TVGN_ROOT = 0, 98 | TVGN_NEXT = 1, TVGN_CHILD = 4; 99 | 100 | #endregion 101 | } 102 | 103 | /// 104 | /// An item of a tree view. 105 | /// 106 | public class SystemTreeViewItem 107 | { 108 | readonly IntPtr handle; 109 | readonly SystemWindow sw; 110 | 111 | internal SystemTreeViewItem(SystemWindow sw, IntPtr handle) 112 | { 113 | this.sw = sw; 114 | this.handle = handle; 115 | } 116 | 117 | /// 118 | /// The title of that item. 119 | /// 120 | public string Title 121 | { 122 | get 123 | { 124 | ProcessMemoryChunk tc = ProcessMemoryChunk.Alloc(sw.Process, 2001); 125 | TVITEM tvi = new TVITEM(); 126 | tvi.hItem = handle; 127 | tvi.mask = TVIF_TEXT; 128 | tvi.cchTextMax = 2000; 129 | tvi.pszText = tc.Location; 130 | ProcessMemoryChunk ic = ProcessMemoryChunk.AllocStruct(sw.Process, tvi); 131 | SystemWindow.SendMessage(new HandleRef(sw, sw.HWnd), TVM_GETITEM, IntPtr.Zero, ic.Location); 132 | tvi = (TVITEM)ic.ReadToStructure(0, typeof(TVITEM)); 133 | if (tvi.pszText != tc.Location) MessageBox.Show(tvi.pszText + " != " + tc.Location); 134 | string result = Encoding.Default.GetString(tc.Read()); 135 | if (result.IndexOf('\0') != -1) result = result.Substring(0, result.IndexOf('\0')); 136 | ic.Dispose(); 137 | tc.Dispose(); 138 | return result; 139 | } 140 | } 141 | 142 | /// 143 | /// All child items of that item. 144 | /// 145 | public SystemTreeViewItem[] Children 146 | { 147 | get { return SystemTreeView.FindSubItems(sw, handle); } 148 | } 149 | 150 | #region PInvoke Declarations 151 | 152 | private static readonly uint TVM_GETITEM = 0x1100 + 12, TVIF_TEXT = 1; 153 | 154 | [StructLayout(LayoutKind.Sequential)] 155 | private struct TVITEM 156 | { 157 | public UInt32 mask; 158 | public IntPtr hItem; 159 | public UInt32 state; 160 | public UInt32 stateMask; 161 | public IntPtr pszText; 162 | public Int32 cchTextMax; 163 | public Int32 iImage; 164 | public Int32 iSelectedImage; 165 | public Int32 cChildren; 166 | public IntPtr lParam; 167 | } 168 | #endregion 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /ManagedWinapi/crosshair.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/ManagedWinapi/crosshair.cur -------------------------------------------------------------------------------- /ManagedWinapi/crosshair.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/ManagedWinapi/crosshair.ico -------------------------------------------------------------------------------- /Switcheroo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Switcheroo", "Switcheroo\Switcheroo.csproj", "{B28E183B-0E38-48A8-8A4E-B4AB7B23CE93}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A} = {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A} 9 | EndProjectSection 10 | EndProject 11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedWinapi", "ManagedWinapi\ManagedWinapi.csproj", "{FBD3EC1E-47E2-4D2D-81C9-D6506125A09A}" 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{B846514D-25BE-4274-972A-0E6E74DD0F8B}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.UnitTests", "Core.UnitTests\Core.UnitTests.csproj", "{CDB9C567-6CFA-4A52-AD14-7DDF82880281}" 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".build", ".build", "{F5126702-2DD8-4A5F-8410-7327D583747C}" 18 | ProjectSection(SolutionItems) = preProject 19 | Build.proj = Build.proj 20 | .build\MSBuild.Community.Tasks.dll = .build\MSBuild.Community.Tasks.dll 21 | .build\MSBuild.Community.Tasks.targets = .build\MSBuild.Community.Tasks.targets 22 | EndProjectSection 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {B28E183B-0E38-48A8-8A4E-B4AB7B23CE93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {B28E183B-0E38-48A8-8A4E-B4AB7B23CE93}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {B28E183B-0E38-48A8-8A4E-B4AB7B23CE93}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {B28E183B-0E38-48A8-8A4E-B4AB7B23CE93}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {FBD3EC1E-47E2-4D2D-81C9-D6506125A09A}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {B846514D-25BE-4274-972A-0E6E74DD0F8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {B846514D-25BE-4274-972A-0E6E74DD0F8B}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {B846514D-25BE-4274-972A-0E6E74DD0F8B}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {B846514D-25BE-4274-972A-0E6E74DD0F8B}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {CDB9C567-6CFA-4A52-AD14-7DDF82880281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {CDB9C567-6CFA-4A52-AD14-7DDF82880281}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {CDB9C567-6CFA-4A52-AD14-7DDF82880281}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {CDB9C567-6CFA-4A52-AD14-7DDF82880281}.Release|Any CPU.Build.0 = Release|Any CPU 46 | EndGlobalSection 47 | GlobalSection(SolutionProperties) = preSolution 48 | HideSolutionNode = FALSE 49 | EndGlobalSection 50 | EndGlobal 51 | -------------------------------------------------------------------------------- /Switcheroo/AboutWindow.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | Switcheroo 14 | 15 | The humble incremental-search task switcher for Windows 16 | 17 | www.switcheroo.io 18 | 19 | 20 | Version: 21 | 22 | 23 | © Copyright 2014 Regin Larsen 24 | 25 | © Copyright 2009, 2010 James Sulak 26 | 27 | 28 | Switcheroo is free software: you can redistribute it and/or modify 29 | it under the terms of the GNU General Public License as published by 30 | the Free Software Foundation, either version 3 of the License, or 31 | (at your option) any later version. 32 | 33 | 34 | Switcheroo is distributed in the hope that it will be useful, 35 | but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 | GNU General Public License for more details. 38 | 39 | 40 | You should have received a copy of the GNU General Public License 41 | along with Switcheroo. If not, see 42 | www.gnu.org/licenses/ 43 | 44 | 45 | Switcheroo makes use of these great open source projects: 46 | 47 | 48 | Managed Windows API 49 | 50 | Copyright © 2006 Michael Schier 51 | 52 | GNU Lesser General Public License (LGPL) 53 | mwinapi.sourceforge.net 54 | 55 | 56 | PortableSettingsProvider 57 | 58 | Copyright © crdx 59 | 60 | The MIT License (MIT) 61 | 62 | 64 | github.com/crdx/PortableSettingsProvider 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Switcheroo/AboutWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Reflection; 22 | using System.Windows; 23 | using System.Diagnostics; 24 | using System.Windows.Documents; 25 | 26 | namespace Switcheroo 27 | { 28 | public partial class AboutWindow : Window 29 | { 30 | public AboutWindow() 31 | { 32 | InitializeComponent(); 33 | VersionNumber.Inlines.Add(Assembly.GetEntryAssembly().GetName().Version.ToString()); 34 | } 35 | 36 | private void HandleRequestNavigate(object sender, RoutedEventArgs e) 37 | { 38 | var hyperlink = e.OriginalSource as Hyperlink; 39 | if (hyperlink == null) return; 40 | 41 | var navigateUri = hyperlink.NavigateUri.ToString(); 42 | Process.Start(new ProcessStartInfo(navigateUri)); 43 | e.Handled = true; 44 | } 45 | 46 | private void Ok_Click(object sender, RoutedEventArgs e) 47 | { 48 | Close(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Switcheroo/AltTabHook.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.Diagnostics; 23 | using System.Windows.Forms; 24 | using ManagedWinapi; 25 | using ManagedWinapi.Hooks; 26 | 27 | namespace Switcheroo 28 | { 29 | public delegate void AltTabHookEventHandler(object sender, AltTabHookEventArgs args); 30 | 31 | public class AltTabHookEventArgs : EventArgs 32 | { 33 | public bool CtrlDown { get; set; } 34 | public bool ShiftDown { get; set; } 35 | public bool Handled { get; set; } 36 | } 37 | 38 | public class AltTabHook : IDisposable 39 | { 40 | public event AltTabHookEventHandler Pressed; 41 | private const int AltKey = 32; 42 | private const int CtrlKey = 11; 43 | private readonly KeyboardKey _shiftKey = new KeyboardKey(Keys.LShiftKey); 44 | private readonly KeyboardKey _ctrlKey = new KeyboardKey(Keys.LControlKey); 45 | private readonly KeyboardKey _altKey = new KeyboardKey(Keys.LMenu); 46 | private readonly int WM_KEYDOWN = 0x0100; 47 | private readonly int WM_SYSKEYDOWN = 0x0104; 48 | 49 | // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable 50 | private readonly LowLevelKeyboardHook _lowLevelKeyboardHook; 51 | 52 | public AltTabHook() 53 | { 54 | _lowLevelKeyboardHook = new LowLevelKeyboardHook(); 55 | _lowLevelKeyboardHook.MessageIntercepted += OnMessageIntercepted; 56 | _lowLevelKeyboardHook.StartHook(); 57 | } 58 | 59 | private void OnMessageIntercepted(LowLevelMessage lowLevelMessage, ref bool handled) 60 | { 61 | var keyboardMessage = lowLevelMessage as LowLevelKeyboardMessage; 62 | if (handled || keyboardMessage == null) 63 | { 64 | return; 65 | } 66 | 67 | if (!IsTabKeyDown(keyboardMessage)) 68 | { 69 | return; 70 | } 71 | 72 | if (!IsKeyDown(_altKey)) 73 | { 74 | return; 75 | } 76 | 77 | var shiftKeyDown = IsKeyDown(_shiftKey); 78 | var ctrlKeyDown = IsKeyDown(_ctrlKey); 79 | 80 | var eventArgs = OnPressed(shiftKeyDown, ctrlKeyDown); 81 | 82 | handled = eventArgs.Handled; 83 | } 84 | 85 | private static bool IsKeyDown(KeyboardKey keyboardKey) 86 | { 87 | return (keyboardKey.AsyncState & 32768) != 0; 88 | } 89 | 90 | private bool IsTabKeyDown(LowLevelKeyboardMessage keyboardMessage) 91 | { 92 | return keyboardMessage.VirtualKeyCode == (int) Keys.Tab && 93 | (keyboardMessage.Message == WM_KEYDOWN || keyboardMessage.Message == WM_SYSKEYDOWN); 94 | } 95 | 96 | private AltTabHookEventArgs OnPressed(bool shiftDown, bool ctrlDown) 97 | { 98 | var altTabHookEventArgs = new AltTabHookEventArgs { ShiftDown = shiftDown, CtrlDown = ctrlDown }; 99 | var handler = Pressed; 100 | if (handler != null) 101 | { 102 | handler(this, altTabHookEventArgs); 103 | } 104 | return altTabHookEventArgs; 105 | } 106 | 107 | public void Dispose() 108 | { 109 | if (_lowLevelKeyboardHook != null) 110 | { 111 | _lowLevelKeyboardHook.Dispose(); 112 | } 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /Switcheroo/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Switcheroo/App.xaml.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Windows; 22 | 23 | namespace Switcheroo 24 | { 25 | /// 26 | /// Interaction logic for App.xaml 27 | /// 28 | public partial class App : Application 29 | { 30 | } 31 | } -------------------------------------------------------------------------------- /Switcheroo/AppWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Switcheroo.Core; 9 | 10 | namespace Switcheroo 11 | { 12 | public class AppWindowViewModel : INotifyPropertyChanged, IWindowText 13 | { 14 | public AppWindowViewModel(AppWindow appWindow) 15 | { 16 | AppWindow = appWindow; 17 | } 18 | 19 | public AppWindow AppWindow { get; private set; } 20 | 21 | #region IWindowText Members 22 | 23 | public string WindowTitle 24 | { 25 | get { return AppWindow.Title; } 26 | } 27 | 28 | public string ProcessTitle 29 | { 30 | get { return AppWindow.ProcessTitle; } 31 | } 32 | 33 | #endregion 34 | 35 | #region Bindable properties 36 | 37 | public IntPtr HWnd 38 | { 39 | get { return AppWindow.HWnd; } 40 | } 41 | 42 | private string _formattedTitle; 43 | 44 | public string FormattedTitle 45 | { 46 | get { return _formattedTitle; } 47 | set 48 | { 49 | _formattedTitle = value; 50 | NotifyOfPropertyChange(() => FormattedTitle); 51 | } 52 | } 53 | 54 | private string _formattedProcessTitle; 55 | 56 | public string FormattedProcessTitle 57 | { 58 | get { return _formattedProcessTitle; } 59 | set 60 | { 61 | _formattedProcessTitle = value; 62 | NotifyOfPropertyChange(() => FormattedProcessTitle); 63 | } 64 | } 65 | 66 | private bool _isBeingClosed = false; 67 | 68 | public bool IsBeingClosed 69 | { 70 | get { return _isBeingClosed; } 71 | set 72 | { 73 | _isBeingClosed = value; 74 | NotifyOfPropertyChange(() => IsBeingClosed); 75 | } 76 | } 77 | 78 | #endregion 79 | 80 | #region INotifyPropertyChanged Members 81 | 82 | public event PropertyChangedEventHandler PropertyChanged; 83 | 84 | private void NotifyOfPropertyChange(Expression> property) 85 | { 86 | var handler = PropertyChanged; 87 | if (handler != null) 88 | handler(this, new PropertyChangedEventArgs(GetPropertyName(property))); 89 | } 90 | 91 | private string GetPropertyName(Expression> property) 92 | { 93 | var lambda = (LambdaExpression) property; 94 | 95 | MemberExpression memberExpression; 96 | if (lambda.Body is UnaryExpression) 97 | { 98 | var unaryExpression = (UnaryExpression) lambda.Body; 99 | memberExpression = (MemberExpression) unaryExpression.Operand; 100 | } 101 | else 102 | { 103 | memberExpression = (MemberExpression) lambda.Body; 104 | } 105 | 106 | return memberExpression.Member.Name; 107 | } 108 | 109 | #endregion 110 | } 111 | } -------------------------------------------------------------------------------- /Switcheroo/AutoStart.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.IO; 23 | using System.Reflection; 24 | using System.Runtime.InteropServices; 25 | 26 | namespace Switcheroo 27 | { 28 | // Create a shortcut file in the current users start up folder 29 | // Based on this answer on Stackoverflow: 30 | // http://stackoverflow.com/a/19914018/198065 31 | public class AutoStart 32 | { 33 | public bool IsEnabled 34 | { 35 | get { return HasShortcut(); } 36 | 37 | set 38 | { 39 | var appLink = GetAppLinkPath(); 40 | 41 | if (value) 42 | { 43 | CreateShortcut(appLink); 44 | } 45 | else if (IsEnabled) 46 | { 47 | DeleteShortcut(appLink); 48 | } 49 | } 50 | } 51 | 52 | private static bool HasShortcut() 53 | { 54 | try 55 | { 56 | return File.Exists(GetAppLinkPath()); 57 | } 58 | catch 59 | { 60 | return false; 61 | } 62 | } 63 | 64 | private static string GetAppLinkPath() 65 | { 66 | var appDataStart = 67 | Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 68 | @"Microsoft\Windows\Start Menu\Programs\Startup"); 69 | var appLink = Path.Combine(appDataStart, "Switcheroo.lnk"); 70 | return appLink; 71 | } 72 | 73 | private static void DeleteShortcut(string appLink) 74 | { 75 | try 76 | { 77 | File.Delete(appLink); 78 | } 79 | catch 80 | { 81 | throw new AutoStartException( 82 | "It was not possible to delete the shortcut to Switcheroo in the startup folder"); 83 | } 84 | } 85 | 86 | private static void CreateShortcut(string appLink) 87 | { 88 | try 89 | { 90 | var exeLocation = Assembly.GetEntryAssembly().Location; 91 | 92 | //Windows Script Host Shell Object 93 | var t = Type.GetTypeFromCLSID(new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")); 94 | dynamic shell = Activator.CreateInstance(t); 95 | try 96 | { 97 | var lnk = shell.CreateShortcut(appLink); 98 | try 99 | { 100 | lnk.TargetPath = exeLocation; 101 | lnk.Save(); 102 | } 103 | finally 104 | { 105 | Marshal.FinalReleaseComObject(lnk); 106 | } 107 | } 108 | finally 109 | { 110 | Marshal.FinalReleaseComObject(shell); 111 | } 112 | } 113 | catch 114 | { 115 | throw new AutoStartException( 116 | "It was not possible to create a shortcut to Switcheroo in the startup folder"); 117 | } 118 | } 119 | } 120 | 121 | public class AutoStartException : Exception 122 | { 123 | public AutoStartException(string message) 124 | : base(message) 125 | { 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /Switcheroo/BoolToWhateverConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Data; 7 | using System.Windows.Media; 8 | 9 | namespace Switcheroo 10 | { 11 | public class BoolConverter : IValueConverter 12 | { 13 | public T IfTrue { get; set; } 14 | public T IfFalse { get; set; } 15 | 16 | #region IValueConverter Members 17 | 18 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 19 | { 20 | return ((bool) value) ? IfTrue : IfFalse; 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, 24 | System.Globalization.CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | 29 | #endregion 30 | } 31 | 32 | 33 | public class BoolToDoubleConverter : BoolConverter 34 | { 35 | } 36 | 37 | public class BoolToColorConverter : BoolConverter 38 | { 39 | } 40 | } -------------------------------------------------------------------------------- /Switcheroo/FormattedTextAttribute.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Windows; 22 | using System.Windows.Controls; 23 | using System.Windows.Documents; 24 | using System.Windows.Markup; 25 | 26 | namespace Switcheroo 27 | { 28 | public class FormattedTextAttribute 29 | { 30 | public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached( 31 | "FormattedText", 32 | typeof (string), 33 | typeof (FormattedTextAttribute), 34 | new UIPropertyMetadata("", FormattedTextChanged)); 35 | 36 | public static void SetFormattedText(DependencyObject textBlock, string value) 37 | { 38 | textBlock.SetValue(FormattedTextProperty, value); 39 | } 40 | 41 | public static string GetFormattedText(DependencyObject textBlock) 42 | { 43 | return (string) textBlock.GetValue(FormattedTextProperty); 44 | } 45 | 46 | private static void FormattedTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 47 | { 48 | var textBlock = d as TextBlock; 49 | if (textBlock == null) 50 | { 51 | return; 52 | } 53 | 54 | var formattedText = (string) e.NewValue ?? string.Empty; 55 | formattedText = 56 | @"" + 57 | formattedText + 58 | ""; 59 | 60 | textBlock.Inlines.Clear(); 61 | var result = (Span) XamlReader.Parse(formattedText); 62 | textBlock.Inlines.Add(result); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Switcheroo/HotKey.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | namespace Switcheroo 22 | { 23 | public class HotKey : ManagedWinapi.Hotkey 24 | { 25 | public void LoadSettings() 26 | { 27 | KeyCode = (System.Windows.Forms.Keys) Properties.Settings.Default.HotKey; 28 | WindowsKey = Properties.Settings.Default.WindowsKey; 29 | Alt = Properties.Settings.Default.Alt; 30 | Ctrl = Properties.Settings.Default.Ctrl; 31 | Shift = Properties.Settings.Default.Shift; 32 | } 33 | 34 | public void SaveSettings() 35 | { 36 | Properties.Settings.Default.HotKey = (int) KeyCode; 37 | Properties.Settings.Default.WindowsKey = WindowsKey; 38 | Properties.Settings.Default.Alt = Alt; 39 | Properties.Settings.Default.Ctrl = Ctrl; 40 | Properties.Settings.Default.Shift = Shift; 41 | Properties.Settings.Default.Save(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Switcheroo/IconToBitmapConverter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System.Drawing; 22 | using System.Drawing.Imaging; 23 | using System.IO; 24 | using System.Windows.Media.Imaging; 25 | 26 | namespace Switcheroo 27 | { 28 | public class IconToBitmapImageConverter 29 | { 30 | public BitmapImage Convert(Icon icon) 31 | { 32 | if (icon == null) 33 | { 34 | return null; 35 | } 36 | 37 | using (var memory = new MemoryStream()) 38 | { 39 | var bitmap = icon.ToBitmap(); 40 | bitmap.Save(memory, ImageFormat.Png); 41 | memory.Position = 0; 42 | var bitmapImage = new BitmapImage(); 43 | bitmapImage.BeginInit(); 44 | bitmapImage.StreamSource = memory; 45 | bitmapImage.CacheOption = BitmapCacheOption.OnLoad; 46 | bitmapImage.EndInit(); 47 | return bitmapImage; 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Switcheroo/OptionsWindow.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Activate Switcheroo with this shortcut: 15 | 21 | Activate Switcheroo with Alt+Tab 22 | 23 | Use Switcheroo instead of the integrated task switcher in Windows. 24 | 25 | Automatically switch window when releasing Alt + Tab 26 | 27 | Faster and more native-like swiching between windows. 28 | 29 | Use Ctrl + Alt + Tab for displaying Switcheroo with search activated, or 30 | press Alt + Q when the Switcheroo overlay appears. 31 | 32 | 33 | 34 | This is needed if you want Alt + Tab to work when programs 35 | running with higher privileges than your user account are in focus. 36 | 37 | * Requires a restart of Switcheroo 38 | 39 | 40 | Theme 41 | 42 | 43 | Light 44 | Dark 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Switcheroo/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.Configuration; 23 | using System.Diagnostics; 24 | using System.Reflection; 25 | using System.Security.Principal; 26 | using System.Threading; 27 | using Switcheroo.Properties; 28 | 29 | namespace Switcheroo 30 | { 31 | internal class Program 32 | { 33 | private const string mutex_id = "DBDE24E4-91F6-11DF-B495-C536DFD72085-switcheroo"; 34 | 35 | [STAThread] 36 | private static void Main() 37 | { 38 | RunAsAdministratorIfConfigured(); 39 | 40 | using (var mutex = new Mutex(false, mutex_id)) 41 | { 42 | var hasHandle = false; 43 | try 44 | { 45 | try 46 | { 47 | hasHandle = mutex.WaitOne(5000, false); 48 | if (hasHandle == false) return; //another instance exist 49 | } 50 | catch (AbandonedMutexException) 51 | { 52 | // Log the fact the mutex was abandoned in another process, it will still get aquired 53 | } 54 | 55 | #if PORTABLE 56 | MakePortable(Settings.Default); 57 | #endif 58 | 59 | MigrateUserSettings(); 60 | 61 | var app = new App 62 | { 63 | MainWindow = new MainWindow() 64 | }; 65 | app.Run(); 66 | } 67 | finally 68 | { 69 | if (hasHandle) 70 | mutex.ReleaseMutex(); 71 | } 72 | } 73 | } 74 | 75 | private static void RunAsAdministratorIfConfigured() 76 | { 77 | if (RunAsAdminRequested() && !IsRunAsAdmin()) 78 | { 79 | ProcessStartInfo proc = new ProcessStartInfo 80 | { 81 | UseShellExecute = true, 82 | WorkingDirectory = Environment.CurrentDirectory, 83 | FileName = Assembly.GetEntryAssembly().CodeBase, 84 | Verb = "runas" 85 | }; 86 | 87 | Process.Start(proc); 88 | Environment.Exit(0); 89 | } 90 | } 91 | 92 | private static bool RunAsAdminRequested() 93 | { 94 | return Settings.Default.RunAsAdmin; 95 | } 96 | 97 | private static void MakePortable(ApplicationSettingsBase settings) 98 | { 99 | var portableSettingsProvider = new PortableSettingsProvider(); 100 | settings.Providers.Add(portableSettingsProvider); 101 | foreach (SettingsProperty prop in settings.Properties) 102 | { 103 | prop.Provider = portableSettingsProvider; 104 | } 105 | settings.Reload(); 106 | } 107 | 108 | private static void MigrateUserSettings() 109 | { 110 | if (!Settings.Default.FirstRun) return; 111 | 112 | Settings.Default.Upgrade(); 113 | Settings.Default.FirstRun = false; 114 | Settings.Default.Save(); 115 | } 116 | 117 | private static bool IsRunAsAdmin() 118 | { 119 | WindowsIdentity id = WindowsIdentity.GetCurrent(); 120 | WindowsPrincipal principal = new WindowsPrincipal(id); 121 | 122 | return principal.IsInRole(WindowsBuiltInRole.Administrator); 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /Switcheroo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using System.Windows; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | 9 | [assembly: AssemblyTitle("Switcheroo")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("Switcheroo")] 14 | [assembly: AssemblyCopyright("Copyright © 2009, 2010, 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | 55 | [assembly: AssemblyVersion("0.0.0.0")] 56 | [assembly: AssemblyFileVersion("0.0.0.0")] -------------------------------------------------------------------------------- /Switcheroo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34011 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Switcheroo.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Switcheroo.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 65 | /// 66 | internal static System.Drawing.Icon icon { 67 | get { 68 | object obj = ResourceManager.GetObject("icon", resourceCulture); 69 | return ((System.Drawing.Icon)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Switcheroo/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | -------------------------------------------------------------------------------- /Switcheroo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Switcheroo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 29 | public bool Ctrl { 30 | get { 31 | return ((bool)(this["Ctrl"])); 32 | } 33 | set { 34 | this["Ctrl"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 41 | public bool Shift { 42 | get { 43 | return ((bool)(this["Shift"])); 44 | } 45 | set { 46 | this["Shift"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 53 | public bool WindowsKey { 54 | get { 55 | return ((bool)(this["WindowsKey"])); 56 | } 57 | set { 58 | this["WindowsKey"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("32")] 65 | public int HotKey { 66 | get { 67 | return ((int)(this["HotKey"])); 68 | } 69 | set { 70 | this["HotKey"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 77 | public bool Alt { 78 | get { 79 | return ((bool)(this["Alt"])); 80 | } 81 | set { 82 | this["Alt"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 89 | public bool FirstRun { 90 | get { 91 | return ((bool)(this["FirstRun"])); 92 | } 93 | set { 94 | this["FirstRun"] = value; 95 | } 96 | } 97 | 98 | [global::System.Configuration.UserScopedSettingAttribute()] 99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 100 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 101 | public bool AltTabHook { 102 | get { 103 | return ((bool)(this["AltTabHook"])); 104 | } 105 | set { 106 | this["AltTabHook"] = value; 107 | } 108 | } 109 | 110 | [global::System.Configuration.UserScopedSettingAttribute()] 111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 112 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 113 | public bool RunAsAdmin { 114 | get { 115 | return ((bool)(this["RunAsAdmin"])); 116 | } 117 | set { 118 | this["RunAsAdmin"] = value; 119 | } 120 | } 121 | 122 | [global::System.Configuration.UserScopedSettingAttribute()] 123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 124 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 125 | public bool AutoSwitch { 126 | get { 127 | return ((bool)(this["AutoSwitch"])); 128 | } 129 | set { 130 | this["AutoSwitch"] = value; 131 | } 132 | } 133 | 134 | [global::System.Configuration.UserScopedSettingAttribute()] 135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 136 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 137 | public bool EnableHotKey { 138 | get { 139 | return ((bool)(this["EnableHotKey"])); 140 | } 141 | set { 142 | this["EnableHotKey"] = value; 143 | } 144 | } 145 | 146 | [global::System.Configuration.UserScopedSettingAttribute()] 147 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 148 | [global::System.Configuration.DefaultSettingValueAttribute("Light")] 149 | public string Theme 150 | { 151 | set 152 | { 153 | this["Theme"] = value; 154 | Switcheroo.Theme.LoadTheme(); 155 | } 156 | get 157 | { 158 | return ((string)(this["Theme"])); 159 | } 160 | 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /Switcheroo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | False 10 | 11 | 12 | False 13 | 14 | 15 | 32 16 | 17 | 18 | True 19 | 20 | 21 | True 22 | 23 | 24 | False 25 | 26 | 27 | False 28 | 29 | 30 | False 31 | 32 | 33 | True 34 | 35 | 36 | -------------------------------------------------------------------------------- /Switcheroo/Theme.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Media; 8 | using Switcheroo.Properties; 9 | 10 | namespace Switcheroo 11 | { 12 | public static class Theme 13 | { 14 | private static SolidColorBrush Background; 15 | private static SolidColorBrush Foreground; 16 | private static MainWindow mainWindow; 17 | 18 | private enum Mode 19 | { 20 | Light, 21 | Dark 22 | } 23 | 24 | public static void SuscribeWindow(MainWindow main) 25 | { 26 | mainWindow = main; 27 | } 28 | 29 | public static void LoadTheme() 30 | { 31 | Mode mode; 32 | Enum.TryParse(Settings.Default.Theme, out mode); 33 | switch (mode) 34 | { 35 | case Mode.Light: 36 | Background = new SolidColorBrush(Color.FromRgb(248, 248, 248)); 37 | Foreground = new SolidColorBrush(Color.FromRgb(0,0,0)); 38 | break; 39 | case Mode.Dark: 40 | Background = new SolidColorBrush(Color.FromRgb(30, 30, 30)); 41 | Foreground = new SolidColorBrush(Color.FromRgb(248, 248, 248)); 42 | break; 43 | default: 44 | throw new ArgumentOutOfRangeException(nameof(mode), mode, null); 45 | } 46 | 47 | SetUpTheme(); 48 | } 49 | 50 | private static void SetUpTheme() 51 | { 52 | mainWindow.Border.Background = 53 | mainWindow.tb.Background = mainWindow.lb.Background 54 | = mainWindow.Border.BorderBrush = Background; 55 | 56 | mainWindow.tb.Foreground = mainWindow.lb.Foreground = Foreground; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Switcheroo/WindowCloser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Switcheroo 5 | { 6 | public class WindowCloser : IDisposable 7 | { 8 | private bool _isDisposed; 9 | 10 | private static readonly TimeSpan CheckInterval = TimeSpan.FromMilliseconds(125); 11 | 12 | public async Task TryCloseAsync(AppWindowViewModel window) 13 | { 14 | window.IsBeingClosed = true; 15 | window.AppWindow.Close(); 16 | 17 | while (!_isDisposed && !window.AppWindow.IsClosedOrHidden) 18 | await Task.Delay(CheckInterval).ConfigureAwait(false); 19 | 20 | return window.AppWindow.IsClosedOrHidden; 21 | } 22 | 23 | public void Dispose() 24 | { 25 | _isDisposed = true; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Switcheroo/WindowHandleToCachedIconConverter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.Globalization; 23 | using System.Runtime.Caching; 24 | using System.Windows.Data; 25 | using System.Windows.Media.Imaging; 26 | 27 | namespace Switcheroo 28 | { 29 | public class WindowHandleToCachedIconConverter : IValueConverter 30 | { 31 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 32 | { 33 | var key = "IconImage-" + value + "-longCache"; 34 | return MemoryCache.Default.Get(key) as BitmapImage; 35 | } 36 | 37 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 38 | { 39 | throw new NotImplementedException(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Switcheroo/WindowHandleToIconConverter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Switcheroo - The incremental-search task switcher for Windows. 3 | * http://www.switcheroo.io/ 4 | * Copyright 2009, 2010 James Sulak 5 | * Copyright 2014 Regin Larsen 6 | * 7 | * Switcheroo is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Switcheroo is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Switcheroo. If not, see . 19 | */ 20 | 21 | using System; 22 | using System.Globalization; 23 | using System.Runtime.Caching; 24 | using System.Windows.Data; 25 | using System.Windows.Media.Imaging; 26 | using Microsoft.Win32; 27 | using Switcheroo.Core; 28 | 29 | namespace Switcheroo 30 | { 31 | public class WindowHandleToIconConverter : IValueConverter 32 | { 33 | private readonly IconToBitmapImageConverter _iconToBitmapConverter; 34 | 35 | public WindowHandleToIconConverter() 36 | { 37 | _iconToBitmapConverter = new IconToBitmapImageConverter(); 38 | } 39 | 40 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 41 | { 42 | var handle = (IntPtr) value; 43 | var key = "IconImage-" + handle; 44 | var shortCacheKey = key + "-shortCache"; 45 | var longCacheKey = key + "-longCache"; 46 | var iconImage = MemoryCache.Default.Get(shortCacheKey) as BitmapImage; 47 | if (iconImage == null) 48 | { 49 | var window = new AppWindow(handle); 50 | var icon = ShouldUseSmallTaskbarIcons() ? window.SmallWindowIcon : window.LargeWindowIcon; 51 | iconImage = _iconToBitmapConverter.Convert(icon) ?? new BitmapImage(); 52 | MemoryCache.Default.Set(shortCacheKey, iconImage, DateTimeOffset.Now.AddSeconds(5)); 53 | MemoryCache.Default.Set(longCacheKey, iconImage, DateTimeOffset.Now.AddMinutes(120)); 54 | } 55 | return iconImage; 56 | } 57 | 58 | private static bool ShouldUseSmallTaskbarIcons() 59 | { 60 | var cacheKey = "SmallTaskbarIcons"; 61 | 62 | var cachedSetting = MemoryCache.Default.Get(cacheKey) as bool?; 63 | if (cachedSetting != null) 64 | { 65 | return cachedSetting.Value; 66 | } 67 | 68 | using ( 69 | var registryKey = 70 | Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced")) 71 | { 72 | if (registryKey == null) 73 | { 74 | return false; 75 | } 76 | 77 | var value = registryKey.GetValue("TaskbarSmallIcons"); 78 | if (value == null) 79 | { 80 | return false; 81 | } 82 | 83 | int intValue; 84 | int.TryParse(value.ToString(), out intValue); 85 | var smallTaskbarIcons = intValue == 1; 86 | MemoryCache.Default.Set(cacheKey, smallTaskbarIcons, DateTimeOffset.Now.AddMinutes(120)); 87 | return smallTaskbarIcons; 88 | } 89 | } 90 | 91 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 92 | { 93 | throw new NotImplementedException(); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Switcheroo/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 |
10 | 11 | 12 | 13 | 14 | 15 | False 16 | 17 | 18 | False 19 | 20 | 21 | False 22 | 23 | 24 | 32 25 | 26 | 27 | True 28 | 29 | 30 | True 31 | 32 | 33 | False 34 | 35 | 36 | False 37 | 38 | 39 | False 40 | 41 | 42 | True 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Switcheroo/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/Switcheroo/icon.ico -------------------------------------------------------------------------------- /Switcheroo/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | Change log 2 | ---------- 3 | ### 2015-04-28: v0.9.0 ### 4 | - Much improved window closing: Switcheroo now stays open, so you can close several windows faster. Thanks to @HellBrick for proposing this idea and sending a pull request! :+1: (#25) 5 | - The focused window is now at the bottom of the list. This makes it faster to switch to the next window as you just need to press Alt+Enter, Enter. No more need to press Arrow Down. This makes Alt+Enter and Alt+Tab work in the same way (#24) 6 | - Add help information to Switcheroo. Features should be more easily discoverable. Just click the question mark in the overlay (#32) 7 | - Add Ctrl+W as a shortcut to close a window. This shortcut fells more intuitive than Ctrl+Enter (#22) 8 | - Allow using Tab and Shift+Tab to navigate the window list (#31) 9 | - Small look and feel adjustments. More prettiness! (#30) 10 | - Deactivate the System Menu for Switcheroo. Because it often gets accidentally activated when using the default Alt+Tab shortcut (#29) 11 | - Key presses in Switcheroo can be sent to other windows. Key presses are now contained within Switcheroo (#34) 12 | - Fix Switcheroo window turning black on activate/dismiss (#30) 13 | - More work around missing Alt+Tab windows. No windows should be forgotten (#36) 14 | - Fix missing scrollbar if list is taller than screen (#37) 15 | - More compatible way of closing windows (#42) 16 | 17 | ### 2015-01-15: v0.8.3 ### 18 | - Crashes on launch in Windows 10 or when .NET 4.6 Preview is installed (#20) 19 | 20 | ### 2014-10-15: v0.8.2 ### 21 | - Use icons from the taskbar (#19) 22 | 23 | ### 2014-10-15: v0.8.1 ### 24 | - Fix crash when opening the Options window while the hotkey is already in use (#18) 25 | 26 | ### 2014-09-03: v0.8.0 ### 27 | - Activate Switcheroo instead of the native task switcher with Alt+Tab [You need to enable this feature under Options] (#16) 28 | - Option whether to start Switcheroo automatically on startup or not (#3) 29 | - Ensure that the input field has a minimum width (#1) 30 | - Remember key bindings and other settings when upgrading (#14) 31 | - The Windows included are closer to those in the native Alt+Tab task switcher (#17) 32 | 33 | ### 2014-04-18: v0.7.3 ### 34 | - Portable version of Switcheroo (#10) 35 | - Icons are now shown for admin processes as well (#11) 36 | - Decrease flickering when closing a window with CTRL+Enter (#12) 37 | 38 | ### 2014-03-04: v0.7.2 ### 39 | - New Switcheroo icon 40 | - Allow circling in the window list (@ovesen) 41 | - Align filtering and highlighting algorithms 42 | - Fix crash when pressing key up or down while the window list is empty (@ovesen) 43 | - Fix potential crash in update check 44 | 45 | ### 2014-01-30: v0.7.1 ### 46 | - Fix crash if process icon could not be found 47 | 48 | ### 2014-01-24: v0.7 ### 49 | - Faster load time and filtering 50 | - Grabs focus right away 51 | - Highlights matching characters 52 | - Included windows should be closer to the default alt+tab 53 | - Informs you when a new version of Switcheroo is available 54 | - Requires .NET 4.5 55 | 56 | ### 2014-01-13: v0.6 ### 57 | - Development continued by Regin Larsen 58 | - Shows process icon and process title in addition to window title 59 | - No window chrome 60 | - Simple scoring algorithm when filtering 61 | - Support for ReSharper like filtering, e.g. hc for HipChat 62 | - New default key binding `Alt + Space` (Windows 8 is using `Win + W`) 63 | 64 | ### 2010-07-18: v0.5 ### 65 | - Hotkey now hides Switcheroo window in addition to showing it (Issue 4) 66 | - Double-clicking on item now activates that window (Issue 4) 67 | - Added mutex to ensure only one instance is running 68 | - Attempted bugfix of Windows 7 64-bit window-switching bug (Issue 3). 69 | 70 | ### 2010-05-03: v0.4.1 ### 71 | - Long windows titles are now truncated. 72 | 73 | ### 2010-02-07: v0.4 ### 74 | - Window now resizes to match height and width of all entries 75 | - Window exception list is now user-editable. 76 | - Tested on 32-bit Windows 7. 77 | 78 | ### 2009-11-09: v0.3 ### 79 | - Added ctrl-enter functionality. 80 | - Mostly migrated to using the Managed Windows API instead of custom window class. 81 | 82 | ### 2009-11-01: v0.2 ### 83 | 84 | ### 2009-10-11: v0.1 ### 85 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/logo.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Switcheroo Switcheroo + mods 2 | ========== 3 | 4 | This is my modded version of [Switcheroo](https://github.com/kvakulo/Switcheroo) branched after the maintainer became unresponsive. 5 | It is distributed as-is with no warranty or guarantees whatsoever. Your patches are welcome. 6 | 7 | Download 8 | -------- 9 | 10 | Grab the binaries **[here](https://github.com/elig0n/Switcheroo/releases)** 11 | 12 | Custom Features 13 | ------- 14 | - *Numerical quick access* - Alt+digit for easy switching to any of the first 10 applications (also hinted on-screen). 15 | - *Light/Dark Theme* 16 | - *Sort* list by process name or title via tray icon menu or shortcut keys in-live list 17 | - *Tray* icon single click open, extended context menu actions. 18 | - Windows list context menu *actions*: close, run, clone instance (duplicate), bring to front 19 | - Home/End/PageUp/PageDown *keys* navigation in the list 20 | - VIM-like navigation *keys* Alt+j Alt+k. Alt+Up/down is working now too for when you opened the application with alt+ shortcut pressed down. 21 | - Export list to JSON 22 | 23 | *Planned:* 24 | ------- 25 | - Performance improvements 26 | - Code cleaning and refactoring, 27 | - Custom hotkeys configuration 28 | 29 | Shortcuts 30 | ----- 31 | 32 | Action | Shortcut | Remarks 33 | ------------------------------ | --------------- | ---------- 34 | Activate Switcheroo | `Alt + Space` | This shortcut can be customized in _Options_ 35 | Activate Switcheroo | `Alt + Tab` | Only works if enabled under _Options_ 36 | _When Switcheroo is open_ | | 37 | Switch to selected window | `Enter`,`Alt` | 38 | Select next/previous | `Tab`/`Shift + Tab`, `Alt + J`/`Alt + K` | 39 | Selection jumps | `Home`, `End`, `PageUp`, `PageDown`| First, Last, Page up, Page down 40 | Switch to n-th window | `Alt + 1..0` | For first ten on the list. 0 for tenth. 41 | Close selected window | `Ctrl + W`,`Alt + X`| 42 | Options | `Alt + O` | 43 | Toggle sort by process name | `Alt + S` | 44 | Dismiss Switcheroo | `Esc` | 45 | 46 | Discord 47 | ------ 48 | Please join our [Discord channel](https://discord.gg/8zMj7fz) for further discussions. 49 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elig0n/Switcheroo/9480df9a8e13be2e103ef34d02a610849095b0bf/screenshot.png --------------------------------------------------------------------------------