├── .gitignore ├── 486 Breakout └── README.md ├── ConsoleEx ├── ConsoleEx.sln ├── ConsoleEx │ ├── ConsoleEnumerations.cs │ ├── ConsoleEx.cs │ ├── ConsoleLib.csproj │ ├── InputBuffer.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ScreenBuffer.cs │ ├── TerminalEmulator.cs │ ├── TerminalInputBuffer.cs │ ├── TerminalScreenBuffer.cs │ └── WinAPI.cs └── ConsoleTest │ ├── App.config │ ├── ConsoleTest.csproj │ ├── Program.cs │ └── Properties │ └── AssemblyInfo.cs ├── Enum.h ├── LICENSE ├── README.md └── SlowCapture ├── README.md ├── SlowCapture.sln └── SlowCapture ├── App.config ├── CaptureOptions.Designer.cs ├── CaptureOptions.cs ├── CaptureOptions.resx ├── ExternalAPI.cs ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── SettingOptions.Designer.cs ├── SettingOptions.cs ├── SettingOptions.resx ├── SlowCapture.csproj └── tortoise.ico /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.pch 68 | *.pdb 69 | *.pgc 70 | *.pgd 71 | *.rsp 72 | *.sbr 73 | *.tlb 74 | *.tli 75 | *.tlh 76 | *.tmp 77 | *.tmp_proj 78 | *.log 79 | *.vspscc 80 | *.vssscc 81 | .builds 82 | *.pidb 83 | *.svclog 84 | *.scc 85 | 86 | # Chutzpah Test files 87 | _Chutzpah* 88 | 89 | # Visual C++ cache files 90 | ipch/ 91 | *.aps 92 | *.ncb 93 | *.opendb 94 | *.opensdf 95 | *.sdf 96 | *.cachefile 97 | *.VC.db 98 | *.VC.VC.opendb 99 | 100 | # Visual Studio profiler 101 | *.psess 102 | *.vsp 103 | *.vspx 104 | *.sap 105 | 106 | # Visual Studio Trace Files 107 | *.e2e 108 | 109 | # TFS 2012 Local Workspace 110 | $tf/ 111 | 112 | # Guidance Automation Toolkit 113 | *.gpState 114 | 115 | # ReSharper is a .NET coding add-in 116 | _ReSharper*/ 117 | *.[Rr]e[Ss]harper 118 | *.DotSettings.user 119 | 120 | # JustCode is a .NET coding add-in 121 | .JustCode 122 | 123 | # TeamCity is a build add-in 124 | _TeamCity* 125 | 126 | # DotCover is a Code Coverage Tool 127 | *.dotCover 128 | 129 | # AxoCover is a Code Coverage Tool 130 | .axoCover/* 131 | !.axoCover/settings.json 132 | 133 | # Visual Studio code coverage results 134 | *.coverage 135 | *.coveragexml 136 | 137 | # NCrunch 138 | _NCrunch_* 139 | .*crunch*.local.xml 140 | nCrunchTemp_* 141 | 142 | # MightyMoose 143 | *.mm.* 144 | AutoTest.Net/ 145 | 146 | # Web workbench (sass) 147 | .sass-cache/ 148 | 149 | # Installshield output folder 150 | [Ee]xpress/ 151 | 152 | # DocProject is a documentation generator add-in 153 | DocProject/buildhelp/ 154 | DocProject/Help/*.HxT 155 | DocProject/Help/*.HxC 156 | DocProject/Help/*.hhc 157 | DocProject/Help/*.hhk 158 | DocProject/Help/*.hhp 159 | DocProject/Help/Html2 160 | DocProject/Help/html 161 | 162 | # Click-Once directory 163 | publish/ 164 | 165 | # Publish Web Output 166 | *.[Pp]ublish.xml 167 | *.azurePubxml 168 | # Note: Comment the next line if you want to checkin your web deploy settings, 169 | # but database connection strings (with potential passwords) will be unencrypted 170 | *.pubxml 171 | *.publishproj 172 | 173 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 174 | # checkin your Azure Web App publish settings, but sensitive information contained 175 | # in these scripts will be unencrypted 176 | PublishScripts/ 177 | 178 | # NuGet Packages 179 | *.nupkg 180 | # The packages folder can be ignored because of Package Restore 181 | **/[Pp]ackages/* 182 | # except build/, which is used as an MSBuild target. 183 | !**/[Pp]ackages/build/ 184 | # Uncomment if necessary however generally it will be regenerated when needed 185 | #!**/[Pp]ackages/repositories.config 186 | # NuGet v3's project.json files produces more ignorable files 187 | *.nuget.props 188 | *.nuget.targets 189 | 190 | # Microsoft Azure Build Output 191 | csx/ 192 | *.build.csdef 193 | 194 | # Microsoft Azure Emulator 195 | ecf/ 196 | rcf/ 197 | 198 | # Windows Store app package directories and files 199 | AppPackages/ 200 | BundleArtifacts/ 201 | Package.StoreAssociation.xml 202 | _pkginfo.txt 203 | *.appx 204 | 205 | # Visual Studio cache files 206 | # files ending in .cache can be ignored 207 | *.[Cc]ache 208 | # but keep track of directories ending in .cache 209 | !*.[Cc]ache/ 210 | 211 | # Others 212 | ClientBin/ 213 | ~$* 214 | *~ 215 | *.dbmdl 216 | *.dbproj.schemaview 217 | *.jfm 218 | *.pfx 219 | *.publishsettings 220 | orleans.codegen.cs 221 | 222 | # Including strong name files can present a security risk 223 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 224 | #*.snk 225 | 226 | # Since there are multiple workflows, uncomment next line to ignore bower_components 227 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 228 | #bower_components/ 229 | 230 | # RIA/Silverlight projects 231 | Generated_Code/ 232 | 233 | # Backup & report files from converting an old project file 234 | # to a newer Visual Studio version. Backup files are not needed, 235 | # because we have git ;-) 236 | _UpgradeReport_Files/ 237 | Backup*/ 238 | UpgradeLog*.XML 239 | UpgradeLog*.htm 240 | ServiceFabricBackup/ 241 | *-bak 242 | 243 | # SQL Server files 244 | *.mdf 245 | *.ldf 246 | *.ndf 247 | 248 | # Business Intelligence projects 249 | *.rdl.data 250 | *.bim.layout 251 | *.bim_*.settings 252 | 253 | # Microsoft Fakes 254 | FakesAssemblies/ 255 | 256 | # GhostDoc plugin setting file 257 | *.GhostDoc.xml 258 | 259 | # Node.js Tools for Visual Studio 260 | .ntvs_analysis.dat 261 | node_modules/ 262 | 263 | # Visual Studio 6 build log 264 | *.plg 265 | 266 | # Visual Studio 6 workspace options file 267 | *.opt 268 | 269 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 270 | *.vbw 271 | 272 | # Visual Studio LightSwitch build output 273 | **/*.HTMLClient/GeneratedArtifacts 274 | **/*.DesktopClient/GeneratedArtifacts 275 | **/*.DesktopClient/ModelManifest.xml 276 | **/*.Server/GeneratedArtifacts 277 | **/*.Server/ModelManifest.xml 278 | _Pvt_Extensions 279 | 280 | # Paket dependency manager 281 | .paket/paket.exe 282 | paket-files/ 283 | 284 | # FAKE - F# Make 285 | .fake/ 286 | 287 | # JetBrains Rider 288 | .idea/ 289 | *.sln.iml 290 | 291 | # CodeRush 292 | .cr/ 293 | 294 | # Python Tools for Visual Studio (PTVS) 295 | __pycache__/ 296 | *.pyc 297 | 298 | # Cake - Uncomment if you are using it 299 | # tools/** 300 | # !tools/packages.config 301 | 302 | # Tabs Studio 303 | *.tss 304 | 305 | # Telerik's JustMock configuration file 306 | *.jmconfig 307 | 308 | # BizTalk build output 309 | *.btp.cs 310 | *.btm.cs 311 | *.odx.cs 312 | *.xsd.cs 313 | 314 | # OpenCover UI analysis results 315 | OpenCover/ 316 | 317 | # Azure Stream Analytics local run output 318 | ASALocalRun/ 319 | 320 | # MSBuild Binary and Structured Log 321 | *.binlog 322 | 323 | -------------------------------------------------------------------------------- /486 Breakout/README.md: -------------------------------------------------------------------------------- 1 | [Board has been moved to a dedicated repo](https://github.com/FoxCutter/486Dev/tree/main/486%20Breakout) 2 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTest", "ConsoleTest\ConsoleTest.csproj", "{979F9604-F884-497C-B668-887874E9033E}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleLib", "ConsoleEx\ConsoleLib.csproj", "{86D20FAF-A792-48CE-93F0-8F76850ECD93}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {979F9604-F884-497C-B668-887874E9033E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {979F9604-F884-497C-B668-887874E9033E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {979F9604-F884-497C-B668-887874E9033E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {979F9604-F884-497C-B668-887874E9033E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {86D20FAF-A792-48CE-93F0-8F76850ECD93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {86D20FAF-A792-48CE-93F0-8F76850ECD93}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {86D20FAF-A792-48CE-93F0-8F76850ECD93}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {86D20FAF-A792-48CE-93F0-8F76850ECD93}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/ConsoleEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace ConsoleLib 7 | { 8 | public static class ConsoleEx 9 | { 10 | #region Event objcets 11 | 12 | public class ConsoleControlEventHandlerArgs : EventArgs 13 | { 14 | public readonly ConsoleExCtrlEventType EventType; 15 | public bool CancelProcessing = false; 16 | 17 | public ConsoleControlEventHandlerArgs(ConsoleExCtrlEventType NewEventType) 18 | { 19 | EventType = NewEventType; 20 | } 21 | } 22 | 23 | public delegate void ConsoleControlEventHandler(object sender, ConsoleControlEventHandlerArgs e); 24 | public static event ConsoleControlEventHandler ConsoleControlEvent = null; 25 | 26 | #endregion 27 | 28 | // Direct access to the Input Buffer ignoring redirection 29 | static public InputBuffer InputBuffer { get; internal set; } 30 | 31 | // Direct access to the Output Buffer ignoring redirection 32 | static public ScreenBuffer ScreenBuffer { get; internal set; } 33 | 34 | static System.IO.TextReader StdInputStream = null; 35 | static System.IO.TextWriter StdErrorStream = null; 36 | static System.IO.TextWriter StdOutputStream = null; 37 | 38 | 39 | static CtrlHandlerRoutine CancelKeyPress = null; 40 | 41 | static ConsoleEx() 42 | { 43 | if (Window != IntPtr.Zero) 44 | { 45 | SetupConsole(); 46 | AttachCtrlHandler(); 47 | } 48 | } 49 | 50 | static void SetupConsole() 51 | { 52 | if (IsOutputRedirected) 53 | ScreenBuffer = ScreenBuffer.OpenCurrentScreenBuffer(); 54 | else 55 | ScreenBuffer = new ScreenBuffer(StdOutput); 56 | 57 | if (IsInputRedirected) 58 | InputBuffer = InputBuffer.OpenCurrentInputBuffer(); 59 | else 60 | InputBuffer = new InputBuffer(StdInput); 61 | } 62 | 63 | public static void AllocConsole() 64 | { 65 | if (!WinAPI.AllocConsole()) 66 | { 67 | throw new ConsoleExException("ConsoleEx: Unable to attach Allocate a new console."); 68 | } 69 | 70 | SetupConsole(); 71 | AttachCtrlHandler(); 72 | } 73 | 74 | public static void FreeConsole() 75 | { 76 | if (!WinAPI.FreeConsole()) 77 | { 78 | throw new ConsoleExException("Unable to set Alloc Console."); 79 | } 80 | 81 | DetachCtrlHandler(); 82 | 83 | InputBuffer = null; 84 | ScreenBuffer = null; 85 | } 86 | 87 | static public void AttachConsoleToProcess(uint ProcessID) 88 | { 89 | if (!WinAPI.AttachConsole(ProcessID)) 90 | { 91 | throw new ConsoleExException("ConsoleEx: Unable to attach process to console."); 92 | } 93 | } 94 | 95 | static public List GetAttachedProcessList() 96 | { 97 | uint[] Data = new uint[1]; 98 | 99 | uint Len = WinAPI.GetConsoleProcessList(Data, (uint)Data.Length); 100 | if (Len > Data.Length) 101 | { 102 | Data = new uint[Len]; 103 | Len = WinAPI.GetConsoleProcessList(Data, (uint)Data.Length); 104 | } 105 | 106 | if (Len == 0) 107 | { 108 | throw new ConsoleExException("ConsoleEx: Unable to get attached process list."); 109 | } 110 | 111 | List Ret = new List(Data); 112 | 113 | return Ret; 114 | } 115 | 116 | 117 | static public ScreenBuffer SwapBuffers(ScreenBuffer NewBuffer, bool SetStdOutput = true) 118 | { 119 | if (!WinAPI.SetConsoleActiveScreenBuffer(NewBuffer.Handle)) 120 | { 121 | throw new ConsoleExException("ConsoleEx: Unable to setacctive output buffer."); 122 | } 123 | 124 | ScreenBuffer OldBuffer = ScreenBuffer; 125 | ScreenBuffer = NewBuffer; 126 | 127 | if (SetStdOutput) 128 | StdOutput = NewBuffer.Handle; 129 | 130 | return OldBuffer; 131 | } 132 | 133 | 134 | #region Alias Functions 135 | 136 | public static void AddAlias(string AliasName, string AliasValue, string AliasExe) 137 | { 138 | if (!WinAPI.AddConsoleAlias(AliasName, AliasValue, AliasExe)) 139 | { 140 | throw new ConsoleExException("ConsoleEx: Unable to Add Alias."); 141 | } 142 | } 143 | 144 | public static string GetAlias(string AliasName, string AliasExe) 145 | { 146 | StringBuilder Data = new StringBuilder(500); 147 | 148 | // Buffer length in in bytes 149 | if (WinAPI.GetConsoleAlias(AliasName, Data, (uint)Data.Capacity * sizeof(char), AliasExe) == 0) 150 | { 151 | throw new ConsoleExException("ConsoleEx: Unable to Get Alias."); 152 | } 153 | 154 | return Data.ToString(); 155 | } 156 | 157 | public static Dictionary GetAliases(string AliasExe) 158 | { 159 | Dictionary Ret = new Dictionary(); 160 | 161 | uint Length = WinAPI.GetConsoleAliasesLength(AliasExe); 162 | 163 | char[] Aliases = new char[Length]; 164 | 165 | // Buffer length in in bytes 166 | if (WinAPI.GetConsoleAliases(Aliases, Length * sizeof(char), AliasExe) == 0) 167 | { 168 | throw new ConsoleExException("ConsoleEx: Unable to set Get Aliases."); 169 | } 170 | 171 | // The results come out in name=value pairs, seperated by Nulls. 172 | int Start = 0; 173 | int PairSplit = 0; 174 | 175 | try 176 | { 177 | 178 | for (int Pos = 0; Pos < Aliases.Length; Pos++) 179 | { 180 | if (Aliases[Pos] == '=') 181 | { 182 | PairSplit = Pos; 183 | } 184 | 185 | if (Aliases[Pos] == '\0') 186 | { 187 | if (Pos != Start) 188 | { 189 | string Value = new string(Aliases, Start, PairSplit - Start); 190 | string Data = new string(Aliases, PairSplit + 1, Pos - PairSplit - 1); 191 | Ret.Add(Value, Data); 192 | } 193 | else 194 | { 195 | break; 196 | } 197 | 198 | Start = Pos + 1; 199 | } 200 | } 201 | } 202 | catch (Exception e) 203 | { 204 | throw new ConsoleExException("ConsoleEx: Unable to set parse Aliases.", e); 205 | } 206 | 207 | return Ret; 208 | } 209 | 210 | public static List GetAliesesExes() 211 | { 212 | List Ret = new List(); 213 | 214 | uint Length = WinAPI.GetConsoleAliasExesLength() * 2; 215 | 216 | char[] Aliases = new char[Length]; 217 | // Buffer length in in bytes 218 | if (WinAPI.GetConsoleAliasExes(Aliases, Length * sizeof(char)) == 0) 219 | { 220 | throw new ConsoleExException("ConsoleEx: Unable to Get Exe list."); 221 | } 222 | 223 | // The results come out seperated by Nulls. 224 | int Start = 0; 225 | 226 | try 227 | { 228 | for (int Pos = 0; Pos < Aliases.Length; Pos++) 229 | { 230 | if (Aliases[Pos] == '\0') 231 | { 232 | if (Pos != Start) 233 | { 234 | string Value = new string(Aliases, Start, Pos - Start); 235 | Ret.Add(Value); 236 | } 237 | else 238 | { 239 | break; 240 | } 241 | 242 | Start = Pos + 1; 243 | } 244 | } 245 | } 246 | catch (Exception e) 247 | { 248 | throw new ConsoleExException("ConsoleEx: Unable to set parse Exe list.", e); 249 | } 250 | 251 | return Ret; 252 | } 253 | 254 | #endregion 255 | 256 | #region Ctrl Handler and Event functions 257 | 258 | static void AttachCtrlHandler() 259 | { 260 | if (CancelKeyPress == null) 261 | CancelKeyPress = new CtrlHandlerRoutine(CtrlHandlerFunction); 262 | 263 | if (!WinAPI.SetConsoleCtrlHandler(CancelKeyPress, true)) 264 | { 265 | throw new ConsoleExException("ConsoleEx: Unable to set Ctrl handler."); 266 | } 267 | } 268 | 269 | static void DetachCtrlHandler() 270 | { 271 | if (CancelKeyPress == null) 272 | return; 273 | 274 | if (!WinAPI.SetConsoleCtrlHandler(CancelKeyPress, false)) 275 | { 276 | throw new ConsoleExException("ConsoleEx: Unable to remove Ctrl handler."); 277 | } 278 | } 279 | 280 | static bool CtrlHandlerFunction(ConsoleExCtrlEventType CtrlType) 281 | { 282 | if (ConsoleControlEvent != null) 283 | { 284 | ConsoleControlEventHandlerArgs Events = new ConsoleControlEventHandlerArgs(CtrlType); 285 | OnConsoleControlEvent(Events); 286 | 287 | return Events.CancelProcessing; 288 | } 289 | 290 | return false; 291 | } 292 | 293 | public static void OnConsoleControlEvent(ConsoleControlEventHandlerArgs e) 294 | { 295 | if (ConsoleControlEvent != null) 296 | { 297 | ConsoleControlEvent(null, e); 298 | } 299 | } 300 | 301 | public static void GenerateCtrlEvent(ConsoleExCtrlEventType Event, uint ProcessGroupId) 302 | { 303 | if (!WinAPI.GenerateConsoleCtrlEvent(Event, ProcessGroupId)) 304 | { 305 | throw new ConsoleExException("ConsoleEx: Unable to generate a control event."); 306 | } 307 | } 308 | 309 | #endregion 310 | 311 | #region Properties 312 | 313 | public static IntPtr Window 314 | { 315 | get { return WinAPI.GetConsoleWindow(); } 316 | } 317 | 318 | public static ConsoleExDisplayModeFlags DisplayMode 319 | { 320 | get 321 | { 322 | ConsoleExDisplayModeFlags Ret; 323 | if (!WinAPI.GetConsoleDisplayMode(out Ret)) 324 | { 325 | throw new ConsoleExException("ConsoleEx: Unable to get display mode."); 326 | } 327 | 328 | return Ret; 329 | } 330 | } 331 | 332 | public static int NumberOfMouseButtons 333 | { 334 | get 335 | { 336 | uint Ret; 337 | if (!WinAPI.GetNumberOfConsoleMouseButtons(out Ret)) 338 | { 339 | throw new ConsoleExException("ConsoleEx: Unable to get mouse buttons."); 340 | } 341 | 342 | return (int)Ret; 343 | } 344 | } 345 | 346 | public static string Title 347 | { 348 | get 349 | { 350 | StringBuilder Data = new StringBuilder(256); 351 | // GetConsoleTitle uses byte count not character count (this is an error in the documentation) 352 | if(WinAPI.GetConsoleTitle(Data, (uint)Data.Capacity * sizeof(char)) == 0) 353 | { 354 | throw new ConsoleExException("ConsoleEx: Unable to get title."); 355 | } 356 | return Data.ToString(); 357 | } 358 | 359 | set 360 | { 361 | if (!WinAPI.SetConsoleTitle(value)) 362 | { 363 | throw new ConsoleExException("ConsoleEx: Unable to set title."); 364 | } 365 | } 366 | } 367 | 368 | public static string OriginalTitle 369 | { 370 | get 371 | { 372 | StringBuilder Data = new StringBuilder(256); 373 | if (WinAPI.GetConsoleOriginalTitle(Data, (uint)Data.Capacity) == 0) 374 | { 375 | throw new ConsoleExException("ConsoleEx: Unable to get orginial title."); 376 | } 377 | return Data.ToString(); 378 | } 379 | } 380 | 381 | public static Encoding InputEncoding 382 | { 383 | get 384 | { 385 | return Encoding.GetEncoding((int)WinAPI.GetConsoleCP()); 386 | } 387 | set 388 | { 389 | if (!WinAPI.SetConsoleCP((uint)value.CodePage)) 390 | { 391 | throw new ConsoleExException("ConsoleEx: Unable to set input code page."); 392 | } 393 | } 394 | } 395 | 396 | public static Encoding OutputEncoding 397 | { 398 | get 399 | { 400 | return Encoding.GetEncoding((int)WinAPI.GetConsoleOutputCP()); 401 | } 402 | set 403 | { 404 | if (!WinAPI.SetConsoleOutputCP((uint)value.CodePage)) 405 | { 406 | throw new ConsoleExException("ConsoleEx: Unable to set input code page."); 407 | } 408 | } 409 | } 410 | 411 | public static ConsoleSelectionInfo ConsoleSelectionInfo 412 | { 413 | get 414 | { 415 | ConsoleSelectionInfo Info; 416 | if (!WinAPI.GetConsoleSelectionInfo(out Info)) 417 | { 418 | throw new ConsoleExException("ConsoleEx: Unable to set console info."); 419 | } 420 | return Info; 421 | } 422 | } 423 | 424 | static public Microsoft.Win32.SafeHandles.SafeFileHandle StdInput 425 | { 426 | get { return GetStdHandle(StdHandleType.STD_INPUT_HANDLE); } 427 | set 428 | { 429 | if (!WinAPI.SetStdHandle(StdHandleType.STD_INPUT_HANDLE, value)) 430 | { 431 | throw new ConsoleExException("ConsoleEx: Unable to set standard input."); 432 | } 433 | 434 | StdInputStream = null; 435 | } 436 | } 437 | 438 | static public Microsoft.Win32.SafeHandles.SafeFileHandle StdOutput 439 | { 440 | get { return GetStdHandle(StdHandleType.STD_OUTPUT_HANDLE); } 441 | set 442 | { 443 | if (!WinAPI.SetStdHandle(StdHandleType.STD_OUTPUT_HANDLE, value)) 444 | { 445 | throw new ConsoleExException("ConsoleEx: Unable to set standard output."); 446 | } 447 | 448 | StdOutputStream = null; 449 | } 450 | } 451 | 452 | static public Microsoft.Win32.SafeHandles.SafeFileHandle StdError 453 | { 454 | get { return GetStdHandle(StdHandleType.STD_ERROR_HANDLE); } 455 | set 456 | { 457 | if (!WinAPI.SetStdHandle(StdHandleType.STD_ERROR_HANDLE, value)) 458 | { 459 | throw new ConsoleExException("ConsoleEx: Unable to set standard error."); 460 | } 461 | 462 | StdErrorStream = null; 463 | } 464 | } 465 | 466 | public static Stream OpenStandardInput() 467 | { 468 | return OpenStandardInput(1024); 469 | } 470 | 471 | public static Stream OpenStandardError() 472 | { 473 | return OpenStandardError(1024); 474 | } 475 | 476 | public static Stream OpenStandardOutput() 477 | { 478 | return OpenStandardOutput(1024); 479 | } 480 | 481 | public static Stream OpenStandardInput(int bufferSize) 482 | { 483 | WinAPI.FileTypes Type = WinAPI.GetFileType(StdInput); 484 | 485 | System.IO.Stream Stream; 486 | 487 | // If it's not a charater stream, use the built in file stream 488 | if (Type == WinAPI.FileTypes.Character) 489 | Stream = new WinAPI.ConsoleStream(StdInput, FileAccess.Read); 490 | else 491 | Stream = new System.IO.FileStream(StdInput, FileAccess.Read, bufferSize); 492 | 493 | return Stream; 494 | } 495 | 496 | public static Stream OpenStandardError(int bufferSize) 497 | { 498 | WinAPI.FileTypes Type = WinAPI.GetFileType(StdError); 499 | 500 | System.IO.Stream Stream; 501 | 502 | // If it's not a charater stream, use the built in file stream 503 | if (Type == WinAPI.FileTypes.Character) 504 | Stream = new WinAPI.ConsoleStream(StdError, FileAccess.Write); 505 | else 506 | Stream = new System.IO.FileStream(StdError, FileAccess.Write, bufferSize); 507 | 508 | return Stream; 509 | } 510 | 511 | public static Stream OpenStandardOutput(int bufferSize) 512 | { 513 | WinAPI.FileTypes Type = WinAPI.GetFileType(StdOutput); 514 | 515 | System.IO.Stream Stream; 516 | 517 | // If it's not a charater stream, use the built in file stream 518 | if (Type == WinAPI.FileTypes.Character) 519 | Stream = new WinAPI.ConsoleStream(StdOutput, FileAccess.Write); 520 | else 521 | Stream = new System.IO.FileStream(StdOutput, FileAccess.Write, bufferSize); 522 | 523 | return Stream; 524 | } 525 | 526 | 527 | // Stream for the StdInput handle 528 | public static TextReader In 529 | { 530 | get 531 | { 532 | if (StdInputStream == null) 533 | { 534 | System.IO.StreamReader Stream = new System.IO.StreamReader(OpenStandardInput(), InputEncoding); 535 | StdInputStream = Stream; 536 | } 537 | 538 | return StdInputStream; 539 | } 540 | } 541 | 542 | // Stream for the StdError handle 543 | public static TextWriter Error 544 | { 545 | get 546 | { 547 | if (StdErrorStream == null) 548 | { 549 | System.IO.StreamWriter Stream = new System.IO.StreamWriter(OpenStandardError(), OutputEncoding); 550 | Stream.AutoFlush = true; 551 | StdErrorStream = Stream; 552 | } 553 | 554 | return StdErrorStream; 555 | } 556 | } 557 | 558 | // Stream for the StdOutput handle 559 | public static TextWriter Out 560 | { 561 | get 562 | { 563 | if (StdOutputStream == null) 564 | { 565 | System.IO.StreamWriter Stream = new System.IO.StreamWriter(OpenStandardOutput(), OutputEncoding); 566 | Stream.AutoFlush = true; 567 | StdOutputStream = Stream; 568 | } 569 | 570 | return StdOutputStream; 571 | } 572 | } 573 | 574 | public static void SetIn(TextReader newIn) 575 | { 576 | StdInputStream = newIn; 577 | } 578 | 579 | public static void SetError(TextWriter newError) 580 | { 581 | StdErrorStream = newError; 582 | } 583 | 584 | public static void SetOut(TextWriter newOut) 585 | { 586 | StdOutputStream = newOut; 587 | } 588 | 589 | 590 | internal static IntPtr RawStdInput 591 | { 592 | get { return WinAPI.GetStdHandle(StdHandleType.STD_INPUT_HANDLE); } 593 | } 594 | 595 | internal static IntPtr RawStdOutput 596 | { 597 | get { return WinAPI.GetStdHandle(StdHandleType.STD_OUTPUT_HANDLE); } 598 | } 599 | 600 | internal static IntPtr RawStdError 601 | { 602 | get { return WinAPI.GetStdHandle(StdHandleType.STD_ERROR_HANDLE); } 603 | } 604 | 605 | public static bool IsInputRedirected 606 | { 607 | get 608 | { 609 | if (WinAPI.GetFileType(StdInput) != WinAPI.FileTypes.Character) 610 | return true; 611 | 612 | return false; 613 | } 614 | } 615 | 616 | public static bool IsOutputRedirected 617 | { 618 | get 619 | { 620 | if (WinAPI.GetFileType(StdOutput) != WinAPI.FileTypes.Character) 621 | return true; 622 | 623 | return false; 624 | } 625 | } 626 | 627 | public static bool IsErrorRedirected 628 | { 629 | get 630 | { 631 | if (WinAPI.GetFileType(StdError) != WinAPI.FileTypes.Character) 632 | return true; 633 | 634 | return false; 635 | } 636 | } 637 | 638 | public static bool TreatControlCAsInput 639 | { 640 | get 641 | { 642 | return !InputBuffer.ProcessedInput; 643 | } 644 | 645 | set 646 | { 647 | InputBuffer.ProcessedInput = !value; 648 | } 649 | } 650 | #endregion 651 | 652 | internal static Microsoft.Win32.SafeHandles.SafeFileHandle GetStdHandle(StdHandleType StdHandle) 653 | { 654 | return new Microsoft.Win32.SafeHandles.SafeFileHandle(WinAPI.GetStdHandle(StdHandle), false); 655 | } 656 | 657 | internal static Microsoft.Win32.SafeHandles.SafeFileHandle GetConsoleOutputHandle() 658 | { 659 | // Open up the handle to the buffer attached to the console, not what is attached to the handle. 660 | Microsoft.Win32.SafeHandles.SafeFileHandle Handle = WinAPI.CreateFile("CONOUT$", WinAPI.DesiredAccess.GENERIC_READ | WinAPI.DesiredAccess.GENERIC_WRITE, 661 | WinAPI.ShareMode.FILE_SHARE_READ | WinAPI.ShareMode.FILE_SHARE_WRITE, 662 | IntPtr.Zero, WinAPI.CreationDispositionType.OPEN_EXISTING, 0, IntPtr.Zero); 663 | 664 | return Handle; 665 | } 666 | 667 | internal static Microsoft.Win32.SafeHandles.SafeFileHandle GetConsoleInputHandle() 668 | { 669 | // Open up the handle to the buffer attached to the console, not what is attached to the handle. 670 | Microsoft.Win32.SafeHandles.SafeFileHandle Handle = WinAPI.CreateFile("CONIN$", WinAPI.DesiredAccess.GENERIC_READ | WinAPI.DesiredAccess.GENERIC_WRITE, 671 | WinAPI.ShareMode.FILE_SHARE_READ | WinAPI.ShareMode.FILE_SHARE_WRITE, 672 | IntPtr.Zero, WinAPI.CreationDispositionType.OPEN_EXISTING, 0, IntPtr.Zero); 673 | 674 | return Handle; 675 | } 676 | 677 | public static void Beep() 678 | { 679 | Beep(800, 200); 680 | } 681 | 682 | public static void Beep(int frequency, int duration) 683 | { 684 | WinAPI.Beep((uint)frequency, (uint)duration); 685 | } 686 | } 687 | } 688 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/ConsoleLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {86D20FAF-A792-48CE-93F0-8F76850ECD93} 8 | Library 9 | Properties 10 | ConsoleLib 11 | ConsoleEx 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 | 61 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/InputBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace ConsoleLib 6 | { 7 | public class InputBuffer : IDisposable 8 | { 9 | Microsoft.Win32.SafeHandles.SafeFileHandle BufferHandle; 10 | bool FreeHandle; 11 | System.IO.TextReader InputStream = null; 12 | KeyEventRecord SavedKey = new KeyEventRecord(); 13 | 14 | public InputBuffer(Microsoft.Win32.SafeHandles.SafeFileHandle Handle) 15 | { 16 | // If we're being attached to an existing handle, sanity check that it's something we can work with. 17 | if (WinAPI.GetFileType(Handle) != WinAPI.FileTypes.Character) 18 | { 19 | throw new Exception("Invalid handle type for Input Buffer."); 20 | } 21 | 22 | // Flag that we're attached to the handle, so we don't accidently free it. 23 | FreeHandle = false; 24 | BufferHandle = Handle; 25 | } 26 | 27 | static internal InputBuffer OpenCurrentInputBuffer() 28 | { 29 | Microsoft.Win32.SafeHandles.SafeFileHandle Handle = ConsoleEx.GetConsoleInputHandle(); 30 | 31 | if (Handle.IsInvalid) 32 | return null; 33 | 34 | InputBuffer Ret = new InputBuffer(Handle); 35 | 36 | // The buffer actually owns this handle, so make sure we free it. 37 | Ret.FreeHandle = true; 38 | 39 | return Ret; 40 | } 41 | 42 | #region Dispose/Finaize 43 | 44 | ~InputBuffer() 45 | { 46 | Dispose(false); 47 | } 48 | 49 | public void Dispose() 50 | { 51 | Dispose(true); 52 | GC.SuppressFinalize(this); 53 | } 54 | 55 | public void Dispose(bool Disposing) 56 | { 57 | if (FreeHandle && !BufferHandle.IsClosed) 58 | BufferHandle.Close(); 59 | } 60 | 61 | #endregion 62 | 63 | #region Properties 64 | 65 | public Microsoft.Win32.SafeHandles.SafeFileHandle Handle 66 | { 67 | get { return BufferHandle; } 68 | } 69 | 70 | public System.IO.TextReader Stream 71 | { 72 | get 73 | { 74 | if (InputStream == null) 75 | { 76 | InputStream = new System.IO.StreamReader(new WinAPI.ConsoleStream(BufferHandle, FileAccess.Read), ConsoleEx.InputEncoding); 77 | } 78 | 79 | return InputStream; 80 | } 81 | } 82 | 83 | public ConsoleExInputMode Mode 84 | { 85 | get 86 | { 87 | ConsoleExInputMode Ret; 88 | if (!WinAPI.GetConsoleInputMode(BufferHandle, out Ret)) 89 | { 90 | throw new ConsoleExException("ConsoleEx: Unable to get input mode."); 91 | } 92 | return Ret; 93 | } 94 | set 95 | { 96 | if (!WinAPI.SetConsoleInputMode(BufferHandle, value)) 97 | { 98 | throw new ConsoleExException("ConsoleEx: Unable to set input mode."); 99 | } 100 | } 101 | } 102 | 103 | public int PendingEventCount 104 | { 105 | get 106 | { 107 | uint Count; 108 | if (!WinAPI.GetNumberOfConsoleInputEvents(BufferHandle, out Count)) 109 | { 110 | throw new ConsoleExException("ConsoleEx: Unable to read pending event count"); 111 | } 112 | 113 | return (int)Count; 114 | } 115 | } 116 | 117 | public bool KeyAvailable 118 | { 119 | get 120 | { 121 | if (SavedKey.RepeatCount != 0) 122 | return true; 123 | 124 | return IsEventPending(InputRecordType.KeyEvent); 125 | } 126 | } 127 | 128 | public bool EchoInput 129 | { 130 | get 131 | { 132 | return (Mode & ConsoleExInputMode.EchoInput) == ConsoleExInputMode.EchoInput; 133 | } 134 | 135 | set 136 | { 137 | if (value) 138 | Mode |= ConsoleExInputMode.EchoInput; 139 | else 140 | Mode &= ~ConsoleExInputMode.EchoInput; 141 | } 142 | } 143 | 144 | public bool InsertMode 145 | { 146 | get 147 | { 148 | return (Mode & ConsoleExInputMode.InsertMode) == ConsoleExInputMode.InsertMode; 149 | } 150 | 151 | set 152 | { 153 | if (value) 154 | Mode |= ConsoleExInputMode.InsertMode | ConsoleExInputMode.ExtendedFlags; 155 | else 156 | Mode &= ~ConsoleExInputMode.InsertMode; 157 | } 158 | } 159 | 160 | public bool LineInput 161 | { 162 | get 163 | { 164 | return (Mode & ConsoleExInputMode.LineInput) == ConsoleExInputMode.LineInput; 165 | } 166 | 167 | set 168 | { 169 | if (value) 170 | Mode |= ConsoleExInputMode.LineInput; 171 | 172 | else 173 | // If you can't turn off LineInput while EchoInput is on, so turn off both. 174 | Mode &= ~(ConsoleExInputMode.LineInput | ConsoleExInputMode.EchoInput); 175 | } 176 | } 177 | 178 | public bool MouseInput 179 | { 180 | get 181 | { 182 | return (Mode & ConsoleExInputMode.MouseInput) == ConsoleExInputMode.MouseInput; 183 | } 184 | 185 | set 186 | { 187 | if (value) 188 | Mode |= ConsoleExInputMode.MouseInput; 189 | else 190 | Mode &= ~ConsoleExInputMode.MouseInput; 191 | } 192 | } 193 | 194 | public bool ProcessedInput 195 | { 196 | get 197 | { 198 | return (Mode & ConsoleExInputMode.ProcessedInput) == ConsoleExInputMode.ProcessedInput; 199 | } 200 | 201 | set 202 | { 203 | if (value) 204 | Mode |= ConsoleExInputMode.ProcessedInput; 205 | else 206 | Mode &= ~ConsoleExInputMode.ProcessedInput; 207 | } 208 | } 209 | 210 | public bool QuickEditMode 211 | { 212 | get 213 | { 214 | return (Mode & ConsoleExInputMode.QuickEditMode) == ConsoleExInputMode.QuickEditMode; 215 | } 216 | 217 | set 218 | { 219 | if (value) 220 | Mode |= ConsoleExInputMode.QuickEditMode | ConsoleExInputMode.ExtendedFlags; 221 | else 222 | Mode &= ~ConsoleExInputMode.QuickEditMode; 223 | } 224 | } 225 | 226 | public bool WindowInput 227 | { 228 | get 229 | { 230 | return (Mode & ConsoleExInputMode.WindowInput) == ConsoleExInputMode.WindowInput; 231 | } 232 | 233 | set 234 | { 235 | if (value) 236 | Mode |= ConsoleExInputMode.WindowInput; 237 | else 238 | Mode &= ~ConsoleExInputMode.WindowInput; 239 | } 240 | } 241 | 242 | public bool VirtualTerminal 243 | { 244 | get 245 | { 246 | return (Mode & ConsoleExInputMode.VirutalTerminalInput) == ConsoleExInputMode.VirutalTerminalInput; 247 | } 248 | 249 | set 250 | { 251 | if (value) 252 | Mode |= ConsoleExInputMode.VirutalTerminalInput; 253 | else 254 | Mode &= ~ConsoleExInputMode.VirutalTerminalInput; 255 | } 256 | } 257 | 258 | public bool CapsLock 259 | { 260 | get 261 | { 262 | return WinAPI.GetKeyState(0x14) != 0; 263 | } 264 | } 265 | 266 | public bool NumberLock 267 | { 268 | get 269 | { 270 | return WinAPI.GetKeyState(0x90) != 0; 271 | } 272 | } 273 | 274 | public bool ScrollLock 275 | { 276 | get 277 | { 278 | return WinAPI.GetKeyState(0x91) != 0; 279 | } 280 | } 281 | 282 | #endregion 283 | 284 | #region Events 285 | 286 | public void Flush() 287 | { 288 | SavedKey.RepeatCount = 0; 289 | if (!WinAPI.FlushConsoleInputBuffer(BufferHandle)) 290 | { 291 | throw new ConsoleExException("ConsoleEx: Unable to flush input buffer."); 292 | } 293 | } 294 | 295 | public bool IsEventPending(InputRecordType EventType) 296 | { 297 | if (PendingEventCount == 0) 298 | return false; 299 | 300 | InputRecord[] Events = PeekPendingEvents(); 301 | 302 | foreach (InputRecord Event in Events) 303 | { 304 | if ((InputRecordType)Event.EventType == EventType) 305 | { 306 | if (Event.KeyEvent.KeyDown != 0) 307 | return true; 308 | } 309 | } 310 | 311 | return false; 312 | } 313 | 314 | public InputRecord[] PeekPendingEvents() 315 | { 316 | return PeekPendingEvents(PendingEventCount); 317 | } 318 | 319 | public InputRecord[] PeekPendingEvents(int Max) 320 | { 321 | if(Max == 0) 322 | return null; 323 | 324 | InputRecord[] EventList = new InputRecord[Max]; 325 | 326 | uint ReadCount; 327 | if (!WinAPI.PeekConsoleInput(BufferHandle, EventList, (uint)Max, out ReadCount)) 328 | { 329 | throw new ConsoleExException("ConsoleEx: Unable to peek at input buffer"); 330 | } 331 | 332 | if (ReadCount < Max) 333 | { 334 | InputRecord[] NewList = new InputRecord[ReadCount]; 335 | Array.Copy(EventList, NewList, ReadCount); 336 | EventList = NewList; 337 | } 338 | 339 | return EventList; 340 | } 341 | 342 | public InputRecord[] ReadPendingEvents() 343 | { 344 | return ReadPendingEvents(PendingEventCount); 345 | } 346 | 347 | public InputRecord[] ReadPendingEvents(int Max) 348 | { 349 | if (Max == 0) 350 | return null; 351 | 352 | InputRecord[] EventList = new InputRecord[Max]; 353 | 354 | uint ReadCount; 355 | if (!WinAPI.ReadConsoleInput(BufferHandle, EventList, (uint)Max, out ReadCount)) 356 | { 357 | throw new ConsoleExException("ConsoleEx: Unable to read input buffer"); 358 | } 359 | 360 | if (ReadCount < Max) 361 | { 362 | InputRecord[] NewList = new InputRecord[ReadCount]; 363 | Array.Copy(EventList, NewList, ReadCount); 364 | EventList = NewList; 365 | } 366 | 367 | return EventList; 368 | } 369 | 370 | public InputRecord NextEvent(InputRecordType Filter = InputRecordType.All) 371 | { 372 | while (true) 373 | { 374 | InputRecord[] EventList = ReadPendingEvents(1); 375 | if (EventList == null) 376 | continue; 377 | 378 | if ((EventList[0].EventType & Filter) != 0) 379 | { 380 | return EventList[0]; 381 | } 382 | } 383 | } 384 | 385 | public InputRecord PeekNextEvent(bool Remove = false) 386 | { 387 | InputRecord[] EventList; 388 | 389 | while (true) 390 | { 391 | if (PendingEventCount == 0) 392 | break; 393 | 394 | if (Remove) 395 | EventList = ReadPendingEvents(1); 396 | else 397 | EventList = PeekPendingEvents(1); 398 | 399 | if (EventList == null) 400 | break; 401 | 402 | return EventList[0]; 403 | } 404 | 405 | return default(InputRecord); 406 | } 407 | 408 | 409 | public int WritePendingEvents(InputRecord[] Events) 410 | { 411 | if (Events == null || Events.Length == 0) 412 | return 0; 413 | 414 | uint Count; 415 | if (!WinAPI.WriteConsoleInput(BufferHandle, Events, (uint)Events.Length, out Count)) 416 | { 417 | throw new ConsoleExException("ConsoleEx: Unable to write to input buffer"); 418 | } 419 | 420 | return (int)Count; 421 | } 422 | 423 | #endregion 424 | 425 | #region Read functions 426 | public ConsoleKeyInfo ReadKey(bool intercept) 427 | { 428 | KeyEventRecord KeyEvent = new KeyEventRecord(); 429 | 430 | if (SavedKey.RepeatCount != 0) 431 | { 432 | KeyEvent = SavedKey; 433 | SavedKey.RepeatCount--; 434 | } 435 | else 436 | { 437 | while (true) 438 | { 439 | KeyEvent = NextEvent(InputRecordType.KeyEvent).KeyEvent; 440 | KeyEvent.RepeatCount--; 441 | 442 | if (CanDisplay(KeyEvent)) 443 | break; 444 | } 445 | } 446 | 447 | if (KeyEvent.RepeatCount != 0) 448 | SavedKey = KeyEvent; 449 | 450 | if (!intercept) 451 | ConsoleEx.ScreenBuffer.Write(KeyEvent.Character); 452 | 453 | bool Shift = (KeyEvent.ControlKeyState & CtrlKeyState.SHIFT_PRESSED) != 0; 454 | bool Ctrl = (KeyEvent.ControlKeyState & (CtrlKeyState.LEFT_CTRL_PRESSED | CtrlKeyState.RIGHT_CTRL_PRESSED)) != 0; 455 | bool Alt = (KeyEvent.ControlKeyState & (CtrlKeyState.LEFT_ALT_PRESSED | CtrlKeyState.RIGHT_ALT_PRESSED)) != 0; 456 | 457 | return new ConsoleKeyInfo(KeyEvent.Character, (ConsoleKey)KeyEvent.VirtualKeyCode, Shift, Alt, Ctrl); 458 | } 459 | 460 | public ConsoleKeyInfo ReadKey() 461 | { 462 | ConsoleKeyInfo Info = ReadKey(false); 463 | 464 | return Info; 465 | } 466 | 467 | public KeyEventRecord ReadKeyEvent() 468 | { 469 | return NextEvent(InputRecordType.KeyEvent).KeyEvent; 470 | } 471 | 472 | public int Read() 473 | { 474 | StringBuilder Data = new StringBuilder(1); 475 | 476 | if(SavedKey.RepeatCount != 0) 477 | { 478 | SavedKey.RepeatCount--; 479 | return (int)SavedKey.Character; 480 | } 481 | 482 | uint DataRead; 483 | if (!WinAPI.ReadConsole(BufferHandle, Data, 1, out DataRead, IntPtr.Zero)) 484 | { 485 | throw new ConsoleExException("ConsoleEx: Unable to read from input buffer."); 486 | } 487 | 488 | return (int)Data[0]; 489 | } 490 | 491 | public string ReadLine() 492 | { 493 | StringBuilder Ret = new StringBuilder(); 494 | StringBuilder Data = new StringBuilder(512); 495 | 496 | bool Done = false; 497 | 498 | do 499 | { 500 | uint DataRead; 501 | if (!WinAPI.ReadConsole(BufferHandle, Data, (uint)Data.Capacity, out DataRead, IntPtr.Zero)) 502 | { 503 | throw new ConsoleExException("ConsoleEx: Unable to read from input buffer."); 504 | } 505 | 506 | Data.Length = (int)DataRead; 507 | Ret.Append(Data); 508 | 509 | // Check for both CL & LF. If it's processed line input we'll get both CR/LF, if it's not we'll just get a CR. 510 | if (Data.Length > 0 && (Data[(int)(DataRead - 1)] == '\n' || Data[(int)(DataRead - 1)] == '\r')) 511 | Done = true; 512 | 513 | } while (!Done); 514 | 515 | if (Ret.Length > 0 && Ret[Ret.Length - 1] == '\n') 516 | Ret.Length--; 517 | 518 | if (Ret.Length > 0 && Ret[Ret.Length - 1] == '\r') 519 | Ret.Length--; 520 | 521 | return Ret.ToString(); 522 | } 523 | 524 | #endregion 525 | 526 | // Returs true if the value of Key.Character can be displayed. 527 | public bool CanDisplay(KeyEventRecord Key) 528 | { 529 | bool AltKey = Key.VirtualKeyCode == 0x12; 530 | bool CtrlKey = Key.VirtualKeyCode == 0x11; 531 | bool ShiftKey = Key.VirtualKeyCode == 0x10; 532 | 533 | // Win and App keys 534 | bool SpecialKey = Key.VirtualKeyCode >= 0x5B && Key.VirtualKeyCode <= 0x5D; 535 | 536 | // Num Lock, Scroll Lock, Caps Lock 537 | bool LockKey = Key.VirtualKeyCode == 0x90 || Key.VirtualKeyCode == 0x91 || Key.VirtualKeyCode == 0x14; 538 | 539 | if (SpecialKey || LockKey || CtrlKey || ShiftKey) 540 | return false; 541 | 542 | // Alt keys are a bit weird in that the Alt-up can contain a valid character, entered via ALT + Numpad 543 | if (Key.KeyDown == 0 && !AltKey) 544 | return false; 545 | 546 | return Key.Character != '\0'; 547 | } 548 | } 549 | } 550 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/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("ConsoleEx")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleEx")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 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("20257b27-37a6-44af-a2e9-6d5f53e375c7")] 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 Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/TerminalEmulator.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 ConsoleLib 8 | { 9 | public class TerminalEmulator 10 | { 11 | internal enum CharacterSet 12 | { 13 | DECLineDrawing, 14 | USASCII, 15 | }; 16 | 17 | internal enum InputMode 18 | { 19 | Normal, 20 | Application, 21 | } 22 | 23 | internal CharacterSet[] CharacterSets = new CharacterSet[2] { CharacterSet.USASCII, CharacterSet.DECLineDrawing }; 24 | 25 | TerminalScreenBuffer MainBuffer; 26 | TerminalScreenBuffer AlternateBuffer; 27 | TerminalInputBuffer InputBuffer; 28 | 29 | TerminalScreenBuffer CurrentBuffer; 30 | 31 | int MainBufferCursorTop; 32 | int MainBufferCursorLeft; 33 | 34 | internal InputMode Keypad; 35 | internal InputMode CursorKeys; 36 | 37 | public TerminalEmulator() 38 | { 39 | // New buffer for the current std output 40 | MainBuffer = new TerminalScreenBuffer(this, ConsoleEx.StdOutput); 41 | InputBuffer = new TerminalInputBuffer(this, ConsoleEx.StdInput); 42 | 43 | // And put our buffers in control 44 | CurrentBuffer = MainBuffer; 45 | ConsoleEx.ScreenBuffer = MainBuffer; 46 | ConsoleEx.InputBuffer = InputBuffer; 47 | 48 | ConsoleEx.ScreenBuffer.ProcessedOutput = false; 49 | ConsoleEx.ScreenBuffer.WrapAtEOL = false; 50 | 51 | CharacterAttribute Temp = ConsoleEx.ScreenBuffer.Attribute; 52 | Temp.Foreground = ConsoleColor.DarkGray; 53 | Temp.Background = ConsoleColor.Black; 54 | ConsoleEx.ScreenBuffer.Attribute = Temp; 55 | 56 | Keypad = InputMode.Normal; 57 | CursorKeys = InputMode.Normal; 58 | 59 | } 60 | 61 | internal void SwitchToAlternateBuffer() 62 | { 63 | MainBufferCursorTop = MainBuffer.CursorTop - MainBuffer.WindowTop; 64 | MainBufferCursorLeft = MainBuffer.CursorLeft - MainBuffer.WindowLeft; 65 | 66 | AlternateBuffer = new TerminalScreenBuffer(this); 67 | 68 | AlternateBuffer.SetCursorPosition(MainBufferCursorLeft, MainBufferCursorTop); 69 | ConsoleEx.SwapBuffers(AlternateBuffer); 70 | CurrentBuffer = AlternateBuffer; 71 | } 72 | 73 | internal void SwitchToMainBuffer() 74 | { 75 | MainBuffer.SetCursorPosition(MainBufferCursorLeft + MainBuffer.WindowLeft, MainBuffer.WindowTop + MainBufferCursorTop); 76 | ConsoleEx.SwapBuffers(MainBuffer); 77 | CurrentBuffer = MainBuffer; 78 | } 79 | 80 | internal void SendResponse(string Value) 81 | { 82 | 83 | } 84 | 85 | 86 | public void SetWindowAndBufferSize(int Width, int Height) 87 | { 88 | ConsoleScreenBufferInfoEx Buffer = CurrentBuffer.ScreenBufferInfo; 89 | 90 | Buffer.Window.Width = (short)Width; 91 | Buffer.BufferSize.X = (short)Width; 92 | Buffer.MaximumWindowSize.X = (short)Width; 93 | 94 | Buffer.Window.Height = Height; 95 | if (Buffer.BufferSize.Y < Buffer.Window.Bottom) 96 | Buffer.BufferSize.Y = Buffer.Window.Bottom; 97 | 98 | Buffer.MaximumWindowSize.Y = (short)Height; 99 | 100 | 101 | CurrentBuffer.ScreenBufferInfo = Buffer; 102 | 103 | 104 | } 105 | 106 | 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/TerminalInputBuffer.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 ConsoleLib 8 | { 9 | class TerminalInputBuffer : InputBuffer 10 | { 11 | TerminalEmulator BaseTerminal; 12 | 13 | public TerminalInputBuffer(TerminalEmulator Terminal, Microsoft.Win32.SafeHandles.SafeFileHandle Handle) 14 | : base(Handle) 15 | { 16 | BaseTerminal = Terminal; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleEx/WinAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Text; 4 | 5 | namespace ConsoleLib 6 | { 7 | public class WinAPI 8 | { 9 | #region Console Stream 10 | 11 | internal class ConsoleStream : System.IO.Stream 12 | { 13 | bool Readable; 14 | bool Writeable; 15 | Microsoft.Win32.SafeHandles.SafeFileHandle BufferHandle; 16 | 17 | public ConsoleStream(Microsoft.Win32.SafeHandles.SafeFileHandle Handle, System.IO.FileAccess Access) 18 | { 19 | BufferHandle = Handle; 20 | Readable = (Access & System.IO.FileAccess.Read) == System.IO.FileAccess.Read; 21 | Writeable = (Access & System.IO.FileAccess.Write) == System.IO.FileAccess.Write; 22 | } 23 | 24 | public override bool CanRead 25 | { 26 | get { return Readable; } 27 | } 28 | 29 | public override bool CanSeek 30 | { 31 | get { return false; } 32 | } 33 | 34 | public override bool CanWrite 35 | { 36 | get { return Writeable; } 37 | } 38 | 39 | public override void Flush() 40 | { 41 | if (Readable) 42 | { 43 | if (!WinAPI.FlushConsoleInputBuffer(BufferHandle)) 44 | { 45 | throw new ConsoleExException("ConsoleEx: Unable to flush input buffer."); 46 | } 47 | } 48 | } 49 | 50 | public override long Length 51 | { 52 | get { throw new NotImplementedException(); } 53 | } 54 | 55 | public override long Position 56 | { 57 | get 58 | { 59 | throw new NotImplementedException(); 60 | } 61 | set 62 | { 63 | throw new NotImplementedException(); 64 | } 65 | } 66 | 67 | public override int Read(byte[] buffer, int offset, int count) 68 | { 69 | if (!Readable) 70 | return 0; 71 | 72 | byte[] Data = new byte[count]; 73 | uint DataRead; 74 | 75 | //if (!WinAPI.ReadConsole(BufferHandle, Data, (uint)count / sizeof(char), out DataRead, IntPtr.Zero)) 76 | if (!WinAPI.ReadFile(BufferHandle, Data, (uint)count, out DataRead, IntPtr.Zero)) 77 | { 78 | throw new ConsoleExException("ConsoleEx: Unable to read from console buffer."); 79 | } 80 | 81 | Data.CopyTo(buffer, offset); 82 | 83 | //return (int)DataRead * sizeof(char); 84 | return (int)DataRead; 85 | } 86 | 87 | public override long Seek(long offset, System.IO.SeekOrigin origin) 88 | { 89 | throw new NotImplementedException(); 90 | } 91 | 92 | public override void SetLength(long value) 93 | { 94 | throw new NotImplementedException(); 95 | } 96 | 97 | public override void Write(byte[] buffer, int offset, int count) 98 | { 99 | if (!Writeable) 100 | return; 101 | 102 | byte[] Data = new byte[count]; 103 | Array.Copy(buffer, offset, Data, 0, count); 104 | 105 | uint DataWritten; 106 | 107 | //if (!WinAPI.WriteConsole(BufferHandle, Data, (uint)count / 2, out DataWritten, IntPtr.Zero)) 108 | if (!WinAPI.WriteFile(BufferHandle, Data, (uint)count, out DataWritten, IntPtr.Zero)) 109 | { 110 | throw new ConsoleExException("ConsoleEx: Unable to write to console."); 111 | } 112 | } 113 | } 114 | 115 | #endregion 116 | 117 | #region FileAPIs 118 | 119 | public enum CreationDispositionType : uint 120 | { 121 | CREATE_NEW = 1, 122 | CREATE_ALWAYS = 2, 123 | OPEN_EXISTING = 3, 124 | OPEN_ALWAYS = 4, 125 | TRUNCATE_EXISTING = 5, 126 | } 127 | 128 | public enum FileTypes : uint 129 | { 130 | Unknown = 0x0000, 131 | Disk = 0x0001, 132 | Character = 0x0002, 133 | Pipe = 0x0003, 134 | Remote = 0x8000, 135 | } 136 | 137 | [DllImport("kernel32.dll", SetLastError = true)] 138 | public static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string Filename, DesiredAccess dwDesiredAccess, ShareMode dwShareMode, IntPtr lpSecurityAttributes, CreationDispositionType CreationDisposition, uint FlagsAndAttributes, IntPtr TemplateFile); 139 | 140 | [DllImport("kernel32.dll", SetLastError = true)] 141 | public static extern bool ReadFile(Microsoft.Win32.SafeHandles.SafeFileHandle hHandle, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] Buffer, uint NumberOfBytesToRead, out uint NumberOfBytesRead, IntPtr Reserved); 142 | 143 | [DllImport("kernel32.dll", SetLastError = true)] 144 | public static extern bool WriteFile(Microsoft.Win32.SafeHandles.SafeFileHandle hHandle, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] Buffer, uint NumberOfBytesToWrite, out uint NumberOfBytesWritten, IntPtr Reserved); 145 | 146 | [DllImport("kernel32.dll", SetLastError = true)] 147 | static public extern FileTypes GetFileType(Microsoft.Win32.SafeHandles.SafeFileHandle hObject); 148 | 149 | [DllImport("user32.dll")] 150 | static public extern short GetKeyState(int virtualKeyCode); 151 | 152 | [DllImport("kernel32.dll")] 153 | static public extern bool Beep(uint Freq, uint Duration); 154 | 155 | [Flags] 156 | public enum DesiredAccess : uint 157 | { 158 | GENERIC_READ = 0x80000000, 159 | GENERIC_WRITE = 0x40000000, 160 | } 161 | 162 | [Flags] 163 | public enum ShareMode : uint 164 | { 165 | FILE_SHARE_READ = 0x00000001, 166 | FILE_SHARE_WRITE = 0x00000002, 167 | } 168 | 169 | #endregion 170 | 171 | #region General Console Funtions 172 | 173 | [DllImport("Kernel32.dll")] 174 | public static extern IntPtr GetConsoleWindow(); 175 | 176 | 177 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 178 | // Size is a Byte Count 179 | public static extern uint GetConsoleTitle(StringBuilder ConsoleTitle, uint Size); 180 | 181 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 182 | // Size is a Character Count 183 | public static extern uint GetConsoleOriginalTitle(StringBuilder ConsoleTitle, uint Size); 184 | 185 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 186 | public static extern bool SetConsoleTitle(string ConsoleTitle); 187 | 188 | 189 | [DllImport("Kernel32.dll")] 190 | public static extern uint GetConsoleCP(); 191 | 192 | [DllImport("Kernel32.dll")] 193 | public static extern uint GetConsoleOutputCP(); 194 | 195 | [DllImport("Kernel32.dll", SetLastError = true)] 196 | public static extern bool SetConsoleCP(uint CodePageID); 197 | 198 | [DllImport("Kernel32.dll", SetLastError = true)] 199 | public static extern bool SetConsoleOutputCP(uint CodePageID); 200 | 201 | 202 | 203 | [DllImport("Kernel32.dll", SetLastError = true)] 204 | public static extern bool AllocConsole(); 205 | 206 | [DllImport("Kernel32.dll", SetLastError = true)] 207 | public static extern bool FreeConsole(); 208 | 209 | [DllImport("Kernel32.dll", SetLastError = true)] 210 | public static extern bool AttachConsole(uint ProcessID); 211 | 212 | [DllImport("Kernel32.dll", SetLastError = true)] 213 | static public extern uint GetConsoleProcessList([Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] ProcessList, uint ProcessCount); 214 | 215 | 216 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 217 | public static extern bool AddConsoleAlias(string Source, string Target, string ExeName); 218 | 219 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 220 | // TargetBufferLength is a Byte Count 221 | public static extern uint GetConsoleAlias(string Source, StringBuilder TargetBuffer, uint TargetBufferLength, string ExeName); 222 | 223 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 224 | // AliasBufferLength is a Byte Count 225 | public static extern uint GetConsoleAliases([Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] char[] AliasBuffer, uint AliasBufferLength, string ExeName); 226 | 227 | [DllImport("Kernel32.dll")] 228 | // Return value is a Character count 229 | static public extern uint GetConsoleAliasesLength(string ExeName); 230 | 231 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 232 | // ExeNameBufferLength is a Byte Count 233 | public static extern uint GetConsoleAliasExes([Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] char[] ExeNameBuffer, uint ExeNameBufferLength); 234 | 235 | [DllImport("Kernel32.dll")] 236 | // Return value is a Character count 237 | static public extern uint GetConsoleAliasExesLength(); 238 | 239 | 240 | [DllImport("Kernel32.dll", SetLastError = true)] 241 | static public extern bool GetConsoleHistoryInfo(ref ConsoleHistoryInfo ConsoleHistoryInfo); 242 | 243 | [DllImport("Kernel32.dll", SetLastError = true)] 244 | static public extern bool SetConsoleHistoryInfo(ref ConsoleHistoryInfo ConsoleHistoryInfo); 245 | 246 | 247 | [DllImport("Kernel32.dll", SetLastError = true)] 248 | static public extern bool GetConsoleSelectionInfo(out ConsoleSelectionInfo ConsoleSelectionInfo); 249 | 250 | [DllImport("Kernel32.dll", SetLastError = true)] 251 | static public extern bool SetConsoleCtrlHandler(CtrlHandlerRoutine HandlerRoutine, bool Add); 252 | 253 | [DllImport("Kernel32.dll", SetLastError = true)] 254 | static public extern bool GenerateConsoleCtrlEvent(ConsoleExCtrlEventType dwCtrlEvent, uint ProcessGroupId); 255 | 256 | 257 | [DllImport("Kernel32.dll", SetLastError = true)] 258 | static public extern IntPtr GetStdHandle(StdHandleType StdHandle); 259 | 260 | [DllImport("Kernel32.dll", SetLastError = true)] 261 | static public extern bool SetStdHandle(StdHandleType StdHandle, Microsoft.Win32.SafeHandles.SafeFileHandle Handle); 262 | 263 | 264 | [DllImport("kernel32.dll", SetLastError = true)] 265 | static public extern bool GetConsoleDisplayMode(out ConsoleExDisplayModeFlags ModeFlags); 266 | 267 | 268 | [DllImport("Kernel32.dll", SetLastError = true)] 269 | static public extern bool GetNumberOfConsoleMouseButtons([Out]out uint NumberOfMouseButtons); 270 | 271 | #endregion 272 | 273 | #region Screen Buffer Functions 274 | 275 | [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "GetConsoleMode")] 276 | static public extern bool GetConsoleOutputMode(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleHandle, out ConsoleExOutputMode Mode); 277 | 278 | [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "SetConsoleMode")] 279 | static public extern bool SetConsoleOutputMode(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleHandle, ConsoleExOutputMode Mode); 280 | 281 | 282 | [DllImport("kernel32.dll", SetLastError = true)] 283 | static public extern bool SetConsoleDisplayMode(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ConsoleExDisplayModeFlags Flags, out Coord NewScreenBufferDimensions); 284 | 285 | 286 | [DllImport("Kernel32.dll", SetLastError = true)] 287 | static public extern Coord GetLargestConsoleWindowSize(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput); 288 | 289 | 290 | [DllImport("Kernel32.dll", SetLastError = true)] 291 | static public extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateConsoleScreenBuffer(DesiredAccess DesiredAccess, ShareMode ShareMode, IntPtr SecurityAttributes, ConsoleFlags Flags, IntPtr ScreenBufferData); 292 | 293 | [DllImport("Kernel32.dll", SetLastError = true)] 294 | static public extern bool SetConsoleActiveScreenBuffer(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput); 295 | 296 | 297 | 298 | [DllImport("Kernel32.dll", SetLastError = true)] 299 | static public extern bool FillConsoleOutputAttribute(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, CharacterAttributeEnum Attribute, uint Length, Coord WriteCoord, out uint NumberOfAttrsWritten); 300 | 301 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 302 | static public extern bool FillConsoleOutputCharacter(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, char Character, uint Length, Coord WriteCoord, out uint NumberOfCharsWritten); 303 | 304 | 305 | [DllImport("Kernel32.dll", SetLastError = true)] 306 | static public extern bool GetConsoleCursorInfo(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, out ConsoleCursorInfo ConsoleCursorInfo); 307 | 308 | [DllImport("Kernel32.dll", SetLastError = true)] 309 | static public extern bool SetConsoleCursorInfo(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref ConsoleCursorInfo ConsoleCursorInfo); 310 | 311 | [DllImport("Kernel32.dll", SetLastError = true)] 312 | static public extern bool SetConsoleCursorPosition(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, Coord CurrentPosition); 313 | 314 | 315 | [DllImport("Kernel32.dll", SetLastError = true)] 316 | static public extern bool GetConsoleScreenBufferInfo(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, out ConsoleScreenBufferInfo ConsoleScreenBufferInfo); 317 | 318 | [DllImport("Kernel32.dll", SetLastError = true)] 319 | static public extern bool GetConsoleScreenBufferInfoEx(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref ConsoleScreenBufferInfoEx ConsoleScreenBufferInfoEx); 320 | 321 | [DllImport("Kernel32.dll", SetLastError = true)] 322 | static public extern bool SetConsoleScreenBufferInfoEx(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref ConsoleScreenBufferInfoEx ConsoleScreenBufferInfoEx); 323 | 324 | 325 | 326 | [DllImport("Kernel32.dll", SetLastError = true)] 327 | static public extern bool SetConsoleScreenBufferSize(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, Coord Size); 328 | 329 | [DllImport("Kernel32.dll", SetLastError = true)] 330 | static public extern bool SetConsoleTextAttribute(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, CharacterAttribute Attributes); 331 | 332 | [DllImport("Kernel32.dll", SetLastError = true)] 333 | static public extern bool SetConsoleWindowInfo(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, bool Absolute, ref SmallRect ConsoleWindow); 334 | 335 | 336 | 337 | [DllImport("Kernel32.dll", SetLastError = true)] 338 | static public extern Coord GetConsoleFontSize(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, uint Font); 339 | 340 | [DllImport("Kernel32.dll", SetLastError = true)] 341 | static public extern bool GetCurrentConsoleFont(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, bool MaximumWindow, out ConsoleFontInfo ConsoleCurrentFont); 342 | 343 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 344 | static public extern bool GetCurrentConsoleFontEx(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, bool MaximumWindow, ref ConsoleFontInfoEx ConsoleCurrentFontEx); 345 | 346 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 347 | static public extern bool SetCurrentConsoleFontEx(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, bool MaximumWindow, ref ConsoleFontInfoEx ConsoleCurrentFontEx); 348 | 349 | 350 | 351 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 352 | static public extern bool ReadConsoleOutput(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] CharInfo[,] Buffer, Coord BufferSize, Coord BufferCoord, ref SmallRect ReadRegion); 353 | 354 | [DllImport("Kernel32.dll", SetLastError = true)] 355 | static public extern bool ReadConsoleOutputAttribute(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] CharacterAttribute[] Attribute, uint Length, Coord ReadCoord, out uint NumberOfAttrsRead); 356 | 357 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 358 | static public extern bool ReadConsoleOutputCharacter(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] Character, uint Length, Coord ReadCoord, out uint NumberOfCharsRead); 359 | 360 | 361 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 362 | static public extern bool WriteConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, string Buffer, uint NumberOfCharsToWrite, out uint NumberOfCharsWritten, IntPtr Reserved); 363 | 364 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 365 | static public extern bool WriteConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] Buffer, uint NumberOfCharsToWrite, out uint NumberOfCharsWritten, IntPtr Reserved); 366 | 367 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 368 | static public extern bool WriteConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref char Buffer, uint NumberOfCharsToWrite, out uint NumberOfCharsWritten, IntPtr Reserved); 369 | 370 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 371 | static public extern bool WriteConsoleOutput(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] CharInfo[,] Buffer, Coord BufferSize, Coord BufferCoord, ref SmallRect WriteRegion); 372 | 373 | [DllImport("Kernel32.dll", SetLastError = true)] 374 | static public extern bool WriteConsoleOutputAttribute(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] CharacterAttribute[] Attribute, uint Length, Coord WriteCoord, out uint NumberOfAttrsWriten); 375 | 376 | [DllImport("Kernel32.dll", SetLastError = true)] 377 | static public extern bool WriteConsoleOutputAttribute(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref CharacterAttribute Attribute, uint Length, Coord WriteCoord, out uint NumberOfAttrsWriten); 378 | 379 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 380 | static public extern bool WriteConsoleOutputCharacter(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] Character, uint Length, Coord WriteCoord, out uint NumberOfCharsWriten); 381 | 382 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 383 | static public extern bool WriteConsoleOutputCharacter(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref char Character, uint Length, Coord WriteCoord, out uint NumberOfCharsWriten); 384 | 385 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 386 | static public extern bool ScrollConsoleScreenBuffer(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref SmallRect ScrollRectangle, IntPtr Reserved, Coord DestinationOrigin, ref CharInfo Fill); 387 | 388 | // Quick hack so we don't have to try to force a SMALL_REC into an IntPtr. 389 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ScrollConsoleScreenBuffer")] 390 | static public extern bool ScrollConsoleScreenBufferWithClipping(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, ref SmallRect ScrollRectangle, ref SmallRect ClippingRectangle, Coord DestinationOrigin, ref CharInfo Fill); 391 | 392 | #endregion 393 | 394 | #region Input Buffer Functions 395 | 396 | [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "GetConsoleMode")] 397 | static public extern bool GetConsoleInputMode(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleHandle, out ConsoleExInputMode Mode); 398 | 399 | [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "SetConsoleMode")] 400 | static public extern bool SetConsoleInputMode(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleHandle, ConsoleExInputMode Mode); 401 | 402 | 403 | [DllImport("Kernel32.dll", SetLastError = true)] 404 | static public extern bool FlushConsoleInputBuffer(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput); 405 | 406 | 407 | [DllImport("Kernel32.dll", SetLastError = true)] 408 | static public extern bool GetNumberOfConsoleInputEvents(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, out uint NumberOfEvents); 409 | 410 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 411 | static public extern bool PeekConsoleInput(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, [Out] InputRecord[] Buffer, uint Length, out uint NumberOfEventsRead); 412 | 413 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 414 | static public extern bool ReadConsoleInput(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, [Out] InputRecord[] Buffer, uint Length, out uint NumberOfEventsRead); 415 | 416 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 417 | static public extern bool ReadConsoleInput(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, out InputRecord Buffer, uint Length, out uint NumberOfEventsRead); 418 | 419 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 420 | static public extern bool WriteConsoleInput(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, InputRecord[] Buffer, uint Length, out uint NumberOfEventsWritten); 421 | 422 | 423 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 424 | static public extern bool ReadConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, StringBuilder Buffer, uint NumberofCharsToRead, out uint NumberOfCharsRead, ref ConsoleReadConsoleControl InputControl); 425 | 426 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 427 | static public extern bool ReadConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, StringBuilder Buffer, uint NumberofCharsToRead, out uint NumberOfCharsRead, IntPtr Reserved); 428 | 429 | 430 | 431 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = "ReadConsoleA")] 432 | static public extern bool ReadConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] Buffer, uint NumberofCharsToRead, out uint NumberOfCharsRead, IntPtr Reserved); 433 | 434 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = "ReadConsoleA")] 435 | static public extern bool ReadConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleInput, ref byte Buffer, uint NumberofCharsToRead, out uint NumberOfCharsRead, IntPtr Reserved); 436 | 437 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = "WriteConsoleA")] 438 | static public extern bool WriteConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] Buffer, uint NumberOfCharsToWrite, out uint NumberOfCharsWritten, IntPtr Reserved); 439 | 440 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = "WriteConsoleA")] 441 | static public extern bool WriteConsole(Microsoft.Win32.SafeHandles.SafeFileHandle ConsoleOutput,ref byte Buffer, uint NumberOfCharsToWrite, out uint NumberOfCharsWritten, IntPtr Reserved); 442 | 443 | #endregion 444 | } 445 | } 446 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleTest/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleTest/ConsoleTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {979F9604-F884-497C-B668-887874E9033E} 8 | Exe 9 | Properties 10 | ConsoleTest 11 | ConsoleTest 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {86d20faf-a792-48ce-93f0-8f76850ecd93} 55 | ConsoleLib 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using ConsoleLib; 7 | using System.IO; 8 | 9 | namespace ConsoleTest 10 | { 11 | struct TTYFrame 12 | { 13 | public int Seconds; 14 | public int uSeconds; 15 | public int Length; 16 | public char[] FrameData; 17 | } 18 | 19 | class Program 20 | { 21 | static void Main(string[] args) 22 | { 23 | ConsoleEx.ScreenBuffer.SetWindowSize(80, 24); 24 | //ConsoleEx.ScreenBuffer.SetCursorPosition(0, ConsoleEx.ScreenBuffer.BufferHeight - ConsoleEx.ScreenBuffer.WindowHeight); 25 | //ConsoleEx.ScreenBuffer.SetWindowPosition(0, ConsoleEx.ScreenBuffer.CursorTop); 26 | 27 | //for(int x = 0; x < 50; x++) 28 | // ConsoleEx.ScreenBuffer.WriteLine("Filling out a line"); 29 | //ConsoleEx.ScreenBuffer.WriteLine("Filling out a line"); 30 | //ConsoleEx.ScreenBuffer.Write("\bFilling...123"); 31 | //ConsoleEx.ScreenBuffer.WriteLine(); 32 | 33 | TerminalEmulator Term = new TerminalEmulator(); 34 | 35 | ConsoleEx.ScreenBuffer.Write("\x01\x1b[A\x1b[100CFilling...123"); 36 | 37 | FileStream InputStream = File.Open(@"d:\putty2.log", FileMode.Open, FileAccess.Read); 38 | StreamReader Input = new StreamReader(InputStream, Encoding.ASCII); 39 | 40 | 41 | while (!Input.EndOfStream) 42 | { 43 | string Temp = Input.ReadLine(); 44 | ConsoleEx.ScreenBuffer.Write(Temp); 45 | ConsoleEx.ScreenBuffer.Write('\r'); 46 | } 47 | 48 | 49 | //int Frame = 1; 50 | 51 | //FileStream InputStream = File.Open(@"..\..\2012-10-29.07_59_36.ttyrec", FileMode.Open, FileAccess.Read); 52 | //BinaryReader Input = new BinaryReader(InputStream, Encoding.ASCII); 53 | 54 | //while (true) 55 | //{ 56 | // TTYFrame CurrentFrame = ReadFrame(Input); 57 | // if (CurrentFrame.Seconds == 0) 58 | // break; 59 | 60 | // //ConsoleEx.ScreenBuffer.WriteLine("{0}: {1}-{2} {3}", Frame, CurrentFrame.Seconds, CurrentFrame.uSeconds, CurrentFrame.Length); 61 | // Frame++; 62 | 63 | // ConsoleEx.ScreenBuffer.Write(CurrentFrame.FrameData); 64 | //} 65 | //Frame++; 66 | } 67 | 68 | static TTYFrame ReadFrame(BinaryReader Input) 69 | { 70 | TTYFrame Ret = new TTYFrame(); 71 | 72 | if (Input.BaseStream.Position == Input.BaseStream.Length) 73 | return Ret; 74 | 75 | Ret.Seconds = Input.ReadInt32(); 76 | Ret.uSeconds = Input.ReadInt32(); 77 | Ret.Length = Input.ReadInt32(); 78 | 79 | Ret.FrameData = Input.ReadChars(Ret.Length); 80 | 81 | return Ret; 82 | } 83 | 84 | 85 | /* 86 | static char[] BoxDrawingSingle = new char[] 87 | { 88 | (char)Characters.UpperLeft, 89 | (char)Characters.UpperRight, 90 | (char)Characters.LowerLeft, 91 | (char)Characters.LowerRight, 92 | (char)Characters.Vertical, 93 | (char)Characters.Horizontal, 94 | (char)Characters.CrossLeft, 95 | (char)Characters.CrossRight, 96 | (char)Characters.CrossDown, 97 | (char)Characters.CrossUp, 98 | (char)Characters.CrossMiddle, 99 | ' ', 100 | }; 101 | 102 | static char[] BoxDrawingDouble = new char[] 103 | { 104 | (char)Characters.DoubleUpperLeft, 105 | (char)Characters.DoubleUpperRight, 106 | (char)Characters.DoubleLowerLeft, 107 | (char)Characters.DoubleLowerRight, 108 | (char)Characters.DoubleVertical, 109 | (char)Characters.DoubleHorizontal, 110 | (char)Characters.DoubleCrossLeft, 111 | (char)Characters.DoubleCrossRight, 112 | (char)Characters.DoubleCrossDown, 113 | (char)Characters.DoubleCrossUp, 114 | (char)Characters.DoubleCrossMiddle, 115 | (char)Characters.LightShade, 116 | }; 117 | 118 | static char[] BoxDrawingDoubleHor = new char[] 119 | { 120 | (char)Characters.DoubleHorUpperLeft, 121 | (char)Characters.DoubleHorUpperRight, 122 | (char)Characters.DoubleHorLowerLeft, 123 | (char)Characters.DoubleHorLowerRight, 124 | (char)Characters.Vertical, 125 | (char)Characters.DoubleHorizontal, 126 | (char)Characters.DoubleHorCrossLeft, 127 | (char)Characters.DoubleHorCrossRight, 128 | (char)Characters.DoubleHorCrossDown, 129 | (char)Characters.DoubleHorCrossUp, 130 | (char)Characters.DoubleHorCrossMiddle, 131 | (char)Characters.MediumShade, 132 | }; 133 | 134 | 135 | static char[] BoxDrawingDoubleVer = new char[] 136 | { 137 | (char)Characters.DoubleVerUpperLeft, 138 | (char)Characters.DoubleVerUpperRight, 139 | (char)Characters.DoubleVerLowerLeft, 140 | (char)Characters.DoubleVerLowerRight, 141 | (char)Characters.DoubleVertical, 142 | (char)Characters.Horizontal, 143 | (char)Characters.DoubleVerCrossLeft, 144 | (char)Characters.DoubleVerCrossRight, 145 | (char)Characters.DoubleVerCrossDown, 146 | (char)Characters.DoubleVerCrossUp, 147 | (char)Characters.DoubleVerCrossMiddle, 148 | (char)Characters.DarkShade, 149 | }; 150 | 151 | 152 | static char[] BoxDrawingText = new char[] 153 | { 154 | '+', 155 | '+', 156 | '+', 157 | '+', 158 | '|', 159 | '-', 160 | '+', 161 | '+', 162 | '+', 163 | '+', 164 | '+', 165 | '#', 166 | }; 167 | 168 | static void DrawBox(char[] Elements) 169 | { 170 | //0┌ 1┐ 2└ 3┘ 4│ 5─ 6├ 7┤ 8┬ 9┴ 10┼ 11(blank) 171 | 172 | // ┌─┬─┐ 173 | ConsoleEx.ScreenBuffer.Write(Elements[0]); 174 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 175 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 176 | ConsoleEx.ScreenBuffer.Write(Elements[8]); 177 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 178 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 179 | ConsoleEx.ScreenBuffer.Write(Elements[1]); 180 | ConsoleEx.ScreenBuffer.WriteLine(); 181 | 182 | // │ │ │ 183 | ConsoleEx.ScreenBuffer.Write(Elements[4]); 184 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 185 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 186 | ConsoleEx.ScreenBuffer.Write(Elements[4]); 187 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 188 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 189 | ConsoleEx.ScreenBuffer.Write(Elements[4]); 190 | ConsoleEx.ScreenBuffer.WriteLine(); 191 | 192 | // ├─┼─┤ 193 | ConsoleEx.ScreenBuffer.Write(Elements[6]); 194 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 195 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 196 | ConsoleEx.ScreenBuffer.Write(Elements[10]); 197 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 198 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 199 | ConsoleEx.ScreenBuffer.Write(Elements[7]); 200 | ConsoleEx.ScreenBuffer.WriteLine(); 201 | 202 | // │ │ │ 203 | ConsoleEx.ScreenBuffer.Write(Elements[4]); 204 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 205 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 206 | ConsoleEx.ScreenBuffer.Write(Elements[4]); 207 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 208 | ConsoleEx.ScreenBuffer.Write(Elements[11]); 209 | ConsoleEx.ScreenBuffer.Write(Elements[4]); 210 | ConsoleEx.ScreenBuffer.WriteLine(); 211 | 212 | // └─┴─┘ 213 | ConsoleEx.ScreenBuffer.Write(Elements[2]); 214 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 215 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 216 | ConsoleEx.ScreenBuffer.Write(Elements[9]); 217 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 218 | ConsoleEx.ScreenBuffer.Write(Elements[5]); 219 | ConsoleEx.ScreenBuffer.Write(Elements[3]); 220 | ConsoleEx.ScreenBuffer.WriteLine(); 221 | } 222 | 223 | static void Main(string[] args) 224 | { 225 | 226 | DrawBox(BoxDrawingSingle); 227 | DrawBox(BoxDrawingDouble); 228 | DrawBox(BoxDrawingDoubleHor); 229 | DrawBox(BoxDrawingDoubleVer); 230 | DrawBox(BoxDrawingText); 231 | 232 | ConsoleEx.InputBuffer.LineInput = false; 233 | ConsoleEx.InputBuffer.ProcessedInput = false; 234 | ConsoleEx.InputBuffer.QuickEditMode = false; 235 | ConsoleEx.InputBuffer.MouseInput = true; 236 | //var a = ConsoleEx.InputBuffer.ReadLine(); 237 | 238 | //ConsoleEx.ScreenBuffer.ProcessedOutput = false; 239 | ConsoleEx.ScreenBuffer.SetWindowSize(80, 25); 240 | ConsoleEx.ScreenBuffer.SetBufferSize(80, 125); 241 | ConsoleEx.ScreenBuffer.Clear(); 242 | 243 | InputRecord Event = new InputRecord(); 244 | bool Done = false; 245 | do 246 | { 247 | //ConsoleEx.ScreenBuffer.SetCursorPosition(10, 10); 248 | Event = ConsoleEx.InputBuffer.NextEvent(); 249 | switch ((InputRecordType)Event.EventType) 250 | { 251 | case InputRecordType.FocusEvent: 252 | ConsoleEx.ScreenBuffer.WriteLine("F: {0}", Event.FocusEvent.SetFocus); 253 | break; 254 | 255 | case InputRecordType.MenuEvent: 256 | //ConsoleEx.ScreenBuffer.WriteLine("M:{0:x}", Event.MenuEvent.CommandID); 257 | break; 258 | 259 | case InputRecordType.WindowBufferSizeEvent: 260 | break; 261 | 262 | case InputRecordType.MouseEvent: 263 | if ((Event.MouseEvent.EventFlags & MouseEventFlags.DOUBLE_CLICK) != 0) 264 | Done = true; 265 | 266 | //ConsoleEx.ScreenBuffer.WriteLine(string.Format("{0}x{1}-{2} {3} {4}", Event.MouseEvent.MousePosition.X, Event.MouseEvent.MousePosition.Y, Event.MouseEvent.EventFlags.ToString(), Event.MouseEvent.ButtonState.ToString(), Event.MouseEvent.ControlKeyState.ToString())); 267 | //ConsoleEx.ScreenBuffer.WritePos(new CharacterAttribute(ConsoleColor.Cyan, ConsoleColor.DarkRed), Event.MouseEvent.MousePosition.X, Event.MouseEvent.MousePosition.Y); 268 | break; 269 | 270 | case InputRecordType.KeyEvent: 271 | if (ConsoleEx.InputBuffer.CanDisplay(Event.KeyEvent)) 272 | { 273 | ConsoleEx.ScreenBuffer.ProcessedOutput = false; 274 | ConsoleEx.ScreenBuffer.Write("{0:X4} ", (int)Event.KeyEvent.Character); 275 | if (Event.KeyEvent.Character > 0 && Event.KeyEvent.Character < 32) 276 | { 277 | ConsoleEx.ScreenBuffer.Write('^'); 278 | ConsoleEx.ScreenBuffer.Write((char)('A' + Event.KeyEvent.Character - 1)); 279 | } 280 | else 281 | ConsoleEx.ScreenBuffer.Write(Event.KeyEvent.Character); 282 | 283 | ConsoleEx.ScreenBuffer.ProcessedOutput = true; 284 | 285 | //if (Event.KeyEvent.Character == '\r') 286 | ConsoleEx.ScreenBuffer.Write('\n'); 287 | } 288 | //else 289 | //{ 290 | // var Key = Event.KeyEvent; 291 | 292 | // ConsoleEx.ScreenBuffer.Write("'{0}' {3:X4} {1} Rep: {2} ", (char)Key.Character, (Key.KeyDown != 0) ? "DOWN" : "UP ", Key.RepeatCount, (int)Key.Character); 293 | // ConsoleEx.ScreenBuffer.Write("Key: {0,2:X}, Scan: {1,2:X} ", Key.VirtualKeyCode, Key.VirtualScanCode); 294 | // ConsoleEx.ScreenBuffer.Write("Ctrl: {0} ", Key.ControlKeyState.ToString()); 295 | // ConsoleEx.ScreenBuffer.WriteLine(); 296 | //} 297 | break; 298 | 299 | case InputRecordType.None: 300 | default: 301 | break; 302 | } 303 | } while (!Done); 304 | 305 | 306 | //bool Done = false; 307 | //do 308 | //{ 309 | // ConsoleKeyInfo t = ConsoleEx.InputBuffer.ReadKey(true); 310 | // ConsoleEx.ScreenBuffer.Write(t.KeyChar); 311 | // if (t.KeyChar == 'q') 312 | // Done = true; 313 | 314 | //} while (!Done); 315 | 316 | 317 | //ConsoleEx.ScreenBuffer.WriteLine("Lorem ipsum dolor sit amet, nec fusce potenti eget egestas, mauris commodo felis vestibulum vestibulum. Urna consequat sed faucibus duis, ac non tristique tortor, eu tristique lacinia vehicula diam, consectetuer quisque felis sollicitudin. Non non diam duis, consectetuer a tortor est nisl. Accumsan pellentesque dictum nulla eget, elit non commodo turpis, libero in viverra nibh amet."); 318 | //ConsoleEx.InputBuffer.Flush(); 319 | //ScreenBuffer NewBuffer = new ScreenBuffer(ConsoleEx.ScreenBuffer, true); 320 | ////var old = ConsoleEx.SwapBuffers(NewBuffer); 321 | ////ConsoleEx.StdOutput = NewBuffer.Handle; 322 | //Console.Out.Write("123456789..."); 323 | 324 | //ConsoleEx.ScreenBuffer.MoveBufferArea(3, 1, 50, 4, 10, 10, '!', ConsoleColor.White, ConsoleColor.Cyan); 325 | ////ConsoleEx.ScreenBuffer.MoveBufferArea(new System.Drawing.Rectangle (3, 1, 40, 5), new System.Drawing.Rectangle (0, 0, 80, 25), new System.Drawing.Point(10, 10), '!', ConsoleColor.White, ConsoleColor.Cyan); 326 | //ConsoleEx.ScreenBuffer.Scroll(4); 327 | 328 | ////ConsoleEx.InputBuffer.EchoInput = false; 329 | //ConsoleEx.ScreenBuffer.VirtualTerminal = true; 330 | //ConsoleEx.ScreenBuffer.NewLineAutoReturn = false; 331 | //ConsoleEx.ScreenBuffer.LVBGridWoldwide = true; 332 | 333 | ////ConsoleEx.InputBuffer.Flush(); 334 | ////var a2 = ConsoleEx.InputBuffer.PeekNextEvent(true); 335 | 336 | //////var a6 = ConsoleEx.InputBuffer.NextEvent(InputRecordType.All); 337 | ////var a = ConsoleEx.InputBuffer.ReadKey(); 338 | 339 | ////ConsoleEx.InputBuffer.Mode &= ~ConsoleExInputMode.EchoInput; 340 | ////ConsoleEx.InputBuffer.Mode &= ~ConsoleExInputMode.LineInput; 341 | ////ConsoleEx.InputBuffer.Mode &= ~ConsoleExInputMode.ProcessedInput; 342 | 343 | ////ConsoleEx.OutputEncoding = System.Text.Encoding.UTF8; 344 | ////Console.OutputEncoding = System.Text.Encoding.UTF8; 345 | ////Console.InputEncoding = System.Text.Encoding.UTF8; 346 | 347 | ////ConsoleEx.OutputEncoding = System.Text.Encoding.Unicode; 348 | ////Console.OutputEncoding = System.Text.Encoding.Unicode; 349 | 350 | ////var i = ConsoleEx.In.ReadLine(); 351 | ////var i2 = ConsoleEx.InputBuffer.Stream.ReadLine(); 352 | //Console.WriteLine(); 353 | //Console.Out.WriteLine("Testing 1®"); 354 | //ConsoleEx.Out.WriteLine("Testing 2®"); 355 | //ConsoleEx.ScreenBuffer.Stream.WriteLine("Testing 3®"); 356 | ////var i = Console.In.ReadLine(); 357 | 358 | //var k = ConsoleEx.InputBuffer.ReadLine(); 359 | 360 | ////var t = ConsoleEx.Window; 361 | 362 | ////ConsoleEx.SwapBuffers(old); 363 | 364 | 365 | } 366 | */ 367 | } 368 | } 369 | -------------------------------------------------------------------------------- /ConsoleEx/ConsoleTest/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("ConsoleTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 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("6359a24e-0b86-4b84-9c1e-99d82add8152")] 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 Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Enum.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Fox Cutter 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | #include 19 | 20 | // Using type traits to allow binary operations on Enum Class types. 21 | // These work by casting down to the underlying type, then casting the result back up to the Enum type. 22 | // 23 | // On release builds, this only adds symantic overhead to the compiler, the resulting binary 24 | // will be the same as for any other integer type (usually a single opcode) 25 | template::value, bool> = true> 26 | constexpr EnumType operator | (EnumType lhs, EnumType rhs) 27 | { 28 | using BaseType = std::underlying_type_t ; 29 | return static_cast(static_cast(lhs) | static_cast(rhs)); 30 | } 31 | 32 | template::value, bool> = true> 33 | constexpr EnumType operator & (EnumType lhs, EnumType rhs) 34 | { 35 | using BaseType = std::underlying_type_t ; 36 | return static_cast(static_cast(lhs) & static_cast(rhs)); 37 | } 38 | 39 | template::value, bool> = true> 40 | constexpr EnumType operator ^ (EnumType lhs, EnumType rhs) 41 | { 42 | using BaseType = std::underlying_type_t ; 43 | return static_cast(static_cast(lhs) ^ static_cast(rhs)); 44 | } 45 | 46 | template::value, bool> = true> 47 | constexpr EnumType operator ~ (EnumType lhs) 48 | { 49 | using BaseType = std::underlying_type_t ; 50 | return static_cast(~static_cast(lhs)); 51 | } 52 | 53 | template::value, bool> = true> 54 | constexpr EnumType operator << (EnumType lhs, ShiftType rhs) 55 | { 56 | using BaseType = std::underlying_type_t ; 57 | return static_cast(static_cast(lhs) << rhs); 58 | } 59 | 60 | template::value, bool> = true> 61 | constexpr EnumType operator >> (EnumType lhs, ShiftType rhs) 62 | { 63 | using BaseType = std::underlying_type_t ; 64 | return static_cast(static_cast(lhs) >> rhs); 65 | } 66 | 67 | 68 | 69 | // Assignment Operators 70 | template::value, bool> = true> 71 | constexpr EnumType operator |= (EnumType& lhs, EnumType rhs) 72 | { 73 | lhs = lhs | rhs; 74 | return lhs; 75 | } 76 | 77 | template::value, bool> = true> 78 | constexpr EnumType operator &= (EnumType& lhs, EnumType rhs) 79 | { 80 | lhs = lhs & rhs; 81 | return lhs; 82 | } 83 | 84 | template::value, bool> = true> 85 | constexpr EnumType operator ^= (EnumType& lhs, EnumType rhs) 86 | { 87 | lhs = lhs ^ rhs; 88 | return lhs; 89 | } 90 | 91 | template::value, bool> = true> 92 | constexpr EnumType operator <<= (EnumType& lhs, ShiftType rhs) 93 | { 94 | lhs = lhs << rhs; 95 | return lhs; 96 | } 97 | 98 | template::value, bool> = true> 99 | constexpr EnumType operator >>= (EnumType& lhs, ShiftType rhs) 100 | { 101 | lhs = lhs >> rhs; 102 | return lhs; 103 | } 104 | 105 | 106 | // Math operators 107 | template::value, bool> = true> 108 | constexpr EnumType operator - (EnumType lhs, EnumType rhs) 109 | { 110 | using BaseType = std::underlying_type_t ; 111 | return static_cast(static_cast(lhs) - static_cast(rhs)); 112 | } 113 | 114 | template::value, bool> = true> 115 | constexpr EnumType operator + (EnumType lhs, EnumType rhs) 116 | { 117 | using BaseType = std::underlying_type_t ; 118 | return static_cast(static_cast(lhs) + static_cast(rhs)); 119 | } 120 | 121 | 122 | template::value, bool> = true> 123 | constexpr EnumType operator ++ (EnumType& lhs) // ++lhs 124 | { 125 | using BaseType = std::underlying_type_t ; 126 | lhs = static_cast(static_cast(lhs) + 1); 127 | return lhs; 128 | } 129 | 130 | template::value, bool> = true> 131 | constexpr EnumType operator ++ (EnumType& lhs, int) // lhs++ 132 | { 133 | using BaseType = std::underlying_type_t ; 134 | EnumType val = lhs; 135 | ++lhs; 136 | return val; 137 | } 138 | 139 | template::value, bool> = true> 140 | constexpr EnumType operator -- (EnumType& lhs) // --lhs 141 | { 142 | using BaseType = std::underlying_type_t ; 143 | lhs = static_cast(static_cast(lhs) - 1); 144 | return lhs; 145 | } 146 | 147 | template::value, bool> = true> 148 | constexpr EnumType operator -- (EnumType& lhs, int) // lhs++ 149 | { 150 | using BaseType = std::underlying_type_t ; 151 | EnumType val = lhs; 152 | --lhs; 153 | return val; 154 | } 155 | 156 | // Generic test function 157 | template::value, bool> = true> 158 | constexpr bool HasFlag(EnumType Value, EnumType Flag) 159 | { 160 | return (Value & Flag) == Flag; 161 | } 162 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023, Fox Cutter 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tools 2 | A collection of presonal tools and other utilities 3 | -------------------------------------------------------------------------------- /SlowCapture/README.md: -------------------------------------------------------------------------------- 1 | # Slow Capture 2 | 3 | Slow Capture is as simple tool to allow streaming of programs that can't be captured by most streaming applications. All it does is take image capture of the application's client, and then displays it on it's own main window. 4 | 5 | This simple approach works in many cases that streaming applications such as OBS or XSplit may fail on. This is because the method that it uses to capture the application is much slower then what streaming programs use, and can have some noticeable delay (10-15 fps is not uncommon). 6 | 7 | ## Why use this instead of 'Desktop Capture' 8 | 9 | Desktop capture is a brute force solution, capturing everything on a specific part of the desktop. This does capture the program in question, but it also captures anything that might be over it (or under if the window is moved or closed). This is a huge security risk these days, so it was better to have the extra step to make sure you have full control over what is streamed. 10 | 11 | ## What applications does Slow Capture support 12 | 13 | In theory it should support any Windows application. It was written with the current version of Microsoft Office in mind, allowing them to be captured for streaming/recording. 14 | 15 | ## Features 16 | 17 | Slow Capture can match a window based on both the application name and optionally the title of the window. In addition to that, Slow Capture can also crop and resize the captured image (Just in case your streaming app of choice can't do so). 18 | 19 | ## Requirements 20 | 21 | .Net Framework 4.6.1 is needed for the program to work. 22 | 23 | ## Installation 24 | 25 | The program is provided as a single EXE file, and should be able to run in place. The settings file will be written to the current directory. 26 | 27 | ## How does it capture windows that streaming programs can't 28 | 29 | By using a different API, as Slow Capture isn't worried about being super fast, it's not using any of the direct methods of capturing the window. Instead it is using those, it uses the "PrintWindow" API. This is a way to 'print' the contents of a window to an arbitrary device context. This is meant for a simple way to render a window to a printer, but works just fine for capturing it for streaming. 30 | 31 | ## Long Term Goals 32 | 33 | In all honestly, the long term goal hope is that this program will become obsolete. It works as a proof of concept for using the PrintWindow API to capture a window, and hopefully streaming programs will add it as a native feature in the future. 34 | 35 | ## Attribution 36 | 37 | Icons made by [Freepik](https://www.flaticon.com/authors/freepik) from [Flaticon](https://www.flaticon.com/) 38 | 39 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.705 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlowCapture", "SlowCapture\SlowCapture.csproj", "{D1415B66-8920-4E72-BA26-AC4050470FFE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D1415B66-8920-4E72-BA26-AC4050470FFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D1415B66-8920-4E72-BA26-AC4050470FFE}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D1415B66-8920-4E72-BA26-AC4050470FFE}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D1415B66-8920-4E72-BA26-AC4050470FFE}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2FF47A72-51D5-4642-B557-E59ECC35C834} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/CaptureOptions.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SlowCapture 2 | { 3 | partial class CaptureOptions 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 Windows Form 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.components = new System.ComponentModel.Container(); 32 | System.Windows.Forms.Label label1; 33 | System.Windows.Forms.Label label2; 34 | this.WindowDropdown = new System.Windows.Forms.ComboBox(); 35 | this.MatchTitleCheck = new System.Windows.Forms.CheckBox(); 36 | this.OKButton = new System.Windows.Forms.Button(); 37 | this.AbortButton = new System.Windows.Forms.Button(); 38 | this.CapturePreview = new System.Windows.Forms.PictureBox(); 39 | this.TopmostOnlyCheck = new System.Windows.Forms.CheckBox(); 40 | this.MethodDropdown = new System.Windows.Forms.ComboBox(); 41 | this.UpdateTimer = new System.Windows.Forms.Timer(this.components); 42 | label1 = new System.Windows.Forms.Label(); 43 | label2 = new System.Windows.Forms.Label(); 44 | ((System.ComponentModel.ISupportInitialize)(this.CapturePreview)).BeginInit(); 45 | this.SuspendLayout(); 46 | // 47 | // label1 48 | // 49 | label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 50 | | System.Windows.Forms.AnchorStyles.Right))); 51 | label1.AutoSize = true; 52 | label1.Location = new System.Drawing.Point(9, 228); 53 | label1.Name = "label1"; 54 | label1.Size = new System.Drawing.Size(46, 13); 55 | label1.TabIndex = 0; 56 | label1.Text = "Window"; 57 | // 58 | // WindowDropdown 59 | // 60 | this.WindowDropdown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 61 | | System.Windows.Forms.AnchorStyles.Right))); 62 | this.WindowDropdown.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 63 | this.WindowDropdown.FormattingEnabled = true; 64 | this.WindowDropdown.Location = new System.Drawing.Point(59, 225); 65 | this.WindowDropdown.Name = "WindowDropdown"; 66 | this.WindowDropdown.Size = new System.Drawing.Size(429, 21); 67 | this.WindowDropdown.TabIndex = 1; 68 | this.WindowDropdown.SelectedIndexChanged += new System.EventHandler(this.WindowDropdown_SelectedIndexChanged); 69 | // 70 | // MatchTitleCheck 71 | // 72 | this.MatchTitleCheck.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 73 | | System.Windows.Forms.AnchorStyles.Right))); 74 | this.MatchTitleCheck.AutoSize = true; 75 | this.MatchTitleCheck.Location = new System.Drawing.Point(59, 279); 76 | this.MatchTitleCheck.Name = "MatchTitleCheck"; 77 | this.MatchTitleCheck.Size = new System.Drawing.Size(79, 17); 78 | this.MatchTitleCheck.TabIndex = 4; 79 | this.MatchTitleCheck.Text = "Match Title"; 80 | this.MatchTitleCheck.UseVisualStyleBackColor = true; 81 | this.MatchTitleCheck.CheckedChanged += new System.EventHandler(this.MatchTitleCheck_CheckedChanged); 82 | // 83 | // OKButton 84 | // 85 | this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 86 | this.OKButton.Location = new System.Drawing.Point(315, 314); 87 | this.OKButton.Name = "OKButton"; 88 | this.OKButton.Size = new System.Drawing.Size(77, 23); 89 | this.OKButton.TabIndex = 6; 90 | this.OKButton.Text = "OK"; 91 | this.OKButton.UseVisualStyleBackColor = true; 92 | this.OKButton.Click += new System.EventHandler(this.OKButton_Click); 93 | // 94 | // AbortButton 95 | // 96 | this.AbortButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 97 | this.AbortButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; 98 | this.AbortButton.Location = new System.Drawing.Point(405, 314); 99 | this.AbortButton.Name = "AbortButton"; 100 | this.AbortButton.Size = new System.Drawing.Size(77, 23); 101 | this.AbortButton.TabIndex = 7; 102 | this.AbortButton.Text = "Cancel"; 103 | this.AbortButton.UseVisualStyleBackColor = true; 104 | this.AbortButton.Click += new System.EventHandler(this.CancelButton_Click); 105 | // 106 | // CapturePreview 107 | // 108 | this.CapturePreview.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 109 | | System.Windows.Forms.AnchorStyles.Left) 110 | | System.Windows.Forms.AnchorStyles.Right))); 111 | this.CapturePreview.BackColor = System.Drawing.SystemColors.ControlDark; 112 | this.CapturePreview.Location = new System.Drawing.Point(12, 12); 113 | this.CapturePreview.Name = "CapturePreview"; 114 | this.CapturePreview.Size = new System.Drawing.Size(479, 207); 115 | this.CapturePreview.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 116 | this.CapturePreview.TabIndex = 4; 117 | this.CapturePreview.TabStop = false; 118 | // 119 | // TopmostOnlyCheck 120 | // 121 | this.TopmostOnlyCheck.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 122 | | System.Windows.Forms.AnchorStyles.Right))); 123 | this.TopmostOnlyCheck.AutoSize = true; 124 | this.TopmostOnlyCheck.Location = new System.Drawing.Point(59, 302); 125 | this.TopmostOnlyCheck.Name = "TopmostOnlyCheck"; 126 | this.TopmostOnlyCheck.Size = new System.Drawing.Size(91, 17); 127 | this.TopmostOnlyCheck.TabIndex = 5; 128 | this.TopmostOnlyCheck.Text = "Topmost Only"; 129 | this.TopmostOnlyCheck.UseVisualStyleBackColor = true; 130 | this.TopmostOnlyCheck.CheckedChanged += new System.EventHandler(this.TopmostOnlyCheck_CheckedChanged); 131 | // 132 | // label2 133 | // 134 | label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 135 | | System.Windows.Forms.AnchorStyles.Right))); 136 | label2.AutoSize = true; 137 | label2.Location = new System.Drawing.Point(12, 254); 138 | label2.Name = "label2"; 139 | label2.Size = new System.Drawing.Size(43, 13); 140 | label2.TabIndex = 2; 141 | label2.Text = "Method"; 142 | // 143 | // MethodDropdown 144 | // 145 | this.MethodDropdown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 146 | | System.Windows.Forms.AnchorStyles.Right))); 147 | this.MethodDropdown.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 148 | this.MethodDropdown.FormattingEnabled = true; 149 | this.MethodDropdown.Items.AddRange(new object[] { 150 | "Direct Capture", 151 | "Desktop Capture"}); 152 | this.MethodDropdown.Location = new System.Drawing.Point(59, 251); 153 | this.MethodDropdown.Name = "MethodDropdown"; 154 | this.MethodDropdown.Size = new System.Drawing.Size(429, 21); 155 | this.MethodDropdown.TabIndex = 3; 156 | this.MethodDropdown.SelectedIndexChanged += new System.EventHandler(this.MethodDropdown_SelectedIndexChanged); 157 | // 158 | // UpdateTimer 159 | // 160 | this.UpdateTimer.Enabled = true; 161 | this.UpdateTimer.Interval = 250; 162 | this.UpdateTimer.Tick += new System.EventHandler(this.UpdateTimer_Tick); 163 | // 164 | // CaptureOptions 165 | // 166 | this.AcceptButton = this.OKButton; 167 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 168 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 169 | this.CancelButton = this.AbortButton; 170 | this.ClientSize = new System.Drawing.Size(500, 344); 171 | this.Controls.Add(this.MethodDropdown); 172 | this.Controls.Add(label2); 173 | this.Controls.Add(this.TopmostOnlyCheck); 174 | this.Controls.Add(this.CapturePreview); 175 | this.Controls.Add(this.AbortButton); 176 | this.Controls.Add(this.OKButton); 177 | this.Controls.Add(label1); 178 | this.Controls.Add(this.WindowDropdown); 179 | this.Controls.Add(this.MatchTitleCheck); 180 | this.MaximizeBox = false; 181 | this.MinimizeBox = false; 182 | this.MinimumSize = new System.Drawing.Size(512, 360); 183 | this.Name = "CaptureOptions"; 184 | this.ShowIcon = false; 185 | this.ShowInTaskbar = false; 186 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; 187 | this.Text = "Capture Options"; 188 | this.Load += new System.EventHandler(this.CaptureOptions_Load); 189 | ((System.ComponentModel.ISupportInitialize)(this.CapturePreview)).EndInit(); 190 | this.ResumeLayout(false); 191 | this.PerformLayout(); 192 | 193 | } 194 | 195 | #endregion 196 | 197 | private System.Windows.Forms.ComboBox WindowDropdown; 198 | private System.Windows.Forms.CheckBox MatchTitleCheck; 199 | private System.Windows.Forms.Button OKButton; 200 | private System.Windows.Forms.Button AbortButton; 201 | private System.Windows.Forms.PictureBox CapturePreview; 202 | private System.Windows.Forms.CheckBox TopmostOnlyCheck; 203 | private System.Windows.Forms.ComboBox MethodDropdown; 204 | private System.Windows.Forms.Timer UpdateTimer; 205 | } 206 | } -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/CaptureOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace SlowCapture 12 | { 13 | public partial class CaptureOptions : Form 14 | { 15 | public bool MatchTitle { get; set; } 16 | public string WindowName { get; set; } 17 | public string WindowTitle { get; set; } 18 | public IntPtr WindowHandle { get; set; } 19 | 20 | public bool TopmostOnly { get; set; } 21 | public CaptureMethod Method { get; set; } 22 | 23 | public CaptureOptions() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | struct WindowData 29 | { 30 | public string Name; 31 | public string Title; 32 | public IntPtr Handle; 33 | 34 | public override string ToString() 35 | { 36 | return string.Format("[{0}] - {1}", Name, Title); 37 | } 38 | 39 | } 40 | 41 | private bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam) 42 | { 43 | int style = ExternalAPI.GetWindowLong(hWnd, -16); 44 | int Exstyle = ExternalAPI.GetWindowLong(hWnd, -20); 45 | 46 | if (!ExternalAPI.IsWindowVisible(hWnd)) 47 | return true; 48 | 49 | // Ignore Popup windows 50 | if ((style & 0x80000000) != 0) 51 | return true; 52 | 53 | uint ProcessID; 54 | StringBuilder TempString = new StringBuilder(); 55 | 56 | ExternalAPI.GetWindowThreadProcessId(hWnd, out ProcessID); 57 | 58 | IntPtr ProcessHandle = ExternalAPI.OpenProcess(0x0400, false, ProcessID); 59 | 60 | TempString.EnsureCapacity(1024); 61 | ExternalAPI.GetModuleFileNameEx(ProcessHandle, IntPtr.Zero, TempString, TempString.Capacity); 62 | 63 | if (TempString.ToString() == System.Reflection.Assembly.GetExecutingAssembly().Location) 64 | return true; 65 | 66 | WindowData Entry; 67 | Entry.Handle = hWnd; 68 | Entry.Name = System.IO.Path.GetFileNameWithoutExtension(TempString.ToString()); 69 | 70 | ExternalAPI.CloseHandle(ProcessHandle); 71 | 72 | int size = ExternalAPI.GetWindowTextLength(hWnd); 73 | if (size != 0) 74 | { 75 | TempString.EnsureCapacity(size + 1); 76 | ExternalAPI.GetWindowText(hWnd, TempString, TempString.Capacity); 77 | 78 | Entry.Title = TempString.ToString(); 79 | } 80 | else 81 | { 82 | Entry.Title = ""; 83 | } 84 | 85 | WindowDropdown.Items.Add(Entry); 86 | 87 | return true; 88 | } 89 | 90 | private void CaptureOptions_Load(object sender, EventArgs e) 91 | { 92 | WindowDropdown.Items.Clear(); 93 | WindowHandle = IntPtr.Zero; 94 | 95 | ExternalAPI.EnumWindows(new ExternalAPI.EnumWindowsProc(EnumWindowsCallback), IntPtr.Zero); 96 | 97 | foreach(WindowData Data in WindowDropdown.Items) 98 | { 99 | if(Data.Name.Equals(WindowName, StringComparison.InvariantCultureIgnoreCase)) 100 | { 101 | if(MatchTitle) 102 | { 103 | if (Data.Title != WindowTitle) 104 | continue; 105 | } 106 | 107 | WindowDropdown.SelectedItem = Data; 108 | break; 109 | } 110 | } 111 | 112 | MatchTitleCheck.Checked = MatchTitle; 113 | TopmostOnlyCheck.Checked = TopmostOnly; 114 | 115 | MethodDropdown.SelectedIndex = (int)Method; 116 | } 117 | 118 | private void MatchTitleCheck_CheckedChanged(object sender, EventArgs e) 119 | { 120 | MatchTitle = MatchTitleCheck.Checked; 121 | } 122 | 123 | private void WindowDropdown_SelectedIndexChanged(object sender, EventArgs e) 124 | { 125 | WindowData Data = (WindowData)WindowDropdown.SelectedItem; 126 | 127 | WindowName = Data.Name; 128 | WindowTitle = Data.Title; 129 | WindowHandle = Data.Handle; 130 | } 131 | 132 | private void OKButton_Click(object sender, EventArgs e) 133 | { 134 | this.DialogResult = DialogResult.OK; 135 | this.Close(); 136 | } 137 | 138 | private void CancelButton_Click(object sender, EventArgs e) 139 | { 140 | this.DialogResult = DialogResult.Cancel; 141 | this.Close(); 142 | 143 | } 144 | 145 | private void MethodDropdown_SelectedIndexChanged(object sender, EventArgs e) 146 | { 147 | Method = (CaptureMethod)MethodDropdown.SelectedIndex; 148 | } 149 | 150 | private void TopmostOnlyCheck_CheckedChanged(object sender, EventArgs e) 151 | { 152 | TopmostOnly = TopmostOnlyCheck.Checked; 153 | } 154 | 155 | private void UpdateTimer_Tick(object sender, EventArgs e) 156 | { 157 | if (TopmostOnly && ExternalAPI.GetForegroundWindow() != WindowHandle) 158 | return; 159 | 160 | if (CapturePreview.Image != null) 161 | CapturePreview.Image.Dispose(); 162 | 163 | CapturePreview.Image = ExternalAPI.CaptureWindow(WindowHandle, Method); 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/CaptureOptions.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 | False 122 | 123 | 124 | False 125 | 126 | 127 | 17, 17 128 | 129 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/ExternalAPI.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.Drawing; 7 | using System.Drawing.Imaging; 8 | using System.Runtime.InteropServices; 9 | 10 | 11 | namespace SlowCapture 12 | { 13 | public class ExternalAPI 14 | { 15 | [StructLayout(LayoutKind.Sequential)] 16 | public struct Rect 17 | { 18 | public int left; 19 | public int top; 20 | public int right; 21 | public int bottom; 22 | } 23 | 24 | [StructLayout(LayoutKind.Sequential)] 25 | public struct Point 26 | { 27 | public int x; 28 | public int y; 29 | } 30 | 31 | public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); 32 | 33 | [DllImport("user32.dll")] 34 | public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); 35 | 36 | [DllImport("user32.dll", CharSet = CharSet.Unicode)] 37 | public static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount); 38 | 39 | [DllImport("user32.dll", CharSet = CharSet.Unicode)] 40 | public static extern int GetWindowTextLength(IntPtr hWnd); 41 | 42 | [DllImport("user32.dll")] 43 | public static extern bool IsWindowVisible(IntPtr hWnd); 44 | 45 | [DllImport("user32.dll")] 46 | public static extern bool IsWindow(IntPtr hWnd); 47 | 48 | [DllImport("user32.dll")] 49 | public static extern bool IsIconic(IntPtr hWnd); 50 | 51 | [DllImport("user32.dll")] 52 | public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect); 53 | 54 | [DllImport("user32.dll")] 55 | public static extern IntPtr GetParent(IntPtr hWnd); 56 | 57 | [DllImport("user32.dll")] 58 | public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); 59 | 60 | [DllImport("user32.dll", CharSet = CharSet.Unicode)] 61 | public static extern int GetWindowLong(IntPtr hWnd, int Index); 62 | 63 | [DllImport("user32.dll")] 64 | public static extern IntPtr GetClientRect(IntPtr hWnd, ref Rect rect); 65 | 66 | [DllImport("user32.dll")] 67 | public static extern IntPtr ClientToScreen(IntPtr hWnd, ref Point point); 68 | 69 | [DllImport("user32.dll")] 70 | public static extern IntPtr GetForegroundWindow(); 71 | 72 | [DllImport("user32.dll")] 73 | public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags); 74 | 75 | 76 | [DllImport("user32.dll")] 77 | public static extern IntPtr CreateMenu(); 78 | 79 | [DllImport("user32.dll")] 80 | public static extern int GetSystemMetrics(int nIndex); 81 | 82 | [DllImport("user32.dll")] 83 | public static extern bool SetMenu(IntPtr hWnd, IntPtr hMenu); 84 | 85 | [DllImport("user32.dll")] 86 | public static extern bool AppendMenu(IntPtr hMenu, uint uFlags, uint uIDNewItem, string NewItem); 87 | 88 | [DllImport("Psapi.dll", CharSet = CharSet.Unicode)] 89 | public static extern int GetProcessImageFileName(IntPtr hProcess, StringBuilder lpImageFileName, int nSize); 90 | 91 | [DllImport("Psapi.dll", CharSet = CharSet.Unicode)] 92 | public static extern int GetModuleFileNameEx(IntPtr Process, IntPtr hModule, StringBuilder lpFilename, int nSize); 93 | 94 | [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] 95 | public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, uint dwProcessId); 96 | 97 | [DllImport("Kernel32.dll")] 98 | public static extern bool CloseHandle(IntPtr hObject); 99 | 100 | [DllImport("kernel32", CharSet = CharSet.Unicode)] 101 | public static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName); 102 | 103 | [DllImport("kernel32", CharSet = CharSet.Unicode)] 104 | public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName); 105 | 106 | public static Bitmap CaptureWindow(IntPtr hWnd, CaptureMethod Method) 107 | { 108 | if (hWnd == IntPtr.Zero) 109 | return null; 110 | 111 | int style = ExternalAPI.GetWindowLong(hWnd, -16); 112 | //int Exstyle = ExternalAPI.GetWindowLong(hWnd, -20); 113 | 114 | // Ignore Popup windows 115 | if ((style & 0x80000000) != 0) 116 | return null; 117 | 118 | var winrect = new ExternalAPI.Rect(); 119 | ExternalAPI.GetWindowRect(hWnd, ref winrect); 120 | 121 | var clientrec = new ExternalAPI.Rect(); 122 | ExternalAPI.GetClientRect(hWnd, ref clientrec); 123 | 124 | int width = clientrec.right - clientrec.left; 125 | int height = clientrec.bottom - clientrec.top; 126 | 127 | if (width <= 0 || height <= 0) 128 | return null; 129 | 130 | var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); 131 | 132 | using (Graphics graphics = Graphics.FromImage(bmp)) 133 | { 134 | if (Method == CaptureMethod.PaintWindow) 135 | { 136 | IntPtr Handle = graphics.GetHdc(); 137 | 138 | ExternalAPI.PrintWindow(hWnd, Handle, 1); 139 | 140 | graphics.ReleaseHdc(Handle); 141 | } 142 | else if (Method == CaptureMethod.DesktopCapture) 143 | { 144 | var tempPoint = new Point(); 145 | tempPoint.x = clientrec.left; 146 | tempPoint.y = clientrec.top; 147 | ClientToScreen(hWnd, ref tempPoint); 148 | 149 | graphics.CopyFromScreen(tempPoint.x, tempPoint.y, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy); 150 | } 151 | } 152 | 153 | return bmp; 154 | 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SlowCapture 2 | { 3 | partial class MainForm 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 Windows Form 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 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 32 | this.PreviewScreen = new System.Windows.Forms.PictureBox(); 33 | ((System.ComponentModel.ISupportInitialize)(this.PreviewScreen)).BeginInit(); 34 | this.SuspendLayout(); 35 | // 36 | // PreviewScreen 37 | // 38 | this.PreviewScreen.BackColor = System.Drawing.SystemColors.ControlDark; 39 | this.PreviewScreen.Dock = System.Windows.Forms.DockStyle.Fill; 40 | this.PreviewScreen.Location = new System.Drawing.Point(0, 0); 41 | this.PreviewScreen.Name = "PreviewScreen"; 42 | this.PreviewScreen.Size = new System.Drawing.Size(456, 291); 43 | this.PreviewScreen.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 44 | this.PreviewScreen.TabIndex = 1; 45 | this.PreviewScreen.TabStop = false; 46 | // 47 | // MainForm 48 | // 49 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 50 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 51 | this.BackColor = System.Drawing.SystemColors.Control; 52 | this.ClientSize = new System.Drawing.Size(456, 291); 53 | this.Controls.Add(this.PreviewScreen); 54 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 55 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 56 | this.Name = "MainForm"; 57 | this.Text = "Slow Capture"; 58 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); 59 | this.Load += new System.EventHandler(this.MainForm_Load); 60 | ((System.ComponentModel.ISupportInitialize)(this.PreviewScreen)).EndInit(); 61 | this.ResumeLayout(false); 62 | 63 | } 64 | 65 | #endregion 66 | private System.Windows.Forms.PictureBox PreviewScreen; 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Drawing.Imaging; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | using System.Diagnostics; 12 | 13 | //
Icons made by Freepik from www.flaticon.com
14 | 15 | namespace SlowCapture 16 | { 17 | public enum CaptureMethod 18 | { 19 | PaintWindow, 20 | DesktopCapture, 21 | } 22 | 23 | public partial class MainForm : Form 24 | { 25 | CaptureOptions CaptureOptionsWindow = new CaptureOptions(); 26 | SettingOptions SettingOptionsWindow = new SettingOptions(); 27 | 28 | private string WindowName = ""; 29 | private string WindowTitle = ""; 30 | private bool MatchWindowTitle = false; 31 | private IntPtr MatchWindowHandle = IntPtr.Zero; 32 | 33 | private bool TopmostOnly = false; 34 | private CaptureMethod Method = CaptureMethod.PaintWindow; 35 | 36 | private bool ResizeOutput = false; 37 | public int ResizeOutputHeight = 720; 38 | public int ResizeOutputWidth = 1024; 39 | 40 | public int CroppingTop = 0; 41 | public int CroppingBottom = 0; 42 | public int CroppingLeft = 0; 43 | public int CroppingRight = 0; 44 | 45 | public int CaptureRate = 0; 46 | 47 | string SettingsFile = ""; 48 | 49 | public MainForm() 50 | { 51 | InitializeComponent(); 52 | 53 | SettingsFile = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "SlowCapture.ini"); 54 | 55 | LoadSettings(); 56 | } 57 | 58 | protected override void WndProc(ref Message m) 59 | { 60 | if(m.Msg == 0x111) // WM_COMMAND 61 | { 62 | int ID = m.WParam.ToInt32(); 63 | if((ID & 0xFFFF) == 0x3000) 64 | { 65 | CaptureOptionsWindow.WindowName = WindowName; 66 | CaptureOptionsWindow.WindowTitle = WindowTitle; 67 | CaptureOptionsWindow.MatchTitle = MatchWindowTitle; 68 | CaptureOptionsWindow.TopmostOnly = TopmostOnly; 69 | CaptureOptionsWindow.Method = Method; 70 | 71 | if (CaptureOptionsWindow.ShowDialog(this) == DialogResult.OK) 72 | { 73 | WindowName = CaptureOptionsWindow.WindowName; 74 | WindowTitle = CaptureOptionsWindow.WindowTitle; 75 | MatchWindowTitle = CaptureOptionsWindow.MatchTitle; 76 | MatchWindowHandle = CaptureOptionsWindow.WindowHandle; 77 | TopmostOnly = CaptureOptionsWindow.TopmostOnly; 78 | Method = CaptureOptionsWindow.Method; 79 | } 80 | } 81 | else if ((ID & 0xFFFF) == 0x3001) 82 | { 83 | SettingOptionsWindow.ResizeOutput = ResizeOutput; 84 | SettingOptionsWindow.ResizeOutputHeight = ResizeOutputHeight; 85 | SettingOptionsWindow.ResizeOutputWidth = ResizeOutputWidth; 86 | 87 | SettingOptionsWindow.CroppingTop = CroppingTop; 88 | SettingOptionsWindow.CroppingBottom = CroppingBottom; 89 | SettingOptionsWindow.CroppingLeft = CroppingLeft; 90 | SettingOptionsWindow.CroppingRight = CroppingRight; 91 | 92 | SettingOptionsWindow.CaptureRate = CaptureRate; 93 | 94 | if(SettingOptionsWindow.ShowDialog(this) == DialogResult.OK) 95 | { 96 | ResizeOutput = SettingOptionsWindow.ResizeOutput; 97 | ResizeOutputHeight = SettingOptionsWindow.ResizeOutputHeight; 98 | ResizeOutputWidth = SettingOptionsWindow.ResizeOutputWidth; 99 | 100 | CroppingTop = SettingOptionsWindow.CroppingTop; 101 | CroppingBottom = SettingOptionsWindow.CroppingBottom; 102 | CroppingLeft = SettingOptionsWindow.CroppingLeft; 103 | CroppingRight = SettingOptionsWindow.CroppingRight; 104 | CaptureRate = SettingOptionsWindow.CaptureRate; 105 | } 106 | } 107 | } 108 | 109 | base.WndProc(ref m); 110 | } 111 | 112 | System.Threading.Thread Updater; 113 | delegate void UpdateCaptureDelegate(Bitmap Image); 114 | UpdateCaptureDelegate UpdateCaptureCallback; 115 | 116 | private void MainForm_Load(object sender, EventArgs e) 117 | { 118 | // Create some classic menus so they arn't in the capture. 119 | IntPtr MenuHandle = ExternalAPI.CreateMenu(); 120 | ExternalAPI.AppendMenu(MenuHandle, 0, 0x3000, "Capture..."); 121 | ExternalAPI.AppendMenu(MenuHandle, 0, 0x3001, "Settings..."); 122 | ExternalAPI.SetMenu(this.Handle, MenuHandle); 123 | 124 | UpdateCaptureCallback += UpdateCapture; 125 | 126 | Updater = new System.Threading.Thread(new System.Threading.ThreadStart(UpdateThread)); 127 | Updater.Start(); 128 | } 129 | 130 | void UpdateCapture(Bitmap Image) 131 | { 132 | if (Image == null) 133 | { 134 | if (PreviewScreen.Image != null) 135 | { 136 | PreviewScreen.Image.Dispose(); 137 | PreviewScreen.Image = null; 138 | } 139 | 140 | return; 141 | } 142 | 143 | int height = Image.Height; 144 | int width = Image.Width; 145 | 146 | if (SettingOptionsWindow.Visible) 147 | { 148 | height -= (SettingOptionsWindow.CroppingBottom + SettingOptionsWindow.CroppingTop); 149 | width -= (SettingOptionsWindow.CroppingLeft + SettingOptionsWindow.CroppingRight); 150 | } 151 | else 152 | { 153 | height -= (CroppingBottom + CroppingTop); 154 | width -= (CroppingLeft + CroppingRight); 155 | } 156 | 157 | if (width > 0 && height > 0) 158 | { 159 | if (PreviewScreen.Image != null) 160 | PreviewScreen.Image.Dispose(); 161 | 162 | try 163 | { 164 | if (SettingOptionsWindow.Visible) 165 | { 166 | PreviewScreen.Image = Image.Clone(new Rectangle(SettingOptionsWindow.CroppingLeft, SettingOptionsWindow.CroppingTop, width, height), Image.PixelFormat); 167 | } 168 | else 169 | { 170 | PreviewScreen.Image = Image.Clone(new Rectangle(CroppingLeft, CroppingTop, width, height), Image.PixelFormat); 171 | } 172 | } 173 | catch 174 | { 175 | return; 176 | } 177 | 178 | int MenuThickness = ExternalAPI.GetSystemMetrics(15); 179 | 180 | if (SettingOptionsWindow.Visible) 181 | { 182 | if (SettingOptionsWindow.ResizeOutput) 183 | { 184 | this.SetClientSizeCore(SettingOptionsWindow.ResizeOutputWidth, SettingOptionsWindow.ResizeOutputHeight + MenuThickness); 185 | } 186 | else 187 | { 188 | this.SetClientSizeCore(width, height + MenuThickness); 189 | } 190 | } 191 | else 192 | { 193 | if (ResizeOutput) 194 | { 195 | this.SetClientSizeCore(ResizeOutputWidth, ResizeOutputHeight + MenuThickness); 196 | } 197 | else 198 | { 199 | this.SetClientSizeCore(width, height + MenuThickness); 200 | } 201 | } 202 | 203 | SettingOptionsWindow.WindowHeight = height; 204 | SettingOptionsWindow.WindowWidth = width; 205 | } 206 | 207 | Image.Dispose(); 208 | } 209 | 210 | 211 | 212 | class EnumCallback 213 | { 214 | public string Name; 215 | public string Title; 216 | public bool MatchTitle; 217 | public IntPtr Handle; 218 | 219 | public bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam) 220 | { 221 | int style = ExternalAPI.GetWindowLong(hWnd, -16); 222 | int Exstyle = ExternalAPI.GetWindowLong(hWnd, -20); 223 | 224 | if (!ExternalAPI.IsWindowVisible(hWnd)) 225 | return true; 226 | 227 | // Ignore Popup windows 228 | if ((style & 0x80000000) != 0) 229 | return true; 230 | 231 | uint ProcessID; 232 | StringBuilder TempString = new StringBuilder(); 233 | 234 | ExternalAPI.GetWindowThreadProcessId(hWnd, out ProcessID); 235 | 236 | IntPtr ProcessHandle = ExternalAPI.OpenProcess(0x0400, false, ProcessID); 237 | TempString.EnsureCapacity(1024); 238 | ExternalAPI.GetModuleFileNameEx(ProcessHandle, IntPtr.Zero, TempString, TempString.Capacity); 239 | ExternalAPI.CloseHandle(ProcessHandle); 240 | 241 | string ExeName = System.IO.Path.GetFileNameWithoutExtension(TempString.ToString()); 242 | 243 | if (Name.Equals(ExeName, StringComparison.InvariantCultureIgnoreCase)) 244 | { 245 | if (MatchTitle) 246 | { 247 | int size = ExternalAPI.GetWindowTextLength(hWnd); 248 | if (size != 0) 249 | { 250 | TempString.EnsureCapacity(size + 1); 251 | ExternalAPI.GetWindowText(hWnd, TempString, TempString.Capacity); 252 | 253 | if(TempString.ToString() == Title) 254 | { 255 | Handle = hWnd; 256 | return false; 257 | } 258 | } 259 | } 260 | else 261 | { 262 | Handle = hWnd; 263 | return false; 264 | } 265 | } 266 | 267 | return true; 268 | } 269 | } 270 | 271 | EnumCallback FindProcessCallback = new EnumCallback(); 272 | 273 | private IntPtr FindWindow (string ProcessName, string WindowTitle, bool MatchTitle) 274 | { 275 | FindProcessCallback.Name = ProcessName; 276 | FindProcessCallback.Title = WindowTitle; 277 | FindProcessCallback.MatchTitle = MatchTitle; 278 | 279 | FindProcessCallback.Handle = IntPtr.Zero; 280 | 281 | ExternalAPI.EnumWindows(new ExternalAPI.EnumWindowsProc(FindProcessCallback.EnumWindowsCallback), IntPtr.Zero); 282 | 283 | return FindProcessCallback.Handle; 284 | } 285 | 286 | public void UpdateThread() 287 | { 288 | while(true) 289 | { 290 | if (SettingOptionsWindow.Visible) 291 | { 292 | System.Threading.Thread.Sleep(SettingOptionsWindow.CaptureRate); 293 | } 294 | else 295 | { 296 | System.Threading.Thread.Sleep(CaptureRate); 297 | } 298 | 299 | if (CaptureOptionsWindow.Visible) 300 | continue; 301 | 302 | // Only look up the Window if we don't have one, or if the one we have is no longer a window or is hidden 303 | if (MatchWindowHandle == IntPtr.Zero || !ExternalAPI.IsWindow(MatchWindowHandle) || !ExternalAPI.IsWindowVisible(MatchWindowHandle)) 304 | { 305 | bool A = ExternalAPI.IsWindow(MatchWindowHandle); 306 | bool B = ExternalAPI.IsWindowVisible(MatchWindowHandle); 307 | 308 | MatchWindowHandle = FindWindow(WindowName, WindowTitle, MatchWindowTitle); 309 | } 310 | 311 | if (TopmostOnly && ExternalAPI.GetForegroundWindow() != MatchWindowHandle) 312 | continue; 313 | 314 | Bitmap Image = null; 315 | if (MatchWindowHandle != IntPtr.Zero) 316 | Image = ExternalAPI.CaptureWindow(MatchWindowHandle, Method); 317 | 318 | this.Invoke(UpdateCaptureCallback, Image); 319 | } 320 | } 321 | 322 | private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 323 | { 324 | Updater.Abort(); 325 | SaveSettings(); 326 | } 327 | 328 | private int[] SplitInput(string Input) 329 | { 330 | string[] Entries = Input.Split(','); 331 | 332 | List Ret = new List(); 333 | 334 | foreach(string Val in Entries) 335 | { 336 | int Temp; 337 | if(int.TryParse(Val.Trim(), out Temp)) 338 | { 339 | Ret.Add(Temp); 340 | } 341 | else 342 | { 343 | Ret.Add(0); 344 | } 345 | } 346 | 347 | return Ret.ToArray(); ; 348 | } 349 | 350 | private void LoadSettings() 351 | { 352 | StringBuilder TempString = new StringBuilder(1024); 353 | 354 | ExternalAPI.GetPrivateProfileString("Capture", "Name", "", TempString, 1024, SettingsFile); 355 | WindowName = TempString.ToString(); 356 | 357 | ExternalAPI.GetPrivateProfileString("Capture", "Title", "", TempString, 1024, SettingsFile); 358 | WindowTitle = TempString.ToString(); 359 | 360 | ExternalAPI.GetPrivateProfileString("Capture", "Match Title", "False", TempString, 1024, SettingsFile); 361 | bool.TryParse(TempString.ToString(), out MatchWindowTitle); 362 | 363 | ExternalAPI.GetPrivateProfileString("Capture", "Topmost Only", "False", TempString, 1024, SettingsFile); 364 | bool.TryParse(TempString.ToString(), out TopmostOnly); 365 | 366 | ExternalAPI.GetPrivateProfileString("Capture", "Capture Method", "", TempString, 1024, SettingsFile); 367 | if (TempString.Length != 0) 368 | { 369 | Enum.TryParse(TempString.ToString(), out Method); 370 | } 371 | 372 | 373 | ExternalAPI.GetPrivateProfileString("Settings", "Resize Output", "False", TempString, 1024, SettingsFile); 374 | bool.TryParse(TempString.ToString(), out ResizeOutput); 375 | 376 | ExternalAPI.GetPrivateProfileString("Settings", "Output Size", "1280, 720", TempString, 1024, SettingsFile); 377 | { 378 | int [] Values = SplitInput(TempString.ToString()); 379 | if(Values.Length >= 2) 380 | { 381 | ResizeOutputWidth = Values[0]; 382 | ResizeOutputHeight = Values[1]; 383 | } 384 | } 385 | 386 | ExternalAPI.GetPrivateProfileString("Settings", "Clipping", "0, 0, 0, 0", TempString, 1024, SettingsFile); 387 | { 388 | int[] Values = SplitInput(TempString.ToString()); 389 | if (Values.Length >= 4) 390 | { 391 | CroppingTop = Values[0]; 392 | CroppingLeft = Values[1]; 393 | CroppingBottom = Values[2]; 394 | CroppingRight = Values[3]; 395 | } 396 | } 397 | 398 | ExternalAPI.GetPrivateProfileString("Settings", "Capture Rate", "0", TempString, 1024, SettingsFile); 399 | int.TryParse(TempString.ToString(), out CaptureRate); 400 | } 401 | 402 | private void SaveSettings() 403 | { 404 | 405 | ExternalAPI.WritePrivateProfileString("Capture", "Name", WindowName, SettingsFile); 406 | ExternalAPI.WritePrivateProfileString("Capture", "Title", WindowTitle, SettingsFile); 407 | ExternalAPI.WritePrivateProfileString("Capture", "Match Title", MatchWindowTitle.ToString(), SettingsFile); 408 | ExternalAPI.WritePrivateProfileString("Capture", "Topmost Only", TopmostOnly.ToString(), SettingsFile); 409 | ExternalAPI.WritePrivateProfileString("Capture", "Capture Method", Method.ToString(), SettingsFile); 410 | 411 | ExternalAPI.WritePrivateProfileString("Settings", "Resize Output", ResizeOutput.ToString(), SettingsFile); 412 | ExternalAPI.WritePrivateProfileString("Settings", "Output Size", string.Format("{0}, {1}", ResizeOutputWidth, ResizeOutputHeight), SettingsFile); 413 | ExternalAPI.WritePrivateProfileString("Settings", "Clipping", string.Format("{0}, {1}, {2}, {3}", CroppingTop, CroppingLeft, CroppingBottom, CroppingRight), SettingsFile); 414 | ExternalAPI.WritePrivateProfileString("Settings", "Capture Rate", CaptureRate.ToString(), SettingsFile); 415 | } 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace SlowCapture 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new MainForm()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/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("SlowCapture")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SlowCapture")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 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("d1415b66-8920-4e72-ba26-ac4050470ffe")] 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 Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/Properties/Resources.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 SlowCapture.Properties 12 | { 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 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SlowCapture.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/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 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/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 SlowCapture.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/SettingOptions.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SlowCapture 2 | { 3 | partial class SettingOptions 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 Windows Form 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 | System.Windows.Forms.GroupBox groupBox3; 32 | System.Windows.Forms.Label label1; 33 | System.Windows.Forms.Label label2; 34 | System.Windows.Forms.Label label3; 35 | System.Windows.Forms.Label label4; 36 | System.Windows.Forms.GroupBox groupBox2; 37 | System.Windows.Forms.Label label11; 38 | System.Windows.Forms.Label label10; 39 | System.Windows.Forms.Label label5; 40 | System.Windows.Forms.Label label6; 41 | System.Windows.Forms.GroupBox groupBox1; 42 | this.CroppingRightControl = new System.Windows.Forms.NumericUpDown(); 43 | this.CroppingBottomControl = new System.Windows.Forms.NumericUpDown(); 44 | this.CroppingTopControl = new System.Windows.Forms.NumericUpDown(); 45 | this.CroppingLeftControl = new System.Windows.Forms.NumericUpDown(); 46 | this.ResizeHeightTextbox = new System.Windows.Forms.TextBox(); 47 | this.ResizeWidthTextbox = new System.Windows.Forms.TextBox(); 48 | this.WindowHeightLabel = new System.Windows.Forms.Label(); 49 | this.WindowWidthLabel = new System.Windows.Forms.Label(); 50 | this.ResizeCaptureCheck = new System.Windows.Forms.CheckBox(); 51 | this.AbortButton = new System.Windows.Forms.Button(); 52 | this.OKButton = new System.Windows.Forms.Button(); 53 | this.CaptureRateBar = new System.Windows.Forms.TrackBar(); 54 | this.CaptureRateDisplay = new System.Windows.Forms.Label(); 55 | groupBox3 = new System.Windows.Forms.GroupBox(); 56 | label1 = new System.Windows.Forms.Label(); 57 | label2 = new System.Windows.Forms.Label(); 58 | label3 = new System.Windows.Forms.Label(); 59 | label4 = new System.Windows.Forms.Label(); 60 | groupBox2 = new System.Windows.Forms.GroupBox(); 61 | label11 = new System.Windows.Forms.Label(); 62 | label10 = new System.Windows.Forms.Label(); 63 | label5 = new System.Windows.Forms.Label(); 64 | label6 = new System.Windows.Forms.Label(); 65 | groupBox1 = new System.Windows.Forms.GroupBox(); 66 | groupBox3.SuspendLayout(); 67 | ((System.ComponentModel.ISupportInitialize)(this.CroppingRightControl)).BeginInit(); 68 | ((System.ComponentModel.ISupportInitialize)(this.CroppingBottomControl)).BeginInit(); 69 | ((System.ComponentModel.ISupportInitialize)(this.CroppingTopControl)).BeginInit(); 70 | ((System.ComponentModel.ISupportInitialize)(this.CroppingLeftControl)).BeginInit(); 71 | groupBox2.SuspendLayout(); 72 | groupBox1.SuspendLayout(); 73 | ((System.ComponentModel.ISupportInitialize)(this.CaptureRateBar)).BeginInit(); 74 | this.SuspendLayout(); 75 | // 76 | // groupBox3 77 | // 78 | groupBox3.Controls.Add(this.CroppingRightControl); 79 | groupBox3.Controls.Add(this.CroppingBottomControl); 80 | groupBox3.Controls.Add(this.CroppingTopControl); 81 | groupBox3.Controls.Add(this.CroppingLeftControl); 82 | groupBox3.Controls.Add(label1); 83 | groupBox3.Controls.Add(label2); 84 | groupBox3.Controls.Add(label3); 85 | groupBox3.Controls.Add(label4); 86 | groupBox3.Location = new System.Drawing.Point(12, 12); 87 | groupBox3.Name = "groupBox3"; 88 | groupBox3.Size = new System.Drawing.Size(318, 108); 89 | groupBox3.TabIndex = 0; 90 | groupBox3.TabStop = false; 91 | groupBox3.Text = "Cropping"; 92 | // 93 | // CroppingRightControl 94 | // 95 | this.CroppingRightControl.Location = new System.Drawing.Point(197, 48); 96 | this.CroppingRightControl.Maximum = new decimal(new int[] { 97 | 9999, 98 | 0, 99 | 0, 100 | 0}); 101 | this.CroppingRightControl.Name = "CroppingRightControl"; 102 | this.CroppingRightControl.Size = new System.Drawing.Size(67, 20); 103 | this.CroppingRightControl.TabIndex = 5; 104 | this.CroppingRightControl.ValueChanged += new System.EventHandler(this.CroppingRightControl_ValueChanged); 105 | // 106 | // CroppingBottomControl 107 | // 108 | this.CroppingBottomControl.Location = new System.Drawing.Point(124, 73); 109 | this.CroppingBottomControl.Maximum = new decimal(new int[] { 110 | 9999, 111 | 0, 112 | 0, 113 | 0}); 114 | this.CroppingBottomControl.Name = "CroppingBottomControl"; 115 | this.CroppingBottomControl.Size = new System.Drawing.Size(67, 20); 116 | this.CroppingBottomControl.TabIndex = 7; 117 | this.CroppingBottomControl.ValueChanged += new System.EventHandler(this.CroppingBottomControl_ValueChanged); 118 | // 119 | // CroppingTopControl 120 | // 121 | this.CroppingTopControl.Location = new System.Drawing.Point(124, 20); 122 | this.CroppingTopControl.Maximum = new decimal(new int[] { 123 | 9999, 124 | 0, 125 | 0, 126 | 0}); 127 | this.CroppingTopControl.Name = "CroppingTopControl"; 128 | this.CroppingTopControl.Size = new System.Drawing.Size(67, 20); 129 | this.CroppingTopControl.TabIndex = 1; 130 | this.CroppingTopControl.ValueChanged += new System.EventHandler(this.CroppingTopControl_ValueChanged); 131 | // 132 | // CroppingLeftControl 133 | // 134 | this.CroppingLeftControl.Location = new System.Drawing.Point(81, 46); 135 | this.CroppingLeftControl.Maximum = new decimal(new int[] { 136 | 9999, 137 | 0, 138 | 0, 139 | 0}); 140 | this.CroppingLeftControl.Name = "CroppingLeftControl"; 141 | this.CroppingLeftControl.Size = new System.Drawing.Size(67, 20); 142 | this.CroppingLeftControl.TabIndex = 3; 143 | this.CroppingLeftControl.ValueChanged += new System.EventHandler(this.CroppingLeftControl_ValueChanged); 144 | // 145 | // label1 146 | // 147 | label1.AutoSize = true; 148 | label1.Location = new System.Drawing.Point(92, 22); 149 | label1.Name = "label1"; 150 | label1.Size = new System.Drawing.Size(26, 13); 151 | label1.TabIndex = 0; 152 | label1.Text = "Top"; 153 | // 154 | // label2 155 | // 156 | label2.AutoSize = true; 157 | label2.Location = new System.Drawing.Point(50, 48); 158 | label2.Name = "label2"; 159 | label2.Size = new System.Drawing.Size(25, 13); 160 | label2.TabIndex = 2; 161 | label2.Text = "Left"; 162 | // 163 | // label3 164 | // 165 | label3.AutoSize = true; 166 | label3.Location = new System.Drawing.Point(159, 48); 167 | label3.Name = "label3"; 168 | label3.Size = new System.Drawing.Size(32, 13); 169 | label3.TabIndex = 4; 170 | label3.Text = "Right"; 171 | // 172 | // label4 173 | // 174 | label4.AutoSize = true; 175 | label4.Location = new System.Drawing.Point(78, 75); 176 | label4.Name = "label4"; 177 | label4.Size = new System.Drawing.Size(40, 13); 178 | label4.TabIndex = 6; 179 | label4.Text = "Bottom"; 180 | // 181 | // groupBox2 182 | // 183 | groupBox2.Controls.Add(this.ResizeHeightTextbox); 184 | groupBox2.Controls.Add(this.ResizeWidthTextbox); 185 | groupBox2.Controls.Add(this.WindowHeightLabel); 186 | groupBox2.Controls.Add(this.WindowWidthLabel); 187 | groupBox2.Controls.Add(label11); 188 | groupBox2.Controls.Add(label10); 189 | groupBox2.Controls.Add(this.ResizeCaptureCheck); 190 | groupBox2.Controls.Add(label5); 191 | groupBox2.Controls.Add(label6); 192 | groupBox2.Location = new System.Drawing.Point(12, 135); 193 | groupBox2.Name = "groupBox2"; 194 | groupBox2.Size = new System.Drawing.Size(318, 101); 195 | groupBox2.TabIndex = 1; 196 | groupBox2.TabStop = false; 197 | groupBox2.Text = "Sizing"; 198 | // 199 | // ResizeHeightTextbox 200 | // 201 | this.ResizeHeightTextbox.Location = new System.Drawing.Point(65, 68); 202 | this.ResizeHeightTextbox.MaxLength = 4; 203 | this.ResizeHeightTextbox.Name = "ResizeHeightTextbox"; 204 | this.ResizeHeightTextbox.Size = new System.Drawing.Size(53, 20); 205 | this.ResizeHeightTextbox.TabIndex = 3; 206 | this.ResizeHeightTextbox.Text = "0"; 207 | this.ResizeHeightTextbox.TextChanged += new System.EventHandler(this.ResizeHeightTextbox_TextChanged); 208 | this.ResizeHeightTextbox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ResizeHeightTextbox_KeyPress); 209 | // 210 | // ResizeWidthTextbox 211 | // 212 | this.ResizeWidthTextbox.Location = new System.Drawing.Point(65, 42); 213 | this.ResizeWidthTextbox.MaxLength = 4; 214 | this.ResizeWidthTextbox.Name = "ResizeWidthTextbox"; 215 | this.ResizeWidthTextbox.Size = new System.Drawing.Size(53, 20); 216 | this.ResizeWidthTextbox.TabIndex = 1; 217 | this.ResizeWidthTextbox.Text = "0"; 218 | this.ResizeWidthTextbox.TextChanged += new System.EventHandler(this.ResizeWidthTextbox_TextChanged); 219 | this.ResizeWidthTextbox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ResizeWidthTextbox_KeyPress); 220 | // 221 | // WindowHeightLabel 222 | // 223 | this.WindowHeightLabel.AutoSize = true; 224 | this.WindowHeightLabel.Location = new System.Drawing.Point(264, 71); 225 | this.WindowHeightLabel.Name = "WindowHeightLabel"; 226 | this.WindowHeightLabel.Size = new System.Drawing.Size(25, 13); 227 | this.WindowHeightLabel.TabIndex = 7; 228 | this.WindowHeightLabel.Text = "720"; 229 | // 230 | // WindowWidthLabel 231 | // 232 | this.WindowWidthLabel.AutoSize = true; 233 | this.WindowWidthLabel.Location = new System.Drawing.Point(264, 45); 234 | this.WindowWidthLabel.Name = "WindowWidthLabel"; 235 | this.WindowWidthLabel.Size = new System.Drawing.Size(31, 13); 236 | this.WindowWidthLabel.TabIndex = 6; 237 | this.WindowWidthLabel.Text = "1280"; 238 | // 239 | // label11 240 | // 241 | label11.AutoSize = true; 242 | label11.Location = new System.Drawing.Point(181, 71); 243 | label11.Name = "label11"; 244 | label11.Size = new System.Drawing.Size(83, 13); 245 | label11.TabIndex = 4; 246 | label11.Text = "Window Height:"; 247 | label11.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 248 | // 249 | // label10 250 | // 251 | label10.AutoSize = true; 252 | label10.Location = new System.Drawing.Point(184, 45); 253 | label10.Name = "label10"; 254 | label10.Size = new System.Drawing.Size(80, 13); 255 | label10.TabIndex = 5; 256 | label10.Text = "Window Width:"; 257 | label10.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 258 | // 259 | // ResizeCaptureCheck 260 | // 261 | this.ResizeCaptureCheck.AutoSize = true; 262 | this.ResizeCaptureCheck.Location = new System.Drawing.Point(13, 19); 263 | this.ResizeCaptureCheck.Name = "ResizeCaptureCheck"; 264 | this.ResizeCaptureCheck.Size = new System.Drawing.Size(98, 17); 265 | this.ResizeCaptureCheck.TabIndex = 0; 266 | this.ResizeCaptureCheck.Text = "Resize Capture"; 267 | this.ResizeCaptureCheck.UseVisualStyleBackColor = true; 268 | this.ResizeCaptureCheck.CheckedChanged += new System.EventHandler(this.ResizeCaptureCheck_CheckedChanged); 269 | // 270 | // label5 271 | // 272 | label5.AutoSize = true; 273 | label5.Location = new System.Drawing.Point(24, 45); 274 | label5.Name = "label5"; 275 | label5.Size = new System.Drawing.Size(35, 13); 276 | label5.TabIndex = 0; 277 | label5.Text = "Width"; 278 | // 279 | // label6 280 | // 281 | label6.AutoSize = true; 282 | label6.Location = new System.Drawing.Point(24, 71); 283 | label6.Name = "label6"; 284 | label6.Size = new System.Drawing.Size(38, 13); 285 | label6.TabIndex = 2; 286 | label6.Text = "Height"; 287 | // 288 | // AbortButton 289 | // 290 | this.AbortButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 291 | this.AbortButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; 292 | this.AbortButton.Location = new System.Drawing.Point(253, 335); 293 | this.AbortButton.Name = "AbortButton"; 294 | this.AbortButton.Size = new System.Drawing.Size(77, 23); 295 | this.AbortButton.TabIndex = 3; 296 | this.AbortButton.Text = "Cancel"; 297 | this.AbortButton.UseVisualStyleBackColor = true; 298 | this.AbortButton.Click += new System.EventHandler(this.AbortButton_Click); 299 | // 300 | // OKButton 301 | // 302 | this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 303 | this.OKButton.Location = new System.Drawing.Point(163, 335); 304 | this.OKButton.Name = "OKButton"; 305 | this.OKButton.Size = new System.Drawing.Size(77, 23); 306 | this.OKButton.TabIndex = 2; 307 | this.OKButton.Text = "OK"; 308 | this.OKButton.UseVisualStyleBackColor = true; 309 | this.OKButton.Click += new System.EventHandler(this.OKButton_Click); 310 | // 311 | // groupBox1 312 | // 313 | groupBox1.Controls.Add(this.CaptureRateDisplay); 314 | groupBox1.Controls.Add(this.CaptureRateBar); 315 | groupBox1.Cursor = System.Windows.Forms.Cursors.Default; 316 | groupBox1.Location = new System.Drawing.Point(12, 251); 317 | groupBox1.Name = "groupBox1"; 318 | groupBox1.Size = new System.Drawing.Size(318, 78); 319 | groupBox1.TabIndex = 2; 320 | groupBox1.TabStop = false; 321 | groupBox1.Text = "Capture Rate"; 322 | // 323 | // CaptureRateBar 324 | // 325 | this.CaptureRateBar.LargeChange = 250; 326 | this.CaptureRateBar.Location = new System.Drawing.Point(13, 19); 327 | this.CaptureRateBar.Maximum = 1000; 328 | this.CaptureRateBar.Name = "CaptureRateBar"; 329 | this.CaptureRateBar.Size = new System.Drawing.Size(299, 45); 330 | this.CaptureRateBar.SmallChange = 50; 331 | this.CaptureRateBar.TabIndex = 0; 332 | this.CaptureRateBar.TickFrequency = 100; 333 | this.CaptureRateBar.TickStyle = System.Windows.Forms.TickStyle.TopLeft; 334 | this.CaptureRateBar.Scroll += new System.EventHandler(this.CaptureRateBar_Scroll); 335 | // 336 | // CaptureRateDisplay 337 | // 338 | this.CaptureRateDisplay.AutoSize = true; 339 | this.CaptureRateDisplay.Location = new System.Drawing.Point(40, 51); 340 | this.CaptureRateDisplay.Name = "CaptureRateDisplay"; 341 | this.CaptureRateDisplay.Size = new System.Drawing.Size(98, 13); 342 | this.CaptureRateDisplay.TabIndex = 1; 343 | this.CaptureRateDisplay.Text = "As Fast as Possible"; 344 | // 345 | // SettingOptions 346 | // 347 | this.AcceptButton = this.OKButton; 348 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 349 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 350 | this.CancelButton = this.AbortButton; 351 | this.ClientSize = new System.Drawing.Size(346, 367); 352 | this.Controls.Add(groupBox1); 353 | this.Controls.Add(this.AbortButton); 354 | this.Controls.Add(this.OKButton); 355 | this.Controls.Add(groupBox3); 356 | this.Controls.Add(groupBox2); 357 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 358 | this.MaximizeBox = false; 359 | this.MinimizeBox = false; 360 | this.Name = "SettingOptions"; 361 | this.ShowIcon = false; 362 | this.ShowInTaskbar = false; 363 | this.Text = "Setting Options"; 364 | this.Load += new System.EventHandler(this.SettingOptions_Load); 365 | groupBox3.ResumeLayout(false); 366 | groupBox3.PerformLayout(); 367 | ((System.ComponentModel.ISupportInitialize)(this.CroppingRightControl)).EndInit(); 368 | ((System.ComponentModel.ISupportInitialize)(this.CroppingBottomControl)).EndInit(); 369 | ((System.ComponentModel.ISupportInitialize)(this.CroppingTopControl)).EndInit(); 370 | ((System.ComponentModel.ISupportInitialize)(this.CroppingLeftControl)).EndInit(); 371 | groupBox2.ResumeLayout(false); 372 | groupBox2.PerformLayout(); 373 | groupBox1.ResumeLayout(false); 374 | groupBox1.PerformLayout(); 375 | ((System.ComponentModel.ISupportInitialize)(this.CaptureRateBar)).EndInit(); 376 | this.ResumeLayout(false); 377 | 378 | } 379 | 380 | #endregion 381 | 382 | private System.Windows.Forms.NumericUpDown CroppingRightControl; 383 | private System.Windows.Forms.NumericUpDown CroppingBottomControl; 384 | private System.Windows.Forms.NumericUpDown CroppingTopControl; 385 | private System.Windows.Forms.NumericUpDown CroppingLeftControl; 386 | private System.Windows.Forms.Label WindowHeightLabel; 387 | private System.Windows.Forms.Label WindowWidthLabel; 388 | private System.Windows.Forms.CheckBox ResizeCaptureCheck; 389 | private System.Windows.Forms.Button AbortButton; 390 | private System.Windows.Forms.Button OKButton; 391 | private System.Windows.Forms.TextBox ResizeHeightTextbox; 392 | private System.Windows.Forms.TextBox ResizeWidthTextbox; 393 | private System.Windows.Forms.TrackBar CaptureRateBar; 394 | private System.Windows.Forms.Label CaptureRateDisplay; 395 | } 396 | } -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/SettingOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace SlowCapture 12 | { 13 | public partial class SettingOptions : Form 14 | { 15 | public ExternalAPI.Rect _Cropping; 16 | 17 | public bool ResizeOutput { get; set; } 18 | public int ResizeOutputHeight { get; set; } 19 | public int ResizeOutputWidth { get; set; } 20 | 21 | public int CroppingTop { get; set; } 22 | public int CroppingBottom { get; set; } 23 | public int CroppingLeft { get; set; } 24 | public int CroppingRight { get; set; } 25 | 26 | public int CaptureRate { get; set; } 27 | 28 | public int WindowHeight 29 | { 30 | set 31 | { 32 | WindowHeightLabel.Text = value.ToString(); 33 | } 34 | } 35 | 36 | public int WindowWidth 37 | { 38 | set 39 | { 40 | WindowWidthLabel.Text = value.ToString(); 41 | } 42 | } 43 | 44 | public SettingOptions() 45 | { 46 | ResizeOutput = false; 47 | ResizeOutputHeight = 0; 48 | ResizeOutputWidth = 0; 49 | 50 | CroppingTop = 0; 51 | CroppingBottom = 0; 52 | CroppingLeft = 0; 53 | CroppingRight = 0; 54 | 55 | CaptureRate = 0; 56 | 57 | InitializeComponent(); 58 | } 59 | 60 | private void OKButton_Click(object sender, EventArgs e) 61 | { 62 | this.DialogResult = DialogResult.OK; 63 | this.Close(); 64 | } 65 | 66 | private void AbortButton_Click(object sender, EventArgs e) 67 | { 68 | this.DialogResult = DialogResult.Cancel; 69 | this.Close(); 70 | } 71 | 72 | private void SettingOptions_Load(object sender, EventArgs e) 73 | { 74 | CroppingTopControl.Value = CroppingTop; 75 | CroppingLeftControl.Value = CroppingLeft; 76 | CroppingBottomControl.Value = CroppingBottom; 77 | CroppingRightControl.Value = CroppingRight; 78 | 79 | ResizeCaptureCheck.Checked = ResizeOutput; 80 | ResizeWidthTextbox.Enabled = ResizeOutput; 81 | ResizeHeightTextbox.Enabled = ResizeOutput; 82 | 83 | ResizeWidthTextbox.Text = ResizeOutputWidth.ToString(); 84 | ResizeHeightTextbox.Text = ResizeOutputHeight.ToString(); 85 | 86 | CaptureRateBar.Value = CaptureRate; 87 | CaptureRateBar_Scroll(null, null); 88 | } 89 | 90 | private void ResizeCaptureCheck_CheckedChanged(object sender, EventArgs e) 91 | { 92 | ResizeOutput = ResizeCaptureCheck.Checked; 93 | ResizeWidthTextbox.Enabled = ResizeOutput; 94 | ResizeHeightTextbox.Enabled = ResizeOutput; 95 | } 96 | 97 | private void CroppingTopControl_ValueChanged(object sender, EventArgs e) 98 | { 99 | CroppingTop = (int)CroppingTopControl.Value; 100 | } 101 | 102 | private void CroppingLeftControl_ValueChanged(object sender, EventArgs e) 103 | { 104 | CroppingLeft = (int)CroppingLeftControl.Value; 105 | } 106 | 107 | private void CroppingRightControl_ValueChanged(object sender, EventArgs e) 108 | { 109 | CroppingRight = (int)CroppingRightControl.Value; 110 | } 111 | 112 | private void CroppingBottomControl_ValueChanged(object sender, EventArgs e) 113 | { 114 | CroppingBottom = (int)CroppingBottomControl.Value; 115 | } 116 | 117 | private void ResizeWidthTextbox_KeyPress(object sender, KeyPressEventArgs e) 118 | { 119 | e.Handled = !(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)); 120 | } 121 | 122 | private void ResizeWidthTextbox_TextChanged(object sender, EventArgs e) 123 | { 124 | int Temp; 125 | if (int.TryParse(ResizeWidthTextbox.Text, out Temp)) 126 | { 127 | ResizeOutputWidth = Temp; 128 | } 129 | } 130 | 131 | private void ResizeHeightTextbox_KeyPress(object sender, KeyPressEventArgs e) 132 | { 133 | e.Handled = !(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)); 134 | } 135 | 136 | private void ResizeHeightTextbox_TextChanged(object sender, EventArgs e) 137 | { 138 | int Temp; 139 | if (int.TryParse(ResizeHeightTextbox.Text, out Temp)) 140 | { 141 | ResizeOutputHeight = Temp; 142 | } 143 | } 144 | 145 | private void CaptureRateBar_Scroll(object sender, EventArgs e) 146 | { 147 | CaptureRate = CaptureRateBar.Value; 148 | 149 | if (CaptureRate == 0) 150 | CaptureRateDisplay.Text = "As Fast as Possible"; 151 | 152 | else 153 | CaptureRateDisplay.Text = string.Format("~{0:F} FPS", 1000.0 / CaptureRate); 154 | 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/SettingOptions.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 | False 122 | 123 | 124 | False 125 | 126 | 127 | False 128 | 129 | 130 | False 131 | 132 | 133 | False 134 | 135 | 136 | False 137 | 138 | 139 | False 140 | 141 | 142 | False 143 | 144 | 145 | False 146 | 147 | 148 | False 149 | 150 | 151 | False 152 | 153 | 154 | False 155 | 156 | 157 | False 158 | 159 | 160 | False 161 | 162 | 163 | False 164 | 165 | 166 | False 167 | 168 | 169 | False 170 | 171 | 172 | False 173 | 174 | 175 | False 176 | 177 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/SlowCapture.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D1415B66-8920-4E72-BA26-AC4050470FFE} 8 | WinExe 9 | SlowCapture 10 | SlowCapture 11 | v4.6.1 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | tortoise.ico 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Form 54 | 55 | 56 | CaptureOptions.cs 57 | 58 | 59 | Form 60 | 61 | 62 | MainForm.cs 63 | 64 | 65 | 66 | 67 | Form 68 | 69 | 70 | SettingOptions.cs 71 | 72 | 73 | 74 | CaptureOptions.cs 75 | 76 | 77 | MainForm.cs 78 | 79 | 80 | ResXFileCodeGenerator 81 | Resources.Designer.cs 82 | Designer 83 | 84 | 85 | True 86 | Resources.resx 87 | 88 | 89 | SettingOptions.cs 90 | 91 | 92 | SettingsSingleFileGenerator 93 | Settings.Designer.cs 94 | 95 | 96 | True 97 | Settings.settings 98 | True 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /SlowCapture/SlowCapture/tortoise.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FoxCutter/Tools/c74888848f691577e15c936b3378850b639cf0ef/SlowCapture/SlowCapture/tortoise.ico --------------------------------------------------------------------------------