From 4d9c3954444a833f34327d22be1d1934e8cf586b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 17 Jul 2018 21:27:51 +0900 Subject: [PATCH 001/167] chore: Add some dependencies. --- Source/Robock/Robock.csproj | 54 +++++++++++++++++++++++++++++++++++ Source/Robock/packages.config | 19 ++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 Source/Robock/packages.config diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index a2a6e59..b1cac64 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -34,13 +34,66 @@ 4 + + ..\packages\MetroRadiance.2.4.0\lib\net46\MetroRadiance.dll + + + ..\packages\MetroRadiance.Chrome.2.2.0\lib\net46\MetroRadiance.Chrome.dll + + + ..\packages\MetroRadiance.Core.2.4.0\lib\net46\MetroRadiance.Core.dll + + + ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll + + + ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.dll + + + ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.Configuration.dll + + + ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.RegistrationByConvention.dll + + + ..\packages\Prism.Core.6.3.0\lib\net45\Prism.dll + + + ..\packages\Prism.Unity.6.3.0\lib\net45\Prism.Unity.Wpf.dll + + + ..\packages\Prism.Wpf.6.3.0\lib\net45\Prism.Wpf.dll + + + ..\packages\ReactiveProperty.5.1.1\lib\net461\ReactiveProperty.dll + + + ..\packages\ReactiveProperty.5.1.1\lib\net461\ReactiveProperty.NET46.dll + + + ..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll + + + ..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll + + + ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll + True + + + ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll + True + + + ..\packages\Prism.Wpf.6.3.0\lib\net45\System.Windows.Interactivity.dll + @@ -90,6 +143,7 @@ ResXFileCodeGenerator Resources.Designer.cs + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/Source/Robock/packages.config b/Source/Robock/packages.config new file mode 100644 index 0000000..ac60634 --- /dev/null +++ b/Source/Robock/packages.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 6b8d35111135442396d89c9c9567ea403037abb8 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 17 Jul 2018 21:31:21 +0900 Subject: [PATCH 002/167] chore: Add directories. --- Source/Robock/Robock.csproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index b1cac64..72d3dc2 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -152,5 +152,13 @@ + + + + + + + + \ No newline at end of file From c27c37066f2a479e6e81e1ee802ed23acb43e56e Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 17 Jul 2018 21:48:17 +0900 Subject: [PATCH 003/167] chore: Apply MVVM pattern. --- Source/Robock/App.xaml | 3 +-- Source/Robock/App.xaml.cs | 19 ++++++++------- Source/Robock/Bootstrapper.cs | 24 +++++++++++++++++++ Source/Robock/Mvvm/ViewModel.cs | 22 +++++++++++++++++ Source/Robock/Robock.csproj | 20 ++++++++-------- Source/Robock/ViewModels/AppShellViewModel.cs | 16 +++++++++++++ .../{MainWindow.xaml => Views/AppShell.xaml} | 10 +++++--- .../AppShell.xaml.cs} | 9 ++++--- 8 files changed, 94 insertions(+), 29 deletions(-) create mode 100644 Source/Robock/Bootstrapper.cs create mode 100644 Source/Robock/Mvvm/ViewModel.cs create mode 100644 Source/Robock/ViewModels/AppShellViewModel.cs rename Source/Robock/{MainWindow.xaml => Views/AppShell.xaml} (50%) rename Source/Robock/{MainWindow.xaml.cs => Views/AppShell.xaml.cs} (72%) diff --git a/Source/Robock/App.xaml b/Source/Robock/App.xaml index 970990b..6243749 100644 --- a/Source/Robock/App.xaml +++ b/Source/Robock/App.xaml @@ -1,7 +1,6 @@  + xmlns:local="clr-namespace:Robock"> diff --git a/Source/Robock/App.xaml.cs b/Source/Robock/App.xaml.cs index f55cc03..b8e6d5b 100644 --- a/Source/Robock/App.xaml.cs +++ b/Source/Robock/App.xaml.cs @@ -1,17 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; +using System.Windows; namespace Robock { /// - /// App.xaml の相互作用ロジック + /// App.xaml の相互作用ロジック /// public partial class App : Application { + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + var bootstrap = new Bootstrapper(); + bootstrap.Run(); + } } -} +} \ No newline at end of file diff --git a/Source/Robock/Bootstrapper.cs b/Source/Robock/Bootstrapper.cs new file mode 100644 index 0000000..a9997ca --- /dev/null +++ b/Source/Robock/Bootstrapper.cs @@ -0,0 +1,24 @@ +using System.Windows; + +using Microsoft.Practices.Unity; + +using Prism.Unity; + +using Robock.Views; + +namespace Robock +{ + internal class Bootstrapper : UnityBootstrapper + { + protected override DependencyObject CreateShell() + { + return Container.Resolve(); + } + + protected override void InitializeShell() + { + // ReSharper disable once PossibleNullReferenceException + Application.Current.MainWindow.Show(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Mvvm/ViewModel.cs b/Source/Robock/Mvvm/ViewModel.cs new file mode 100644 index 0000000..ae05646 --- /dev/null +++ b/Source/Robock/Mvvm/ViewModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Reactive.Disposables; + +using Prism.Mvvm; + +namespace Robock.Mvvm +{ + public class ViewModel : BindableBase, IDisposable + { + public CompositeDisposable CompositeDisposable { get; } + + public ViewModel() + { + CompositeDisposable = new CompositeDisposable(); + } + + public void Dispose() + { + CompositeDisposable?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 72d3dc2..d96669d 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -112,18 +112,20 @@ MSBuild:Compile Designer - - MSBuild:Compile - Designer - + + + + AppShell.xaml + App.xaml Code - - MainWindow.xaml - Code - + + + Designer + MSBuild:Compile + @@ -156,8 +158,6 @@ - - diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs new file mode 100644 index 0000000..e32e443 --- /dev/null +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -0,0 +1,16 @@ +using Reactive.Bindings; + +using Robock.Mvvm; + +namespace Robock.ViewModels +{ + public class AppShellViewModel : ViewModel + { + public ReactiveProperty Title { get; } + + public AppShellViewModel() + { + Title = new ReactiveProperty("Robock"); + } + } +} \ No newline at end of file diff --git a/Source/Robock/MainWindow.xaml b/Source/Robock/Views/AppShell.xaml similarity index 50% rename from Source/Robock/MainWindow.xaml rename to Source/Robock/Views/AppShell.xaml index 8679d3a..66a5eea 100644 --- a/Source/Robock/MainWindow.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -1,12 +1,16 @@ - diff --git a/Source/Robock/MainWindow.xaml.cs b/Source/Robock/Views/AppShell.xaml.cs similarity index 72% rename from Source/Robock/MainWindow.xaml.cs rename to Source/Robock/Views/AppShell.xaml.cs index d6140ad..1980935 100644 --- a/Source/Robock/MainWindow.xaml.cs +++ b/Source/Robock/Views/AppShell.xaml.cs @@ -10,17 +10,16 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using System.Windows.Navigation; using System.Windows.Shapes; -namespace Robock +namespace Robock.Views { /// - /// MainWindow.xaml の相互作用ロジック + /// AppShell.xaml の相互作用ロジック /// - public partial class MainWindow : Window + public partial class AppShell : Window { - public MainWindow() + public AppShell() { InitializeComponent(); } From 8194e101b1380f704a6a7bd7c818ca3655678c3d Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 17 Jul 2018 21:56:47 +0900 Subject: [PATCH 004/167] chore: Apply Metro theme --- .../Actions/DataContextDisposeAction.cs | 19 ++++ Source/Robock/App.xaml | 10 +- Source/Robock/Robock.csproj | 1 + Source/Robock/Views/AppShell.xaml | 100 +++++++++++++++--- Source/Robock/Views/AppShell.xaml.cs | 25 ++--- 5 files changed, 124 insertions(+), 31 deletions(-) create mode 100644 Source/Robock/Actions/DataContextDisposeAction.cs diff --git a/Source/Robock/Actions/DataContextDisposeAction.cs b/Source/Robock/Actions/DataContextDisposeAction.cs new file mode 100644 index 0000000..805fb2a --- /dev/null +++ b/Source/Robock/Actions/DataContextDisposeAction.cs @@ -0,0 +1,19 @@ +using System; +using System.Windows; +using System.Windows.Interactivity; + +namespace Robock.Actions +{ + public class DataContextDisposeAction : TriggerAction + { + #region Overrides of TriggerAction + + protected override void Invoke(object parameter) + { + var disposable = AssociatedObject.DataContext as IDisposable; + disposable?.Dispose(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/Robock/App.xaml b/Source/Robock/App.xaml index 6243749..85dcff2 100644 --- a/Source/Robock/App.xaml +++ b/Source/Robock/App.xaml @@ -2,5 +2,13 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Robock"> - + + + + + + + + + diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index d96669d..bd6549f 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -112,6 +112,7 @@ MSBuild:Compile Designer + diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 66a5eea..48b833b 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -1,16 +1,84 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Robock/Views/AppShell.xaml.cs b/Source/Robock/Views/AppShell.xaml.cs index 1980935..a5f5fff 100644 --- a/Source/Robock/Views/AppShell.xaml.cs +++ b/Source/Robock/Views/AppShell.xaml.cs @@ -1,27 +1,24 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; + +using MetroRadiance.UI.Controls; namespace Robock.Views { /// - /// AppShell.xaml の相互作用ロジック + /// AppShell.xaml の相互作用ロジック /// - public partial class AppShell : Window + public partial class AppShell : MetroWindow { public AppShell() { InitializeComponent(); } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + Application.Current.Shutdown(); + } } -} +} \ No newline at end of file From 39afbc401d7485fed91b84677d4816007cc89700 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 18 Jul 2018 00:25:51 +0900 Subject: [PATCH 005/167] feat(arch): Drop x86, AnyCPU support. --- Source/Robock.sln | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Robock.sln b/Source/Robock.sln index 5e7b94b..b50115a 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -7,14 +7,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Robock", "Robock\Robock.csp EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|Any CPU.Build.0 = Release|Any CPU + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.ActiveCfg = Debug|x64 + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.Build.0 = Debug|x64 + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.ActiveCfg = Release|x64 + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 8d2ecc5a55b464cc8b723782c6e6375d197a1d1d Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 18 Jul 2018 00:26:06 +0900 Subject: [PATCH 006/167] chore: Add copyright --- Source/Robock/Properties/AssemblyInfo.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Robock/Properties/AssemblyInfo.cs b/Source/Robock/Properties/AssemblyInfo.cs index c1f5ff6..a67a7fd 100644 --- a/Source/Robock/Properties/AssemblyInfo.cs +++ b/Source/Robock/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Robock")] -[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyCopyright("Copyright © Mikazuki 2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -30,7 +30,6 @@ //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - [assembly: ThemeInfo( ResourceDictionaryLocation.None, //テーマ固有のリソース ディクショナリが置かれている場所 //(リソースがページ、 @@ -40,7 +39,6 @@ //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます) )] - // アセンブリのバージョン情報は次の 4 つの値で構成されています: // // メジャー バージョン @@ -52,4 +50,4 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file From 147f02316c962278f944775d7eead8005e7a9a5f Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 18 Jul 2018 00:27:19 +0900 Subject: [PATCH 007/167] feat(about): Add about page. --- Source/Robock/App.xaml | 2 + .../Robock/Behaviors/ScrollToTopBehavior.cs | 26 ++ Source/Robock/Models/License.cs | 287 ++++++++++++++++++ Source/Robock/Models/ProductInfo.cs | 170 +++++++++++ Source/Robock/Styles/Controls.TabControl.xaml | 51 ++++ Source/Robock/Styles/Controls.xaml | 5 + Source/Robock/ViewModels/LicenseViewModel.cs | 39 +++ .../ViewModels/Tabs/AboutTabViewModel.cs | 22 ++ Source/Robock/Views/AppShell.xaml | 26 +- Source/Robock/Views/Tabs/AboutTab.xaml.cs | 28 ++ Source/Robock/packages.config | 1 + 11 files changed, 655 insertions(+), 2 deletions(-) create mode 100644 Source/Robock/Behaviors/ScrollToTopBehavior.cs create mode 100644 Source/Robock/Models/License.cs create mode 100644 Source/Robock/Models/ProductInfo.cs create mode 100644 Source/Robock/Styles/Controls.TabControl.xaml create mode 100644 Source/Robock/Styles/Controls.xaml create mode 100644 Source/Robock/ViewModels/LicenseViewModel.cs create mode 100644 Source/Robock/ViewModels/Tabs/AboutTabViewModel.cs create mode 100644 Source/Robock/Views/Tabs/AboutTab.xaml.cs diff --git a/Source/Robock/App.xaml b/Source/Robock/App.xaml index 85dcff2..1e331b3 100644 --- a/Source/Robock/App.xaml +++ b/Source/Robock/App.xaml @@ -4,10 +4,12 @@ xmlns:local="clr-namespace:Robock"> + + diff --git a/Source/Robock/Behaviors/ScrollToTopBehavior.cs b/Source/Robock/Behaviors/ScrollToTopBehavior.cs new file mode 100644 index 0000000..1c6e8bd --- /dev/null +++ b/Source/Robock/Behaviors/ScrollToTopBehavior.cs @@ -0,0 +1,26 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Interactivity; + +namespace Robock.Behaviors +{ + internal class ScrollToTopBehavior : Behavior + { + protected override void OnAttached() + { + base.OnAttached(); + AssociatedObject.DataContextChanged += OnDataContextChanged; + } + + protected override void OnDetaching() + { + AssociatedObject.DataContextChanged -= OnDataContextChanged; + base.OnDetaching(); + } + + private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) + { + AssociatedObject.ScrollToTop(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Models/License.cs b/Source/Robock/Models/License.cs new file mode 100644 index 0000000..0037d76 --- /dev/null +++ b/Source/Robock/Models/License.cs @@ -0,0 +1,287 @@ +namespace Robock.Models +{ + public class License + { + public string Name { get; set; } + + public string Url { get; set; } + public string[] Authors { get; set; } = new string[0]; + public string Body { get; set; } + + // ReSharper disable InconsistentNaming + public const string Apache = @" +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + ""License"" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + ""Licensor"" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + ""Legal Entity"" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + ""control"" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + ""You"" (or ""Your"") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + ""Source"" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + ""Object"" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + ""Work"" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + ""Derivative Works"" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + ""Contribution"" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, ""submitted"" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as ""Not a Contribution."" + + ""Contributor"" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a ""NOTICE"" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an ""AS IS"" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets ""{}"" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same ""printed page"" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the ""License""); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an ""AS IS"" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +"; + + public const string ApacheMs = @" +======================================================================================== +Microsoft patterns & practices (http://microsoft.com/practices) +UNITY +======================================================================================== + +Copyright (c) Microsoft. All rights reserved. +Microsoft would like to thank its contributors, a list +of whom are at http://aka.ms/entlib-contributors + +Licensed under the Apache License, Version 2.0 (the ""License""); you +may not use this file except in compliance with the License. You may +obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an ""AS IS"" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing permissions +and limitations under the License."; + + public const string MIT = @" +The MIT License (MIT) + +Copyright (c) {yyyy} {name of copyright owner} + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the ""Software""), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE."; + + public const string MSPL = @" +Microsoft Public License (MS-PL) +This license governs use of the accompanying software. If you use the software, you +accept this license. If you do not accept the license, do not use the software. + +1. Definitions +The terms ""reproduce,"" ""reproduction,"" ""derivative works,"" and ""distribution"" have the +same meaning here as under U.S. copyright law. +A ""contribution"" is the original software, or any additions or changes to the software. +A ""contributor"" is any person that distributes its contribution under this license. +""Licensed patents"" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. +(E) The software is licensed ""as-is."" You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. +"; + + // ReSharper restore InconsistentNaming + } +} \ No newline at end of file diff --git a/Source/Robock/Models/ProductInfo.cs b/Source/Robock/Models/ProductInfo.cs new file mode 100644 index 0000000..ff60073 --- /dev/null +++ b/Source/Robock/Models/ProductInfo.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Reflection; + +namespace Robock.Models +{ + public static class ProductInfo + { + public static readonly ReadOnlyCollection LicenseNotices = new List + { + new License + { + Name = "CommonServiceLocator", + Url = "https://github.com/unitycontainer/commonservicelocator", + Body = License.MSPL + }, + new License + { + Name = "FontAwesome", + Url = "https://github.com/FortAwesome/Font-Awesome", + Authors = new[] {"Fort Awesome"}, + Body = @" +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.**" + }, + new License + { + Name = "FontAwesome.Sharp", + Url = "https://github.com/awesome-inc/FontAwesome.Sharp", + Authors = new[] {"Awesome Incremented"}, + Body = License.Apache + }, + new License + { + Name = "MetroRadiance", + Url = "https://github.com/Grabacr07/MetroRadiance", + Authors = new[] {"Manato KAMEYA"}, + Body = License.MIT.Replace("{yyyy}", "2014").Replace("{name of copyright owner}", "Manato KAMEYA") + }, + new License + { + Name = "MetroRadiance.Chrome", + Url = "https://github.com/Grabacr07/MetroRadiance", + Authors = new[] {"Manato KAMEYA"}, + Body = License.MIT.Replace("{yyyy}", "2014").Replace("{name of copyright owner}", "Manato KAMEYA") + }, + new License + { + Name = "MetroRadiance.Core", + Url = "https://github.com/Grabacr07/MetroRadiance", + Authors = new[] {"Manato KAMEYA"}, + Body = License.MIT.Replace("{yyyy}", "2014").Replace("{name of copyright owner}", "Manato KAMEYA") + }, + new License + { + Name = "Microsoft.Practices.Unity", + Url = "https://github.com/unitycontainer/unity", + Body = License.ApacheMs + }, + new License + { + Name = "Microsoft.Practices.Unity.Configuration", + Url = "https://github.com/unitycontainer/unity", + Body = License.ApacheMs + }, + new License + { + Name = "Microsoft.Practices.Unity.RegistrationByConvetion", + Url = "https://github.com/unitycontainer/unity", + Body = License.ApacheMs + }, + new License + { + Name = "Prism", + Url = "https://github.com/PrismLibrary/Prism", + Authors = new[] {".NET Foundation"}, + Body = License.MIT.Replace("{yyyy}", "").Replace("{name of copyright owner}", ".NET Foundation") + }, + new License + { + Name = "Prism.Unity.Wpf", + Url = "https://github.com/PrismLibrary/Prism", + Authors = new[] {".NET Foundation"}, + Body = License.MIT.Replace("{yyyy}", "").Replace("{name of copyright owner}", ".NET Foundation") + }, + new License + { + Name = "Prism.Wpf", + Url = "https://github.com/PrismLibrary/Prism", + Authors = new[] {".NET Foundation"}, + Body = License.MIT.Replace("{yyyy}", "").Replace("{name of copyright owner}", ".NET Foundation") + }, + new License + { + Name = "ReactiveProperty", + Url = "https://github.com/runceel/ReactiveProperty", + Authors = new[] {"neuecc", "xin9le", "okazuki"}, + Body = License.MIT.Replace("{yyyy}", "2018").Replace("{name of copyright owner}", "neuecc, xin9le, okazuki") + }, + new License + { + Name = "System.Reactive", + Url = "https://github.com/dotnet/reactive", + Authors = new[] {".NET Foundation and Contributors"}, + Body = @" +Copyright (c) .NET Foundation and Contributors +All Rights Reserved + +Licensed under the Apache License, Version 2.0 (the ""License""); you +may not use this file except in compliance with the License. You may +obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an ""AS IS"" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing permissions +and limitations under the License." + } + }.OrderBy(w => w.Name).ToList().AsReadOnly(); + + public static Lazy Name => new Lazy(() => GetAssemblyInfo().Title); + + public static Lazy Description => new Lazy(() => GetAssemblyInfo().Description); + + public static Lazy Copyright => new Lazy(() => GetAssemblyInfo().Copyright); + + public static Lazy Version => new Lazy(() => Assembly.GetExecutingAssembly().GetName().Version.ToString()); + + private static T GetAssemblyInfo() where T : Attribute + { + return (T) Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(T)); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Styles/Controls.TabControl.xaml b/Source/Robock/Styles/Controls.TabControl.xaml new file mode 100644 index 0000000..511e039 --- /dev/null +++ b/Source/Robock/Styles/Controls.TabControl.xaml @@ -0,0 +1,51 @@ + + + + + \ No newline at end of file diff --git a/Source/Robock/Styles/Controls.xaml b/Source/Robock/Styles/Controls.xaml new file mode 100644 index 0000000..7e6926a --- /dev/null +++ b/Source/Robock/Styles/Controls.xaml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Robock/ViewModels/LicenseViewModel.cs b/Source/Robock/ViewModels/LicenseViewModel.cs new file mode 100644 index 0000000..d82bc75 --- /dev/null +++ b/Source/Robock/ViewModels/LicenseViewModel.cs @@ -0,0 +1,39 @@ +using System.Diagnostics; +using System.Windows.Input; + +using Prism.Commands; + +using Robock.Models; +using Robock.Mvvm; + +namespace Robock.ViewModels +{ + internal class LicenseViewModel : ViewModel + { + private readonly License _license; + + public string Url => _license.Url.Replace("https://", ""); + public string Name => _license.Name; + public string Authors => string.Join(", ", _license.Authors); + public bool IsShowAuthors => !string.IsNullOrWhiteSpace(Authors); + public string LicenseBody => _license.Body.Substring(2); // First character must be NewLine + + public LicenseViewModel(License license) + { + _license = license; + } + + #region OpenHyperlinkCommand + + private ICommand _openHyperlinkCommand; + + public ICommand OpenHyperlinkCommand => _openHyperlinkCommand ?? (_openHyperlinkCommand = new DelegateCommand(OpenHyperlink)); + + private void OpenHyperlink() + { + Process.Start(_license.Url); + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/AboutTabViewModel.cs b/Source/Robock/ViewModels/Tabs/AboutTabViewModel.cs new file mode 100644 index 0000000..94ef890 --- /dev/null +++ b/Source/Robock/ViewModels/Tabs/AboutTabViewModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.ObjectModel; +using System.Linq; + +using Robock.Models; +using Robock.Mvvm; + +namespace Robock.ViewModels.Tabs +{ + internal class AboutTabViewModel : ViewModel + { + public ReadOnlyCollection Libraries => ProductInfo.LicenseNotices.Select(w => new LicenseViewModel(w)).ToList().AsReadOnly(); + + public string Name => ProductInfo.Name.Value; + + public string Version => $"Version {ProductInfo.Version.Value}".Trim(); + + public string Copyright => ProductInfo.Copyright.Value; + + public string OsVersion => $"OsVersion = {Environment.OSVersion}"; + } +} \ No newline at end of file diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 48b833b..3471c69 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -4,11 +4,12 @@ xmlns:actions="clr-namespace:Robock.Actions" xmlns:chrome="http://schemes.grabacr.net/winfx/2014/chrome" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" - xmlns:local="clr-namespace:Robock.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls" xmlns:prism="http://prismlibrary.com/" + xmlns:tabs="clr-namespace:Robock.Views.Tabs" xmlns:vm="clr-namespace:Robock.ViewModels" Title="{Binding Title.Value, Mode=OneWay}" Width="800" @@ -57,7 +58,7 @@ Margin="3,0,0,0" VerticalAlignment="Center" FontFamily="Meiryo UI" - FontSize="13" + FontSize="16" Foreground="{DynamicResource ForegroundBrushKey}" Text="{Binding Title.Value}" TextTrimming="CharacterEllipsis" /> @@ -68,6 +69,27 @@ + + + + diff --git a/Source/Robock/Views/Tabs/AboutTab.xaml b/Source/Robock/Views/Tabs/AboutTab.xaml new file mode 100644 index 0000000..4262d95 --- /dev/null +++ b/Source/Robock/Views/Tabs/AboutTab.xaml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Project Home : + + + + + + Author(s) : + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Robock/Win32/Native/README.txt b/Source/Robock/Win32/Native/README.txt new file mode 100644 index 0000000..2332a3a --- /dev/null +++ b/Source/Robock/Win32/Native/README.txt @@ -0,0 +1,4 @@ +Robock.Win32.Native namespace +---- + +Many codes are cited from P/Invoke.net. \ No newline at end of file From 207a0a7857a520931061e36f5559475b46b73567 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 19 Jul 2018 21:45:05 +0900 Subject: [PATCH 010/167] chore: Support Hi-DPI monitors. --- Source/Robock/Models/Desktop.cs | 2 + Source/Robock/Robock.csproj | 11 +++ .../ViewModels/Tabs/DesktopViewModel.cs | 1 + Source/Robock/ViewModels/Tabs/TabViewModel.cs | 2 +- Source/Robock/Views/AppShell.xaml | 3 +- Source/Robock/Views/Tabs/AboutTab.xaml | 2 +- Source/Robock/Views/Tabs/AboutTab.xaml.cs | 19 +---- Source/Robock/Views/Tabs/DesktopTab.xaml | 23 ++++++ Source/Robock/Views/Tabs/DesktopTab.xaml.cs | 15 ++++ Source/Robock/app.manifest | 72 +++++++++++++++++++ 10 files changed, 131 insertions(+), 19 deletions(-) create mode 100644 Source/Robock/Views/Tabs/DesktopTab.xaml create mode 100644 Source/Robock/Views/Tabs/DesktopTab.xaml.cs create mode 100644 Source/Robock/app.manifest diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 8729a96..867aed4 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -12,6 +12,8 @@ public class Desktop public int No { get; } public bool IsPrimary => _screen.Primary; public string MonitorName => _screen.DeviceName; + public double Height => _screen.Bounds.Height; + public double Width => _screen.Bounds.Width; public Desktop(Screen screen, int index) { diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index dcfb28b..daada54 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -53,6 +53,9 @@ MinimumRecommendedRules.ruleset true + + app.manifest + ..\packages\FontAwesome.Sharp.5.0.13\lib\net40\FontAwesome.Sharp.dll @@ -160,6 +163,9 @@ AboutTab.xaml + + DesktopTab.xaml + Designer MSBuild:Compile @@ -177,6 +183,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + @@ -196,6 +206,7 @@ ResXFileCodeGenerator Resources.Designer.cs + SettingsSingleFileGenerator diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 2b0f577..5dda4de 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -6,6 +6,7 @@ public class DesktopViewModel : TabViewModel { private readonly Desktop _desktop; + public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; public bool IsPrimary => _desktop.IsPrimary; public DesktopViewModel(Desktop desktop) : base($":Desktop: Desktop {desktop.No}") diff --git a/Source/Robock/ViewModels/Tabs/TabViewModel.cs b/Source/Robock/ViewModels/Tabs/TabViewModel.cs index b0a2f29..9b2efc9 100644 --- a/Source/Robock/ViewModels/Tabs/TabViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/TabViewModel.cs @@ -6,7 +6,7 @@ public class TabViewModel : ViewModel { public string Title { get; } - public TabViewModel(string title) + protected TabViewModel(string title) { Title = title; } diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 85bf734..1ca8504 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -76,7 +76,8 @@ ItemsSource="{Binding Tabs}"> - + diff --git a/Source/Robock/Views/Tabs/AboutTab.xaml b/Source/Robock/Views/Tabs/AboutTab.xaml index 4262d95..1a8513f 100644 --- a/Source/Robock/Views/Tabs/AboutTab.xaml +++ b/Source/Robock/Views/Tabs/AboutTab.xaml @@ -17,7 +17,7 @@ diff --git a/Source/Robock/Views/Tabs/AboutTab.xaml.cs b/Source/Robock/Views/Tabs/AboutTab.xaml.cs index abb6be0..26b916c 100644 --- a/Source/Robock/Views/Tabs/AboutTab.xaml.cs +++ b/Source/Robock/Views/Tabs/AboutTab.xaml.cs @@ -1,22 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using System.Windows.Controls; namespace Robock.Views.Tabs { /// - /// AboutTab.xaml の相互作用ロジック + /// AboutTab.xaml の相互作用ロジック /// public partial class AboutTab : UserControl { @@ -25,4 +12,4 @@ public AboutTab() InitializeComponent(); } } -} +} \ No newline at end of file diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml new file mode 100644 index 0000000..636a23f --- /dev/null +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -0,0 +1,23 @@ + + + + + + + Resolution: + + + + diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml.cs b/Source/Robock/Views/Tabs/DesktopTab.xaml.cs new file mode 100644 index 0000000..9a906a9 --- /dev/null +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace Robock.Views.Tabs +{ + /// + /// DesktopTab.xaml の相互作用ロジック + /// + public partial class DesktopTab : UserControl + { + public DesktopTab() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/app.manifest b/Source/Robock/app.manifest new file mode 100644 index 0000000..3b0c66e --- /dev/null +++ b/Source/Robock/app.manifest @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true/PM + + + + + + \ No newline at end of file From 102f51b636aaba46d45ebf39cfd0439406d82d17 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 19 Jul 2018 22:46:14 +0900 Subject: [PATCH 011/167] feat(monitors): Show current monitors position. --- Source/Robock/Models/Desktop.cs | 2 + Source/Robock/Robock.csproj | 8 ++++ Source/Robock/ViewModels/AppShellViewModel.cs | 10 +++- .../ViewModels/Tabs/DesktopViewModel.cs | 18 +++++++- .../ViewModels/VirtualScreenViewModel.cs | 23 ++++++++++ Source/Robock/Views/AppShell.xaml | 8 +++- Source/Robock/Views/Monitors.xaml | 46 +++++++++++++++++++ Source/Robock/Views/Monitors.xaml.cs | 28 +++++++++++ 8 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 Source/Robock/ViewModels/VirtualScreenViewModel.cs create mode 100644 Source/Robock/Views/Monitors.xaml create mode 100644 Source/Robock/Views/Monitors.xaml.cs diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 867aed4..c5854f9 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -12,6 +12,8 @@ public class Desktop public int No { get; } public bool IsPrimary => _screen.Primary; public string MonitorName => _screen.DeviceName; + public double X => _screen.Bounds.X; + public double Y => _screen.Bounds.Y; public double Height => _screen.Bounds.Height; public double Width => _screen.Bounds.Width; diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index daada54..d6d3350 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -152,6 +152,7 @@ + AppShell.xaml @@ -160,6 +161,9 @@ Code + + Monitors.xaml + AboutTab.xaml @@ -179,6 +183,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index 748a525..17f2684 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -14,6 +14,7 @@ public class AppShellViewModel : ViewModel { public ReactiveProperty Title { get; } public ReactiveCollection Tabs { get; } + public VirtualScreenViewModel VirtualScreen { get; } public AppShellViewModel() { @@ -22,12 +23,17 @@ public AppShellViewModel() { new AboutTabViewModel() }; + VirtualScreen = new VirtualScreenViewModel(); var desktopManager = new DesktopManager(); desktopManager.Desktops.CollectionChangedAsObservable().Subscribe(w => { - if (w.Action == NotifyCollectionChangedAction.Add && w.NewItems[0] is Desktop desktop) - Tabs.Insert(desktop.No - 1, new DesktopViewModel(desktop)); + if (w.Action != NotifyCollectionChangedAction.Add || !(w.NewItems[0] is Desktop desktop)) + return; + + var viewModel = new DesktopViewModel(desktop); + Tabs.Insert(desktop.No - 1, viewModel); + VirtualScreen.Desktops.Insert(desktop.No - 1, viewModel); }); desktopManager.Initialize(); diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 5dda4de..2ce52c1 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,17 +1,33 @@ -using Robock.Models; +using System.Windows; + +using Robock.Models; namespace Robock.ViewModels.Tabs { public class DesktopViewModel : TabViewModel { + private const double Scale = 15; + private readonly Desktop _desktop; + private readonly double _offsetX; + private readonly double _offsetY; + public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; public bool IsPrimary => _desktop.IsPrimary; + public double VirtualScreenX => (_offsetX + _desktop.X) / Scale; + public double VirtualScreenY => (_offsetY + _desktop.Y) / Scale; + public double VirtualScreenHeight => _desktop.Height / Scale; + public double VirtualScreenWidth => _desktop.Width / Scale; + public DesktopViewModel(Desktop desktop) : base($":Desktop: Desktop {desktop.No}") { _desktop = desktop; + + // 仮想スクリーン周りの計算 + _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; + _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/VirtualScreenViewModel.cs b/Source/Robock/ViewModels/VirtualScreenViewModel.cs new file mode 100644 index 0000000..6f94da0 --- /dev/null +++ b/Source/Robock/ViewModels/VirtualScreenViewModel.cs @@ -0,0 +1,23 @@ +using System.Collections.ObjectModel; +using System.Windows; + +using Robock.Mvvm; +using Robock.ViewModels.Tabs; + +namespace Robock.ViewModels +{ + public class VirtualScreenViewModel : ViewModel + { + private const double Scale = 15; + + public ObservableCollection Desktops { get; } + + public double VirtualScreenWidth => SystemParameters.VirtualScreenWidth / Scale; + public double VirtualScreenHeight => SystemParameters.VirtualScreenHeight / Scale; + + public VirtualScreenViewModel() + { + Desktops = new ObservableCollection(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 1ca8504..268fd9a 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -6,6 +6,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:local="clr-namespace:Robock.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls" xmlns:prism="http://prismlibrary.com/" @@ -76,8 +77,11 @@ ItemsSource="{Binding Tabs}"> - + + + + diff --git a/Source/Robock/Views/Monitors.xaml b/Source/Robock/Views/Monitors.xaml new file mode 100644 index 0000000..101ba0e --- /dev/null +++ b/Source/Robock/Views/Monitors.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Robock/Views/Monitors.xaml.cs b/Source/Robock/Views/Monitors.xaml.cs new file mode 100644 index 0000000..528a723 --- /dev/null +++ b/Source/Robock/Views/Monitors.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Robock.Views +{ + /// + /// Monitors.xaml の相互作用ロジック + /// + public partial class Monitors : UserControl + { + public Monitors() + { + InitializeComponent(); + } + } +} From 844ad1b93915b033b7f4cb25964ddfdecb6c1fdc Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 19 Jul 2018 23:26:52 +0900 Subject: [PATCH 012/167] chore(monitors): Highlight selected monitor. --- .../ViewModels/Tabs/DesktopViewModel.cs | 6 +++++ .../ViewModels/VirtualScreenViewModel.cs | 15 ++++++++++- Source/Robock/Views/AppShell.xaml | 3 ++- Source/Robock/Views/Monitors.xaml | 25 +++++++++++++++++-- Source/Robock/Views/Monitors.xaml.cs | 19 +++----------- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 2ce52c1..8399b8d 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,5 +1,7 @@ using System.Windows; +using Reactive.Bindings; + using Robock.Models; namespace Robock.ViewModels.Tabs @@ -12,6 +14,8 @@ public class DesktopViewModel : TabViewModel private readonly double _offsetX; private readonly double _offsetY; + public ReactiveProperty IsSelected { get; } + public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; public bool IsPrimary => _desktop.IsPrimary; @@ -28,6 +32,8 @@ public DesktopViewModel(Desktop desktop) : base($":Desktop: Desktop {desktop.No} // 仮想スクリーン周りの計算 _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; + + IsSelected = new ReactiveProperty(false); } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/VirtualScreenViewModel.cs b/Source/Robock/ViewModels/VirtualScreenViewModel.cs index 6f94da0..9aa2500 100644 --- a/Source/Robock/ViewModels/VirtualScreenViewModel.cs +++ b/Source/Robock/ViewModels/VirtualScreenViewModel.cs @@ -1,6 +1,9 @@ -using System.Collections.ObjectModel; +using System; +using System.Collections.ObjectModel; using System.Windows; +using Reactive.Bindings; + using Robock.Mvvm; using Robock.ViewModels.Tabs; @@ -11,6 +14,7 @@ public class VirtualScreenViewModel : ViewModel private const double Scale = 15; public ObservableCollection Desktops { get; } + public ReactiveProperty SelectedIndex { get; } public double VirtualScreenWidth => SystemParameters.VirtualScreenWidth / Scale; public double VirtualScreenHeight => SystemParameters.VirtualScreenHeight / Scale; @@ -18,6 +22,15 @@ public class VirtualScreenViewModel : ViewModel public VirtualScreenViewModel() { Desktops = new ObservableCollection(); + SelectedIndex = new ReactiveProperty(0); + SelectedIndex.Subscribe(w => + { + if (w < 0 || w >= Desktops.Count) + return; + foreach (var desktop in Desktops) + desktop.IsSelected.Value = false; + Desktops[w].IsSelected.Value = true; + }); } } } \ No newline at end of file diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 268fd9a..81bc7d3 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -74,7 +74,8 @@ + ItemsSource="{Binding Tabs}" + SelectedIndex="{Binding VirtualScreen.SelectedIndex.Value, Mode=OneWayToSource}"> diff --git a/Source/Robock/Views/Monitors.xaml b/Source/Robock/Views/Monitors.xaml index 101ba0e..1d16539 100644 --- a/Source/Robock/Views/Monitors.xaml +++ b/Source/Robock/Views/Monitors.xaml @@ -27,12 +27,33 @@ + + + + + + - /// Monitors.xaml の相互作用ロジック + /// Monitors.xaml の相互作用ロジック /// public partial class Monitors : UserControl { @@ -25,4 +12,4 @@ public Monitors() InitializeComponent(); } } -} +} \ No newline at end of file From 9272368b0c6a0518cb927b3924e6ae95f01e523f Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 19 Jul 2018 23:28:19 +0900 Subject: [PATCH 013/167] chore: Apply Window's color. --- Source/Robock/App.xaml.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Robock/App.xaml.cs b/Source/Robock/App.xaml.cs index b8e6d5b..2e86d55 100644 --- a/Source/Robock/App.xaml.cs +++ b/Source/Robock/App.xaml.cs @@ -1,5 +1,7 @@ using System.Windows; +using MetroRadiance.UI; + namespace Robock { /// @@ -11,6 +13,10 @@ protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); + ShutdownMode = ShutdownMode.OnMainWindowClose; + + ThemeService.Current.Register(this, Theme.Windows, Accent.Windows); + var bootstrap = new Bootstrapper(); bootstrap.Run(); } From e4d8d8caf4cd1b0fbd49702d636be193caf11ba9 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 19 Jul 2018 23:33:38 +0900 Subject: [PATCH 014/167] chore: UI improvement --- Source/Robock/Views/AppShell.xaml | 7 +++++-- Source/Robock/Views/AppShell.xaml.cs | 11 +---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 81bc7d3..c566745 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -78,8 +78,11 @@ SelectedIndex="{Binding VirtualScreen.SelectedIndex.Value, Mode=OneWayToSource}"> - - + + + diff --git a/Source/Robock/Views/AppShell.xaml.cs b/Source/Robock/Views/AppShell.xaml.cs index a5f5fff..cd15523 100644 --- a/Source/Robock/Views/AppShell.xaml.cs +++ b/Source/Robock/Views/AppShell.xaml.cs @@ -1,7 +1,4 @@ -using System; -using System.Windows; - -using MetroRadiance.UI.Controls; +using MetroRadiance.UI.Controls; namespace Robock.Views { @@ -14,11 +11,5 @@ public AppShell() { InitializeComponent(); } - - protected override void OnClosed(EventArgs e) - { - base.OnClosed(e); - Application.Current.Shutdown(); - } } } \ No newline at end of file From da2d7e0b51bc802a3f14bd3798a828f892e8439f Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 19 Jul 2018 23:35:35 +0900 Subject: [PATCH 015/167] refactor: Use LINQ query for filtering. --- Source/Robock/ViewModels/VirtualScreenViewModel.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Robock/ViewModels/VirtualScreenViewModel.cs b/Source/Robock/ViewModels/VirtualScreenViewModel.cs index 9aa2500..294fd1a 100644 --- a/Source/Robock/ViewModels/VirtualScreenViewModel.cs +++ b/Source/Robock/ViewModels/VirtualScreenViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.ObjectModel; +using System.Reactive.Linq; using System.Windows; using Reactive.Bindings; @@ -23,10 +24,8 @@ public VirtualScreenViewModel() { Desktops = new ObservableCollection(); SelectedIndex = new ReactiveProperty(0); - SelectedIndex.Subscribe(w => + SelectedIndex.Where(w => Desktops.Count > w && w >= 0).Subscribe(w => { - if (w < 0 || w >= Desktops.Count) - return; foreach (var desktop in Desktops) desktop.IsSelected.Value = false; Desktops[w].IsSelected.Value = true; From 7490d2b136eeab44c23d1a698a535907a926659e Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 20 Jul 2018 00:36:45 +0900 Subject: [PATCH 016/167] fix(copyrigt): Fix copyright format. --- Source/Robock/Properties/AssemblyInfo.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Source/Robock/Properties/AssemblyInfo.cs b/Source/Robock/Properties/AssemblyInfo.cs index a67a7fd..2fa3475 100644 --- a/Source/Robock/Properties/AssemblyInfo.cs +++ b/Source/Robock/Properties/AssemblyInfo.cs @@ -1,24 +1,24 @@ using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Windows; // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 // アセンブリに関連付けられている情報を変更するには、 // これらの属性値を変更してください。 + [assembly: AssemblyTitle("Robock")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Robock")] -[assembly: AssemblyCopyright("Copyright © Mikazuki 2018")] +[assembly: AssemblyCopyright("Copyright © 2018 Mikazuki")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから // 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 // その型の ComVisible 属性を true に設定してください。 + [assembly: ComVisible(false)] //ローカライズ可能なアプリケーションのビルドを開始するには、 @@ -32,12 +32,12 @@ [assembly: ThemeInfo( ResourceDictionaryLocation.None, //テーマ固有のリソース ディクショナリが置かれている場所 - //(リソースがページ、 - //またはアプリケーション リソース ディクショナリに見つからない場合に使用されます) + //(リソースがページ、 + //またはアプリケーション リソース ディクショナリに見つからない場合に使用されます) ResourceDictionaryLocation.SourceAssembly //汎用リソース ディクショナリが置かれている場所 - //(リソースがページ、 - //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます) -)] + //(リソースがページ、 + //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます) + )] // アセンブリのバージョン情報は次の 4 つの値で構成されています: // @@ -49,5 +49,6 @@ // すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] + [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file From c06de8f39144033ef06be5118b6658ace688318e Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 20 Jul 2018 23:25:41 +0900 Subject: [PATCH 017/167] chore: Process to Window --- Source/Robock/Models/Window.cs | 12 ++++ Source/Robock/Models/WindowManager.cs | 69 +++++++++++++++++++ Source/Robock/Robock.csproj | 4 ++ Source/Robock/ViewModels/AppShellViewModel.cs | 8 ++- .../ViewModels/Tabs/DesktopViewModel.cs | 10 ++- Source/Robock/ViewModels/WindowViewModel.cs | 16 +++++ Source/Robock/Views/AppShell.xaml | 15 +--- Source/Robock/Views/Tabs/DesktopTab.xaml | 38 ++++++++-- Source/Robock/Win32/Native/NativeMethods.cs | 25 +++++++ 9 files changed, 173 insertions(+), 24 deletions(-) create mode 100644 Source/Robock/Models/Window.cs create mode 100644 Source/Robock/Models/WindowManager.cs create mode 100644 Source/Robock/ViewModels/WindowViewModel.cs create mode 100644 Source/Robock/Win32/Native/NativeMethods.cs diff --git a/Source/Robock/Models/Window.cs b/Source/Robock/Models/Window.cs new file mode 100644 index 0000000..2e37e5a --- /dev/null +++ b/Source/Robock/Models/Window.cs @@ -0,0 +1,12 @@ +using System; + +namespace Robock.Models +{ + // Win32 Unmaneged + public class Window + { + public IntPtr Handle { get; set; } + public string Title { get; set; } + public bool IsMarked { get; set; } + } +} \ No newline at end of file diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs new file mode 100644 index 0000000..a14d5e5 --- /dev/null +++ b/Source/Robock/Models/WindowManager.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Reactive.Linq; +using System.Text; + +using Robock.Win32.Native; + +namespace Robock.Models +{ + public class WindowManager : IDisposable + { + private IDisposable _timer; + public ObservableCollection Windows { get; } + + public WindowManager() + { + Windows = new ObservableCollection(); + } + + public void Dispose() + { + _timer?.Dispose(); + } + + public void Start() + { + _timer = Observable.Timer(TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(1)).Subscribe(w => FindWindows()); + } + + private void FindWindows() + { + var windows = new List(); + + NativeMethods.EnumWindows((hWnd, lParam) => + { + // Filter by Window is visible + if (!NativeMethods.IsWindowVisible(hWnd)) + return true; + + // Filter by Window Title + var title = new StringBuilder(1024); + NativeMethods.GetWindowText(hWnd, title, title.Capacity); + if (string.IsNullOrWhiteSpace(title.ToString())) + return true; // Skipped + + windows.Add(new Window {Handle = hWnd, Title = title.ToString()}); + return true; + }, IntPtr.Zero); + + // Add windows + foreach (var process in windows) + if (Windows.SingleOrDefault(w => w.Handle == process.Handle) == null) + { + Windows.Add(process); + process.IsMarked = true; + } + else + { + process.IsMarked = true; + } + + // Remove killed windows. + foreach (var window in windows.Where(w => !w.IsMarked)) + Windows.Remove(window); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index d6d3350..5374491 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -145,9 +145,12 @@ + + + @@ -170,6 +173,7 @@ DesktopTab.xaml + Designer MSBuild:Compile diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index 17f2684..3c01c88 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -26,17 +26,23 @@ public AppShellViewModel() VirtualScreen = new VirtualScreenViewModel(); var desktopManager = new DesktopManager(); + var processManager = new WindowManager(); + + // Subscribe desktopManager.Desktops.CollectionChangedAsObservable().Subscribe(w => { if (w.Action != NotifyCollectionChangedAction.Add || !(w.NewItems[0] is Desktop desktop)) return; - var viewModel = new DesktopViewModel(desktop); + var viewModel = new DesktopViewModel(desktop, processManager); Tabs.Insert(desktop.No - 1, viewModel); VirtualScreen.Desktops.Insert(desktop.No - 1, viewModel); }); desktopManager.Initialize(); + processManager.Start(); + + CompositeDisposable.Add(processManager); } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 8399b8d..bcf5f1f 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,4 +1,5 @@ -using System.Windows; +using System; +using System.Windows; using Reactive.Bindings; @@ -15,6 +16,8 @@ public class DesktopViewModel : TabViewModel private readonly double _offsetY; public ReactiveProperty IsSelected { get; } + public ReactiveProperty SelectedWindow { get; } + public ReadOnlyReactiveCollection Windows { get; } public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; @@ -25,7 +28,7 @@ public class DesktopViewModel : TabViewModel public double VirtualScreenHeight => _desktop.Height / Scale; public double VirtualScreenWidth => _desktop.Width / Scale; - public DesktopViewModel(Desktop desktop) : base($":Desktop: Desktop {desktop.No}") + public DesktopViewModel(Desktop desktop, WindowManager windowManager) : base($":Desktop: Desktop {desktop.No}") { _desktop = desktop; @@ -34,6 +37,9 @@ public DesktopViewModel(Desktop desktop) : base($":Desktop: Desktop {desktop.No} _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; IsSelected = new ReactiveProperty(false); + SelectedWindow = new ReactiveProperty(); + SelectedWindow.Subscribe(w => { }); + Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/WindowViewModel.cs b/Source/Robock/ViewModels/WindowViewModel.cs new file mode 100644 index 0000000..85d2cbd --- /dev/null +++ b/Source/Robock/ViewModels/WindowViewModel.cs @@ -0,0 +1,16 @@ +using Robock.Models; +using Robock.Mvvm; + +namespace Robock.ViewModels +{ + public class WindowViewModel : ViewModel + { + private readonly Window _window; + public string Name => $"{_window.Title}"; + + public WindowViewModel(Window process) + { + _window = process; + } + } +} \ No newline at end of file diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index c566745..2640ad3 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -83,7 +83,7 @@ - @@ -110,19 +110,6 @@ - diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index 636a23f..e7a4100 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -3,8 +3,10 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:vm="clr-namespace:Robock.ViewModels.Tabs" - d:DataContext="{d:DesignInstance vm:DesktopViewModel}" + xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls" + xmlns:tvm="clr-namespace:Robock.ViewModels.Tabs" + xmlns:vm="clr-namespace:Robock.ViewModels" + d:DataContext="{d:DesignInstance tvm:DesktopViewModel}" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> @@ -15,9 +17,31 @@ - - Resolution: - - + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/Source/Robock/Win32/Native/NativeMethods.cs b/Source/Robock/Win32/Native/NativeMethods.cs new file mode 100644 index 0000000..709b82d --- /dev/null +++ b/Source/Robock/Win32/Native/NativeMethods.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Robock.Win32.Native +{ + public static class NativeMethods + { + #region User32 + + public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + + [DllImport("user32")] + public static extern bool IsWindowVisible(IntPtr hWnd); + + #endregion + } +} \ No newline at end of file From dda301b76365e85bd651390cd15238fbed5999ce Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 20 Jul 2018 23:26:46 +0900 Subject: [PATCH 018/167] refactor: Add .dll extension --- Source/Robock/Win32/Native/NativeMethods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock/Win32/Native/NativeMethods.cs b/Source/Robock/Win32/Native/NativeMethods.cs index 709b82d..9582c2b 100644 --- a/Source/Robock/Win32/Native/NativeMethods.cs +++ b/Source/Robock/Win32/Native/NativeMethods.cs @@ -17,7 +17,7 @@ public static class NativeMethods [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); - [DllImport("user32")] + [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd); #endregion From 0faa9f9dbe4e63e9121b58a9275e9969e8c7de0d Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 00:13:40 +0900 Subject: [PATCH 019/167] feat(preview): Show placehold preview as image. --- .../Robock/ViewModels/Tabs/DesktopViewModel.cs | 11 +++++++++++ Source/Robock/Views/AppShell.xaml | 18 ++++++++++++------ Source/Robock/Views/Tabs/DesktopTab.xaml | 5 +++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index bcf5f1f..c54406a 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -18,6 +18,7 @@ public class DesktopViewModel : TabViewModel public ReactiveProperty IsSelected { get; } public ReactiveProperty SelectedWindow { get; } public ReadOnlyReactiveCollection Windows { get; } + public string AspectRatio { get; } public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; @@ -36,6 +37,16 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager) : base($": _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; + // アスペクト比 + // ReSharper disable once RedundantAssignment + var (a, b, remainder) = (_desktop.Height, _desktop.Width, .0); + do + { + remainder = a % b; + (a, b) = (b, remainder); + } while (Math.Abs(remainder) > 0); + AspectRatio = $"http://placehold.jp/ffffff/ffffff/{_desktop.Width / a}x{_desktop.Height / a}.png?text=%20"; + IsSelected = new ReactiveProperty(false); SelectedWindow = new ReactiveProperty(); SelectedWindow.Subscribe(w => { }); diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 2640ad3..639a12c 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -78,14 +78,20 @@ SelectedIndex="{Binding VirtualScreen.SelectedIndex.Value, Mode=OneWayToSource}"> - - + + + + + + - - + - + diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index e7a4100..b9f9c69 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -42,6 +42,11 @@ + \ No newline at end of file From a56ecf0130f327086f4002d1a2080b805a24ed74 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 01:52:50 +0900 Subject: [PATCH 020/167] feat(preview): Previewed by DWM. --- .../ControlPositionBindingBehavior.cs | 79 +++++++++++++++ Source/Robock/Models/DesktopWindowManager.cs | 76 +++++++++++++++ Source/Robock/Robock.csproj | 3 + Source/Robock/Styles/Controls.TabControl.xaml | 96 +++++++++---------- Source/Robock/ViewModels/AppShellViewModel.cs | 16 +++- .../ViewModels/Tabs/DesktopViewModel.cs | 39 +++++++- Source/Robock/ViewModels/WindowViewModel.cs | 5 +- Source/Robock/Views/AppShell.xaml.cs | 12 ++- Source/Robock/Views/Tabs/DesktopTab.xaml | 13 ++- .../Win32/Native/DWM_THUMBNAIL_PROPERTIES.cs | 19 ++++ Source/Robock/Win32/Native/NativeMethods.cs | 17 ++++ 11 files changed, 317 insertions(+), 58 deletions(-) create mode 100644 Source/Robock/Behaviors/ControlPositionBindingBehavior.cs create mode 100644 Source/Robock/Models/DesktopWindowManager.cs create mode 100644 Source/Robock/Win32/Native/DWM_THUMBNAIL_PROPERTIES.cs diff --git a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs new file mode 100644 index 0000000..f7a567a --- /dev/null +++ b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs @@ -0,0 +1,79 @@ +using System.Windows; +using System.Windows.Interactivity; + +namespace Robock.Behaviors +{ + /// + /// アタッチされたコントロールの、 TopLevelWindow に対しての座標を VM にぶんなげる + /// + public class ControlPositionBindingBehavior : Behavior + { + public static readonly DependencyProperty LeftProperty = + DependencyProperty.Register(nameof(Left), typeof(int), typeof(ControlPositionBindingBehavior)); + + public static readonly DependencyProperty TopProperty = + DependencyProperty.Register(nameof(Top), typeof(int), typeof(ControlPositionBindingBehavior)); + + public static readonly DependencyProperty HeightProperty = + DependencyProperty.Register(nameof(Height), typeof(int), typeof(ControlPositionBindingBehavior)); + + public static readonly DependencyProperty WidthProperty = + DependencyProperty.Register(nameof(Width), typeof(int), typeof(ControlPositionBindingBehavior)); + + public int Left + { + get => (int) GetValue(LeftProperty); + set => SetValue(LeftProperty, value); + } + + public int Top + { + get => (int) GetValue(TopProperty); + set => SetValue(TopProperty, value); + } + + public int Height + { + get => (int) GetValue(HeightProperty); + set => SetValue(HeightProperty, value); + } + + public int Width + { + get => (int) GetValue(WidthProperty); + set => SetValue(WidthProperty, value); + } + + protected override void OnAttached() + { + base.OnAttached(); + if (Application.Current.MainWindow != null) + Application.Current.MainWindow.SizeChanged += MainWindowOnSizeChanged; + AssociatedObject.SizeChanged += AssociatedObjectSizeChanged; + } + + protected override void OnDetaching() + { + AssociatedObject.SizeChanged -= AssociatedObjectSizeChanged; + if (Application.Current.MainWindow != null) + Application.Current.MainWindow.SizeChanged -= MainWindowOnSizeChanged; + base.OnDetaching(); + } + + private void MainWindowOnSizeChanged(object sender, SizeChangedEventArgs e) + { + if (Application.Current.MainWindow == null) + return; + + var relative = AssociatedObject.TransformToAncestor(Application.Current.MainWindow).Transform(new Point()); + Left = (int) relative.X; + Top = (int) relative.Y; + } + + private void AssociatedObjectSizeChanged(object sender, SizeChangedEventArgs e) + { + Height = (int) AssociatedObject.ActualHeight; + Width = (int) AssociatedObject.ActualWidth; + } + } +} \ No newline at end of file diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs new file mode 100644 index 0000000..9e2778f --- /dev/null +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -0,0 +1,76 @@ +using System; +using System.Windows; +using System.Windows.Interop; + +using Robock.Win32.Native; + +using Size = System.Drawing.Size; + +namespace Robock.Models +{ + /// + /// Desktop Window Manager Wrapper Class + /// + public class DesktopWindowManager : IDisposable + { + private IntPtr _hWnd; + private IntPtr _thumb; + + public bool IsRendering => _thumb != IntPtr.Zero; + + public DesktopWindowManager() + { + _thumb = IntPtr.Zero; + } + + public void Dispose() + { + Stop(); + } + + public void Initialize() + { + _hWnd = new WindowInteropHelper(Application.Current.MainWindow ?? throw new InvalidOperationException()).Handle; + } + + public void Stop() + { + if (_thumb != IntPtr.Zero) + NativeMethods.DwmUnregisterThumbnail(_thumb); + _thumb = IntPtr.Zero; + } + + public void Start(IntPtr src, int left, int top, int height, int width) + { + Stop(); + + var registered = NativeMethods.DwmRegisterThumbnail(_hWnd, src, out _thumb); + if (registered == 0) + StartRender(left, top, height, width); + } + + public void Redender(int left, int top, int height, int width) + { + StartRender(left, top, height, width); + } + + private void StartRender(int left, int top, int height, int width) + { + if (_thumb == IntPtr.Zero) + return; + + Size size; + NativeMethods.DwmQueryThumbnailSourceSize(_thumb, out size); + + var props = new DWM_THUMBNAIL_PROPERTIES + { + fVisible = true, + dwFlags = 0x8 | 0x4 | 0x1, + opacity = 255, + rcDestination = new RECT {left = left, top = top, right = left + width, bottom = top + height} + }; + + NativeMethods.DwmUpdateThumbnailProperties(_thumb, ref props); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 5374491..31fa3a1 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -141,9 +141,11 @@ Designer + + @@ -173,6 +175,7 @@ DesktopTab.xaml + Designer diff --git a/Source/Robock/Styles/Controls.TabControl.xaml b/Source/Robock/Styles/Controls.TabControl.xaml index 511e039..5bbdd10 100644 --- a/Source/Robock/Styles/Controls.TabControl.xaml +++ b/Source/Robock/Styles/Controls.TabControl.xaml @@ -1,51 +1,51 @@  - - - + + + \ No newline at end of file diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index 3c01c88..1c3747f 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -12,12 +12,17 @@ namespace Robock.ViewModels { public class AppShellViewModel : ViewModel { + private readonly DesktopWindowManager _desktopWindowManager; public ReactiveProperty Title { get; } public ReactiveCollection Tabs { get; } public VirtualScreenViewModel VirtualScreen { get; } public AppShellViewModel() { + var desktopManager = new DesktopManager(); + var processManager = new WindowManager(); + _desktopWindowManager = new DesktopWindowManager(); + Title = new ReactiveProperty("Robock"); Tabs = new ReactiveCollection { @@ -25,16 +30,13 @@ public AppShellViewModel() }; VirtualScreen = new VirtualScreenViewModel(); - var desktopManager = new DesktopManager(); - var processManager = new WindowManager(); - // Subscribe desktopManager.Desktops.CollectionChangedAsObservable().Subscribe(w => { if (w.Action != NotifyCollectionChangedAction.Add || !(w.NewItems[0] is Desktop desktop)) return; - var viewModel = new DesktopViewModel(desktop, processManager); + var viewModel = new DesktopViewModel(desktop, processManager, _desktopWindowManager); Tabs.Insert(desktop.No - 1, viewModel); VirtualScreen.Desktops.Insert(desktop.No - 1, viewModel); }); @@ -43,6 +45,12 @@ public AppShellViewModel() processManager.Start(); CompositeDisposable.Add(processManager); + CompositeDisposable.Add(_desktopWindowManager); + } + + public void Initialize() + { + _desktopWindowManager.Initialize(); } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index c54406a..e1691f2 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Reactive.Linq; using System.Windows; using Reactive.Bindings; @@ -12,6 +13,7 @@ public class DesktopViewModel : TabViewModel private const double Scale = 15; private readonly Desktop _desktop; + private readonly DesktopWindowManager _desktopWindowManager; private readonly double _offsetX; private readonly double _offsetY; @@ -20,6 +22,11 @@ public class DesktopViewModel : TabViewModel public ReadOnlyReactiveCollection Windows { get; } public string AspectRatio { get; } + public ReactiveProperty PreviewAreaLeft { get; } + public ReactiveProperty PreviewAreaTop { get; } + public ReactiveProperty PreviewAreaHeight { get; } + public ReactiveProperty PreviewAreaWidth { get; } + public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; public bool IsPrimary => _desktop.IsPrimary; @@ -29,9 +36,10 @@ public class DesktopViewModel : TabViewModel public double VirtualScreenHeight => _desktop.Height / Scale; public double VirtualScreenWidth => _desktop.Width / Scale; - public DesktopViewModel(Desktop desktop, WindowManager windowManager) : base($":Desktop: Desktop {desktop.No}") + public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWindowManager desktopWindowManager) : base($":Desktop: Desktop {desktop.No}") { _desktop = desktop; + _desktopWindowManager = desktopWindowManager; // 仮想スクリーン周りの計算 _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; @@ -47,10 +55,37 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager) : base($": } while (Math.Abs(remainder) > 0); AspectRatio = $"http://placehold.jp/ffffff/ffffff/{_desktop.Width / a}x{_desktop.Height / a}.png?text=%20"; + // プレビュー + PreviewAreaLeft = new ReactiveProperty(); + PreviewAreaTop = new ReactiveProperty(); + PreviewAreaHeight = new ReactiveProperty(); + PreviewAreaWidth = new ReactiveProperty(); + var observer = new[] + { + PreviewAreaLeft, + PreviewAreaTop, + PreviewAreaHeight, + PreviewAreaWidth + }.CombineLatest(); + observer.Subscribe(w => Render()); + IsSelected = new ReactiveProperty(false); + IsSelected.Subscribe(w => Render()); SelectedWindow = new ReactiveProperty(); - SelectedWindow.Subscribe(w => { }); + SelectedWindow.Where(w => w != null).Subscribe(w => Render()); Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); } + + private void Render() + { + _desktopWindowManager.Stop(); + if (SelectedWindow?.Value == null) + return; + + if (_desktopWindowManager.IsRendering) + _desktopWindowManager.Redender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value); + else + _desktopWindowManager.Start(SelectedWindow.Value.Handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value); + } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/WindowViewModel.cs b/Source/Robock/ViewModels/WindowViewModel.cs index 85d2cbd..10bdc9b 100644 --- a/Source/Robock/ViewModels/WindowViewModel.cs +++ b/Source/Robock/ViewModels/WindowViewModel.cs @@ -1,4 +1,6 @@ -using Robock.Models; +using System; + +using Robock.Models; using Robock.Mvvm; namespace Robock.ViewModels @@ -7,6 +9,7 @@ public class WindowViewModel : ViewModel { private readonly Window _window; public string Name => $"{_window.Title}"; + public IntPtr Handle => _window.Handle; public WindowViewModel(Window process) { diff --git a/Source/Robock/Views/AppShell.xaml.cs b/Source/Robock/Views/AppShell.xaml.cs index cd15523..a7f3c6c 100644 --- a/Source/Robock/Views/AppShell.xaml.cs +++ b/Source/Robock/Views/AppShell.xaml.cs @@ -1,4 +1,8 @@ -using MetroRadiance.UI.Controls; +using System; + +using MetroRadiance.UI.Controls; + +using Robock.ViewModels; namespace Robock.Views { @@ -11,5 +15,11 @@ public AppShell() { InitializeComponent(); } + + protected override void OnActivated(EventArgs e) + { + (DataContext as AppShellViewModel)?.Initialize(); + base.OnActivated(e); + } } } \ No newline at end of file diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index b9f9c69..b5074ad 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -1,7 +1,9 @@  + SelectedItem="{Binding SelectedWindow.Value, Mode=TwoWay}"> + Stretch="Uniform"> + + + + \ No newline at end of file diff --git a/Source/Robock/Win32/Native/DWM_THUMBNAIL_PROPERTIES.cs b/Source/Robock/Win32/Native/DWM_THUMBNAIL_PROPERTIES.cs new file mode 100644 index 0000000..d1b2837 --- /dev/null +++ b/Source/Robock/Win32/Native/DWM_THUMBNAIL_PROPERTIES.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; + +// ReSharper disable FieldCanBeMadeReadOnly.Global +// ReSharper disable InconsistentNaming +// ReSharper disable MemberCanBePrivate.Global + +namespace Robock.Win32.Native +{ + [StructLayout(LayoutKind.Sequential)] + public struct DWM_THUMBNAIL_PROPERTIES + { + public int dwFlags; + public RECT rcDestination; + public RECT rcSource; + public byte opacity; + public bool fVisible; + public bool fSourceClientAreaOnly; + } +} \ No newline at end of file diff --git a/Source/Robock/Win32/Native/NativeMethods.cs b/Source/Robock/Win32/Native/NativeMethods.cs index 9582c2b..b50e6f7 100644 --- a/Source/Robock/Win32/Native/NativeMethods.cs +++ b/Source/Robock/Win32/Native/NativeMethods.cs @@ -1,4 +1,5 @@ using System; +using System.Drawing; using System.Runtime.InteropServices; using System.Text; @@ -6,6 +7,22 @@ namespace Robock.Win32.Native { public static class NativeMethods { + #region Dwmapi + + [DllImport("dwmapi.dll", SetLastError = true)] + public static extern int DwmRegisterThumbnail(IntPtr dest, IntPtr src, out IntPtr thumb); + + [DllImport("dwmapi.dll")] + public static extern int DwmUnregisterThumbnail(IntPtr thumb); + + [DllImport("dwmapi.dll", PreserveSig = false)] + public static extern void DwmQueryThumbnailSourceSize(IntPtr hThumbnail, out Size size); + + [DllImport("dwmapi.dll", PreserveSig = true)] + public static extern int DwmUpdateThumbnailProperties(IntPtr hThumbnail, ref DWM_THUMBNAIL_PROPERTIES props); + + #endregion + #region User32 public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); From 598c65112de2b368d50bfd613d0c2cd7da023db3 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 02:05:01 +0900 Subject: [PATCH 021/167] fix: add item --- Source/Robock/Robock.csproj | 1 + Source/Robock/Win32/Native/RECT.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 Source/Robock/Win32/Native/RECT.cs diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 31fa3a1..36022c5 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -177,6 +177,7 @@ + Designer MSBuild:Compile diff --git a/Source/Robock/Win32/Native/RECT.cs b/Source/Robock/Win32/Native/RECT.cs new file mode 100644 index 0000000..6ca60b3 --- /dev/null +++ b/Source/Robock/Win32/Native/RECT.cs @@ -0,0 +1,17 @@ +using System.Runtime.InteropServices; + +// ReSharper disable FieldCanBeMadeReadOnly.Global +// ReSharper disable InconsistentNaming +// ReSharper disable MemberCanBePrivate.Global + +namespace Robock.Win32.Native +{ + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } +} \ No newline at end of file From 2c2043d7df9263f7ae08c4c781cb2cac5860326a Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 02:11:03 +0900 Subject: [PATCH 022/167] refactor: Add AspectHelper. --- Source/Robock/Models/AspectHelper.cs | 25 +++++++++++++++++++ Source/Robock/Robock.csproj | 1 + .../ViewModels/Tabs/DesktopViewModel.cs | 9 +------ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 Source/Robock/Models/AspectHelper.cs diff --git a/Source/Robock/Models/AspectHelper.cs b/Source/Robock/Models/AspectHelper.cs new file mode 100644 index 0000000..39f87b9 --- /dev/null +++ b/Source/Robock/Models/AspectHelper.cs @@ -0,0 +1,25 @@ +using System; + +namespace Robock.Models +{ + public static class AspectHelper + { + /// + /// アスペクト比求めるくん + /// + /// + /// + /// HxW + public static string Calc(double height, double width) + { + // ReSharper disable once RedundantAssignment + var (a, b, remainder) = (height, width, .0); + do + { + remainder = a % b; + (a, b) = (b, remainder); + } while (Math.Abs(remainder) > 0); + return $"{height / a}x{width / a}"; + } + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 36022c5..ad4bd0b 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -147,6 +147,7 @@ + diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index e1691f2..362c817 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -46,14 +46,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; // アスペクト比 - // ReSharper disable once RedundantAssignment - var (a, b, remainder) = (_desktop.Height, _desktop.Width, .0); - do - { - remainder = a % b; - (a, b) = (b, remainder); - } while (Math.Abs(remainder) > 0); - AspectRatio = $"http://placehold.jp/ffffff/ffffff/{_desktop.Width / a}x{_desktop.Height / a}.png?text=%20"; + AspectRatio = $"http://placehold.jp/ffffff/ffffff/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}.png?text=%20"; // プレビュー PreviewAreaLeft = new ReactiveProperty(); From b01691e41bbcfe1dcb21f68590a7475aa1b1d7c9 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 02:22:42 +0900 Subject: [PATCH 023/167] fix: Fix some bugs --- Source/Robock/Models/AspectHelper.cs | 4 ++-- Source/Robock/Robock.csproj | 1 + Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 13 ++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/Robock/Models/AspectHelper.cs b/Source/Robock/Models/AspectHelper.cs index 39f87b9..ef734de 100644 --- a/Source/Robock/Models/AspectHelper.cs +++ b/Source/Robock/Models/AspectHelper.cs @@ -9,7 +9,7 @@ public static class AspectHelper /// /// /// - /// HxW + /// WxH public static string Calc(double height, double width) { // ReSharper disable once RedundantAssignment @@ -19,7 +19,7 @@ public static string Calc(double height, double width) remainder = a % b; (a, b) = (b, remainder); } while (Math.Abs(remainder) > 0); - return $"{height / a}x{width / a}"; + return $"{width / a}x{height / a}"; } } } \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index ad4bd0b..e943941 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -152,6 +152,7 @@ + diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 362c817..4ce81f0 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -63,15 +63,22 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin observer.Subscribe(w => Render()); IsSelected = new ReactiveProperty(false); - IsSelected.Subscribe(w => Render()); + IsSelected.Subscribe(w => + { + _desktopWindowManager.Stop(); + Render(); + }); SelectedWindow = new ReactiveProperty(); - SelectedWindow.Where(w => w != null).Subscribe(w => Render()); + SelectedWindow.Where(w => w != null).Subscribe(w => + { + _desktopWindowManager.Stop(); + Render(); + }); Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); } private void Render() { - _desktopWindowManager.Stop(); if (SelectedWindow?.Value == null) return; From f92aef7a61a95863bf18f0a6ed96eab4df8e767f Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 03:06:13 +0900 Subject: [PATCH 024/167] docs: Add TODO --- Source/Robock/Models/DesktopWindowManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index 9e2778f..72ee6ee 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -62,6 +62,7 @@ private void StartRender(int left, int top, int height, int width) Size size; NativeMethods.DwmQueryThumbnailSourceSize(_thumb, out size); + // TODO: Keep aspect ratio of source var props = new DWM_THUMBNAIL_PROPERTIES { fVisible = true, From 5c43b50463328395b31c372b0bd5621e3b4109d7 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 16:19:46 +0900 Subject: [PATCH 025/167] fix: Rendering position is fixed --- Source/Robock/Behaviors/ControlPositionBindingBehavior.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs index f7a567a..2e75523 100644 --- a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs +++ b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs @@ -74,6 +74,9 @@ private void AssociatedObjectSizeChanged(object sender, SizeChangedEventArgs e) { Height = (int) AssociatedObject.ActualHeight; Width = (int) AssociatedObject.ActualWidth; + + // When rendered size is changed, should update relative points. + MainWindowOnSizeChanged(null, null); } } } \ No newline at end of file From 0eb7a31416cff6a1df557ae231bba2378483fa27 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 21 Jul 2018 16:20:34 +0900 Subject: [PATCH 026/167] feat(core): Disable button --- Source/Robock/Models/DesktopWindowManager.cs | 20 ++++++++++++++++--- .../ViewModels/Tabs/DesktopViewModel.cs | 12 ++++++++++- Source/Robock/Views/Tabs/DesktopTab.xaml | 17 +++++++++++++--- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index 72ee6ee..a92a9dd 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -2,6 +2,8 @@ using System.Windows; using System.Windows.Interop; +using Prism.Mvvm; + using Robock.Win32.Native; using Size = System.Drawing.Size; @@ -11,13 +13,11 @@ namespace Robock.Models /// /// Desktop Window Manager Wrapper Class /// - public class DesktopWindowManager : IDisposable + public class DesktopWindowManager : BindableBase, IDisposable { private IntPtr _hWnd; private IntPtr _thumb; - public bool IsRendering => _thumb != IntPtr.Zero; - public DesktopWindowManager() { _thumb = IntPtr.Zero; @@ -38,6 +38,7 @@ public void Stop() if (_thumb != IntPtr.Zero) NativeMethods.DwmUnregisterThumbnail(_thumb); _thumb = IntPtr.Zero; + IsRendering = false; } public void Start(IntPtr src, int left, int top, int height, int width) @@ -58,6 +59,7 @@ private void StartRender(int left, int top, int height, int width) { if (_thumb == IntPtr.Zero) return; + IsRendering = true; Size size; NativeMethods.DwmQueryThumbnailSourceSize(_thumb, out size); @@ -73,5 +75,17 @@ private void StartRender(int left, int top, int height, int width) NativeMethods.DwmUpdateThumbnailProperties(_thumb, ref props); } + + #region IsRendering + + private bool _isRendering; + + public bool IsRendering + { + get => _isRendering; + set => SetProperty(ref _isRendering, value); + } + + #endregion } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 4ce81f0..d68adf7 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,8 +1,10 @@ using System; +using System.Linq; using System.Reactive.Linq; using System.Windows; using Reactive.Bindings; +using Reactive.Bindings.Extensions; using Robock.Models; @@ -26,6 +28,8 @@ public class DesktopViewModel : TabViewModel public ReactiveProperty PreviewAreaTop { get; } public ReactiveProperty PreviewAreaHeight { get; } public ReactiveProperty PreviewAreaWidth { get; } + public ReactiveCommand ApplyWallpaperCommand { get; } + public ReactiveCommand DiscardWallpaperCommand { get; } public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; @@ -62,6 +66,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin }.CombineLatest(); observer.Subscribe(w => Render()); + Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); IsSelected = new ReactiveProperty(false); IsSelected.Subscribe(w => { @@ -74,7 +79,12 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin _desktopWindowManager.Stop(); Render(); }); - Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); + ApplyWallpaperCommand = new[] + { + SelectedWindow.Select(w => w != null), + _desktopWindowManager.ObserveProperty(w => w.IsRendering) + }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); + ApplyWallpaperCommand.Subscribe(w => { }); } private void Render() diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index b5074ad..28c2e9f 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -20,11 +20,22 @@ + + Date: Sun, 22 Jul 2018 03:03:29 +0900 Subject: [PATCH 046/167] feat(preview): Keep aspect ratio of source. --- Source/Robock/Models/DesktopWindowManager.cs | 20 ++++++++- .../ViewModels/Tabs/DesktopViewModel.cs | 41 +++++++++++-------- Source/Robock/Views/Tabs/DesktopTab.xaml | 10 ++--- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index bed250e..638a8b9 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -6,6 +6,8 @@ using Robock.Shared.Win32; +using Size = System.Drawing.Size; + namespace Robock.Models { /// @@ -37,6 +39,7 @@ public void Stop() NativeMethods.DwmUnregisterThumbnail(_thumb); _thumb = IntPtr.Zero; IsRendering = false; + Size = new Size(1, 1); } public void Start(IntPtr src, int left, int top, int height, int width) @@ -53,7 +56,7 @@ public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int StartRender(left, top, height, width); } - public void Redender(int left, int top, int height, int width) + public void Rerender(int left, int top, int height, int width) { StartRender(left, top, height, width); } @@ -65,7 +68,8 @@ private void StartRender(int left, int top, int height, int width) IsRendering = true; // 入力ソースのアスペクト比を保つべきか、破棄すべきか - NativeMethods.DwmQueryThumbnailSourceSize(_thumb, out _); + NativeMethods.DwmQueryThumbnailSourceSize(_thumb, out var size); + Size = size; var props = new DWM_THUMBNAIL_PROPERTIES { @@ -90,5 +94,17 @@ public bool IsRendering } #endregion + + #region Size + + private Size _size; + + public Size Size + { + get => _size; + set => SetProperty(ref _size, value); + } + + #endregion } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index c7db595..4bf9c1f 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -25,11 +25,12 @@ public class DesktopViewModel : TabViewModel public ReadOnlyReactiveCollection Windows { get; } public string AspectRatio { get; } - // Preview - public ReactiveProperty PreviewAreaLeft { get; } - public ReactiveProperty PreviewAreaTop { get; } - public ReactiveProperty PreviewAreaHeight { get; } - public ReactiveProperty PreviewAreaWidth { get; } + // Editor + public ReactiveProperty EditorAspectRatio { get; } + public ReactiveProperty EditorAreaLeft { get; } + public ReactiveProperty EditorAreaTop { get; } + public ReactiveProperty EditorAreaHeight { get; } + public ReactiveProperty EditorAreaWidth { get; } // Selected public ReactiveProperty SelectedAreaLeft { get; } @@ -59,22 +60,28 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; - // アスペクト比 + // プレビュー AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; - // プレビュー - PreviewAreaLeft = new ReactiveProperty(); - PreviewAreaTop = new ReactiveProperty(); - PreviewAreaHeight = new ReactiveProperty(); - PreviewAreaWidth = new ReactiveProperty(); + // エディター + EditorAspectRatio = new ReactiveProperty("https://placehold.mochizuki.moe/1x1/"); + EditorAreaLeft = new ReactiveProperty(); + EditorAreaTop = new ReactiveProperty(); + EditorAreaHeight = new ReactiveProperty(); + EditorAreaWidth = new ReactiveProperty(); var observer = new[] { - PreviewAreaLeft, - PreviewAreaTop, - PreviewAreaHeight, - PreviewAreaWidth + EditorAreaLeft, + EditorAreaTop, + EditorAreaHeight, + EditorAreaWidth }.CombineLatest(); observer.Subscribe(w => Render()).AddTo(this); + desktopWindowManager.ObserveProperty(w => w.Size).Subscribe(w => + { + // + EditorAspectRatio.Value = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(w.Height, w.Width)}/000000%2C000/000000%2C000/"; + }).AddTo(this); // 選択範囲 SelectedAreaLeft = new ReactiveProperty(); @@ -111,9 +118,9 @@ private void Render() return; if (_desktopWindowManager.IsRendering) - _desktopWindowManager.Redender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value); + _desktopWindowManager.Rerender(EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); else - _desktopWindowManager.Start(SelectedWindow.Value.Handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value); + _desktopWindowManager.Start(SelectedWindow.Value.Handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); } } } \ No newline at end of file diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index 240fb9c..76c662f 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -86,13 +86,13 @@ Top="{Binding SelectedAreaTop.Value, Mode=OneWayToSource}" /> - + Date: Sun, 22 Jul 2018 03:46:14 +0900 Subject: [PATCH 047/167] feat: Array Thumbnails --- Source/Robock/Models/DesktopWindowManager.cs | 98 +++++++++---------- Source/Robock/Models/Thumbnail.cs | 53 ++++++++++ Source/Robock/Robock.csproj | 1 + .../ViewModels/Tabs/DesktopViewModel.cs | 25 +++-- Source/Robock/Views/Tabs/DesktopTab.xaml | 9 +- 5 files changed, 129 insertions(+), 57 deletions(-) create mode 100644 Source/Robock/Models/Thumbnail.cs diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index 638a8b9..abff63a 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Interop; @@ -15,17 +16,31 @@ namespace Robock.Models /// public class DesktopWindowManager : BindableBase, IDisposable { + #region Constants + + // ReSharper disable InconsistentNaming + public const int EDITOR_INDEX = 0; + public const int PREVIEW_INDEX = 1; + + // ReSharper enable InconsistentNaming + + #endregion + private IntPtr _hWnd; - private IntPtr _thumb; - public DesktopWindowManager() + public List Thumbnails { get; } + + public DesktopWindowManager(int capacity = 5) { - _thumb = IntPtr.Zero; + Thumbnails = new List(); + for (var i = 0; i < capacity; i++) + Thumbnails.Add(new Thumbnail()); } public void Dispose() { - Stop(); + for (var i = 0; i < Thumbnails.Count; i++) + Stop(i); } public void Initialize() @@ -33,43 +48,52 @@ public void Initialize() _hWnd = new WindowInteropHelper(Application.Current.MainWindow ?? throw new InvalidOperationException()).Handle; } - public void Stop() + public void Stop(int index = 0) { - if (_thumb != IntPtr.Zero) - NativeMethods.DwmUnregisterThumbnail(_thumb); - _thumb = IntPtr.Zero; - IsRendering = false; - Size = new Size(1, 1); + if (Thumbnails[index].Handle != IntPtr.Zero) + NativeMethods.DwmUnregisterThumbnail(Thumbnails[index].Handle); + Thumbnails[index].Handle = IntPtr.Zero; + Thumbnails[index].IsRendering = false; + Thumbnails[index].Size = new Size(1, 1); } - public void Start(IntPtr src, int left, int top, int height, int width) + public void Start(IntPtr src, int left, int top, int height, int width, int index = 0) { - StartTo(src, _hWnd, left, top, height, width); + StartTo(src, _hWnd, left, top, height, width, index); } - public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int width) + public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int width, int index = 0) { - Stop(); + Stop(index); + + var registered = NativeMethods.DwmRegisterThumbnail(dest, src, out var thumbnail); + Thumbnails[index].Handle = thumbnail; - var registered = NativeMethods.DwmRegisterThumbnail(dest, src, out _thumb); if (registered == 0) - StartRender(left, top, height, width); + StartRender(left, top, height, width, index); } - public void Rerender(int left, int top, int height, int width) + public void Rerender(int left, int top, int height, int width, int index = 0) { - StartRender(left, top, height, width); + Render(left, top, height, width, index); } - private void StartRender(int left, int top, int height, int width) + private void StartRender(int left, int top, int height, int width, int index = 0) { - if (_thumb == IntPtr.Zero) + if (Thumbnails[index].Handle == IntPtr.Zero) return; - IsRendering = true; + Thumbnails[index].IsRendering = true; - // 入力ソースのアスペクト比を保つべきか、破棄すべきか - NativeMethods.DwmQueryThumbnailSourceSize(_thumb, out var size); - Size = size; + NativeMethods.DwmQueryThumbnailSourceSize(Thumbnails[index].Handle, out var size); + Thumbnails[index].Size = size; + + Render(left, top, height, width, index); + } + + private void Render(int left, int top, int height, int width, int index = 0) + { + if (Thumbnails[index].Handle == IntPtr.Zero) + return; var props = new DWM_THUMBNAIL_PROPERTIES { @@ -80,31 +104,7 @@ private void StartRender(int left, int top, int height, int width) fSourceClientAreaOnly = true }; - NativeMethods.DwmUpdateThumbnailProperties(_thumb, ref props); - } - - #region IsRendering - - private bool _isRendering; - - public bool IsRendering - { - get => _isRendering; - set => SetProperty(ref _isRendering, value); + NativeMethods.DwmUpdateThumbnailProperties(Thumbnails[index].Handle, ref props); } - - #endregion - - #region Size - - private Size _size; - - public Size Size - { - get => _size; - set => SetProperty(ref _size, value); - } - - #endregion } } \ No newline at end of file diff --git a/Source/Robock/Models/Thumbnail.cs b/Source/Robock/Models/Thumbnail.cs new file mode 100644 index 0000000..8350373 --- /dev/null +++ b/Source/Robock/Models/Thumbnail.cs @@ -0,0 +1,53 @@ +using System; +using System.Drawing; + +using Prism.Mvvm; + +namespace Robock.Models +{ + public class Thumbnail : BindableBase + { + public Thumbnail() + { + Handle = IntPtr.Zero; + IsRendering = false; + Size = new Size(1, 1); + } + + #region Handle + + private IntPtr _handle; + + public IntPtr Handle + { + get => _handle; + set => SetProperty(ref _handle, value); + } + + #endregion + + #region IsRendering + + private bool _isRendering; + + public bool IsRendering + { + get => _isRendering; + set => SetProperty(ref _isRendering, value); + } + + #endregion + + #region Size + + private Size _size; + + public Size Size + { + get => _size; + set => SetProperty(ref _size, value); + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 8794722..5256541 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -148,6 +148,7 @@ + diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 4bf9c1f..8f3ea8f 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -23,7 +23,6 @@ public class DesktopViewModel : TabViewModel public ReactiveProperty IsSelected { get; } public ReactiveProperty SelectedWindow { get; } public ReadOnlyReactiveCollection Windows { get; } - public string AspectRatio { get; } // Editor public ReactiveProperty EditorAspectRatio { get; } @@ -38,6 +37,13 @@ public class DesktopViewModel : TabViewModel public ReactiveProperty SelectedAreaHeight { get; } public ReactiveProperty SelectedAreaWidth { get; } + // Preview + public string AspectRatio { get; } + public ReactiveProperty PreviewAreaLeft { get; } + public ReactiveProperty PreviewAreaTop { get; } + public ReactiveProperty PreviewAreaHeight { get; } + public ReactiveProperty PreviewAreaWidth { get; } + public ReactiveCommand ApplyWallpaperCommand { get; } public ReactiveCommand DiscardWallpaperCommand { get; } public ReactiveCommand ReloadWindowsCommand { get; } @@ -60,9 +66,6 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; - // プレビュー - AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; - // エディター EditorAspectRatio = new ReactiveProperty("https://placehold.mochizuki.moe/1x1/"); EditorAreaLeft = new ReactiveProperty(); @@ -77,7 +80,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin EditorAreaWidth }.CombineLatest(); observer.Subscribe(w => Render()).AddTo(this); - desktopWindowManager.ObserveProperty(w => w.Size).Subscribe(w => + desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.Size).Subscribe(w => { // EditorAspectRatio.Value = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(w.Height, w.Width)}/000000%2C000/000000%2C000/"; @@ -89,6 +92,14 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedAreaHeight = new ReactiveProperty(); SelectedAreaWidth = new ReactiveProperty(); + // プレビュー + AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; + PreviewAreaLeft = new ReactiveProperty(); + PreviewAreaTop = new ReactiveProperty(); + PreviewAreaHeight = new ReactiveProperty(); + PreviewAreaWidth = new ReactiveProperty(); + + // 他 Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); IsSelected = new ReactiveProperty(false); IsSelected.Subscribe(w => @@ -105,7 +116,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin ApplyWallpaperCommand = new[] { SelectedWindow.Select(w => w != null), - _desktopWindowManager.ObserveProperty(w => w.IsRendering) + _desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.IsRendering) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); ApplyWallpaperCommand.Subscribe(_ => { }).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); @@ -117,7 +128,7 @@ private void Render() if (SelectedWindow?.Value == null) return; - if (_desktopWindowManager.IsRendering) + if (_desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].IsRendering) _desktopWindowManager.Rerender(EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); else _desktopWindowManager.Start(SelectedWindow.Value.Handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index 76c662f..efa8818 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -113,7 +113,14 @@ Text="Live Preview:" /> + Stretch="Uniform"> + + + + \ No newline at end of file From f566ea44cc67e5145cc836fd2ff603f7535cf79b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 04:16:24 +0900 Subject: [PATCH 048/167] feat(preview): Live Preview! --- .../Behaviors/RectangleSelectorBehavior.cs | 4 ++ Source/Robock/Models/DesktopWindowManager.cs | 23 ++++--- .../ViewModels/Tabs/DesktopViewModel.cs | 69 ++++++++++++++++--- 3 files changed, 77 insertions(+), 19 deletions(-) diff --git a/Source/Robock/Behaviors/RectangleSelectorBehavior.cs b/Source/Robock/Behaviors/RectangleSelectorBehavior.cs index 6bd764c..1bc2c21 100644 --- a/Source/Robock/Behaviors/RectangleSelectorBehavior.cs +++ b/Source/Robock/Behaviors/RectangleSelectorBehavior.cs @@ -80,6 +80,10 @@ private void AssociatedObjectOnMouseLeftButtonDown(object sender, MouseButtonEve private void AssociatedObjectOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { _isSelecting = false; + Top = (int) Rectangle.Margin.Top; + Left = (int) Rectangle.Margin.Left; + Width = (int) Rectangle.Width; + Height = (int) Rectangle.Height; } private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs e) diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index abff63a..fed698e 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -57,12 +57,12 @@ public void Stop(int index = 0) Thumbnails[index].Size = new Size(1, 1); } - public void Start(IntPtr src, int left, int top, int height, int width, int index = 0) + public void Start(IntPtr src, int left, int top, int height, int width, int index = 0, RECT? rect = null) { - StartTo(src, _hWnd, left, top, height, width, index); + StartTo(src, _hWnd, left, top, height, width, index, rect); } - public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int width, int index = 0) + public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int width, int index = 0, RECT? rect = null) { Stop(index); @@ -70,15 +70,15 @@ public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int Thumbnails[index].Handle = thumbnail; if (registered == 0) - StartRender(left, top, height, width, index); + StartRender(left, top, height, width, index, rect); } - public void Rerender(int left, int top, int height, int width, int index = 0) + public void Rerender(int left, int top, int height, int width, int index = 0, RECT? rect = null) { - Render(left, top, height, width, index); + Render(left, top, height, width, index, rect); } - private void StartRender(int left, int top, int height, int width, int index = 0) + private void StartRender(int left, int top, int height, int width, int index = 0, RECT? rect = null) { if (Thumbnails[index].Handle == IntPtr.Zero) return; @@ -87,10 +87,10 @@ private void StartRender(int left, int top, int height, int width, int index = 0 NativeMethods.DwmQueryThumbnailSourceSize(Thumbnails[index].Handle, out var size); Thumbnails[index].Size = size; - Render(left, top, height, width, index); + Render(left, top, height, width, index, rect); } - private void Render(int left, int top, int height, int width, int index = 0) + private void Render(int left, int top, int height, int width, int index = 0, RECT? rect = null) { if (Thumbnails[index].Handle == IntPtr.Zero) return; @@ -103,6 +103,11 @@ private void Render(int left, int top, int height, int width, int index = 0) rcDestination = new RECT {left = left, top = top, right = left + width, bottom = top + height}, fSourceClientAreaOnly = true }; + if (rect != null) + { + props.rcSource = rect.Value; + props.dwFlags |= (int) DWM_TNP.DWM_TNP_RECTSOURCE; + } NativeMethods.DwmUpdateThumbnailProperties(Thumbnails[index].Handle, ref props); } diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 8f3ea8f..969c55f 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -8,6 +8,7 @@ using Robock.Models; using Robock.Shared.Extensions; +using Robock.Shared.Win32; namespace Robock.ViewModels.Tabs { @@ -72,14 +73,14 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin EditorAreaTop = new ReactiveProperty(); EditorAreaHeight = new ReactiveProperty(); EditorAreaWidth = new ReactiveProperty(); - var observer = new[] + var editorArea = new[] { EditorAreaLeft, EditorAreaTop, EditorAreaHeight, EditorAreaWidth }.CombineLatest(); - observer.Subscribe(w => Render()).AddTo(this); + editorArea.Subscribe(w => Render(DesktopWindowManager.EDITOR_INDEX)).AddTo(this); desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.Size).Subscribe(w => { // @@ -91,6 +92,14 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedAreaTop = new ReactiveProperty(); SelectedAreaHeight = new ReactiveProperty(); SelectedAreaWidth = new ReactiveProperty(); + var selectedArea = new[] + { + SelectedAreaLeft, + SelectedAreaTop, + SelectedAreaHeight, + SelectedAreaWidth + }.CombineLatest(); + selectedArea.Subscribe(w => Render(DesktopWindowManager.PREVIEW_INDEX)).AddTo(this); // プレビュー AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; @@ -98,20 +107,35 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin PreviewAreaTop = new ReactiveProperty(); PreviewAreaHeight = new ReactiveProperty(); PreviewAreaWidth = new ReactiveProperty(); + var previewArea = new[] + { + EditorAreaLeft, + EditorAreaTop, + EditorAreaHeight, + EditorAreaWidth + }.CombineLatest(); + previewArea.Subscribe(w => Render(DesktopWindowManager.PREVIEW_INDEX)).AddTo(this); + desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.IsRendering).Subscribe(w => + { + // + Render(DesktopWindowManager.PREVIEW_INDEX); + }).AddTo(this); // 他 Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); IsSelected = new ReactiveProperty(false); IsSelected.Subscribe(w => { - _desktopWindowManager.Stop(); - Render(); + _desktopWindowManager.Stop(0); + _desktopWindowManager.Stop(1); + Render(DesktopWindowManager.EDITOR_INDEX); }).AddTo(this); SelectedWindow = new ReactiveProperty(); SelectedWindow.Where(w => w != null).Subscribe(w => { - _desktopWindowManager.Stop(); - Render(); + _desktopWindowManager.Stop(0); + _desktopWindowManager.Stop(1); + Render(DesktopWindowManager.EDITOR_INDEX); }).AddTo(this); ApplyWallpaperCommand = new[] { @@ -123,15 +147,40 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin ReloadWindowsCommand.Subscribe(_ => windowManager.ForceUpdate()).AddTo(this); } - private void Render() + private void Render(int index) { if (SelectedWindow?.Value == null) return; - if (_desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].IsRendering) - _desktopWindowManager.Rerender(EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + if (index == DesktopWindowManager.EDITOR_INDEX) + { + if (_desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].IsRendering) + _desktopWindowManager.Rerender(EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + else + _desktopWindowManager.Start(SelectedWindow.Value.Handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + } else - _desktopWindowManager.Start(SelectedWindow.Value.Handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + { + // 描画サイズから、縮小された割合を計算 + var multi = _desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].Size.Height / (double) EditorAreaHeight.Value; + + // 選択された領域を取得 + RECT? rect = null; + if (SelectedAreaHeight.Value != 0) + rect = new RECT + { + top = (int) (SelectedAreaTop.Value * multi), + left = (int) (SelectedAreaLeft.Value * multi), + bottom = (int) ((SelectedAreaTop.Value + SelectedAreaHeight.Value) * multi), + right = (int) ((SelectedAreaLeft.Value + SelectedAreaWidth.Value) * multi) + }; + + if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PREVIEW_INDEX].IsRendering) + _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); + else + _desktopWindowManager.Start(SelectedWindow.Value.Handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, + rect); + } } } } \ No newline at end of file From 0e5b66e5a000054fdebf6b729039adf1f82d9e41 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 11:54:35 +0900 Subject: [PATCH 049/167] fix: Window title is chnaged. --- Source/Robock/Models/Window.cs | 17 +++++++++++++++-- Source/Robock/Models/WindowManager.cs | 4 +++- Source/Robock/ViewModels/WindowViewModel.cs | 11 ++++++++--- Source/Robock/Views/Tabs/DesktopTab.xaml | 2 +- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Source/Robock/Models/Window.cs b/Source/Robock/Models/Window.cs index 2e37e5a..3727453 100644 --- a/Source/Robock/Models/Window.cs +++ b/Source/Robock/Models/Window.cs @@ -1,12 +1,25 @@ using System; +using Prism.Mvvm; + namespace Robock.Models { // Win32 Unmaneged - public class Window + public class Window : BindableBase { public IntPtr Handle { get; set; } - public string Title { get; set; } public bool IsMarked { get; set; } + + #region Title + + private string _title; + + public string Title + { + get => _title; + set => SetProperty(ref _title, value); + } + + #endregion } } \ No newline at end of file diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs index 86a9148..1c9f0fd 100644 --- a/Source/Robock/Models/WindowManager.cs +++ b/Source/Robock/Models/WindowManager.cs @@ -67,7 +67,9 @@ private void FindWindows() } else { - Windows.Single(w => w.Handle == window.Handle).IsMarked = true; + var exist = Windows.Single(w => w.Handle == window.Handle); + exist.IsMarked = true; + exist.Title = window.Title; } // Remove killed windows. diff --git a/Source/Robock/ViewModels/WindowViewModel.cs b/Source/Robock/ViewModels/WindowViewModel.cs index 3aaf1da..fb2910e 100644 --- a/Source/Robock/ViewModels/WindowViewModel.cs +++ b/Source/Robock/ViewModels/WindowViewModel.cs @@ -1,6 +1,10 @@ using System; +using Reactive.Bindings; +using Reactive.Bindings.Extensions; + using Robock.Models; +using Robock.Shared.Extensions; using Robock.Shared.Mvvm; namespace Robock.ViewModels @@ -8,12 +12,13 @@ namespace Robock.ViewModels public class WindowViewModel : ViewModel { private readonly Window _window; - public string Name => $"{_window.Title}"; + public ReactiveProperty Title { get; } public IntPtr Handle => _window.Handle; - public WindowViewModel(Window process) + public WindowViewModel(Window window) { - _window = process; + _window = window; + Title = window.ObserveProperty(w => w.Title).ToReactiveProperty().AddTo(this); } } } \ No newline at end of file diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index efa8818..db126a6 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -58,7 +58,7 @@ From 9d320318962d41c38312d76f248b9882c3191ccf Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 12:08:55 +0900 Subject: [PATCH 050/167] fix: For selected area is nothing. --- Source/Robock/Models/DesktopWindowManager.cs | 7 +-- .../ViewModels/Tabs/DesktopViewModel.cs | 46 ++++++++++++------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index fed698e..17b2d65 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -18,11 +18,8 @@ public class DesktopWindowManager : BindableBase, IDisposable { #region Constants - // ReSharper disable InconsistentNaming - public const int EDITOR_INDEX = 0; - public const int PREVIEW_INDEX = 1; - - // ReSharper enable InconsistentNaming + public const int EditorIndex = 0; + public const int PreviewIndex = 1; #endregion diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 969c55f..8f4d164 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Windows; @@ -80,8 +81,8 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin EditorAreaHeight, EditorAreaWidth }.CombineLatest(); - editorArea.Subscribe(w => Render(DesktopWindowManager.EDITOR_INDEX)).AddTo(this); - desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.Size).Subscribe(w => + editorArea.Subscribe(w => Render(DesktopWindowManager.EditorIndex)).AddTo(this); + desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.Size).Subscribe(w => { // EditorAspectRatio.Value = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(w.Height, w.Width)}/000000%2C000/000000%2C000/"; @@ -99,7 +100,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedAreaHeight, SelectedAreaWidth }.CombineLatest(); - selectedArea.Subscribe(w => Render(DesktopWindowManager.PREVIEW_INDEX)).AddTo(this); + selectedArea.Subscribe(w => Render(DesktopWindowManager.PreviewIndex)).AddTo(this); // プレビュー AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; @@ -114,11 +115,11 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin EditorAreaHeight, EditorAreaWidth }.CombineLatest(); - previewArea.Subscribe(w => Render(DesktopWindowManager.PREVIEW_INDEX)).AddTo(this); - desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.IsRendering).Subscribe(w => + previewArea.Subscribe(w => Render(DesktopWindowManager.PreviewIndex)).AddTo(this); + desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.IsRendering).Subscribe(w => { // - Render(DesktopWindowManager.PREVIEW_INDEX); + Render(DesktopWindowManager.PreviewIndex); }).AddTo(this); // 他 @@ -128,19 +129,19 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin { _desktopWindowManager.Stop(0); _desktopWindowManager.Stop(1); - Render(DesktopWindowManager.EDITOR_INDEX); + Render(DesktopWindowManager.EditorIndex); }).AddTo(this); SelectedWindow = new ReactiveProperty(); SelectedWindow.Where(w => w != null).Subscribe(w => { _desktopWindowManager.Stop(0); _desktopWindowManager.Stop(1); - Render(DesktopWindowManager.EDITOR_INDEX); + Render(DesktopWindowManager.EditorIndex); }).AddTo(this); ApplyWallpaperCommand = new[] { SelectedWindow.Select(w => w != null), - _desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].ObserveProperty(w => w.IsRendering) + _desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.IsRendering) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); ApplyWallpaperCommand.Subscribe(_ => { }).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); @@ -151,21 +152,24 @@ private void Render(int index) { if (SelectedWindow?.Value == null) return; + var handle = SelectedWindow.Value.Handle; - if (index == DesktopWindowManager.EDITOR_INDEX) + if (index == DesktopWindowManager.EditorIndex) { - if (_desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].IsRendering) + if (_desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].IsRendering) _desktopWindowManager.Rerender(EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); else - _desktopWindowManager.Start(SelectedWindow.Value.Handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + _desktopWindowManager.Start(handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); } else { + var editor = DesktopWindowManager.EditorIndex; + // 描画サイズから、縮小された割合を計算 - var multi = _desktopWindowManager.Thumbnails[DesktopWindowManager.EDITOR_INDEX].Size.Height / (double) EditorAreaHeight.Value; + var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; // 選択された領域を取得 - RECT? rect = null; + RECT rect; if (SelectedAreaHeight.Value != 0) rect = new RECT { @@ -174,12 +178,20 @@ private void Render(int index) bottom = (int) ((SelectedAreaTop.Value + SelectedAreaHeight.Value) * multi), right = (int) ((SelectedAreaLeft.Value + SelectedAreaWidth.Value) * multi) }; + else + rect = new RECT + { + top = 0, + left = 0, + bottom = _desktopWindowManager.Thumbnails[editor].Size.Height, + right = _desktopWindowManager.Thumbnails[editor].Size.Width + }; - if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PREVIEW_INDEX].IsRendering) + Debug.WriteLine($"{SelectedAreaTop.Value}, {SelectedAreaLeft.Value}, {SelectedAreaHeight.Value}, {SelectedAreaWidth.Value}"); + if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); else - _desktopWindowManager.Start(SelectedWindow.Value.Handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, - rect); + _desktopWindowManager.Start(handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); } } } From 91cd97fbfca40342433d2d2ca9f6a3fe2831bb31 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 12:17:24 +0900 Subject: [PATCH 051/167] refactor: Calc rect in utility --- Source/Robock/Models/RectUtil.cs | 18 +++++++++++++ .../ViewModels/Tabs/DesktopViewModel.cs | 25 +++---------------- 2 files changed, 21 insertions(+), 22 deletions(-) create mode 100644 Source/Robock/Models/RectUtil.cs diff --git a/Source/Robock/Models/RectUtil.cs b/Source/Robock/Models/RectUtil.cs new file mode 100644 index 0000000..1ed286c --- /dev/null +++ b/Source/Robock/Models/RectUtil.cs @@ -0,0 +1,18 @@ +using Robock.Shared.Win32; + +namespace Robock.Models +{ + public static class RectUtil + { + public static RECT AsRect(double top, double left, double height, double width, double multi = 1) + { + return new RECT + { + top = (int) (top * multi), + left = (int) (left * multi), + bottom = (int) ((top + height) * multi), + right = (int) ((left + width) * multi) + }; + } + } +} \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 8f4d164..7cfcd14 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Windows; @@ -9,7 +8,6 @@ using Robock.Models; using Robock.Shared.Extensions; -using Robock.Shared.Win32; namespace Robock.ViewModels.Tabs { @@ -167,27 +165,10 @@ private void Render(int index) // 描画サイズから、縮小された割合を計算 var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; + var rect = SelectedAreaHeight.Value != 0 + ? RectUtil.AsRect(SelectedAreaTop.Value, SelectedAreaLeft.Value, SelectedAreaTop.Value, SelectedAreaWidth.Value, multi) + : RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); - // 選択された領域を取得 - RECT rect; - if (SelectedAreaHeight.Value != 0) - rect = new RECT - { - top = (int) (SelectedAreaTop.Value * multi), - left = (int) (SelectedAreaLeft.Value * multi), - bottom = (int) ((SelectedAreaTop.Value + SelectedAreaHeight.Value) * multi), - right = (int) ((SelectedAreaLeft.Value + SelectedAreaWidth.Value) * multi) - }; - else - rect = new RECT - { - top = 0, - left = 0, - bottom = _desktopWindowManager.Thumbnails[editor].Size.Height, - right = _desktopWindowManager.Thumbnails[editor].Size.Width - }; - - Debug.WriteLine($"{SelectedAreaTop.Value}, {SelectedAreaLeft.Value}, {SelectedAreaHeight.Value}, {SelectedAreaWidth.Value}"); if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); else From 4c3af7c751be31065b5f9e8eb2c5c6fffc621da8 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 13:55:00 +0900 Subject: [PATCH 052/167] feat: Fix height --- README.md | 3 +- Source/Robock/Robock.csproj | 1 + .../ViewModels/Tabs/DesktopViewModel.cs | 2 +- Source/Robock/Views/Tabs/DesktopTab.xaml | 35 ++++++++++++------- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 912751d..2f0f032 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,13 @@ ## Requirements -* Windows 7 SP1 以降 +* Windows 7 SP1 以降 (64-bit) * Windows 7 については DWM を有効にする必要があり * Windows 8.1 以前についてはサポート、 Pull Request 共に受け付けていません * .NET Framework 4.7.2 以降 * Dirext3D 9.0Ex および HLSL 2.0 に対応したビデオカード * Windows Display Driver Model に対応したビデオカード +* インターネット接続 * YouTube で 1080p 動画をフルスクリーンで見てもカクつかない程度のスペック diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 5256541..acfc331 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -148,6 +148,7 @@ + diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 7cfcd14..253dc67 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -166,7 +166,7 @@ private void Render(int index) // 描画サイズから、縮小された割合を計算 var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; var rect = SelectedAreaHeight.Value != 0 - ? RectUtil.AsRect(SelectedAreaTop.Value, SelectedAreaLeft.Value, SelectedAreaTop.Value, SelectedAreaWidth.Value, multi) + ? RectUtil.AsRect(SelectedAreaTop.Value, SelectedAreaLeft.Value, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi) : RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index db126a6..254aadb 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -72,12 +72,17 @@ Grid.ColumnSpan="2" Margin="0,5,0,10" Text="Select the square range from live editor that you want to use as wallpaper : " /> - - + + + + + - + - - - + + + + + + - @@ -121,6 +132,6 @@ Top="{Binding PreviewAreaTop.Value, Mode=OneWayToSource}" /> - + \ No newline at end of file From 25ead0a5c8eaae0ae4de89d2b2a61368869c5b47 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 14:00:23 +0900 Subject: [PATCH 053/167] Revert "refactor: Calc rect in utility" This reverts commit 91cd97fbfca40342433d2d2ca9f6a3fe2831bb31. --- Source/Robock/Models/RectUtil.cs | 18 ------------- Source/Robock/Robock.csproj | 1 - .../ViewModels/Tabs/DesktopViewModel.cs | 25 ++++++++++++++++--- 3 files changed, 22 insertions(+), 22 deletions(-) delete mode 100644 Source/Robock/Models/RectUtil.cs diff --git a/Source/Robock/Models/RectUtil.cs b/Source/Robock/Models/RectUtil.cs deleted file mode 100644 index 1ed286c..0000000 --- a/Source/Robock/Models/RectUtil.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Robock.Shared.Win32; - -namespace Robock.Models -{ - public static class RectUtil - { - public static RECT AsRect(double top, double left, double height, double width, double multi = 1) - { - return new RECT - { - top = (int) (top * multi), - left = (int) (left * multi), - bottom = (int) ((top + height) * multi), - right = (int) ((left + width) * multi) - }; - } - } -} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index acfc331..5256541 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -148,7 +148,6 @@ - diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 253dc67..8f4d164 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Windows; @@ -8,6 +9,7 @@ using Robock.Models; using Robock.Shared.Extensions; +using Robock.Shared.Win32; namespace Robock.ViewModels.Tabs { @@ -165,10 +167,27 @@ private void Render(int index) // 描画サイズから、縮小された割合を計算 var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; - var rect = SelectedAreaHeight.Value != 0 - ? RectUtil.AsRect(SelectedAreaTop.Value, SelectedAreaLeft.Value, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi) - : RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); + // 選択された領域を取得 + RECT rect; + if (SelectedAreaHeight.Value != 0) + rect = new RECT + { + top = (int) (SelectedAreaTop.Value * multi), + left = (int) (SelectedAreaLeft.Value * multi), + bottom = (int) ((SelectedAreaTop.Value + SelectedAreaHeight.Value) * multi), + right = (int) ((SelectedAreaLeft.Value + SelectedAreaWidth.Value) * multi) + }; + else + rect = new RECT + { + top = 0, + left = 0, + bottom = _desktopWindowManager.Thumbnails[editor].Size.Height, + right = _desktopWindowManager.Thumbnails[editor].Size.Width + }; + + Debug.WriteLine($"{SelectedAreaTop.Value}, {SelectedAreaLeft.Value}, {SelectedAreaHeight.Value}, {SelectedAreaWidth.Value}"); if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); else From 79ef8c505bec3f9a0d56839bd180312df7d96834 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 14:00:27 +0900 Subject: [PATCH 054/167] Revert "Revert "refactor: Calc rect in utility"" This reverts commit 25ead0a5c8eaae0ae4de89d2b2a61368869c5b47. --- Source/Robock/Models/RectUtil.cs | 18 +++++++++++++ Source/Robock/Robock.csproj | 1 + .../ViewModels/Tabs/DesktopViewModel.cs | 25 +++---------------- 3 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 Source/Robock/Models/RectUtil.cs diff --git a/Source/Robock/Models/RectUtil.cs b/Source/Robock/Models/RectUtil.cs new file mode 100644 index 0000000..1ed286c --- /dev/null +++ b/Source/Robock/Models/RectUtil.cs @@ -0,0 +1,18 @@ +using Robock.Shared.Win32; + +namespace Robock.Models +{ + public static class RectUtil + { + public static RECT AsRect(double top, double left, double height, double width, double multi = 1) + { + return new RECT + { + top = (int) (top * multi), + left = (int) (left * multi), + bottom = (int) ((top + height) * multi), + right = (int) ((left + width) * multi) + }; + } + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 5256541..acfc331 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -148,6 +148,7 @@ + diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 8f4d164..253dc67 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Windows; @@ -9,7 +8,6 @@ using Robock.Models; using Robock.Shared.Extensions; -using Robock.Shared.Win32; namespace Robock.ViewModels.Tabs { @@ -167,27 +165,10 @@ private void Render(int index) // 描画サイズから、縮小された割合を計算 var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; + var rect = SelectedAreaHeight.Value != 0 + ? RectUtil.AsRect(SelectedAreaTop.Value, SelectedAreaLeft.Value, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi) + : RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); - // 選択された領域を取得 - RECT rect; - if (SelectedAreaHeight.Value != 0) - rect = new RECT - { - top = (int) (SelectedAreaTop.Value * multi), - left = (int) (SelectedAreaLeft.Value * multi), - bottom = (int) ((SelectedAreaTop.Value + SelectedAreaHeight.Value) * multi), - right = (int) ((SelectedAreaLeft.Value + SelectedAreaWidth.Value) * multi) - }; - else - rect = new RECT - { - top = 0, - left = 0, - bottom = _desktopWindowManager.Thumbnails[editor].Size.Height, - right = _desktopWindowManager.Thumbnails[editor].Size.Width - }; - - Debug.WriteLine($"{SelectedAreaTop.Value}, {SelectedAreaLeft.Value}, {SelectedAreaHeight.Value}, {SelectedAreaWidth.Value}"); if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); else From 3f15f27babb943dacf1b42f8c4a8556e4200f2db Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 14:21:48 +0900 Subject: [PATCH 055/167] fix: If coords are greatly of Grid and Iage, preview will be incorrect. --- .../ViewModels/Tabs/DesktopViewModel.cs | 19 ++++++++++++++++--- Source/Robock/Views/Tabs/DesktopTab.xaml | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 253dc67..5414005 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -44,6 +44,10 @@ public class DesktopViewModel : TabViewModel public ReactiveProperty PreviewAreaHeight { get; } public ReactiveProperty PreviewAreaWidth { get; } + // Grid + public ReactiveProperty GridAreaLeft { get; } + public ReactiveProperty GridAreaTop { get; } + public ReactiveCommand ApplyWallpaperCommand { get; } public ReactiveCommand DiscardWallpaperCommand { get; } public ReactiveCommand ReloadWindowsCommand { get; } @@ -120,6 +124,10 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin Render(DesktopWindowManager.PreviewIndex); }).AddTo(this); + // 親 + GridAreaLeft = new ReactiveProperty(); + GridAreaTop = new ReactiveProperty(); + // 他 Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); IsSelected = new ReactiveProperty(false); @@ -165,9 +173,14 @@ private void Render(int index) // 描画サイズから、縮小された割合を計算 var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; - var rect = SelectedAreaHeight.Value != 0 - ? RectUtil.AsRect(SelectedAreaTop.Value, SelectedAreaLeft.Value, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi) - : RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); + + var rect = RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); + if (SelectedAreaHeight.Value != 0) + { + // Grid と Image のズレが大きいと、描画領域がずれてしまうので、補正する + var diff = new Size(EditorAreaLeft.Value - GridAreaLeft.Value, EditorAreaTop.Value - GridAreaTop.Value); + rect = RectUtil.AsRect(SelectedAreaTop.Value - diff.Height, SelectedAreaLeft.Value - diff.Width, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi); + } if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index 254aadb..ea64137 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -84,6 +84,8 @@ Text="Live Editor:" /> + Date: Sun, 22 Jul 2018 15:07:07 +0900 Subject: [PATCH 056/167] docs: Add donation addresses. --- README.md | 9 ++- .../Robock.Background.csproj | 4 + Source/Robock.Background/app.manifest | 76 +++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 Source/Robock.Background/app.manifest diff --git a/README.md b/README.md index 2f0f032..410c86e 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,11 @@ * Robock * Robock.Background -* Robock.Shared \ No newline at end of file +* Robock.Shared + + +## Donation + +* BTC : `1NFcYczriqTEzVgzfurTMJNbhxPY1vyki9` +* ETH : `0x3cd67f16c2d7fe518e924930f645dd73aadaaf39` +* MONA : `MC4x87u1ffmhsRhHof1sHz8UAtNtKCTQut` diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 6ae0ad8..aa7bfcf 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -33,6 +33,9 @@ prompt 4 + + app.manifest + ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll @@ -130,6 +133,7 @@ ResXFileCodeGenerator Resources.Designer.cs + SettingsSingleFileGenerator diff --git a/Source/Robock.Background/app.manifest b/Source/Robock.Background/app.manifest new file mode 100644 index 0000000..6aca63b --- /dev/null +++ b/Source/Robock.Background/app.manifest @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From cdbcfb127e37773eec005149c1d4b032680755ef Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 15:52:52 +0900 Subject: [PATCH 057/167] chore(dwm): Preview's opacity = 255. --- Source/Robock/Models/DesktopWindowManager.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock/Models/DesktopWindowManager.cs index 17b2d65..2079672 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock/Models/DesktopWindowManager.cs @@ -16,13 +16,6 @@ namespace Robock.Models /// public class DesktopWindowManager : BindableBase, IDisposable { - #region Constants - - public const int EditorIndex = 0; - public const int PreviewIndex = 1; - - #endregion - private IntPtr _hWnd; public List Thumbnails { get; } @@ -96,7 +89,7 @@ private void Render(int left, int top, int height, int width, int index = 0, REC { fVisible = true, dwFlags = (int) (DWM_TNP.DWM_TNP_VISIBLE | DWM_TNP.DWM_TNP_OPACITY | DWM_TNP.DWM_TNP_RECTDESTINATION | DWM_TNP.DWM_TNP_SOURCECLIENTAREAONLY), - opacity = 255 / 2, + opacity = (byte) (255 / (index == EditorIndex ? 2 : 1)), rcDestination = new RECT {left = left, top = top, right = left + width, bottom = top + height}, fSourceClientAreaOnly = true }; @@ -108,5 +101,12 @@ private void Render(int left, int top, int height, int width, int index = 0, REC NativeMethods.DwmUpdateThumbnailProperties(Thumbnails[index].Handle, ref props); } + + #region Constants + + public const int EditorIndex = 0; + public const int PreviewIndex = 1; + + #endregion } } \ No newline at end of file From d75c9986ce114d5af34f19bb15e74095d2fd254b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 17:17:15 +0900 Subject: [PATCH 058/167] feat(wcf): Communication --- .../Robock.Background.csproj | 21 +++++++ .../ViewModels/AppShellViewModel.cs | 21 ++++++- Source/Robock.Background/Views/AppShell.xaml | 9 +-- .../Communication/IRobockDuplex.cs | 41 +++++++++++++ .../Communication/IRobockDuplexCallback.cs | 38 ++++++++++++ .../Communication/RobockClient.cs | 59 +++++++++++++++++++ .../Communication/RobockServer.cs | 56 ++++++++++++++++++ .../Models/DesktopWindowManager.cs | 2 +- .../Models/RectUtil.cs | 2 +- .../Models/Thumbnail.cs | 2 +- Source/Robock.Shared/Mvvm/ViewModel.cs | 2 +- Source/Robock.Shared/Robock.Shared.csproj | 9 +++ Source/Robock.sln | 4 +- Source/Robock/Models/Desktop.cs | 14 ++++- Source/Robock/Robock.csproj | 3 - Source/Robock/ViewModels/AppShellViewModel.cs | 1 + .../ViewModels/Tabs/DesktopViewModel.cs | 3 +- 17 files changed, 270 insertions(+), 17 deletions(-) create mode 100644 Source/Robock.Shared/Communication/IRobockDuplex.cs create mode 100644 Source/Robock.Shared/Communication/IRobockDuplexCallback.cs create mode 100644 Source/Robock.Shared/Communication/RobockClient.cs create mode 100644 Source/Robock.Shared/Communication/RobockServer.cs rename Source/{Robock => Robock.Shared}/Models/DesktopWindowManager.cs (99%) rename Source/{Robock => Robock.Shared}/Models/RectUtil.cs (93%) rename Source/{Robock => Robock.Shared}/Models/Thumbnail.cs (96%) diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index aa7bfcf..822d7cc 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -36,6 +36,26 @@ app.manifest + + true + ..\Robock\bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll @@ -82,6 +102,7 @@ ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll True + diff --git a/Source/Robock.Background/ViewModels/AppShellViewModel.cs b/Source/Robock.Background/ViewModels/AppShellViewModel.cs index e1feb51..2588d95 100644 --- a/Source/Robock.Background/ViewModels/AppShellViewModel.cs +++ b/Source/Robock.Background/ViewModels/AppShellViewModel.cs @@ -1,6 +1,23 @@ -using Robock.Shared.Mvvm; +using System; +using System.Reactive.Linq; + +using Robock.Shared.Communication; +using Robock.Shared.Extensions; +using Robock.Shared.Mvvm; namespace Robock.Background.ViewModels { - public class AppShellViewModel : ViewModel { } + public class AppShellViewModel : ViewModel + { + private RobockServer _server; + + public AppShellViewModel() + { + Observable.Return(0).Delay(TimeSpan.FromMilliseconds(500)).Subscribe(_ => + { + _server = new RobockServer().AddTo(this); + _server.Start(); + }); + } + } } \ No newline at end of file diff --git a/Source/Robock.Background/Views/AppShell.xaml b/Source/Robock.Background/Views/AppShell.xaml index e5aa3ab..da91435 100644 --- a/Source/Robock.Background/Views/AppShell.xaml +++ b/Source/Robock.Background/Views/AppShell.xaml @@ -4,14 +4,15 @@ xmlns:actions="clr-namespace:Robock.Shared.Actions;assembly=Robock.Shared" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" - xmlns:local="clr-namespace:Robock.Background.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" - Title="AppShell" - Width="800" - Height="450" + Title="Robock.Background" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> + + + diff --git a/Source/Robock.Shared/Communication/IRobockDuplex.cs b/Source/Robock.Shared/Communication/IRobockDuplex.cs new file mode 100644 index 0000000..79c7acd --- /dev/null +++ b/Source/Robock.Shared/Communication/IRobockDuplex.cs @@ -0,0 +1,41 @@ +using System; +using System.ServiceModel; + +namespace Robock.Shared.Communication +{ + [ServiceContract(Namespace = "robock://localhost", SessionMode = SessionMode.Required, CallbackContract = typeof(IRobockDuplexCallback))] + public interface IRobockDuplex + { + /// + /// Handshake between Robock and Robock.Background + /// + /// Wallpaper index (e.g. 0 = Primary) + [OperationContract(IsOneWay = true)] + void Handshake(int index); + + /// + /// Apply wallpaper + /// + /// UUID of Robock.Background + /// hWnd of source window + /// left position of rendering area + /// top position of rendering area + /// height of rendering area + /// width of rendering area + [OperationContract(IsOneWay = true)] + void ApplyWallpaper(string uuid, IntPtr src, int left, int top, int height, int width); + + /// + /// Discard wallpaper + /// + /// UUID of Robock.Background + [OperationContract(IsOneWay = true)] + void DiscardWallpaper(string uuid); + + /// + /// Close communication pipe + /// + /// UUID of Robock.Background + void Close(string uuid); + } +} \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs b/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs new file mode 100644 index 0000000..1aefa8f --- /dev/null +++ b/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs @@ -0,0 +1,38 @@ +using System.ServiceModel; + +// ReSharper disable OperationContractWithoutServiceContract + +namespace Robock.Shared.Communication +{ + public interface IRobockDuplexCallback + { + /// + /// Handshake() callback + /// + /// UUID of Robock.Background + [OperationContract(IsOneWay = true)] + void HandshakeCallback(string uuid); + + /// + /// ApplyWallpaper() callback + /// + /// UUID of Robock.Background + /// If wallpaper applied to background, returns true + [OperationContract(IsOneWay = true)] + void ApplyWallpaperCallback(string uuid, bool isSucceed); + + /// + /// DiscardWallpaper() callback + /// + /// UUID of Robock.Background + [OperationContract(IsOneWay = true)] + void DiscardWallpaperCallback(string uuid); + + /// + /// Close() callback + /// + /// UUID of Robock.Background + [OperationContract(IsOneWay = true)] + void CloseCallback(string uuid); + } +} \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/RobockClient.cs b/Source/Robock.Shared/Communication/RobockClient.cs new file mode 100644 index 0000000..9d19eb7 --- /dev/null +++ b/Source/Robock.Shared/Communication/RobockClient.cs @@ -0,0 +1,59 @@ +using System; +using System.ServiceModel; + +namespace Robock.Shared.Communication +{ + public class RobockClient : IRobockDuplexCallback + { + private readonly IRobockDuplex _channel; + + public RobockClient() + { + _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), "net.pipe://localhost/Robock").CreateChannel(); + } + + public void HandshakeCallback(string uuid) + { + // throw new NotImplementedException(); + } + + public void ApplyWallpaperCallback(string uuid, bool isSucceed) + { + // throw new NotImplementedException(); + } + + public void DiscardWallpaperCallback(string uuid) + { + // throw new NotImplementedException(); + } + + public void CloseCallback(string uuid) + { + // throw new NotImplementedException(); + } + + #region IRobockDuples + + public void Handshake(int index) + { + _channel.Handshake(index); + } + + public void ApplyWallpaper(string uuid, IntPtr src, int left, int top, int height, int width) + { + _channel.ApplyWallpaper(uuid, src, left, top, height, width); + } + + public void DiscardWallpaper(string uuid) + { + _channel.DiscardWallpaper(uuid); + } + + public void Close(string uuid) + { + _channel.Close(uuid); + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/RobockServer.cs b/Source/Robock.Shared/Communication/RobockServer.cs new file mode 100644 index 0000000..5b0f84a --- /dev/null +++ b/Source/Robock.Shared/Communication/RobockServer.cs @@ -0,0 +1,56 @@ +using System; +using System.ServiceModel; +using System.Windows; + +namespace Robock.Shared.Communication +{ + [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] + public class RobockServer : IRobockDuplex, IDisposable + { + private readonly string _uuid; + private ServiceHost _serviceHost; + + private IRobockDuplexCallback Callback => OperationContext.Current.GetCallbackChannel(); + + public RobockServer() + { + _uuid = Guid.NewGuid().ToString(); + } + + public void Dispose() + { + _serviceHost.Close(); + ((IDisposable) _serviceHost)?.Dispose(); + } + + public void Handshake(int index) + { + Callback.HandshakeCallback(_uuid); + } + + public void ApplyWallpaper(string uuid, IntPtr src, int left, int top, int height, int width) + { + MessageBox.Show("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + Callback.ApplyWallpaperCallback(uuid, true); + } + + public void DiscardWallpaper(string uuid) + { + Callback.DiscardWallpaperCallback(uuid); + } + + public void Close(string uuid) + { + Callback.CloseCallback(uuid); + _serviceHost.Close(); + } + + // + public void Start() + { + _serviceHost = new ServiceHost(typeof(RobockServer)); + _serviceHost.AddServiceEndpoint(typeof(IRobockDuplex), new NetNamedPipeBinding(), "net.pipe://localhost/Robock"); + _serviceHost.Open(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Models/DesktopWindowManager.cs b/Source/Robock.Shared/Models/DesktopWindowManager.cs similarity index 99% rename from Source/Robock/Models/DesktopWindowManager.cs rename to Source/Robock.Shared/Models/DesktopWindowManager.cs index 2079672..b28def5 100644 --- a/Source/Robock/Models/DesktopWindowManager.cs +++ b/Source/Robock.Shared/Models/DesktopWindowManager.cs @@ -9,7 +9,7 @@ using Size = System.Drawing.Size; -namespace Robock.Models +namespace Robock.Shared.Models { /// /// Desktop Window Manager Wrapper Class diff --git a/Source/Robock/Models/RectUtil.cs b/Source/Robock.Shared/Models/RectUtil.cs similarity index 93% rename from Source/Robock/Models/RectUtil.cs rename to Source/Robock.Shared/Models/RectUtil.cs index 1ed286c..d0a05c8 100644 --- a/Source/Robock/Models/RectUtil.cs +++ b/Source/Robock.Shared/Models/RectUtil.cs @@ -1,6 +1,6 @@ using Robock.Shared.Win32; -namespace Robock.Models +namespace Robock.Shared.Models { public static class RectUtil { diff --git a/Source/Robock/Models/Thumbnail.cs b/Source/Robock.Shared/Models/Thumbnail.cs similarity index 96% rename from Source/Robock/Models/Thumbnail.cs rename to Source/Robock.Shared/Models/Thumbnail.cs index 8350373..c16b366 100644 --- a/Source/Robock/Models/Thumbnail.cs +++ b/Source/Robock.Shared/Models/Thumbnail.cs @@ -3,7 +3,7 @@ using Prism.Mvvm; -namespace Robock.Models +namespace Robock.Shared.Models { public class Thumbnail : BindableBase { diff --git a/Source/Robock.Shared/Mvvm/ViewModel.cs b/Source/Robock.Shared/Mvvm/ViewModel.cs index e42728d..4491923 100644 --- a/Source/Robock.Shared/Mvvm/ViewModel.cs +++ b/Source/Robock.Shared/Mvvm/ViewModel.cs @@ -14,7 +14,7 @@ public ViewModel() CompositeDisposable = new CompositeDisposable(); } - public void Dispose() + public virtual void Dispose() { CompositeDisposable?.Dispose(); } diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 92d9292..02092a6 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -42,6 +42,7 @@ ..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll + @@ -55,7 +56,14 @@ + + + + + + + @@ -71,5 +79,6 @@ + \ No newline at end of file diff --git a/Source/Robock.sln b/Source/Robock.sln index 0cccf82..af4b6d8 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -32,8 +32,8 @@ Global {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.Build.0 = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.ActiveCfg = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.Build.0 = Release|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|x64 + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index c5854f9..5772a68 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -1,4 +1,8 @@ -using System.Windows.Forms; +using System; +using System.Diagnostics; +using System.Windows.Forms; + +using Robock.Shared.Communication; namespace Robock.Models { @@ -7,6 +11,7 @@ namespace Robock.Models /// public class Desktop { + private readonly RobockClient _client; private readonly Screen _screen; public int No { get; } @@ -21,6 +26,13 @@ public Desktop(Screen screen, int index) { _screen = screen; No = index; + _client = new RobockClient(); + Process.Start("Robock.Background.exe"); + } + + public void ApplyWallpaper() + { + _client.ApplyWallpaper("", IntPtr.Zero, 0, 0, 0, 0); } } } \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index acfc331..3c5b908 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -145,11 +145,8 @@ - - - diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index f8c5de9..556e2c4 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -6,6 +6,7 @@ using Robock.Models; using Robock.Shared.Extensions; +using Robock.Shared.Models; using Robock.Shared.Mvvm; using Robock.ViewModels.Tabs; diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 5414005..9599adc 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -8,6 +8,7 @@ using Robock.Models; using Robock.Shared.Extensions; +using Robock.Shared.Models; namespace Robock.ViewModels.Tabs { @@ -149,7 +150,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedWindow.Select(w => w != null), _desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.IsRendering) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); - ApplyWallpaperCommand.Subscribe(_ => { }).AddTo(this); + ApplyWallpaperCommand.Subscribe(_ => _desktop.ApplyWallpaper()).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); ReloadWindowsCommand.Subscribe(_ => windowManager.ForceUpdate()).AddTo(this); } From 36bb11b87fb9d6295ae399504a18a629e6f6d627 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 18:03:49 +0900 Subject: [PATCH 059/167] feat(background): Support multiple connections. --- Source/Robock.Background/Views/AppShell.xaml | 2 + .../Robock.Background/Views/AppShell.xaml.cs | 22 +++++------ .../Communication/IRobockDuplex.cs | 16 ++++---- .../Communication/IRobockDuplexCallback.cs | 12 ++---- .../Communication/RobockClient.cs | 38 +++++++++++-------- .../Communication/RobockServer.cs | 36 +++++++++++------- Source/Robock/Models/Desktop.cs | 31 ++++++++++++--- Source/Robock/Models/DesktopManager.cs | 11 +++++- Source/Robock/ViewModels/AppShellViewModel.cs | 2 +- .../ViewModels/Tabs/DesktopViewModel.cs | 29 +++++++++----- 10 files changed, 125 insertions(+), 74 deletions(-) diff --git a/Source/Robock.Background/Views/AppShell.xaml b/Source/Robock.Background/Views/AppShell.xaml index da91435..d6546e6 100644 --- a/Source/Robock.Background/Views/AppShell.xaml +++ b/Source/Robock.Background/Views/AppShell.xaml @@ -7,6 +7,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" Title="Robock.Background" + Width="960" + Height="540" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> diff --git a/Source/Robock.Background/Views/AppShell.xaml.cs b/Source/Robock.Background/Views/AppShell.xaml.cs index 9fa1824..51e17cb 100644 --- a/Source/Robock.Background/Views/AppShell.xaml.cs +++ b/Source/Robock.Background/Views/AppShell.xaml.cs @@ -1,21 +1,10 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; namespace Robock.Background.Views { /// - /// AppShell.xaml の相互作用ロジック + /// AppShell.xaml の相互作用ロジック /// public partial class AppShell : Window { @@ -23,5 +12,12 @@ public AppShell() { InitializeComponent(); } + + protected override void OnActivated(EventArgs e) + { + base.OnActivated(e); + + // Hide(); + } } -} +} \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/IRobockDuplex.cs b/Source/Robock.Shared/Communication/IRobockDuplex.cs index 79c7acd..fff985a 100644 --- a/Source/Robock.Shared/Communication/IRobockDuplex.cs +++ b/Source/Robock.Shared/Communication/IRobockDuplex.cs @@ -9,33 +9,33 @@ public interface IRobockDuplex /// /// Handshake between Robock and Robock.Background /// - /// Wallpaper index (e.g. 0 = Primary) + /// X + /// Y + /// Height + /// Width [OperationContract(IsOneWay = true)] - void Handshake(int index); + void Handshake(int x, int y, int height, int width); /// /// Apply wallpaper /// - /// UUID of Robock.Background /// hWnd of source window /// left position of rendering area /// top position of rendering area /// height of rendering area /// width of rendering area [OperationContract(IsOneWay = true)] - void ApplyWallpaper(string uuid, IntPtr src, int left, int top, int height, int width); + void ApplyWallpaper(IntPtr src, int left, int top, int height, int width); /// /// Discard wallpaper /// - /// UUID of Robock.Background [OperationContract(IsOneWay = true)] - void DiscardWallpaper(string uuid); + void DiscardWallpaper(); /// /// Close communication pipe /// - /// UUID of Robock.Background - void Close(string uuid); + void Close(); } } \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs b/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs index 1aefa8f..f202cdf 100644 --- a/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs +++ b/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs @@ -9,30 +9,26 @@ public interface IRobockDuplexCallback /// /// Handshake() callback /// - /// UUID of Robock.Background [OperationContract(IsOneWay = true)] - void HandshakeCallback(string uuid); + void HandshakeCallback(); /// /// ApplyWallpaper() callback /// - /// UUID of Robock.Background /// If wallpaper applied to background, returns true [OperationContract(IsOneWay = true)] - void ApplyWallpaperCallback(string uuid, bool isSucceed); + void ApplyWallpaperCallback(bool isSucceed); /// /// DiscardWallpaper() callback /// - /// UUID of Robock.Background [OperationContract(IsOneWay = true)] - void DiscardWallpaperCallback(string uuid); + void DiscardWallpaperCallback(); /// /// Close() callback /// - /// UUID of Robock.Background [OperationContract(IsOneWay = true)] - void CloseCallback(string uuid); + void CloseCallback(); } } \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/RobockClient.cs b/Source/Robock.Shared/Communication/RobockClient.cs index 9d19eb7..15c9232 100644 --- a/Source/Robock.Shared/Communication/RobockClient.cs +++ b/Source/Robock.Shared/Communication/RobockClient.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.ServiceModel; namespace Robock.Shared.Communication @@ -7,51 +8,58 @@ public class RobockClient : IRobockDuplexCallback { private readonly IRobockDuplex _channel; - public RobockClient() + public RobockClient(string uuid) { - _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), "net.pipe://localhost/Robock").CreateChannel(); + _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{uuid}").CreateChannel(); } - public void HandshakeCallback(string uuid) + public void HandshakeCallback() { - // throw new NotImplementedException(); + Debug.WriteLine("Handshake ended"); } - public void ApplyWallpaperCallback(string uuid, bool isSucceed) + public void ApplyWallpaperCallback(bool isSucceed) { // throw new NotImplementedException(); } - public void DiscardWallpaperCallback(string uuid) + public void DiscardWallpaperCallback() { // throw new NotImplementedException(); } - public void CloseCallback(string uuid) + public void CloseCallback() { // throw new NotImplementedException(); } #region IRobockDuples - public void Handshake(int index) + public void Handshake(int x, int y, int height, int width) { - _channel.Handshake(index); + _channel.Handshake(x, y, height, width); } - public void ApplyWallpaper(string uuid, IntPtr src, int left, int top, int height, int width) + public void ApplyWallpaper(IntPtr src, int left, int top, int height, int width) { - _channel.ApplyWallpaper(uuid, src, left, top, height, width); + _channel.ApplyWallpaper(src, left, top, height, width); } - public void DiscardWallpaper(string uuid) + public void DiscardWallpaper() { - _channel.DiscardWallpaper(uuid); + _channel.DiscardWallpaper(); } - public void Close(string uuid) + public void Close() { - _channel.Close(uuid); + try + { + _channel.Close(); + } + catch + { + // ignored + } } #endregion diff --git a/Source/Robock.Shared/Communication/RobockServer.cs b/Source/Robock.Shared/Communication/RobockServer.cs index 5b0f84a..711f9ee 100644 --- a/Source/Robock.Shared/Communication/RobockServer.cs +++ b/Source/Robock.Shared/Communication/RobockServer.cs @@ -14,7 +14,8 @@ public class RobockServer : IRobockDuplex, IDisposable public RobockServer() { - _uuid = Guid.NewGuid().ToString(); + var args = Environment.GetCommandLineArgs(); + _uuid = args[1]; } public void Dispose() @@ -23,34 +24,43 @@ public void Dispose() ((IDisposable) _serviceHost)?.Dispose(); } - public void Handshake(int index) + public void Handshake(int x, int y, int height, int width) { - Callback.HandshakeCallback(_uuid); + Callback.HandshakeCallback(); } - public void ApplyWallpaper(string uuid, IntPtr src, int left, int top, int height, int width) + public void ApplyWallpaper(IntPtr src, int left, int top, int height, int width) { - MessageBox.Show("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - Callback.ApplyWallpaperCallback(uuid, true); + Callback.ApplyWallpaperCallback(true); } - public void DiscardWallpaper(string uuid) + public void DiscardWallpaper() { - Callback.DiscardWallpaperCallback(uuid); + Callback.DiscardWallpaperCallback(); } - public void Close(string uuid) + public void Close() { - Callback.CloseCallback(uuid); + Callback.CloseCallback(); _serviceHost.Close(); } // public void Start() { - _serviceHost = new ServiceHost(typeof(RobockServer)); - _serviceHost.AddServiceEndpoint(typeof(IRobockDuplex), new NetNamedPipeBinding(), "net.pipe://localhost/Robock"); - _serviceHost.Open(); + if (string.IsNullOrWhiteSpace(_uuid)) + throw new ArgumentException("uuid"); + + try + { + _serviceHost = new ServiceHost(typeof(RobockServer)); + _serviceHost.AddServiceEndpoint(typeof(IRobockDuplex), new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}"); + _serviceHost.Open(); + } + catch (Exception e) + { + MessageBox.Show(e.Message); + } } } } \ No newline at end of file diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 5772a68..a209642 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -9,9 +9,10 @@ namespace Robock.Models /// /// Desktop is equals to Monitor, Monitor has a one Desktop. /// - public class Desktop + public class Desktop : IDisposable { private readonly RobockClient _client; + private readonly Process _process; private readonly Screen _screen; public int No { get; } @@ -26,13 +27,33 @@ public Desktop(Screen screen, int index) { _screen = screen; No = index; - _client = new RobockClient(); - Process.Start("Robock.Background.exe"); + var uuid = $"Background.Desktop{index}"; + _client = new RobockClient(uuid); + _process = Process.Start("Robock.Background.exe", $"{uuid}"); } - public void ApplyWallpaper() + public void Dispose() { - _client.ApplyWallpaper("", IntPtr.Zero, 0, 0, 0, 0); + try + { + _client.Close(); + _process?.CloseMainWindow(); + _process?.Dispose(); + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + } + } + + public void Handshake() + { + _client.Handshake((int) X, (int) Y, (int) Height, (int) Width); + } + + public void ApplyWallpaper(IntPtr hWnd, int left, int top, int height, int width) + { + _client.ApplyWallpaper(hWnd, left, top, height, width); } } } \ No newline at end of file diff --git a/Source/Robock/Models/DesktopManager.cs b/Source/Robock/Models/DesktopManager.cs index 99d70db..69cbbdd 100644 --- a/Source/Robock/Models/DesktopManager.cs +++ b/Source/Robock/Models/DesktopManager.cs @@ -1,4 +1,5 @@ -using System.Collections.ObjectModel; +using System; +using System.Collections.ObjectModel; using System.Linq; using System.Windows.Forms; @@ -6,7 +7,7 @@ namespace Robock.Models { - public class DesktopManager : BindableBase + public class DesktopManager : BindableBase, IDisposable { public ObservableCollection Desktops { get; } @@ -15,6 +16,12 @@ public DesktopManager() Desktops = new ObservableCollection(); } + public void Dispose() + { + foreach (var desktop in Desktops) + desktop.Dispose(); + } + public void Initialize() { foreach (var obj in Screen.AllScreens.Select((w, i) => new {Screen = w, Index = i})) diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index 556e2c4..48f1003 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -21,7 +21,7 @@ public class AppShellViewModel : ViewModel public AppShellViewModel() { - var desktopManager = new DesktopManager(); + var desktopManager = new DesktopManager().AddTo(this); var processManager = new WindowManager().AddTo(this); _desktopWindowManager = new DesktopWindowManager().AddTo(this); diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 9599adc..04f6faf 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -9,6 +9,7 @@ using Robock.Models; using Robock.Shared.Extensions; using Robock.Shared.Models; +using Robock.Shared.Win32; namespace Robock.ViewModels.Tabs { @@ -150,7 +151,14 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedWindow.Select(w => w != null), _desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.IsRendering) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); - ApplyWallpaperCommand.Subscribe(_ => _desktop.ApplyWallpaper()).AddTo(this); + ApplyWallpaperCommand.Subscribe(_ => + { + // タイミングどこが良いか問題 + _desktop.Handshake(); + + var rect = CalcRenderingRect(); + _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, rect.left, rect.top, rect.bottom - rect.top, rect.right - rect.left); + }).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); ReloadWindowsCommand.Subscribe(_ => windowManager.ForceUpdate()).AddTo(this); } @@ -172,16 +180,9 @@ private void Render(int index) { var editor = DesktopWindowManager.EditorIndex; - // 描画サイズから、縮小された割合を計算 - var multi = _desktopWindowManager.Thumbnails[editor].Size.Height / (double) EditorAreaHeight.Value; - var rect = RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); if (SelectedAreaHeight.Value != 0) - { - // Grid と Image のズレが大きいと、描画領域がずれてしまうので、補正する - var diff = new Size(EditorAreaLeft.Value - GridAreaLeft.Value, EditorAreaTop.Value - GridAreaTop.Value); - rect = RectUtil.AsRect(SelectedAreaTop.Value - diff.Height, SelectedAreaLeft.Value - diff.Width, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi); - } + rect = CalcRenderingRect(); if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); @@ -189,5 +190,15 @@ private void Render(int index) _desktopWindowManager.Start(handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); } } + + private RECT CalcRenderingRect() + { + // 描画サイズから、縮小された割合を計算 + var multi = _desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].Size.Height / (double) EditorAreaHeight.Value; + + // Grid と Image のズレが大きいと、描画領域がずれてしまうので、補正する + var diff = new Size(EditorAreaLeft.Value - GridAreaLeft.Value, EditorAreaTop.Value - GridAreaTop.Value); + return RectUtil.AsRect(SelectedAreaTop.Value - diff.Height, SelectedAreaLeft.Value - diff.Width, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi); + } } } \ No newline at end of file From 9a36c542e738717fdc00e7fc60606fdd6c48dd7c Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 19:23:32 +0900 Subject: [PATCH 060/167] feat: Rendering! --- .../Communication/IRobockDuplex.cs | 9 ++--- .../Communication/RobockClient.cs | 8 ++-- .../Communication/RobockServer.cs | 39 +++++++++++++++++-- Source/Robock/Models/Desktop.cs | 10 ++++- .../ViewModels/Tabs/DesktopViewModel.cs | 12 +++++- 5 files changed, 62 insertions(+), 16 deletions(-) diff --git a/Source/Robock.Shared/Communication/IRobockDuplex.cs b/Source/Robock.Shared/Communication/IRobockDuplex.cs index fff985a..a8cc4fd 100644 --- a/Source/Robock.Shared/Communication/IRobockDuplex.cs +++ b/Source/Robock.Shared/Communication/IRobockDuplex.cs @@ -1,6 +1,8 @@ using System; using System.ServiceModel; +using Robock.Shared.Win32; + namespace Robock.Shared.Communication { [ServiceContract(Namespace = "robock://localhost", SessionMode = SessionMode.Required, CallbackContract = typeof(IRobockDuplexCallback))] @@ -20,12 +22,9 @@ public interface IRobockDuplex /// Apply wallpaper /// /// hWnd of source window - /// left position of rendering area - /// top position of rendering area - /// height of rendering area - /// width of rendering area + /// [OperationContract(IsOneWay = true)] - void ApplyWallpaper(IntPtr src, int left, int top, int height, int width); + void ApplyWallpaper(IntPtr src, RECT? rect); /// /// Discard wallpaper diff --git a/Source/Robock.Shared/Communication/RobockClient.cs b/Source/Robock.Shared/Communication/RobockClient.cs index 15c9232..91679d9 100644 --- a/Source/Robock.Shared/Communication/RobockClient.cs +++ b/Source/Robock.Shared/Communication/RobockClient.cs @@ -2,6 +2,8 @@ using System.Diagnostics; using System.ServiceModel; +using Robock.Shared.Win32; + namespace Robock.Shared.Communication { public class RobockClient : IRobockDuplexCallback @@ -20,7 +22,7 @@ public void HandshakeCallback() public void ApplyWallpaperCallback(bool isSucceed) { - // throw new NotImplementedException(); + Debug.WriteLine(isSucceed ? "Rendering Success" : "Rendering Failed"); } public void DiscardWallpaperCallback() @@ -40,9 +42,9 @@ public void Handshake(int x, int y, int height, int width) _channel.Handshake(x, y, height, width); } - public void ApplyWallpaper(IntPtr src, int left, int top, int height, int width) + public void ApplyWallpaper(IntPtr src, RECT? rect) { - _channel.ApplyWallpaper(src, left, top, height, width); + _channel.ApplyWallpaper(src, rect); } public void DiscardWallpaper() diff --git a/Source/Robock.Shared/Communication/RobockServer.cs b/Source/Robock.Shared/Communication/RobockServer.cs index 711f9ee..bf75555 100644 --- a/Source/Robock.Shared/Communication/RobockServer.cs +++ b/Source/Robock.Shared/Communication/RobockServer.cs @@ -1,14 +1,25 @@ using System; +using System.Diagnostics; +using System.Reactive.Linq; using System.ServiceModel; using System.Windows; +using Robock.Refrection; +using Robock.Shared.Models; +using Robock.Shared.Win32; + namespace Robock.Shared.Communication { - [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] + [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class RobockServer : IRobockDuplex, IDisposable { + private readonly DesktopWindowManager _desktopWindowManager; private readonly string _uuid; + private int _height; private ServiceHost _serviceHost; + private int _width; + private int _x; + private int _y; private IRobockDuplexCallback Callback => OperationContext.Current.GetCallbackChannel(); @@ -16,6 +27,19 @@ public RobockServer() { var args = Environment.GetCommandLineArgs(); _uuid = args[1]; + _desktopWindowManager = new DesktopWindowManager(); + + Observable.Return(0).ObserveOn(Application.Current.Dispatcher).Subscribe(_ => + { + try + { + _desktopWindowManager.Initialize(); + } + catch (Exception e) + { + Debug.WriteLine(e.Message); + } + }); } public void Dispose() @@ -26,16 +50,23 @@ public void Dispose() public void Handshake(int x, int y, int height, int width) { - Callback.HandshakeCallback(); + _x = x; + _y = y; + _height = height; + _width = width; } - public void ApplyWallpaper(IntPtr src, int left, int top, int height, int width) + public void ApplyWallpaper(IntPtr src, RECT? rect) { - Callback.ApplyWallpaperCallback(true); + _desktopWindowManager.Start(src, 0, 0, _height, _width, 0, rect); + + Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[0].IsRendering); } public void DiscardWallpaper() { + _desktopWindowManager.Stop(); + Callback.DiscardWallpaperCallback(); } diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index a209642..cafeb41 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -3,6 +3,7 @@ using System.Windows.Forms; using Robock.Shared.Communication; +using Robock.Shared.Win32; namespace Robock.Models { @@ -51,9 +52,14 @@ public void Handshake() _client.Handshake((int) X, (int) Y, (int) Height, (int) Width); } - public void ApplyWallpaper(IntPtr hWnd, int left, int top, int height, int width) + public void ApplyWallpaper(IntPtr hWnd, RECT? rect) { - _client.ApplyWallpaper(hWnd, left, top, height, width); + _client.ApplyWallpaper(hWnd, rect); + } + + public void DiscardWallpaper() + { + _client.DiscardWallpaper(); } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 04f6faf..6d1a720 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -156,8 +156,16 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin // タイミングどこが良いか問題 _desktop.Handshake(); - var rect = CalcRenderingRect(); - _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, rect.left, rect.top, rect.bottom - rect.top, rect.right - rect.left); + _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : (RECT?) null); + }).AddTo(this); + DiscardWallpaperCommand = new[] + { + SelectedWindow.Select(w => w != null) + }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); + DiscardWallpaperCommand.Subscribe(_ => + { + // + _desktop.DiscardWallpaper(); }).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); ReloadWindowsCommand.Subscribe(_ => windowManager.ForceUpdate()).AddTo(this); From 6a8b952f00e57781bb1783114f631d64efd447d6 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 22:34:33 +0900 Subject: [PATCH 061/167] feat: Hide background window. --- .../Models/BackgroundService.cs | 56 ++++++++++++++ .../Robock.Background.csproj | 6 +- .../ViewModels/AppShellViewModel.cs | 9 ++- .../Robock.Background/Views/AppShell.xaml.cs | 6 +- .../Communication/RobockServer.cs | 1 - Source/Robock.Shared/Robock.Shared.csproj | 2 + .../Win32/DeviceContextValues.cs | 77 +++++++++++++++++++ Source/Robock.Shared/Win32/NativeMethods.cs | 48 +++++++++++- .../Win32/TernaryRasterOperations.cs | 60 +++++++++++++++ 9 files changed, 255 insertions(+), 10 deletions(-) create mode 100644 Source/Robock.Background/Models/BackgroundService.cs create mode 100644 Source/Robock.Shared/Win32/DeviceContextValues.cs create mode 100644 Source/Robock.Shared/Win32/TernaryRasterOperations.cs diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs new file mode 100644 index 0000000..6e6621a --- /dev/null +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -0,0 +1,56 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Windows.Interop; + +using Robock.Shared.Win32; + +using Application = System.Windows.Application; + +namespace Robock.Background.Models +{ + public static class BackgroundService + { + private static Bitmap _bitmap; + public static IntPtr WindowHandle { get; private set; } + + public static void Initialize() + { + WindowHandle = new WindowInteropHelper(Application.Current.MainWindow ?? throw new InvalidOperationException()).Handle; + } + + // 描画範囲外へ飛ばす + public static void MoveToOutsideOfDesktop() + { + if (WindowHandle == null || WindowHandle == IntPtr.Zero) + throw new InvalidOperationException(); + + var rect = SystemInformation.VirtualScreen; + var x = 10000; + var y = 10000; + + if (x < rect.Right) + x = rect.Right; + if (y < rect.Bottom) + y = rect.Bottom; + + NativeMethods.GetWindowRect(WindowHandle, out var window); + if (!NativeMethods.MoveWindow(WindowHandle, x, y, window.right - window.left, window.bottom - window.top, true)) + MessageBox.Show(NativeMethods.GetLastError().ToString()); + } + + public static IntPtr FindWorkerW() + { + var workerW = IntPtr.Zero; + NativeMethods.EnumWindows((hWnd, lParam) => + { + var shell = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "", null); + if (shell != IntPtr.Zero) + workerW = NativeMethods.FindWindowEx(IntPtr.Zero, hWnd, "WorkerW", null); + return true; + }, IntPtr.Zero); + + return workerW; + } + } +} \ No newline at end of file diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 822d7cc..e63acd3 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -91,6 +91,7 @@ + ..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll @@ -130,6 +131,7 @@ App.xaml Code + AppShell.xaml @@ -170,9 +172,7 @@ Robock.Shared - - - + Designer diff --git a/Source/Robock.Background/ViewModels/AppShellViewModel.cs b/Source/Robock.Background/ViewModels/AppShellViewModel.cs index 2588d95..36a88d4 100644 --- a/Source/Robock.Background/ViewModels/AppShellViewModel.cs +++ b/Source/Robock.Background/ViewModels/AppShellViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Reactive.Linq; +using Robock.Background.Models; using Robock.Shared.Communication; using Robock.Shared.Extensions; using Robock.Shared.Mvvm; @@ -9,14 +10,14 @@ namespace Robock.Background.ViewModels { public class AppShellViewModel : ViewModel { - private RobockServer _server; - public AppShellViewModel() { + BackgroundService.SaveCurrentWallpaper(); + Observable.Return(0).Delay(TimeSpan.FromMilliseconds(500)).Subscribe(_ => { - _server = new RobockServer().AddTo(this); - _server.Start(); + var server = new RobockServer().AddTo(this); + server.Start(); }); } } diff --git a/Source/Robock.Background/Views/AppShell.xaml.cs b/Source/Robock.Background/Views/AppShell.xaml.cs index 51e17cb..4dd48bc 100644 --- a/Source/Robock.Background/Views/AppShell.xaml.cs +++ b/Source/Robock.Background/Views/AppShell.xaml.cs @@ -1,6 +1,8 @@ using System; using System.Windows; +using Robock.Background.Models; + namespace Robock.Background.Views { /// @@ -17,7 +19,9 @@ protected override void OnActivated(EventArgs e) { base.OnActivated(e); - // Hide(); + // 表示されてから + BackgroundService.Initialize(); + BackgroundService.MoveToOutsideOfDesktop(); } } } \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/RobockServer.cs b/Source/Robock.Shared/Communication/RobockServer.cs index bf75555..d2aee57 100644 --- a/Source/Robock.Shared/Communication/RobockServer.cs +++ b/Source/Robock.Shared/Communication/RobockServer.cs @@ -4,7 +4,6 @@ using System.ServiceModel; using System.Windows; -using Robock.Refrection; using Robock.Shared.Models; using Robock.Shared.Win32; diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 02092a6..1071846 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -67,11 +67,13 @@ + + diff --git a/Source/Robock.Shared/Win32/DeviceContextValues.cs b/Source/Robock.Shared/Win32/DeviceContextValues.cs new file mode 100644 index 0000000..96e97fa --- /dev/null +++ b/Source/Robock.Shared/Win32/DeviceContextValues.cs @@ -0,0 +1,77 @@ +using System; + +namespace Robock.Shared.Win32 +{ + [Flags] + public enum DeviceContextValues : uint + { + /// + /// DCX_WINDOW: Returns a DC that corresponds to the window rectangle rather + /// than the client rectangle. + /// + Window = 0x00000001, + + /// + /// DCX_CACHE: Returns a DC from the cache, rather than the OWNDC or CLASSDC + /// window. Essentially overrides CS_OWNDC and CS_CLASSDC. + /// + Cache = 0x00000002, + + /// + /// DCX_NORESETATTRS: Does not reset the attributes of this DC to the + /// default attributes when this DC is released. + /// + NoResetAttrs = 0x00000004, + + /// + /// DCX_CLIPCHILDREN: Excludes the visible regions of all child windows + /// below the window identified by hWnd. + /// + ClipChildren = 0x00000008, + + /// + /// DCX_CLIPSIBLINGS: Excludes the visible regions of all sibling windows + /// above the window identified by hWnd. + /// + ClipSiblings = 0x00000010, + + /// + /// DCX_PARENTCLIP: Uses the visible region of the parent window. The + /// parent's WS_CLIPCHILDREN and CS_PARENTDC style bits are ignored. The origin is + /// set to the upper-left corner of the window identified by hWnd. + /// + ParentClip = 0x00000020, + + /// + /// DCX_EXCLUDERGN: The clipping region identified by hrgnClip is excluded + /// from the visible region of the returned DC. + /// + ExcludeRgn = 0x00000040, + + /// + /// DCX_INTERSECTRGN: The clipping region identified by hrgnClip is + /// intersected with the visible region of the returned DC. + /// + IntersectRgn = 0x00000080, + + /// DCX_EXCLUDEUPDATE: Unknown...Undocumented + ExcludeUpdate = 0x00000100, + + /// DCX_INTERSECTUPDATE: Unknown...Undocumented + IntersectUpdate = 0x00000200, + + /// + /// DCX_LOCKWINDOWUPDATE: Allows drawing even if there is a LockWindowUpdate + /// call in effect that would otherwise exclude this window. Used for drawing during + /// tracking. + /// + LockWindowUpdate = 0x00000400, + + /// + /// DCX_VALIDATE When specified with DCX_INTERSECTUPDATE, causes the DC to + /// be completely validated. Using this function with both DCX_INTERSECTUPDATE and + /// DCX_VALIDATE is identical to using the BeginPaint function. + /// + Validate = 0x00200000 + } +} \ No newline at end of file diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index 32789ef..be2c12c 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -7,6 +7,37 @@ namespace Robock.Shared.Win32 { public static class NativeMethods { + #region Kernel32 + + [DllImport("kernel32.dll")] + public static extern uint GetLastError(); + + #endregion + + #region Gdi32 + + [DllImport("gdi32.dll", SetLastError = true)] + public static extern IntPtr CreateCompatibleDC(IntPtr hdc); + + [DllImport("gdi32.dll")] + public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); + + [DllImport("gdi32.dll")] + public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); + + [DllImport("gdi32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop); + + [DllImport("gdi32.dll")] + public static extern bool DeleteDC(IntPtr hdc); + + [DllImport("gdi32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DeleteObject(IntPtr hObject); + + #endregion + #region Dwmapi [DllImport("dwmapi.dll", SetLastError = true)] @@ -41,11 +72,26 @@ public static class NativeMethods public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle); + public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result); + [DllImport("user32.dll", SetLastError = true)] + public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); + + [DllImport("user32.dll")] + public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, DeviceContextValues flags); + + [DllImport("user32.dll")] + public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc); + + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); + #endregion } } \ No newline at end of file diff --git a/Source/Robock.Shared/Win32/TernaryRasterOperations.cs b/Source/Robock.Shared/Win32/TernaryRasterOperations.cs new file mode 100644 index 0000000..421ff50 --- /dev/null +++ b/Source/Robock.Shared/Win32/TernaryRasterOperations.cs @@ -0,0 +1,60 @@ +// ReSharper disable FieldCanBeMadeReadOnly.Global +// ReSharper disable InconsistentNaming +// ReSharper disable MemberCanBePrivate.Global + +namespace Robock.Shared.Win32 +{ + public enum TernaryRasterOperations : uint + { + /// dest = source + SRCCOPY = 0x00CC0020, + + /// dest = source OR dest + SRCPAINT = 0x00EE0086, + + /// dest = source AND dest + SRCAND = 0x008800C6, + + /// dest = source XOR dest + SRCINVERT = 0x00660046, + + /// dest = source AND (NOT dest) + SRCERASE = 0x00440328, + + /// dest = (NOT source) + NOTSRCCOPY = 0x00330008, + + /// dest = (NOT src) AND (NOT dest) + NOTSRCERASE = 0x001100A6, + + /// dest = (source AND pattern) + MERGECOPY = 0x00C000CA, + + /// dest = (NOT source) OR dest + MERGEPAINT = 0x00BB0226, + + /// dest = pattern + PATCOPY = 0x00F00021, + + /// dest = DPSnoo + PATPAINT = 0x00FB0A09, + + /// dest = pattern XOR dest + PATINVERT = 0x005A0049, + + /// dest = (NOT dest) + DSTINVERT = 0x00550009, + + /// dest = BLACK + BLACKNESS = 0x00000042, + + /// dest = WHITE + WHITENESS = 0x00FF0062, + + /// + /// Capture window as seen on screen. This includes layered windows + /// such as WPF windows with AllowsTransparency="true" + /// + CAPTUREBLT = 0x40000000 + } +} \ No newline at end of file From 302ec712c32ac147eb995fe6e73d60caa12ce6ed Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 22:38:15 +0900 Subject: [PATCH 062/167] refactor: Move client/server's implementations to Robock/Background assemblies. --- .../Communication => Robock.Background/Models}/RobockServer.cs | 3 ++- Source/Robock.Background/Robock.Background.csproj | 1 + Source/Robock.Background/ViewModels/AppShellViewModel.cs | 1 - Source/Robock.Shared/Robock.Shared.csproj | 2 -- .../Communication => Robock/Models}/RobockClient.cs | 3 ++- Source/Robock/Robock.csproj | 2 ++ 6 files changed, 7 insertions(+), 5 deletions(-) rename Source/{Robock.Shared/Communication => Robock.Background/Models}/RobockServer.cs (97%) rename Source/{Robock.Shared/Communication => Robock/Models}/RobockClient.cs (96%) diff --git a/Source/Robock.Shared/Communication/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs similarity index 97% rename from Source/Robock.Shared/Communication/RobockServer.cs rename to Source/Robock.Background/Models/RobockServer.cs index d2aee57..1a335fc 100644 --- a/Source/Robock.Shared/Communication/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -4,10 +4,11 @@ using System.ServiceModel; using System.Windows; +using Robock.Shared.Communication; using Robock.Shared.Models; using Robock.Shared.Win32; -namespace Robock.Shared.Communication +namespace Robock.Background.Models { [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class RobockServer : IRobockDuplex, IDisposable diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index e63acd3..7918111 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -132,6 +132,7 @@ Code + AppShell.xaml diff --git a/Source/Robock.Background/ViewModels/AppShellViewModel.cs b/Source/Robock.Background/ViewModels/AppShellViewModel.cs index 36a88d4..05471c5 100644 --- a/Source/Robock.Background/ViewModels/AppShellViewModel.cs +++ b/Source/Robock.Background/ViewModels/AppShellViewModel.cs @@ -2,7 +2,6 @@ using System.Reactive.Linq; using Robock.Background.Models; -using Robock.Shared.Communication; using Robock.Shared.Extensions; using Robock.Shared.Mvvm; diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 1071846..018677c 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -58,8 +58,6 @@ - - diff --git a/Source/Robock.Shared/Communication/RobockClient.cs b/Source/Robock/Models/RobockClient.cs similarity index 96% rename from Source/Robock.Shared/Communication/RobockClient.cs rename to Source/Robock/Models/RobockClient.cs index 91679d9..fbc0ee7 100644 --- a/Source/Robock.Shared/Communication/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -2,9 +2,10 @@ using System.Diagnostics; using System.ServiceModel; +using Robock.Shared.Communication; using Robock.Shared.Win32; -namespace Robock.Shared.Communication +namespace Robock.Models { public class RobockClient : IRobockDuplexCallback { diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 3c5b908..9ea79f8 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -117,6 +117,7 @@ ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll True + @@ -147,6 +148,7 @@ + From 177a0f46ef62bbe3caa5d683c06698728e6ab568 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 22 Jul 2018 23:20:13 +0900 Subject: [PATCH 063/167] feat: Progress --- .../Models/BackgroundService.cs | 65 ++++++++++++++++++- .../Robock.Background/Models/RobockServer.cs | 4 ++ .../Robock.Background/Views/AppShell.xaml.cs | 10 ++- Source/Robock.Background/app.manifest | 13 ++-- Source/Robock/Models/RobockClient.cs | 2 +- 5 files changed, 81 insertions(+), 13 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 6e6621a..ad3b53a 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -39,12 +39,75 @@ public static void MoveToOutsideOfDesktop() MessageBox.Show(NativeMethods.GetLastError().ToString()); } + public static void DrawAfterWorkerW(int x, int y, int width, int height) + { + try + { + if (WindowHandle == IntPtr.Zero) + throw new InvalidOperationException(); + + var workerW = FindWorkerW(); + NativeMethods.MoveWindow(WindowHandle, x, y, width, height, true); + if (workerW == IntPtr.Zero) + throw new InvalidOperationException(); + + NativeMethods.SetParent(WindowHandle, workerW); + MessageBox.Show(NativeMethods.GetLastError().ToString()); + } + catch (Exception e) + { + MessageBox.Show(e.Message); + } + } + + public static void DrawAsNormal() + { + if (WindowHandle == null || WindowHandle == IntPtr.Zero) + throw new InvalidOperationException(); + + NativeMethods.SetParent(WindowHandle, (IntPtr) null); + MoveToOutsideOfDesktop(); + } + + // いじっちゃうと自前で戻さないと、前描画した物が残り続けるので、予めビットマップをメモリに保存しておく + public static void SaveCurrentWallpaper() + { + var workerW = FindWorkerW(); + var hdcSrc = NativeMethods.GetDCEx(workerW, IntPtr.Zero, DeviceContextValues.Window | DeviceContextValues.Cache | DeviceContextValues.LockWindowUpdate); + var hdcDest = NativeMethods.CreateCompatibleDC(hdcSrc); + NativeMethods.GetWindowRect(workerW, out var rect); + var (width, height) = (rect.right - rect.left, rect.bottom - rect.top); + + var hBitmap = NativeMethods.CreateCompatibleBitmap(hdcSrc, width, height); + var hOld = NativeMethods.SelectObject(hdcDest, hBitmap); + NativeMethods.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, TernaryRasterOperations.SRCCOPY); + NativeMethods.SelectObject(hdcDest, hOld); + NativeMethods.DeleteDC(hdcDest); + NativeMethods.ReleaseDC(workerW, hdcSrc); + + _bitmap = Image.FromHbitmap(hBitmap); + NativeMethods.DeleteObject(hBitmap); + } + + public static void RestoreWallpaper() + { + var workerW = FindWorkerW(); + + var hdcSrc = NativeMethods.GetDCEx(workerW, IntPtr.Zero, DeviceContextValues.Window | DeviceContextValues.Cache | DeviceContextValues.LockWindowUpdate); + using (var graphic = Graphics.FromHdc(hdcSrc)) + graphic.DrawImage(_bitmap, new PointF(0, 0)); + NativeMethods.ReleaseDC(workerW, hdcSrc); + } + public static IntPtr FindWorkerW() { + var progman = NativeMethods.FindWindow("Progman", null); + NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out var result); + var workerW = IntPtr.Zero; NativeMethods.EnumWindows((hWnd, lParam) => { - var shell = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "", null); + var shell = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null); if (shell != IntPtr.Zero) workerW = NativeMethods.FindWindowEx(IntPtr.Zero, hWnd, "WorkerW", null); return true; diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 1a335fc..3ca8780 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -59,6 +59,7 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT? rect) { _desktopWindowManager.Start(src, 0, 0, _height, _width, 0, rect); + BackgroundService.DrawAfterWorkerW(_x, _y, _width, _height); Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[0].IsRendering); } @@ -66,12 +67,15 @@ public void ApplyWallpaper(IntPtr src, RECT? rect) public void DiscardWallpaper() { _desktopWindowManager.Stop(); + BackgroundService.DrawAsNormal(); + BackgroundService.RestoreWallpaper(); Callback.DiscardWallpaperCallback(); } public void Close() { + DiscardWallpaper(); Callback.CloseCallback(); _serviceHost.Close(); } diff --git a/Source/Robock.Background/Views/AppShell.xaml.cs b/Source/Robock.Background/Views/AppShell.xaml.cs index 4dd48bc..6f7b9f8 100644 --- a/Source/Robock.Background/Views/AppShell.xaml.cs +++ b/Source/Robock.Background/Views/AppShell.xaml.cs @@ -10,6 +10,8 @@ namespace Robock.Background.Views /// public partial class AppShell : Window { + private bool _isFirstRun = true; + public AppShell() { InitializeComponent(); @@ -20,8 +22,12 @@ protected override void OnActivated(EventArgs e) base.OnActivated(e); // 表示されてから - BackgroundService.Initialize(); - BackgroundService.MoveToOutsideOfDesktop(); + if (_isFirstRun) + { + BackgroundService.Initialize(); + BackgroundService.MoveToOutsideOfDesktop(); + _isFirstRun = false; + } } } } \ No newline at end of file diff --git a/Source/Robock.Background/app.manifest b/Source/Robock.Background/app.manifest index 6aca63b..b6cdff5 100644 --- a/Source/Robock.Background/app.manifest +++ b/Source/Robock.Background/app.manifest @@ -1,6 +1,6 @@  - + @@ -41,7 +41,6 @@ - @@ -49,13 +48,11 @@ 示します。Windows Presentation Foundation (WPF) アプリケーションは自動的に DPI に対応し、オプトインする必要は ありません。さらに、この設定にオプトインする .NET Framework 4.6 を対象とする Windows Forms アプリケーションは、 app.config ファイルで 'EnableWindowsFormsHighDpiAutoResizing' 設定を 'true' に設定する必要があります。--> - - - + \ No newline at end of file diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index fbc0ee7..7ea371e 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -28,7 +28,7 @@ public void ApplyWallpaperCallback(bool isSucceed) public void DiscardWallpaperCallback() { - // throw new NotImplementedException(); + Debug.WriteLine("Discard finished."); } public void CloseCallback() From 003bbe3e3e64877457d1bc7cb2256b173ac9f3ea Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 23 Jul 2018 00:21:45 +0900 Subject: [PATCH 064/167] bug: Fix --- Source/Robock.Background/Models/RobockServer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 3ca8780..1cd441d 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -58,15 +58,15 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT? rect) { - _desktopWindowManager.Start(src, 0, 0, _height, _width, 0, rect); + _desktopWindowManager.Start(src, 0, 0, _height, _width, 1, rect); BackgroundService.DrawAfterWorkerW(_x, _y, _width, _height); - Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[0].IsRendering); + Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[1].IsRendering); } public void DiscardWallpaper() { - _desktopWindowManager.Stop(); + _desktopWindowManager.Stop(1); BackgroundService.DrawAsNormal(); BackgroundService.RestoreWallpaper(); From e70248c9a3c8b91f64b852ece7a7112b47963834 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 23 Jul 2018 01:00:18 +0900 Subject: [PATCH 065/167] chore: Hmm. --- .../Models/BackgroundService.cs | 51 +++++++++- .../Robock.Background/Models/RobockServer.cs | 2 +- Source/Robock.Shared/Robock.Shared.csproj | 1 + Source/Robock.Shared/Win32/NativeMethods.cs | 6 ++ .../Robock.Shared/Win32/SetWindowPosFlags.cs | 93 +++++++++++++++++++ 5 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 Source/Robock.Shared/Win32/SetWindowPosFlags.cs diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index ad3b53a..b356049 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -1,5 +1,7 @@ using System; using System.Drawing; +using System.Reactive.Linq; +using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Interop; @@ -12,6 +14,7 @@ namespace Robock.Background.Models public static class BackgroundService { private static Bitmap _bitmap; + private static bool _drawing; public static IntPtr WindowHandle { get; private set; } public static void Initialize() @@ -51,8 +54,11 @@ public static void DrawAfterWorkerW(int x, int y, int width, int height) if (workerW == IntPtr.Zero) throw new InvalidOperationException(); - NativeMethods.SetParent(WindowHandle, workerW); - MessageBox.Show(NativeMethods.GetLastError().ToString()); + Observable.Return(1).Delay(TimeSpan.FromSeconds(5)).Subscribe(_ => + { + NativeMethods.SetWindowPos(WindowHandle, new IntPtr(1), x, y, width, height, SetWindowPosFlags.ShowWindow); + MessageBox.Show(NativeMethods.GetLastError().ToString()); + }); } catch (Exception e) { @@ -60,13 +66,54 @@ public static void DrawAfterWorkerW(int x, int y, int width, int height) } } + public static void DrawOnWorkerW(int x, int y, int width, int height) + { + _drawing = true; + NativeMethods.MoveWindow(WindowHandle, x, y, width, height, true); + var task = Task.Run(() => + { + NativeMethods.MoveWindow(WindowHandle, 10000, 10000, width, height, true); + + var period = 1000f / 30f; + var nextFrame = (double) Environment.TickCount; + while (_drawing) + { + var tick = (double) Environment.TickCount; + if (tick < nextFrame) + { + if (nextFrame - tick > 1) + Task.Delay(TimeSpan.FromMilliseconds(nextFrame - tick)).Wait(); + continue; + } + if (Environment.TickCount >= nextFrame + period) + { + nextFrame += period; + continue; + } + + var workerW = FindWorkerW(); + + var hdcSrc = NativeMethods.GetDC(WindowHandle); + var hdcDest = NativeMethods.GetDCEx(workerW, IntPtr.Zero, DeviceContextValues.Window | DeviceContextValues.Cache | DeviceContextValues.LockWindowUpdate); + + NativeMethods.BitBlt(hdcDest, x, y, width, height, hdcSrc, 0, 0, TernaryRasterOperations.SRCCOPY); + NativeMethods.ReleaseDC(WindowHandle, hdcSrc); + NativeMethods.ReleaseDC(workerW, hdcDest); + + nextFrame += period; + } + }); + } + public static void DrawAsNormal() { if (WindowHandle == null || WindowHandle == IntPtr.Zero) throw new InvalidOperationException(); + _drawing = false; NativeMethods.SetParent(WindowHandle, (IntPtr) null); MoveToOutsideOfDesktop(); + RestoreWallpaper(); } // いじっちゃうと自前で戻さないと、前描画した物が残り続けるので、予めビットマップをメモリに保存しておく diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 1cd441d..6d7e3eb 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -59,7 +59,7 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT? rect) { _desktopWindowManager.Start(src, 0, 0, _height, _width, 1, rect); - BackgroundService.DrawAfterWorkerW(_x, _y, _width, _height); + BackgroundService.DrawOnWorkerW(_x, _y, _width, _height); Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[1].IsRendering); } diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 018677c..2918e7d 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -71,6 +71,7 @@ + diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index be2c12c..40fc0ab 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -83,6 +83,9 @@ public static class NativeMethods [DllImport("user32.dll", SetLastError = true)] public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); + [DllImport("user32.dll")] + public static extern IntPtr GetDC(IntPtr hWnd); + [DllImport("user32.dll")] public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, DeviceContextValues flags); @@ -92,6 +95,9 @@ public static class NativeMethods [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags uFlags); + #endregion } } \ No newline at end of file diff --git a/Source/Robock.Shared/Win32/SetWindowPosFlags.cs b/Source/Robock.Shared/Win32/SetWindowPosFlags.cs new file mode 100644 index 0000000..4529187 --- /dev/null +++ b/Source/Robock.Shared/Win32/SetWindowPosFlags.cs @@ -0,0 +1,93 @@ +using System; + +// ReSharper disable FieldCanBeMadeReadOnly.Global +// ReSharper disable InconsistentNaming +// ReSharper disable MemberCanBePrivate.Global + +namespace Robock.Shared.Win32 +{ + [Flags] + public enum SetWindowPosFlags : uint + { + /// + /// If the calling thread and the thread that owns the window are attached to different input queues, + /// the system posts the request to the thread that owns the window. This prevents the calling thread from + /// blocking its execution while other threads process the request. + /// + /// SWP_ASYNCWINDOWPOS + AsynchronousWindowPosition = 0x4000, + + /// Prevents generation of the WM_SYNCPAINT message. + /// SWP_DEFERERASE + DeferErase = 0x2000, + + /// Draws a frame (defined in the window's class description) around the window. + /// SWP_DRAWFRAME + DrawFrame = 0x0020, + + /// + /// Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to + /// the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE + /// is sent only when the window's size is being changed. + /// + /// SWP_FRAMECHANGED + FrameChanged = 0x0020, + + /// Hides the window. + /// SWP_HIDEWINDOW + HideWindow = 0x0080, + + /// + /// Does not activate the window. If this flag is not set, the window is activated and moved to the + /// top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter + /// parameter). + /// + /// SWP_NOACTIVATE + DoNotActivate = 0x0010, + + /// + /// Discards the entire contents of the client area. If this flag is not specified, the valid + /// contents of the client area are saved and copied back into the client area after the window is sized or + /// repositioned. + /// + /// SWP_NOCOPYBITS + DoNotCopyBits = 0x0100, + + /// Retains the current position (ignores X and Y parameters). + /// SWP_NOMOVE + IgnoreMove = 0x0002, + + /// Does not change the owner window's position in the Z order. + /// SWP_NOOWNERZORDER + DoNotChangeOwnerZOrder = 0x0200, + + /// + /// Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to + /// the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent + /// window uncovered as a result of the window being moved. When this flag is set, the application must + /// explicitly invalidate or redraw any parts of the window and parent window that need redrawing. + /// + /// SWP_NOREDRAW + DoNotRedraw = 0x0008, + + /// Same as the SWP_NOOWNERZORDER flag. + /// SWP_NOREPOSITION + DoNotReposition = 0x0200, + + /// Prevents the window from receiving the WM_WINDOWPOSCHANGING message. + /// SWP_NOSENDCHANGING + DoNotSendChangingEvent = 0x0400, + + /// Retains the current size (ignores the cx and cy parameters). + /// SWP_NOSIZE + IgnoreResize = 0x0001, + + /// Retains the current Z order (ignores the hWndInsertAfter parameter). + /// SWP_NOZORDER + IgnoreZOrder = 0x0004, + + /// Displays the window. + /// SWP_SHOWWINDOW + ShowWindow = 0x0040 + } +} \ No newline at end of file From fea85cd0e54b0256f6ba2eb996b29e972d8ae95b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 24 Jul 2018 00:34:53 +0900 Subject: [PATCH 066/167] fix: Fix null reference exception --- Source/Robock.Background/Models/RobockServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 6d7e3eb..d7202e9 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -44,7 +44,7 @@ public RobockServer() public void Dispose() { - _serviceHost.Close(); + _serviceHost?.Close(); ((IDisposable) _serviceHost)?.Dispose(); } From 1ddce89ed67e20d4345485cc2118457655ab3252 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 24 Jul 2018 21:27:25 +0900 Subject: [PATCH 067/167] fix: As flags --- Source/Robock.Shared/Win32/TernaryRasterOperations.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Robock.Shared/Win32/TernaryRasterOperations.cs b/Source/Robock.Shared/Win32/TernaryRasterOperations.cs index 421ff50..f0c3cbf 100644 --- a/Source/Robock.Shared/Win32/TernaryRasterOperations.cs +++ b/Source/Robock.Shared/Win32/TernaryRasterOperations.cs @@ -2,8 +2,11 @@ // ReSharper disable InconsistentNaming // ReSharper disable MemberCanBePrivate.Global +using System; + namespace Robock.Shared.Win32 { + [Flags] public enum TernaryRasterOperations : uint { /// dest = source From 9ae7c96592bfcd499da41860dc333d99ea1eccb0 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 24 Jul 2018 21:27:59 +0900 Subject: [PATCH 068/167] feat: Don't display some windows. Can't render these windows by DWM. --- Source/Robock/Models/Ignores.cs | 16 ++++++++++++++++ Source/Robock/Robock.csproj | 1 + 2 files changed, 17 insertions(+) create mode 100644 Source/Robock/Models/Ignores.cs diff --git a/Source/Robock/Models/Ignores.cs b/Source/Robock/Models/Ignores.cs new file mode 100644 index 0000000..af800c4 --- /dev/null +++ b/Source/Robock/Models/Ignores.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Robock.Models +{ + public class Ignores + { + public static List IgnoreWindowTitles = new List + { + "ChromeWindow", // Robock's window separator + "Robock", // Myself + "Robock.Background", // Myself + "NVIDIA GeForce Overlay", // + "Program Manager" // Desktop + }; + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 9ea79f8..7c803be 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -146,6 +146,7 @@ + From ba83b9c11bcb4ce0481d5dc69c48ee01bf9ffc50 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 24 Jul 2018 21:28:13 +0900 Subject: [PATCH 069/167] fix: Implement --- Source/Robock/Models/WindowManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs index 1c9f0fd..1dd7187 100644 --- a/Source/Robock/Models/WindowManager.cs +++ b/Source/Robock/Models/WindowManager.cs @@ -50,6 +50,8 @@ private void FindWindows() if (string.IsNullOrWhiteSpace(title.ToString())) return true; // Skipped + if (Ignores.IgnoreWindowTitles.Contains(title.ToString())) + return true; windows.Add(new Window {Handle = hWnd, Title = title.ToString()}); return true; }, IntPtr.Zero); From d0adf1810015833535c4337fc96d7ed140923eaf Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 25 Jul 2018 08:38:26 +0900 Subject: [PATCH 070/167] refactor: As func --- .../Models/BackgroundService.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index b356049..86522bb 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -28,15 +28,7 @@ public static void MoveToOutsideOfDesktop() if (WindowHandle == null || WindowHandle == IntPtr.Zero) throw new InvalidOperationException(); - var rect = SystemInformation.VirtualScreen; - var x = 10000; - var y = 10000; - - if (x < rect.Right) - x = rect.Right; - if (y < rect.Bottom) - y = rect.Bottom; - + var (x, y) = GetPreviewWindowPosition(); NativeMethods.GetWindowRect(WindowHandle, out var window); if (!NativeMethods.MoveWindow(WindowHandle, x, y, window.right - window.left, window.bottom - window.top, true)) MessageBox.Show(NativeMethods.GetLastError().ToString()); @@ -162,5 +154,19 @@ public static IntPtr FindWorkerW() return workerW; } + + private static (int, int) GetPreviewWindowPosition() + { + var rect = SystemInformation.VirtualScreen; + var x = 10000; + var y = 10000; + + if (x < rect.Right) + x = rect.Right; + if (y < rect.Bottom) + y = rect.Bottom; + + return (x, y); + } } } \ No newline at end of file From 19d38812e5580914625d022dc7805d7297838073 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 25 Jul 2018 23:04:05 +0900 Subject: [PATCH 071/167] feat(shared): Dynamic Import --- Source/Robock.Shared/Win32/NativeMethods.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index 40fc0ab..8356c32 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -12,6 +12,12 @@ public static class NativeMethods [DllImport("kernel32.dll")] public static extern uint GetLastError(); + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr GetModuleHandle(string lpModuleName); + + [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] + public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); + #endregion #region Gdi32 From 74813be894b1cff288df6061efb7ede1a3319194 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 25 Jul 2018 23:04:26 +0900 Subject: [PATCH 072/167] chore(background): Add DirectX Wrapper for C# (SharpDX) --- Source/Robock.Background/Robock.Background.csproj | 3 +++ Source/Robock.Background/packages.config | 1 + 2 files changed, 4 insertions(+) diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 7918111..13bb9e6 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -84,6 +84,9 @@ ..\packages\ReactiveProperty.5.1.1\lib\net461\ReactiveProperty.NET46.dll + + ..\packages\SharpDX.4.1.0\lib\net45\SharpDX.dll + ..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll diff --git a/Source/Robock.Background/packages.config b/Source/Robock.Background/packages.config index 2434120..83763c9 100644 --- a/Source/Robock.Background/packages.config +++ b/Source/Robock.Background/packages.config @@ -5,6 +5,7 @@ + From 6a59f1191ce3f208e8cbf9fe0ee2b3d97254f996 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 25 Jul 2018 23:06:26 +0900 Subject: [PATCH 073/167] style: Add .dll suffix --- Source/Robock.Shared/Win32/NativeMethods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index 8356c32..4150aef 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -15,7 +15,7 @@ public static class NativeMethods [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); - [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] + [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); #endregion From bdfdb60344ca50942dee56ede7434d076d525cd2 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 25 Jul 2018 23:41:45 +0900 Subject: [PATCH 074/167] chore: Remove old code. --- .../Models/BackgroundService.cs | 160 +++--------------- .../Robock.Background/Models/RobockServer.cs | 7 +- .../ViewModels/AppShellViewModel.cs | 2 - .../Robock.Background/Views/AppShell.xaml.cs | 14 +- 4 files changed, 37 insertions(+), 146 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 86522bb..67ed766 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -1,161 +1,44 @@ using System; -using System.Drawing; -using System.Reactive.Linq; -using System.Threading.Tasks; using System.Windows.Forms; -using System.Windows.Interop; using Robock.Shared.Win32; -using Application = System.Windows.Application; +// ReSharper disable LocalizableElement namespace Robock.Background.Models { - public static class BackgroundService + // TODO: Error handling, remove all MessageBox from this model. + // 様々な理由から Singleton にせざるを得ない (RobockService への注入不可) + public class BackgroundService { - private static Bitmap _bitmap; - private static bool _drawing; - public static IntPtr WindowHandle { get; private set; } + private IntPtr _hWnd; - public static void Initialize() + public void Initialize(IntPtr hWnd) { - WindowHandle = new WindowInteropHelper(Application.Current.MainWindow ?? throw new InvalidOperationException()).Handle; + if (hWnd == IntPtr.Zero) + MessageBox.Show(""); + _hWnd = hWnd; } - // 描画範囲外へ飛ばす - public static void MoveToOutsideOfDesktop() + public void MoveToOutsideOfVirtualScreen() { - if (WindowHandle == null || WindowHandle == IntPtr.Zero) - throw new InvalidOperationException(); - var (x, y) = GetPreviewWindowPosition(); - NativeMethods.GetWindowRect(WindowHandle, out var window); - if (!NativeMethods.MoveWindow(WindowHandle, x, y, window.right - window.left, window.bottom - window.top, true)) - MessageBox.Show(NativeMethods.GetLastError().ToString()); + NativeMethods.GetWindowRect(_hWnd, out var window); + if (!NativeMethods.MoveWindow(_hWnd, x, y, window.right - window.left, window.bottom - window.top, true)) + MessageBox.Show("MoveWindow failed"); } - public static void DrawAfterWorkerW(int x, int y, int width, int height) + public void StartRender(IntPtr hWnd, int x, int y, int width, int height) { - try - { - if (WindowHandle == IntPtr.Zero) - throw new InvalidOperationException(); - - var workerW = FindWorkerW(); - NativeMethods.MoveWindow(WindowHandle, x, y, width, height, true); - if (workerW == IntPtr.Zero) - throw new InvalidOperationException(); - - Observable.Return(1).Delay(TimeSpan.FromSeconds(5)).Subscribe(_ => - { - NativeMethods.SetWindowPos(WindowHandle, new IntPtr(1), x, y, width, height, SetWindowPosFlags.ShowWindow); - MessageBox.Show(NativeMethods.GetLastError().ToString()); - }); - } - catch (Exception e) - { - MessageBox.Show(e.Message); - } + // NativeMethods.SetParent(_hWnd, NativeMethods.FindWindow("Progman", null)); } - public static void DrawOnWorkerW(int x, int y, int width, int height) + public void StopRender() { - _drawing = true; - NativeMethods.MoveWindow(WindowHandle, x, y, width, height, true); - var task = Task.Run(() => - { - NativeMethods.MoveWindow(WindowHandle, 10000, 10000, width, height, true); - - var period = 1000f / 30f; - var nextFrame = (double) Environment.TickCount; - while (_drawing) - { - var tick = (double) Environment.TickCount; - if (tick < nextFrame) - { - if (nextFrame - tick > 1) - Task.Delay(TimeSpan.FromMilliseconds(nextFrame - tick)).Wait(); - continue; - } - if (Environment.TickCount >= nextFrame + period) - { - nextFrame += period; - continue; - } - - var workerW = FindWorkerW(); - - var hdcSrc = NativeMethods.GetDC(WindowHandle); - var hdcDest = NativeMethods.GetDCEx(workerW, IntPtr.Zero, DeviceContextValues.Window | DeviceContextValues.Cache | DeviceContextValues.LockWindowUpdate); - - NativeMethods.BitBlt(hdcDest, x, y, width, height, hdcSrc, 0, 0, TernaryRasterOperations.SRCCOPY); - NativeMethods.ReleaseDC(WindowHandle, hdcSrc); - NativeMethods.ReleaseDC(workerW, hdcDest); - - nextFrame += period; - } - }); + // NativeMethods.SetParent(_hWnd, (IntPtr) null); } - public static void DrawAsNormal() - { - if (WindowHandle == null || WindowHandle == IntPtr.Zero) - throw new InvalidOperationException(); - - _drawing = false; - NativeMethods.SetParent(WindowHandle, (IntPtr) null); - MoveToOutsideOfDesktop(); - RestoreWallpaper(); - } - - // いじっちゃうと自前で戻さないと、前描画した物が残り続けるので、予めビットマップをメモリに保存しておく - public static void SaveCurrentWallpaper() - { - var workerW = FindWorkerW(); - var hdcSrc = NativeMethods.GetDCEx(workerW, IntPtr.Zero, DeviceContextValues.Window | DeviceContextValues.Cache | DeviceContextValues.LockWindowUpdate); - var hdcDest = NativeMethods.CreateCompatibleDC(hdcSrc); - NativeMethods.GetWindowRect(workerW, out var rect); - var (width, height) = (rect.right - rect.left, rect.bottom - rect.top); - - var hBitmap = NativeMethods.CreateCompatibleBitmap(hdcSrc, width, height); - var hOld = NativeMethods.SelectObject(hdcDest, hBitmap); - NativeMethods.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, TernaryRasterOperations.SRCCOPY); - NativeMethods.SelectObject(hdcDest, hOld); - NativeMethods.DeleteDC(hdcDest); - NativeMethods.ReleaseDC(workerW, hdcSrc); - - _bitmap = Image.FromHbitmap(hBitmap); - NativeMethods.DeleteObject(hBitmap); - } - - public static void RestoreWallpaper() - { - var workerW = FindWorkerW(); - - var hdcSrc = NativeMethods.GetDCEx(workerW, IntPtr.Zero, DeviceContextValues.Window | DeviceContextValues.Cache | DeviceContextValues.LockWindowUpdate); - using (var graphic = Graphics.FromHdc(hdcSrc)) - graphic.DrawImage(_bitmap, new PointF(0, 0)); - NativeMethods.ReleaseDC(workerW, hdcSrc); - } - - public static IntPtr FindWorkerW() - { - var progman = NativeMethods.FindWindow("Progman", null); - NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out var result); - - var workerW = IntPtr.Zero; - NativeMethods.EnumWindows((hWnd, lParam) => - { - var shell = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null); - if (shell != IntPtr.Zero) - workerW = NativeMethods.FindWindowEx(IntPtr.Zero, hWnd, "WorkerW", null); - return true; - }, IntPtr.Zero); - - return workerW; - } - - private static (int, int) GetPreviewWindowPosition() + private (int, int) GetPreviewWindowPosition() { var rect = SystemInformation.VirtualScreen; var x = 10000; @@ -168,5 +51,12 @@ private static (int, int) GetPreviewWindowPosition() return (x, y); } + + #region Singleton + + private static BackgroundService _backgroundService; + public static BackgroundService Instance => _backgroundService ?? (_backgroundService = new BackgroundService()); + + #endregion } } \ No newline at end of file diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index d7202e9..3f097bf 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -13,6 +13,7 @@ namespace Robock.Background.Models [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class RobockServer : IRobockDuplex, IDisposable { + private readonly BackgroundService _backgroundService; private readonly DesktopWindowManager _desktopWindowManager; private readonly string _uuid; private int _height; @@ -27,6 +28,7 @@ public RobockServer() { var args = Environment.GetCommandLineArgs(); _uuid = args[1]; + _backgroundService = BackgroundService.Instance; _desktopWindowManager = new DesktopWindowManager(); Observable.Return(0).ObserveOn(Application.Current.Dispatcher).Subscribe(_ => @@ -59,7 +61,7 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT? rect) { _desktopWindowManager.Start(src, 0, 0, _height, _width, 1, rect); - BackgroundService.DrawOnWorkerW(_x, _y, _width, _height); + _backgroundService.StartRender(src, _x, _y, _width, _height); Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[1].IsRendering); } @@ -67,8 +69,7 @@ public void ApplyWallpaper(IntPtr src, RECT? rect) public void DiscardWallpaper() { _desktopWindowManager.Stop(1); - BackgroundService.DrawAsNormal(); - BackgroundService.RestoreWallpaper(); + _backgroundService.StopRender(); Callback.DiscardWallpaperCallback(); } diff --git a/Source/Robock.Background/ViewModels/AppShellViewModel.cs b/Source/Robock.Background/ViewModels/AppShellViewModel.cs index 05471c5..decf27e 100644 --- a/Source/Robock.Background/ViewModels/AppShellViewModel.cs +++ b/Source/Robock.Background/ViewModels/AppShellViewModel.cs @@ -11,8 +11,6 @@ public class AppShellViewModel : ViewModel { public AppShellViewModel() { - BackgroundService.SaveCurrentWallpaper(); - Observable.Return(0).Delay(TimeSpan.FromMilliseconds(500)).Subscribe(_ => { var server = new RobockServer().AddTo(this); diff --git a/Source/Robock.Background/Views/AppShell.xaml.cs b/Source/Robock.Background/Views/AppShell.xaml.cs index 6f7b9f8..353a362 100644 --- a/Source/Robock.Background/Views/AppShell.xaml.cs +++ b/Source/Robock.Background/Views/AppShell.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Windows; +using System.Windows.Interop; using Robock.Background.Models; @@ -22,12 +23,13 @@ protected override void OnActivated(EventArgs e) base.OnActivated(e); // 表示されてから - if (_isFirstRun) - { - BackgroundService.Initialize(); - BackgroundService.MoveToOutsideOfDesktop(); - _isFirstRun = false; - } + if (!_isFirstRun) + return; + + _isFirstRun = false; + + BackgroundService.Instance.Initialize(new WindowInteropHelper(this).Handle); + BackgroundService.Instance.MoveToOutsideOfVirtualScreen(); } } } \ No newline at end of file From d421b56086d4b19358a2c561cd4a0bbbf34d0535 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 26 Jul 2018 08:13:43 +0900 Subject: [PATCH 075/167] fix: Render size/pos of preview. --- .../Robock.Background/Models/RobockServer.cs | 2 +- .../Models/DesktopWindowManager.cs | 30 +++--- Source/Robock.Shared/Win32/RECT.cs | 5 + Source/Robock/Models/IgnoreComparator.cs | 20 ++++ Source/Robock/Robock.csproj | 1 + .../ViewModels/Tabs/DesktopViewModel.cs | 97 +++++++++++-------- 6 files changed, 100 insertions(+), 55 deletions(-) create mode 100644 Source/Robock/Models/IgnoreComparator.cs diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 3f097bf..497a489 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -60,7 +60,7 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT? rect) { - _desktopWindowManager.Start(src, 0, 0, _height, _width, 1, rect); + _desktopWindowManager.Start(1, src, 0, 0, _height, _width, rect); _backgroundService.StartRender(src, _x, _y, _width, _height); Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[1].IsRendering); diff --git a/Source/Robock.Shared/Models/DesktopWindowManager.cs b/Source/Robock.Shared/Models/DesktopWindowManager.cs index b28def5..57ba362 100644 --- a/Source/Robock.Shared/Models/DesktopWindowManager.cs +++ b/Source/Robock.Shared/Models/DesktopWindowManager.cs @@ -20,7 +20,7 @@ public class DesktopWindowManager : BindableBase, IDisposable public List Thumbnails { get; } - public DesktopWindowManager(int capacity = 5) + public DesktopWindowManager(int capacity = 2) { Thumbnails = new List(); for (var i = 0; i < capacity; i++) @@ -38,21 +38,21 @@ public void Initialize() _hWnd = new WindowInteropHelper(Application.Current.MainWindow ?? throw new InvalidOperationException()).Handle; } - public void Stop(int index = 0) + public void Stop(int index) { if (Thumbnails[index].Handle != IntPtr.Zero) NativeMethods.DwmUnregisterThumbnail(Thumbnails[index].Handle); Thumbnails[index].Handle = IntPtr.Zero; Thumbnails[index].IsRendering = false; - Thumbnails[index].Size = new Size(1, 1); + Thumbnails[index].Size = new Size(0, 0); } - public void Start(IntPtr src, int left, int top, int height, int width, int index = 0, RECT? rect = null) + public void Start(int index, IntPtr src, int left, int top, int height, int width, RECT? rect = null) { - StartTo(src, _hWnd, left, top, height, width, index, rect); + StartTo(index, src, _hWnd, left, top, height, width, rect); } - public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int width, int index = 0, RECT? rect = null) + public void StartTo(int index, IntPtr src, IntPtr dest, int left, int top, int height, int width, RECT? rect = null) { Stop(index); @@ -60,15 +60,17 @@ public void StartTo(IntPtr src, IntPtr dest, int left, int top, int height, int Thumbnails[index].Handle = thumbnail; if (registered == 0) - StartRender(left, top, height, width, index, rect); + StartRender(index, left, top, height, width, rect); + else + throw new InvalidOperationException(); } - public void Rerender(int left, int top, int height, int width, int index = 0, RECT? rect = null) + public void Rerender(int index, int left, int top, int height, int width, RECT? rect = null) { - Render(left, top, height, width, index, rect); + Render(index, left, top, height, width, rect); } - private void StartRender(int left, int top, int height, int width, int index = 0, RECT? rect = null) + private void StartRender(int index, int left, int top, int height, int width, RECT? rect = null) { if (Thumbnails[index].Handle == IntPtr.Zero) return; @@ -77,10 +79,10 @@ private void StartRender(int left, int top, int height, int width, int index = 0 NativeMethods.DwmQueryThumbnailSourceSize(Thumbnails[index].Handle, out var size); Thumbnails[index].Size = size; - Render(left, top, height, width, index, rect); + Render(index, left, top, height, width, rect); } - private void Render(int left, int top, int height, int width, int index = 0, RECT? rect = null) + private void Render(int index, int left, int top, int height, int width, RECT? rect = null) { if (Thumbnails[index].Handle == IntPtr.Zero) return; @@ -93,7 +95,9 @@ private void Render(int left, int top, int height, int width, int index = 0, REC rcDestination = new RECT {left = left, top = top, right = left + width, bottom = top + height}, fSourceClientAreaOnly = true }; - if (rect != null) + + // fuck + if (rect != null && !rect.Value.IsEmpty()) { props.rcSource = rect.Value; props.dwFlags |= (int) DWM_TNP.DWM_TNP_RECTSOURCE; diff --git a/Source/Robock.Shared/Win32/RECT.cs b/Source/Robock.Shared/Win32/RECT.cs index f7545ef..1c95cff 100644 --- a/Source/Robock.Shared/Win32/RECT.cs +++ b/Source/Robock.Shared/Win32/RECT.cs @@ -13,5 +13,10 @@ public struct RECT public int top; public int right; public int bottom; + + public bool IsEmpty() + { + return left == 0 && top == 0 && right == 0 && bottom == 0; + } } } \ No newline at end of file diff --git a/Source/Robock/Models/IgnoreComparator.cs b/Source/Robock/Models/IgnoreComparator.cs new file mode 100644 index 0000000..a9bad7a --- /dev/null +++ b/Source/Robock/Models/IgnoreComparator.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace Robock.Models +{ + internal class IgnoreComparator : IEqualityComparer + { + public bool Equals(int x, int y) + { + if (x != 0 && y == 0) + return true; // 通知すると死ぬ + return x == y; + } + + public int GetHashCode(int obj) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 7c803be..56dfc10 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -146,6 +146,7 @@ + diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 6d1a720..e9698af 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Windows; @@ -19,6 +20,7 @@ public class DesktopViewModel : TabViewModel private readonly Desktop _desktop; private readonly DesktopWindowManager _desktopWindowManager; + private readonly object _lockObj = new object(); private readonly double _offsetX; private readonly double _offsetY; @@ -72,21 +74,35 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin _offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; _offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; + // タブの選択状態 + IsSelected = new ReactiveProperty(false); + IsSelected.Subscribe(w => + { + if (w) + { + Render(0); + } + else + { + _desktopWindowManager.Stop(0); + _desktopWindowManager.Stop(1); + } + }).AddTo(this); + // エディター EditorAspectRatio = new ReactiveProperty("https://placehold.mochizuki.moe/1x1/"); EditorAreaLeft = new ReactiveProperty(); EditorAreaTop = new ReactiveProperty(); EditorAreaHeight = new ReactiveProperty(); EditorAreaWidth = new ReactiveProperty(); - var editorArea = new[] + new[] { EditorAreaLeft, EditorAreaTop, EditorAreaHeight, EditorAreaWidth - }.CombineLatest(); - editorArea.Subscribe(w => Render(DesktopWindowManager.EditorIndex)).AddTo(this); - desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.Size).Subscribe(w => + }.CombineLatest().Where(w => IsSelected.Value).Subscribe(w => Render(0)).AddTo(this); + desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.Size).Subscribe(w => { // EditorAspectRatio.Value = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(w.Height, w.Width)}/000000%2C000/000000%2C000/"; @@ -97,34 +113,39 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedAreaTop = new ReactiveProperty(); SelectedAreaHeight = new ReactiveProperty(); SelectedAreaWidth = new ReactiveProperty(); - var selectedArea = new[] + new[] { SelectedAreaLeft, SelectedAreaTop, SelectedAreaHeight, SelectedAreaWidth - }.CombineLatest(); - selectedArea.Subscribe(w => Render(DesktopWindowManager.PreviewIndex)).AddTo(this); + }.CombineLatest().Where(w => IsSelected.Value).Subscribe(w => Render(1)).AddTo(this); // プレビュー AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; - PreviewAreaLeft = new ReactiveProperty(); - PreviewAreaTop = new ReactiveProperty(); - PreviewAreaHeight = new ReactiveProperty(); - PreviewAreaWidth = new ReactiveProperty(); - var previewArea = new[] + PreviewAreaLeft = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); + PreviewAreaTop = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); + PreviewAreaHeight = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); + PreviewAreaWidth = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); + new[] { - EditorAreaLeft, - EditorAreaTop, - EditorAreaHeight, - EditorAreaWidth - }.CombineLatest(); - previewArea.Subscribe(w => Render(DesktopWindowManager.PreviewIndex)).AddTo(this); - desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.IsRendering).Subscribe(w => + PreviewAreaLeft, + PreviewAreaTop, + PreviewAreaHeight, + PreviewAreaWidth + }.CombineLatest().Subscribe(w => { // - Render(DesktopWindowManager.PreviewIndex); - }).AddTo(this); + Render(1); + }); + desktopWindowManager.Thumbnails[0] + .ObserveProperty(w => w.IsRendering) + .Where(w => w) + .Subscribe(w => + { + // + Render(1); + }).AddTo(this); // 親 GridAreaLeft = new ReactiveProperty(); @@ -132,24 +153,17 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin // 他 Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); - IsSelected = new ReactiveProperty(false); - IsSelected.Subscribe(w => - { - _desktopWindowManager.Stop(0); - _desktopWindowManager.Stop(1); - Render(DesktopWindowManager.EditorIndex); - }).AddTo(this); SelectedWindow = new ReactiveProperty(); - SelectedWindow.Where(w => w != null).Subscribe(w => + SelectedWindow.Where(w => w != null && IsSelected.Value).Subscribe(w => { _desktopWindowManager.Stop(0); _desktopWindowManager.Stop(1); - Render(DesktopWindowManager.EditorIndex); + Render(0); }).AddTo(this); ApplyWallpaperCommand = new[] { SelectedWindow.Select(w => w != null), - _desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].ObserveProperty(w => w.IsRendering) + _desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.IsRendering) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); ApplyWallpaperCommand.Subscribe(_ => { @@ -177,32 +191,33 @@ private void Render(int index) return; var handle = SelectedWindow.Value.Handle; - if (index == DesktopWindowManager.EditorIndex) + if (index == 0) { - if (_desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].IsRendering) - _desktopWindowManager.Rerender(EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + if (_desktopWindowManager.Thumbnails[0].IsRendering) + _desktopWindowManager.Rerender(0, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); else - _desktopWindowManager.Start(handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); + _desktopWindowManager.Start(0, handle, EditorAreaLeft.Value, EditorAreaTop.Value, EditorAreaHeight.Value, EditorAreaWidth.Value); } else { - var editor = DesktopWindowManager.EditorIndex; - - var rect = RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[editor].Size.Height, _desktopWindowManager.Thumbnails[editor].Size.Width); + var rect = RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[0].Size.Height, _desktopWindowManager.Thumbnails[0].Size.Width); if (SelectedAreaHeight.Value != 0) rect = CalcRenderingRect(); + if (PreviewAreaHeight.Value == 0) + throw new InvalidOperationException("Fucking "); + if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) - _desktopWindowManager.Rerender(PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); + _desktopWindowManager.Rerender(1, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, rect); else - _desktopWindowManager.Start(handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, index, rect); + _desktopWindowManager.Start(1, handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, rect); } } private RECT CalcRenderingRect() { // 描画サイズから、縮小された割合を計算 - var multi = _desktopWindowManager.Thumbnails[DesktopWindowManager.EditorIndex].Size.Height / (double) EditorAreaHeight.Value; + var multi = _desktopWindowManager.Thumbnails[0].Size.Height / (double) EditorAreaHeight.Value; // Grid と Image のズレが大きいと、描画領域がずれてしまうので、補正する var diff = new Size(EditorAreaLeft.Value - GridAreaLeft.Value, EditorAreaTop.Value - GridAreaTop.Value); From fd9385813bfd6bcbd9dff725328c4f2412b5e01a Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 26 Jul 2018 08:16:21 +0900 Subject: [PATCH 076/167] refactor: Remove unused using --- Source/Robock.Shared/Models/DesktopWindowManager.cs | 1 - Source/Robock/Models/IgnoreComparator.cs | 2 +- Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/Robock.Shared/Models/DesktopWindowManager.cs b/Source/Robock.Shared/Models/DesktopWindowManager.cs index 57ba362..ba5bac3 100644 --- a/Source/Robock.Shared/Models/DesktopWindowManager.cs +++ b/Source/Robock.Shared/Models/DesktopWindowManager.cs @@ -96,7 +96,6 @@ private void Render(int index, int left, int top, int height, int width, RECT? r fSourceClientAreaOnly = true }; - // fuck if (rect != null && !rect.Value.IsEmpty()) { props.rcSource = rect.Value; diff --git a/Source/Robock/Models/IgnoreComparator.cs b/Source/Robock/Models/IgnoreComparator.cs index a9bad7a..42a9798 100644 --- a/Source/Robock/Models/IgnoreComparator.cs +++ b/Source/Robock/Models/IgnoreComparator.cs @@ -8,7 +8,7 @@ internal class IgnoreComparator : IEqualityComparer public bool Equals(int x, int y) { if (x != 0 && y == 0) - return true; // 通知すると死ぬ + return true; // なぜか新しい値に0が降ってきて、それを通知すると死ぬ return x == y; } diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index e9698af..6078ff5 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Windows; From 6ede0e9268ddc861eb94747d857affe1aa1a61fe Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 26 Jul 2018 08:19:53 +0900 Subject: [PATCH 077/167] refactor(shared): Remove not work func --- Source/Robock.Shared/Models/DesktopWindowManager.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/Robock.Shared/Models/DesktopWindowManager.cs b/Source/Robock.Shared/Models/DesktopWindowManager.cs index ba5bac3..19ec1dc 100644 --- a/Source/Robock.Shared/Models/DesktopWindowManager.cs +++ b/Source/Robock.Shared/Models/DesktopWindowManager.cs @@ -48,15 +48,10 @@ public void Stop(int index) } public void Start(int index, IntPtr src, int left, int top, int height, int width, RECT? rect = null) - { - StartTo(index, src, _hWnd, left, top, height, width, rect); - } - - public void StartTo(int index, IntPtr src, IntPtr dest, int left, int top, int height, int width, RECT? rect = null) { Stop(index); - var registered = NativeMethods.DwmRegisterThumbnail(dest, src, out var thumbnail); + var registered = NativeMethods.DwmRegisterThumbnail(_hWnd, src, out var thumbnail); Thumbnails[index].Handle = thumbnail; if (registered == 0) From 3bb15925634749945c713a098fa663ebb38be080 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 27 Jul 2018 00:18:24 +0900 Subject: [PATCH 078/167] feat: Use Direct3D10 as rendering method. --- Source/Robock.Background/App.config | 8 +++ .../Models/BackgroundService.cs | 64 ++++++++++++++++++- .../Robock.Background.csproj | 12 ++++ Source/Robock.Background/Views/AppShell.xaml | 9 ++- .../Robock.Background/Views/AppShell.xaml.cs | 10 ++- Source/Robock.Background/packages.config | 4 ++ 6 files changed, 102 insertions(+), 5 deletions(-) diff --git a/Source/Robock.Background/App.config b/Source/Robock.Background/App.config index 0c924e7..af8a2fe 100644 --- a/Source/Robock.Background/App.config +++ b/Source/Robock.Background/App.config @@ -9,6 +9,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 67ed766..2348ccc 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -1,6 +1,9 @@ using System; +using System.Runtime.InteropServices; using System.Windows.Forms; +using Microsoft.Wpf.Interop.DirectX; + using Robock.Shared.Win32; // ReSharper disable LocalizableElement @@ -11,13 +14,23 @@ namespace Robock.Background.Models // 様々な理由から Singleton にせざるを得ない (RobockService への注入不可) public class BackgroundService { + private D3D11Image _dxImage; private IntPtr _hWnd; + private IntPtr _srcWindowHandle; + private DGetDxSharedSurface GetDxSharedSurface { get; set; } - public void Initialize(IntPtr hWnd) + public void Initialize(IntPtr hWnd, D3D11Image dxImage) { if (hWnd == IntPtr.Zero) MessageBox.Show(""); _hWnd = hWnd; + _dxImage = dxImage; + _dxImage.WindowOwner = hWnd; + _dxImage.OnRender = Render; + _dxImage.RequestRender(); + + var funcPtr = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("user32"), "DwmGetDxSharedSurface"); + GetDxSharedSurface = Marshal.GetDelegateForFunctionPointer(funcPtr); } public void MoveToOutsideOfVirtualScreen() @@ -30,12 +43,38 @@ public void MoveToOutsideOfVirtualScreen() public void StartRender(IntPtr hWnd, int x, int y, int width, int height) { - // NativeMethods.SetParent(_hWnd, NativeMethods.FindWindow("Progman", null)); + _srcWindowHandle = hWnd; + + // 1st, send 0x052C (undocumented) message to progman + var workerW = FindWorkerW(); + var progman = NativeMethods.FindWindow("Progman", null); + + // 2nd, move self to rendering position + var (x1, y1) = GetPreviewWindowPosition(); + NativeMethods.MoveWindow(_hWnd, x1, y1, width, height, true); + + // 3rd, stick myself to progman + NativeMethods.SetParent(_hWnd, progman); + } + + private void Render(IntPtr hSurface, bool isNewSurface) + { + if (_srcWindowHandle == IntPtr.Zero) + return; + + GetDxSharedSurface(_srcWindowHandle, out var phSurface, out var pAdapterLuid, out var pFmtWindow, out var pPresentFlgs, out var pWin32KUpdateId); } public void StopRender() { - // NativeMethods.SetParent(_hWnd, (IntPtr) null); + _srcWindowHandle = IntPtr.Zero; + + NativeMethods.SetParent(_hWnd, (IntPtr) null); + } + + public void Release() + { + _dxImage.Dispose(); } private (int, int) GetPreviewWindowPosition() @@ -52,6 +91,25 @@ public void StopRender() return (x, y); } + private IntPtr FindWorkerW() + { + var progman = NativeMethods.FindWindow("Progman", null); + NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out var result); + + var workerW = IntPtr.Zero; + NativeMethods.EnumWindows((hWnd, lParam) => + { + var shell = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null); + if (shell != IntPtr.Zero) + workerW = NativeMethods.FindWindowEx(IntPtr.Zero, hWnd, "WorkerW", null); + return true; + }, IntPtr.Zero); + + return workerW; + } + + private delegate bool DGetDxSharedSurface(IntPtr hWnd, out IntPtr phSurface, out long pAdapterLuid, out int pFmtWindow, out int pPresentFlgs, out long pWin32KUpdateId); + #region Singleton private static BackgroundService _backgroundService; diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 13bb9e6..f9be00f 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -69,6 +69,9 @@ ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.RegistrationByConvention.dll + + ..\packages\Microsoft.Wpf.Interop.DirectX-x64.0.9.0-beta-22856\lib\net45\Microsoft.Wpf.Interop.DirectX.dll + ..\packages\Prism.Core.6.3.0\lib\net45\Prism.dll @@ -87,6 +90,15 @@ ..\packages\SharpDX.4.1.0\lib\net45\SharpDX.dll + + ..\packages\SharpDX.D3DCompiler.4.1.0\lib\net45\SharpDX.D3DCompiler.dll + + + ..\packages\SharpDX.Direct3D10.4.1.0\lib\net45\SharpDX.Direct3D10.dll + + + ..\packages\SharpDX.DXGI.4.1.0\lib\net45\SharpDX.DXGI.dll + ..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll diff --git a/Source/Robock.Background/Views/AppShell.xaml b/Source/Robock.Background/Views/AppShell.xaml index d6546e6..f12ceee 100644 --- a/Source/Robock.Background/Views/AppShell.xaml +++ b/Source/Robock.Background/Views/AppShell.xaml @@ -3,6 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:actions="clr-namespace:Robock.Shared.Actions;assembly=Robock.Shared" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:directx="clr-namespace:Microsoft.Wpf.Interop.DirectX;assembly=Microsoft.Wpf.Interop.DirectX" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" @@ -20,5 +21,11 @@ - + + + + + + + diff --git a/Source/Robock.Background/Views/AppShell.xaml.cs b/Source/Robock.Background/Views/AppShell.xaml.cs index 353a362..0bb4617 100644 --- a/Source/Robock.Background/Views/AppShell.xaml.cs +++ b/Source/Robock.Background/Views/AppShell.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Windows; using System.Windows.Interop; @@ -28,8 +29,15 @@ protected override void OnActivated(EventArgs e) _isFirstRun = false; - BackgroundService.Instance.Initialize(new WindowInteropHelper(this).Handle); + BackgroundService.Instance.Initialize(new WindowInteropHelper(this).Handle, InteropImage); BackgroundService.Instance.MoveToOutsideOfVirtualScreen(); } + + protected override void OnClosing(CancelEventArgs e) + { + BackgroundService.Instance.Release(); + + base.OnClosing(e); + } } } \ No newline at end of file diff --git a/Source/Robock.Background/packages.config b/Source/Robock.Background/packages.config index 83763c9..1cf626d 100644 --- a/Source/Robock.Background/packages.config +++ b/Source/Robock.Background/packages.config @@ -1,11 +1,15 @@  + + + + From 6268309a7946a9225e08344f5c8f4c713fecea51 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 27 Jul 2018 08:18:20 +0900 Subject: [PATCH 079/167] fix: Position is absolute of window. --- Source/Robock.Background/Models/BackgroundService.cs | 8 ++++---- Source/Robock/Models/Desktop.cs | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 2348ccc..48c178f 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -49,12 +49,12 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) var workerW = FindWorkerW(); var progman = NativeMethods.FindWindow("Progman", null); - // 2nd, move self to rendering position + // 2nd, stick myself to progman + NativeMethods.SetParent(_hWnd, progman); + + // 3rd, move self to rendering position var (x1, y1) = GetPreviewWindowPosition(); NativeMethods.MoveWindow(_hWnd, x1, y1, width, height, true); - - // 3rd, stick myself to progman - NativeMethods.SetParent(_hWnd, progman); } private void Render(IntPtr hSurface, bool isNewSurface) diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index cafeb41..d445931 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -1,8 +1,8 @@ using System; using System.Diagnostics; +using System.Windows; using System.Windows.Forms; -using Robock.Shared.Communication; using Robock.Shared.Win32; namespace Robock.Models @@ -49,7 +49,10 @@ public void Dispose() public void Handshake() { - _client.Handshake((int) X, (int) Y, (int) Height, (int) Width); + var offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; + var offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; + + _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width); } public void ApplyWallpaper(IntPtr hWnd, RECT? rect) From 6bfbe7f77ae60e3599355b0d337c3a28c83ba108 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 27 Jul 2018 08:23:49 +0900 Subject: [PATCH 080/167] fix(background): StartRender and StopRender --- Source/Robock.Background/Models/BackgroundService.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 48c178f..0334fe9 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -53,8 +53,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) NativeMethods.SetParent(_hWnd, progman); // 3rd, move self to rendering position - var (x1, y1) = GetPreviewWindowPosition(); - NativeMethods.MoveWindow(_hWnd, x1, y1, width, height, true); + NativeMethods.MoveWindow(_hWnd, x, y, width, height, true); } private void Render(IntPtr hSurface, bool isNewSurface) @@ -69,7 +68,13 @@ public void StopRender() { _srcWindowHandle = IntPtr.Zero; + // 1st, set parent to desktop (nullptr) NativeMethods.SetParent(_hWnd, (IntPtr) null); + + // 2nd, move self to outside of desktop + NativeMethods.GetWindowRect(_hWnd, out var window); + var (x, y) = GetPreviewWindowPosition(); + NativeMethods.MoveWindow(_hWnd, x, y, window.right - window.left, window.bottom - window.top, true); } public void Release() From 5fd60d6359b8b25bfe7b8b317ea5c33659084ea2 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 27 Jul 2018 21:58:00 +0900 Subject: [PATCH 081/167] style: fix --- Source/Robock.Background/Models/BackgroundService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 0334fe9..6b624fe 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; @@ -47,6 +48,8 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) // 1st, send 0x052C (undocumented) message to progman var workerW = FindWorkerW(); + if (workerW == IntPtr.Zero) + Debug.WriteLine("WARNING: Unknown desktop structure"); // SHELLDLL_DefView だとか WorkerW なくても動くが、ログだけ残しとく var progman = NativeMethods.FindWindow("Progman", null); // 2nd, stick myself to progman @@ -99,7 +102,7 @@ public void Release() private IntPtr FindWorkerW() { var progman = NativeMethods.FindWindow("Progman", null); - NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out var result); + NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out _); var workerW = IntPtr.Zero; NativeMethods.EnumWindows((hWnd, lParam) => From b4ad171f58c66888cff4bca1970199a8b80290fc Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 13:37:42 +0900 Subject: [PATCH 082/167] refactor: DWM cannot use in background (child) window. --- .../Robock.Background/Models/RobockServer.cs | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 497a489..c01d25c 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -1,11 +1,8 @@ using System; -using System.Diagnostics; -using System.Reactive.Linq; using System.ServiceModel; using System.Windows; using Robock.Shared.Communication; -using Robock.Shared.Models; using Robock.Shared.Win32; namespace Robock.Background.Models @@ -14,7 +11,6 @@ namespace Robock.Background.Models public class RobockServer : IRobockDuplex, IDisposable { private readonly BackgroundService _backgroundService; - private readonly DesktopWindowManager _desktopWindowManager; private readonly string _uuid; private int _height; private ServiceHost _serviceHost; @@ -29,19 +25,6 @@ public RobockServer() var args = Environment.GetCommandLineArgs(); _uuid = args[1]; _backgroundService = BackgroundService.Instance; - _desktopWindowManager = new DesktopWindowManager(); - - Observable.Return(0).ObserveOn(Application.Current.Dispatcher).Subscribe(_ => - { - try - { - _desktopWindowManager.Initialize(); - } - catch (Exception e) - { - Debug.WriteLine(e.Message); - } - }); } public void Dispose() @@ -60,15 +43,13 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT? rect) { - _desktopWindowManager.Start(1, src, 0, 0, _height, _width, rect); _backgroundService.StartRender(src, _x, _y, _width, _height); - Callback.ApplyWallpaperCallback(_desktopWindowManager.Thumbnails[1].IsRendering); + Callback.ApplyWallpaperCallback(true); } public void DiscardWallpaper() { - _desktopWindowManager.Stop(1); _backgroundService.StopRender(); Callback.DiscardWallpaperCallback(); From b446587139be3e46a1d947a5a001b73427837bc7 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 14:57:48 +0900 Subject: [PATCH 083/167] feat(background): Change override to event --- Source/Robock.Background/Views/AppShell.xaml | 12 ++++---- .../Robock.Background/Views/AppShell.xaml.cs | 28 ++++++------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/Source/Robock.Background/Views/AppShell.xaml b/Source/Robock.Background/Views/AppShell.xaml index f12ceee..e87d054 100644 --- a/Source/Robock.Background/Views/AppShell.xaml +++ b/Source/Robock.Background/Views/AppShell.xaml @@ -21,11 +21,9 @@ - - - - - - - + + + + + diff --git a/Source/Robock.Background/Views/AppShell.xaml.cs b/Source/Robock.Background/Views/AppShell.xaml.cs index 0bb4617..9e1d47e 100644 --- a/Source/Robock.Background/Views/AppShell.xaml.cs +++ b/Source/Robock.Background/Views/AppShell.xaml.cs @@ -1,5 +1,4 @@ -using System; -using System.ComponentModel; +using System.ComponentModel; using System.Windows; using System.Windows.Interop; @@ -12,32 +11,23 @@ namespace Robock.Background.Views /// public partial class AppShell : Window { - private bool _isFirstRun = true; - public AppShell() { InitializeComponent(); - } - - protected override void OnActivated(EventArgs e) - { - base.OnActivated(e); - - // 表示されてから - if (!_isFirstRun) - return; - - _isFirstRun = false; - BackgroundService.Instance.Initialize(new WindowInteropHelper(this).Handle, InteropImage); - BackgroundService.Instance.MoveToOutsideOfVirtualScreen(); + Closing += OnClosing; + Loaded += OnLoaded; } - protected override void OnClosing(CancelEventArgs e) + private void OnClosing(object sender, CancelEventArgs e) { BackgroundService.Instance.Release(); + } - base.OnClosing(e); + private void OnLoaded(object sender, RoutedEventArgs e) + { + BackgroundService.Instance.Initialize(new WindowInteropHelper(this).Handle, InteropImage); + BackgroundService.Instance.MoveToOutsideOfVirtualScreen(); } } } \ No newline at end of file From 6afd7de590941134e2198d9bfc9b817baed2a264 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 15:21:16 +0900 Subject: [PATCH 084/167] feat(background): Render --- .../Models/BackgroundService.cs | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 6b624fe..41e7009 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; +using System.Windows.Media; using Microsoft.Wpf.Interop.DirectX; @@ -17,6 +18,7 @@ public class BackgroundService { private D3D11Image _dxImage; private IntPtr _hWnd; + private TimeSpan _lastRender; private IntPtr _srcWindowHandle; private DGetDxSharedSurface GetDxSharedSurface { get; set; } @@ -28,10 +30,11 @@ public void Initialize(IntPtr hWnd, D3D11Image dxImage) _dxImage = dxImage; _dxImage.WindowOwner = hWnd; _dxImage.OnRender = Render; - _dxImage.RequestRender(); var funcPtr = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("user32"), "DwmGetDxSharedSurface"); GetDxSharedSurface = Marshal.GetDelegateForFunctionPointer(funcPtr); + + _dxImage.RequestRender(); } public void MoveToOutsideOfVirtualScreen() @@ -46,19 +49,36 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) { _srcWindowHandle = hWnd; - // 1st, send 0x052C (undocumented) message to progman + // 1st, change DirectX rendering size and register composition event. + _dxImage.Dispatcher.Invoke(() => + { + _dxImage.SetPixelSize(width, height); + CompositionTarget.Rendering += CompositionTargetOnRendering; + }); + + // 2st, find WorkerW and send 0x052C (undocumented) message to progman var workerW = FindWorkerW(); if (workerW == IntPtr.Zero) Debug.WriteLine("WARNING: Unknown desktop structure"); // SHELLDLL_DefView だとか WorkerW なくても動くが、ログだけ残しとく var progman = NativeMethods.FindWindow("Progman", null); - // 2nd, stick myself to progman + // 3rd, stick myself to progman NativeMethods.SetParent(_hWnd, progman); - // 3rd, move self to rendering position + // 4th, move self to rendering position NativeMethods.MoveWindow(_hWnd, x, y, width, height, true); } + private void CompositionTargetOnRendering(object sender, EventArgs e) + { + if (!(e is RenderingEventArgs args) || _lastRender == args.RenderingTime) + return; + + // Request next frame to Render() + _dxImage.RequestRender(); + _lastRender = args.RenderingTime; + } + private void Render(IntPtr hSurface, bool isNewSurface) { if (_srcWindowHandle == IntPtr.Zero) @@ -71,13 +91,14 @@ public void StopRender() { _srcWindowHandle = IntPtr.Zero; - // 1st, set parent to desktop (nullptr) + // 1st, unregister composition rendering event. + _dxImage.Dispatcher.Invoke(() => { CompositionTarget.Rendering -= CompositionTargetOnRendering; }); + + // 2nd, set parent to desktop (nullptr) NativeMethods.SetParent(_hWnd, (IntPtr) null); - // 2nd, move self to outside of desktop - NativeMethods.GetWindowRect(_hWnd, out var window); - var (x, y) = GetPreviewWindowPosition(); - NativeMethods.MoveWindow(_hWnd, x, y, window.right - window.left, window.bottom - window.top, true); + // 3rd, move self to outside of desktop + MoveToOutsideOfVirtualScreen(); } public void Release() From f3300110bf5ddcdedde38f17fef00ea3e8bd5ed6 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 15:56:33 +0900 Subject: [PATCH 085/167] refactor: Remove unused lines, props --- Source/Robock.Shared/Mvvm/ViewModel.cs | 2 +- Source/Robock.Shared/Refrection/RefrectionHelper.cs | 2 +- Source/Robock/Models/Desktop.cs | 1 - Source/Robock/Models/Ignores.cs | 4 ++-- Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 2 -- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Source/Robock.Shared/Mvvm/ViewModel.cs b/Source/Robock.Shared/Mvvm/ViewModel.cs index 4491923..451875c 100644 --- a/Source/Robock.Shared/Mvvm/ViewModel.cs +++ b/Source/Robock.Shared/Mvvm/ViewModel.cs @@ -9,7 +9,7 @@ public class ViewModel : BindableBase, IDisposable { public CompositeDisposable CompositeDisposable { get; } - public ViewModel() + protected ViewModel() { CompositeDisposable = new CompositeDisposable(); } diff --git a/Source/Robock.Shared/Refrection/RefrectionHelper.cs b/Source/Robock.Shared/Refrection/RefrectionHelper.cs index 061c1f9..c4e0ce4 100644 --- a/Source/Robock.Shared/Refrection/RefrectionHelper.cs +++ b/Source/Robock.Shared/Refrection/RefrectionHelper.cs @@ -1,6 +1,6 @@ using System.Reflection; -namespace Robock.Refrection +namespace Robock.Shared.Refrection { public static class RefrectionHelper { diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index d445931..5dc00f7 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -18,7 +18,6 @@ public class Desktop : IDisposable public int No { get; } public bool IsPrimary => _screen.Primary; - public string MonitorName => _screen.DeviceName; public double X => _screen.Bounds.X; public double Y => _screen.Bounds.Y; public double Height => _screen.Bounds.Height; diff --git a/Source/Robock/Models/Ignores.cs b/Source/Robock/Models/Ignores.cs index af800c4..f789ca3 100644 --- a/Source/Robock/Models/Ignores.cs +++ b/Source/Robock/Models/Ignores.cs @@ -2,9 +2,9 @@ namespace Robock.Models { - public class Ignores + public static class Ignores { - public static List IgnoreWindowTitles = new List + public static readonly List IgnoreWindowTitles = new List { "ChromeWindow", // Robock's window separator "Robock", // Myself diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 6078ff5..c2050c0 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -19,7 +19,6 @@ public class DesktopViewModel : TabViewModel private readonly Desktop _desktop; private readonly DesktopWindowManager _desktopWindowManager; - private readonly object _lockObj = new object(); private readonly double _offsetX; private readonly double _offsetY; @@ -57,7 +56,6 @@ public class DesktopViewModel : TabViewModel public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; - public bool IsPrimary => _desktop.IsPrimary; public double VirtualScreenX => (_offsetX + _desktop.X) / Scale; public double VirtualScreenY => (_offsetY + _desktop.Y) / Scale; From 9f466a96ddc20527c0eaf91286566dc64e9ebb33 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 20:03:08 +0900 Subject: [PATCH 086/167] feat(background): Point --- .../Robock.Background/Models/BackgroundService.cs | 8 ++++++++ Source/Robock.Background/Models/DxRenderer.cs | 13 +++++++++++++ Source/Robock.Background/Robock.Background.csproj | 1 + 3 files changed, 22 insertions(+) create mode 100644 Source/Robock.Background/Models/DxRenderer.cs diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 41e7009..abe98be 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -19,6 +19,7 @@ public class BackgroundService private D3D11Image _dxImage; private IntPtr _hWnd; private TimeSpan _lastRender; + private DxRenderer _renderer; private IntPtr _srcWindowHandle; private DGetDxSharedSurface GetDxSharedSurface { get; set; } @@ -28,6 +29,11 @@ public void Initialize(IntPtr hWnd, D3D11Image dxImage) MessageBox.Show(""); _hWnd = hWnd; _dxImage = dxImage; + + // Initialize DirectX devices. + _renderer = new DxRenderer(); + _renderer.Init(); + _dxImage.WindowOwner = hWnd; _dxImage.OnRender = Render; @@ -85,6 +91,7 @@ private void Render(IntPtr hSurface, bool isNewSurface) return; GetDxSharedSurface(_srcWindowHandle, out var phSurface, out var pAdapterLuid, out var pFmtWindow, out var pPresentFlgs, out var pWin32KUpdateId); + _renderer.Render(hSurface, phSurface, isNewSurface); } public void StopRender() @@ -103,6 +110,7 @@ public void StopRender() public void Release() { + _renderer.Dispose(); _dxImage.Dispose(); } diff --git a/Source/Robock.Background/Models/DxRenderer.cs b/Source/Robock.Background/Models/DxRenderer.cs new file mode 100644 index 0000000..d4203c3 --- /dev/null +++ b/Source/Robock.Background/Models/DxRenderer.cs @@ -0,0 +1,13 @@ +using System; + +namespace Robock.Background.Models +{ + public class DxRenderer : IDisposable + { + public void Dispose() { } + + public void Init() { } + + public void Render(IntPtr hSurface, IntPtr phSurface, bool isNewSurface) { } + } +} \ No newline at end of file diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index f9be00f..6672088 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -147,6 +147,7 @@ Code + From b5ee7ea76e382e6dd033adb3d9b747ab1016cece Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 23:12:23 +0900 Subject: [PATCH 087/167] feat(background): Fix rendering cycle --- Source/Robock.Background/App.config | 11 +++--- .../Models/BackgroundService.cs | 37 ++++++++++++------- Source/Robock.Background/Models/DxRenderer.cs | 5 +-- .../Robock.Background/Models/RobockServer.cs | 13 ++----- .../Robock.Background.csproj | 10 ++++- Source/Robock.Background/packages.config | 4 +- 6 files changed, 47 insertions(+), 33 deletions(-) diff --git a/Source/Robock.Background/App.config b/Source/Robock.Background/App.config index af8a2fe..4aa637f 100644 --- a/Source/Robock.Background/App.config +++ b/Source/Robock.Background/App.config @@ -1,8 +1,9 @@  + - - - + + + @@ -11,11 +12,11 @@ - + - + diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index abe98be..14651c3 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -17,10 +17,14 @@ namespace Robock.Background.Models public class BackgroundService { private D3D11Image _dxImage; + private int _height; private IntPtr _hWnd; private TimeSpan _lastRender; private DxRenderer _renderer; private IntPtr _srcWindowHandle; + private int _width; + private int _x; + private int _y; private DGetDxSharedSurface GetDxSharedSurface { get; set; } public void Initialize(IntPtr hWnd, D3D11Image dxImage) @@ -30,17 +34,8 @@ public void Initialize(IntPtr hWnd, D3D11Image dxImage) _hWnd = hWnd; _dxImage = dxImage; - // Initialize DirectX devices. - _renderer = new DxRenderer(); - _renderer.Init(); - _dxImage.WindowOwner = hWnd; _dxImage.OnRender = Render; - - var funcPtr = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("user32"), "DwmGetDxSharedSurface"); - GetDxSharedSurface = Marshal.GetDelegateForFunctionPointer(funcPtr); - - _dxImage.RequestRender(); } public void MoveToOutsideOfVirtualScreen() @@ -51,6 +46,22 @@ public void MoveToOutsideOfVirtualScreen() MessageBox.Show("MoveWindow failed"); } + public void SetupRenderer(int x, int y, int width, int height) + { + _x = x; + _y = y; + _width = width; + _height = height; + + // Initialize DirectX devices. + _renderer = new DxRenderer(); + + var funcPtr = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("user32"), "DwmGetDxSharedSurface"); + GetDxSharedSurface = Marshal.GetDelegateForFunctionPointer(funcPtr); + + _dxImage.Dispatcher.Invoke(() => _dxImage.RequestRender()); + } + public void StartRender(IntPtr hWnd, int x, int y, int width, int height) { _srcWindowHandle = hWnd; @@ -58,7 +69,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) // 1st, change DirectX rendering size and register composition event. _dxImage.Dispatcher.Invoke(() => { - _dxImage.SetPixelSize(width, height); + _dxImage.SetPixelSize(_width, _height); CompositionTarget.Rendering += CompositionTargetOnRendering; }); @@ -72,7 +83,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) NativeMethods.SetParent(_hWnd, progman); // 4th, move self to rendering position - NativeMethods.MoveWindow(_hWnd, x, y, width, height, true); + NativeMethods.MoveWindow(_hWnd, _x, _y, _width, _height, true); } private void CompositionTargetOnRendering(object sender, EventArgs e) @@ -91,7 +102,7 @@ private void Render(IntPtr hSurface, bool isNewSurface) return; GetDxSharedSurface(_srcWindowHandle, out var phSurface, out var pAdapterLuid, out var pFmtWindow, out var pPresentFlgs, out var pWin32KUpdateId); - _renderer.Render(hSurface, phSurface, isNewSurface); + _renderer.Render(hSurface, phSurface, _width, _height, isNewSurface); } public void StopRender() @@ -110,7 +121,7 @@ public void StopRender() public void Release() { - _renderer.Dispose(); + _renderer?.Dispose(); _dxImage.Dispose(); } diff --git a/Source/Robock.Background/Models/DxRenderer.cs b/Source/Robock.Background/Models/DxRenderer.cs index d4203c3..51b7824 100644 --- a/Source/Robock.Background/Models/DxRenderer.cs +++ b/Source/Robock.Background/Models/DxRenderer.cs @@ -6,8 +6,7 @@ public class DxRenderer : IDisposable { public void Dispose() { } - public void Init() { } - - public void Render(IntPtr hSurface, IntPtr phSurface, bool isNewSurface) { } + // 基本 hSurface, phSurface は変わらないと思われ + public void Render(IntPtr hSurface, IntPtr phSurface, int width, int height, bool isNewSurface) { } } } \ No newline at end of file diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index c01d25c..3086e8e 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -12,11 +12,7 @@ public class RobockServer : IRobockDuplex, IDisposable { private readonly BackgroundService _backgroundService; private readonly string _uuid; - private int _height; private ServiceHost _serviceHost; - private int _width; - private int _x; - private int _y; private IRobockDuplexCallback Callback => OperationContext.Current.GetCallbackChannel(); @@ -35,15 +31,14 @@ public void Dispose() public void Handshake(int x, int y, int height, int width) { - _x = x; - _y = y; - _height = height; - _width = width; + _backgroundService.SetupRenderer(x, y, width, height); + + Callback.HandshakeCallback(); } public void ApplyWallpaper(IntPtr src, RECT? rect) { - _backgroundService.StartRender(src, _x, _y, _width, _height); + _backgroundService.StartRender(src, rect?.left ?? 0, rect?.top ?? 0, rect?.right - rect?.left ?? 0, rect?.bottom - rect?.top ?? 0); Callback.ApplyWallpaperCallback(true); } diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 6672088..9e82f17 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -93,12 +93,18 @@ ..\packages\SharpDX.D3DCompiler.4.1.0\lib\net45\SharpDX.D3DCompiler.dll - - ..\packages\SharpDX.Direct3D10.4.1.0\lib\net45\SharpDX.Direct3D10.dll + + ..\packages\SharpDX.Desktop.4.1.0\lib\net45\SharpDX.Desktop.dll + + + ..\packages\SharpDX.Direct3D11.4.1.0\lib\net45\SharpDX.Direct3D11.dll ..\packages\SharpDX.DXGI.4.1.0\lib\net45\SharpDX.DXGI.dll + + ..\packages\SharpDX.Mathematics.4.1.0\lib\net45\SharpDX.Mathematics.dll + ..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll diff --git a/Source/Robock.Background/packages.config b/Source/Robock.Background/packages.config index 1cf626d..0726363 100644 --- a/Source/Robock.Background/packages.config +++ b/Source/Robock.Background/packages.config @@ -8,8 +8,10 @@ - + + + From c6a85c7c3f18455e6aac329ff51a4ffa2c3b1884 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 23:16:25 +0900 Subject: [PATCH 088/167] refactor(core): Remove unreachable reference. --- Source/Robock.Background/Robock.Background.csproj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 9e82f17..f8bb84b 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -116,14 +116,6 @@ ..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll - - ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll - True - - - ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll - True - From 0147cc8fed1a3e1d1b856145b1d71ea50d87958e Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 28 Jul 2018 23:19:37 +0900 Subject: [PATCH 089/167] chore(shared): Remove x86 --- Source/Robock.Shared/Robock.Shared.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 2918e7d..b80898f 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -20,6 +20,7 @@ DEBUG;TRACE prompt 4 + x64 pdbonly From dda6e0c91cb7cb1b84355d59047139944ac62326 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 29 Jul 2018 02:53:16 +0900 Subject: [PATCH 090/167] chore(core): Add license notices. --- Source/Robock/Models/ProductInfo.cs | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Source/Robock/Models/ProductInfo.cs b/Source/Robock/Models/ProductInfo.cs index ff60073..87ecf4f 100644 --- a/Source/Robock/Models/ProductInfo.cs +++ b/Source/Robock/Models/ProductInfo.cs @@ -151,6 +151,55 @@ obtain a copy of the License at WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License." + }, + new License + { + Name = "SharpDx", + Url = "http://sharpdx.org/", + Authors = new[] {"Alexandre Mutel"}, + Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") + }, + new License + { + Name = "SharpDx.D3DCompiler", + Url = "http://sharpdx.org/", + Authors = new[] {"Alexandre Mutel"}, + Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") + }, + new License + { + Name = "SharpDx.Desktop", + Url = "http://sharpdx.org/", + Authors = new[] {"Alexandre Mutel"}, + Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") + }, + new License + { + Name = "SharpDx.Direct3D11", + Url = "http://sharpdx.org/", + Authors = new[] {"Alexandre Mutel"}, + Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") + }, + new License + { + Name = "SharpDx.DXGI", + Url = "http://sharpdx.org/", + Authors = new[] {"Alexandre Mutel"}, + Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") + }, + new License + { + Name = "SharpDx.Mathematics", + Url = "http://sharpdx.org/", + Authors = new[] {"Alexandre Mutel"}, + Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") + }, + new License + { + Name = "Microsoft.Wpf.Interop.DirectX", + Url = "https://github.com/Microsoft/WPFDXInterop", + Authors = new[] {"Microsoft"}, + Body = License.MIT.Replace("{yyyy}", "2015").Replace("{name of copyright owner}", "Microsoft") } }.OrderBy(w => w.Name).ToList().AsReadOnly(); From 7974e8b0004b31ca02ec58e76c0bed07584345d3 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 29 Jul 2018 02:58:41 +0900 Subject: [PATCH 091/167] fix(core): Crash when window resize. --- .../Behaviors/ControlPositionBindingBehavior.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs index 2e75523..1a0b862 100644 --- a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs +++ b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs @@ -65,9 +65,17 @@ private void MainWindowOnSizeChanged(object sender, SizeChangedEventArgs e) if (Application.Current.MainWindow == null) return; - var relative = AssociatedObject.TransformToAncestor(Application.Current.MainWindow).Transform(new Point()); - Left = (int) relative.X; - Top = (int) relative.Y; + try + { + var relative = AssociatedObject.TransformToAncestor(Application.Current.MainWindow).Transform(new Point()); + Left = (int) relative.X; + Top = (int) relative.Y; + } + catch + { + // ignored + // 何もないタブで動作させると死ぬらしい + } } private void AssociatedObjectSizeChanged(object sender, SizeChangedEventArgs e) From 886a98e76310c61a603e97c0486ef0385f03215b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 29 Jul 2018 03:01:53 +0900 Subject: [PATCH 092/167] fix(core): Preview is not hide on about page. --- Source/Robock/ViewModels/VirtualScreenViewModel.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Robock/ViewModels/VirtualScreenViewModel.cs b/Source/Robock/ViewModels/VirtualScreenViewModel.cs index 67a6f6c..b0c62d7 100644 --- a/Source/Robock/ViewModels/VirtualScreenViewModel.cs +++ b/Source/Robock/ViewModels/VirtualScreenViewModel.cs @@ -24,10 +24,12 @@ public VirtualScreenViewModel() { Desktops = new ObservableCollection(); SelectedIndex = new ReactiveProperty(0); - SelectedIndex.Where(w => Desktops.Count > w && w >= 0).Subscribe(w => + SelectedIndex.Where(w => w >= 0).Subscribe(w => { foreach (var desktop in Desktops) desktop.IsSelected.Value = false; + if (w >= Desktops.Count) + return; Desktops[w].IsSelected.Value = true; }); } From dcc929f36b96af46973d0c39fdb61368d926b3d1 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 29 Jul 2018 03:15:19 +0900 Subject: [PATCH 093/167] feat(core): Avoid using try-catch expression for performance. --- .../ControlPositionBindingBehavior.cs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs index 1a0b862..a5c9ab5 100644 --- a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs +++ b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs @@ -1,5 +1,6 @@ using System.Windows; using System.Windows.Interactivity; +using System.Windows.Media; namespace Robock.Behaviors { @@ -65,17 +66,15 @@ private void MainWindowOnSizeChanged(object sender, SizeChangedEventArgs e) if (Application.Current.MainWindow == null) return; - try - { - var relative = AssociatedObject.TransformToAncestor(Application.Current.MainWindow).Transform(new Point()); - Left = (int) relative.X; - Top = (int) relative.Y; - } - catch - { - // ignored - // 何もないタブで動作させると死ぬらしい - } + var parent = VisualTreeHelper.GetParent(AssociatedObject) as FrameworkElement; + while (parent != null && !(parent is Window)) + parent = VisualTreeHelper.GetParent(parent) as FrameworkElement; + + if (parent == null) + return; + var relative = AssociatedObject.TransformToAncestor(Application.Current.MainWindow).Transform(new Point()); + Left = (int) relative.X; + Top = (int) relative.Y; } private void AssociatedObjectSizeChanged(object sender, SizeChangedEventArgs e) From 20ae8bcfd84181ff7a6eeaf274cf0479181b6411 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 29 Jul 2018 22:22:46 +0900 Subject: [PATCH 094/167] refactor: Drop SharpDX references. --- Source/Robock.Background/Models/DxRenderer.cs | 12 ------ .../Robock.Background.csproj | 19 --------- Source/Robock.Background/packages.config | 6 --- Source/Robock/Models/ProductInfo.cs | 42 ------------------- 4 files changed, 79 deletions(-) delete mode 100644 Source/Robock.Background/Models/DxRenderer.cs diff --git a/Source/Robock.Background/Models/DxRenderer.cs b/Source/Robock.Background/Models/DxRenderer.cs deleted file mode 100644 index 51b7824..0000000 --- a/Source/Robock.Background/Models/DxRenderer.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Robock.Background.Models -{ - public class DxRenderer : IDisposable - { - public void Dispose() { } - - // 基本 hSurface, phSurface は変わらないと思われ - public void Render(IntPtr hSurface, IntPtr phSurface, int width, int height, bool isNewSurface) { } - } -} \ No newline at end of file diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index f8bb84b..d6e658c 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -87,24 +87,6 @@ ..\packages\ReactiveProperty.5.1.1\lib\net461\ReactiveProperty.NET46.dll - - ..\packages\SharpDX.4.1.0\lib\net45\SharpDX.dll - - - ..\packages\SharpDX.D3DCompiler.4.1.0\lib\net45\SharpDX.D3DCompiler.dll - - - ..\packages\SharpDX.Desktop.4.1.0\lib\net45\SharpDX.Desktop.dll - - - ..\packages\SharpDX.Direct3D11.4.1.0\lib\net45\SharpDX.Direct3D11.dll - - - ..\packages\SharpDX.DXGI.4.1.0\lib\net45\SharpDX.DXGI.dll - - - ..\packages\SharpDX.Mathematics.4.1.0\lib\net45\SharpDX.Mathematics.dll - ..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll @@ -145,7 +127,6 @@ Code - diff --git a/Source/Robock.Background/packages.config b/Source/Robock.Background/packages.config index 0726363..402bb46 100644 --- a/Source/Robock.Background/packages.config +++ b/Source/Robock.Background/packages.config @@ -6,12 +6,6 @@ - - - - - - diff --git a/Source/Robock/Models/ProductInfo.cs b/Source/Robock/Models/ProductInfo.cs index 87ecf4f..5d68ad9 100644 --- a/Source/Robock/Models/ProductInfo.cs +++ b/Source/Robock/Models/ProductInfo.cs @@ -153,48 +153,6 @@ obtain a copy of the License at and limitations under the License." }, new License - { - Name = "SharpDx", - Url = "http://sharpdx.org/", - Authors = new[] {"Alexandre Mutel"}, - Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") - }, - new License - { - Name = "SharpDx.D3DCompiler", - Url = "http://sharpdx.org/", - Authors = new[] {"Alexandre Mutel"}, - Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") - }, - new License - { - Name = "SharpDx.Desktop", - Url = "http://sharpdx.org/", - Authors = new[] {"Alexandre Mutel"}, - Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") - }, - new License - { - Name = "SharpDx.Direct3D11", - Url = "http://sharpdx.org/", - Authors = new[] {"Alexandre Mutel"}, - Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") - }, - new License - { - Name = "SharpDx.DXGI", - Url = "http://sharpdx.org/", - Authors = new[] {"Alexandre Mutel"}, - Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") - }, - new License - { - Name = "SharpDx.Mathematics", - Url = "http://sharpdx.org/", - Authors = new[] {"Alexandre Mutel"}, - Body = License.MIT.Replace("{yyyy}", "2010-2015").Replace("{name of copyright owner}", "SharpDX - Alexandre Mutel") - }, - new License { Name = "Microsoft.Wpf.Interop.DirectX", Url = "https://github.com/Microsoft/WPFDXInterop", From 81654138e5987de9ac5c0ad5e45628398eca2997 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 29 Jul 2018 22:31:32 +0900 Subject: [PATCH 095/167] feat(native): Add Native(C++/CLI) project for DirectX --- .../Robock.Background.Native/AssemblyInfo.cpp | 22 +++ Source/Robock.Background.Native/Resource.h | 3 + .../Robock.Background.Native.cpp | 9 + .../Robock.Background.Native.h | 18 ++ .../Robock.Background.Native.vcxproj | 160 ++++++++++++++++++ .../Robock.Background.Native.vcxproj.filters | 49 ++++++ Source/Robock.Background.Native/app.ico | Bin 0 -> 41395 bytes Source/Robock.Background.Native/app.rc | Bin 0 -> 2520 bytes Source/Robock.Background.Native/stdafx.cpp | 1 + Source/Robock.Background.Native/stdafx.h | 7 + .../Models/BackgroundService.cs | 6 +- .../Robock.Background.csproj | 4 + Source/Robock.sln | 24 +++ 13 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 Source/Robock.Background.Native/AssemblyInfo.cpp create mode 100644 Source/Robock.Background.Native/Resource.h create mode 100644 Source/Robock.Background.Native/Robock.Background.Native.cpp create mode 100644 Source/Robock.Background.Native/Robock.Background.Native.h create mode 100644 Source/Robock.Background.Native/Robock.Background.Native.vcxproj create mode 100644 Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters create mode 100644 Source/Robock.Background.Native/app.ico create mode 100644 Source/Robock.Background.Native/app.rc create mode 100644 Source/Robock.Background.Native/stdafx.cpp create mode 100644 Source/Robock.Background.Native/stdafx.h diff --git a/Source/Robock.Background.Native/AssemblyInfo.cpp b/Source/Robock.Background.Native/AssemblyInfo.cpp new file mode 100644 index 0000000..e04cca7 --- /dev/null +++ b/Source/Robock.Background.Native/AssemblyInfo.cpp @@ -0,0 +1,22 @@ +#include "stdafx.h" + +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +[assembly:AssemblyTitleAttribute(L"Robock.Background.Native")]; +[assembly:AssemblyDescriptionAttribute(L"Robock Background Worker (Native DirectX)")]; +[assembly:AssemblyConfigurationAttribute(L"")]; +[assembly:AssemblyCompanyAttribute(L"")]; +[assembly:AssemblyProductAttribute(L"Robock.Background.Native")]; +[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2018 Mikazuki")]; +[assembly:AssemblyTrademarkAttribute(L"")]; +[assembly:AssemblyCultureAttribute(L"")]; + +[assembly:AssemblyVersionAttribute("1.0.*")]; + +[assembly:ComVisible(false)]; + +[assembly:CLSCompliantAttribute(true)]; diff --git a/Source/Robock.Background.Native/Resource.h b/Source/Robock.Background.Native/Resource.h new file mode 100644 index 0000000..16e656e --- /dev/null +++ b/Source/Robock.Background.Native/Resource.h @@ -0,0 +1,3 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ で生成されたインクルード ファイル。 +// 使用 app.rc diff --git a/Source/Robock.Background.Native/Robock.Background.Native.cpp b/Source/Robock.Background.Native/Robock.Background.Native.cpp new file mode 100644 index 0000000..8ef4dd7 --- /dev/null +++ b/Source/Robock.Background.Native/Robock.Background.Native.cpp @@ -0,0 +1,9 @@ +#include "stdafx.h" + +#include "Robock.Background.Native.h" + +using namespace DirectX; +using namespace DirectX::PackedVector; + +using namespace Robock::Background::Native; + diff --git a/Source/Robock.Background.Native/Robock.Background.Native.h b/Source/Robock.Background.Native/Robock.Background.Native.h new file mode 100644 index 0000000..0ab3215 --- /dev/null +++ b/Source/Robock.Background.Native/Robock.Background.Native.h @@ -0,0 +1,18 @@ +#pragma once + +using namespace System; + +namespace Robock +{ + namespace Background + { + namespace Native + { + public ref class DxRenderer + { + // TODO: このクラスのメソッドをここに追加します。 + public: + }; + } // namespace Native + } // namespace Background +} // namespace Robock diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj new file mode 100644 index 0000000..ac873c5 --- /dev/null +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1} + v4.7.2 + ManagedCProj + RobockBackgroundNative + 10.0.17134.0 + + + + DynamicLibrary + true + v141 + true + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + DynamicLibrary + true + v141 + true + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Level3 + Disabled + _DEBUG;%(PreprocessorDefinitions) + Use + + + d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + WIN32;_DEBUG;%(PreprocessorDefinitions) + Use + + + + + + + + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + Use + + + + + + + + Level3 + NDEBUG;%(PreprocessorDefinitions) + Use + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters new file mode 100644 index 0000000..7312942 --- /dev/null +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters @@ -0,0 +1,49 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + + + リソース ファイル + + + + + リソース ファイル + + + \ No newline at end of file diff --git a/Source/Robock.Background.Native/app.ico b/Source/Robock.Background.Native/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..789d7ccbb56ed92f1bb005054ec7e67257ddc37e GIT binary patch literal 41395 zcmeHQZA=_R7=DjCkZTKK8e`L%_DrfaQ35q-NU0yk2`Okwv@x+7+O*QNL}I~`Y8$Mc zweceoTVpWz1KLD?5Tj6HjAC->RZTH5(3+Y^qR}Q*QIUg61#Btj%&kM`7H)6nj+0&P zne4DLH}A~6^UO0d@9xgBL=JKjcMi&?At%w>EL>Qq#oKdt>C$N+(Rua|At$Lyk0H7#>diEi}F0wek;+HU7|b|XXU)xB+Bzp4Xf+HR-)G) zs@#~fX!#;mY)(aa>1JM9q{b|Es@mJmiXcbB=8Zn;=)3uM7IEz^*;GQ*b!7464yF^i z>&qW&Ajxqo~ z`o$M|S6|Ksp*!JynDLQBBox`-#bTKXNNLW6@ zgkx${f)e9J7HU zW>BoNwY0UbHnH&K*Qp-nz06Nvr^+meah=M<;eY@TNCN~S6LgB(nf&r-v~=^*=c0n&Ojh75tz+RnK5HVPvXohh+3)UAs(fW-b|Sp*ELAr(aAhg;CWNC zNg-csQaH8gOTI~A>mQ?;HLt$xf4z2e-!~6*cy1{Dt+(p06<@t|uzZicMMS~oQ0<3D z0x!1grj?D(wFOt)E;k)Ed9+Tg3NEWIIN#a3e!Td!+uXBZlaG*-5o1m2`SF#ewPVG* z`nqqrRCRT#YNfyP4BvY&bah{6bzfHSM$0IhOhc`lceYNT^Phg?sL%8lI?Ns?&V`*c zRdBocy$a9gPIeW|Bs$T^;GR!b6_sshE;@YY_gp~UPvB*7Kl6N3QpB;1NN_*^2mk>f zpdrBaQ2Eo`hgtjKfdM$cIKcK+E@&TbtfT$t|Aou}RsOSm)?qt)eP5#e#_0u9G5^8-Gva`rFPQ&e|Jj)XdOjO*ANC*YKRsXU%zfB@ z$=iQ=KG;33I{(?dy?Xu8el`17kDuM+=zsLT5eMwf?|AwfwVkKM%WwB|v>)T&hy!-# zcRc-#+K%yWJT~HChjicv4%m(ZY5o2e-U9>zKp=e)5dSYJ-Z^~{vUkhl^=tHZCp?kH z`q>9+;D7)SxP}0;>rdL;uu&S+@th^rgWXn^{AFF=V`xmP6 zLQm8mZTksaRPj`m7xe&t;4gDP@IsYOs`8>9xo#d7zpIv~Dlh6m{oudM0l^DZKB>x! zdgQug{)_ZfpHctp{7*IRqI}>VjlUj`bctK)VsIXmk>B_FKdTq@^7|D0wuFay@!ess zi$&(x%>|#u+@X3Fb@P0QtXIgd%~cBlKUMBUn?5AqRsh+Gt>a9)^4aj3_&%Y=|+=(c!3oH9iI{G|}Zd zpnSyklCl9?tsAq~VBc^gYi;zYlf^QYxJ%BqX-d1C?NIyD>ZW4rv$#UaYHMZM>IHV4 zY;R*9H5}pyMU=6JGaSIDw8;K0DmbO2#%~pQN-FHjit|B!B<~6195XY@N$`)ORPGI) zo0-)xni6lN_$c7GCBZi1ILiB)45!ZU` z8QfAbBK8gSdK`&Wnk^IC1~-<8W6PNfezo7V)iIpuTkB%6c-gkT7`9WdD&)v6O61Kp zzdkLlV+$GE%G-7JW<6zcU(AZnrJ{Ya(LSF!+h%<8v0SFTV_MyzAH_+|lE=%>XFNU8 zLwbF}3Zy6stT3uX{v-y!iBMO8Yi%_-D5t`qO!ng8z7=E6SBi!x2@t6mCeZvU{l#BYc=-jt_g;>}@B z9=ccO68v~O#3M|0bS_G@hAfExRRlzsDx9%3Q8)iQObc7z|3SX~b+|kxJ16rI-DM_p I6Z{p~AG16luK)l5 literal 0 HcmV?d00001 diff --git a/Source/Robock.Background.Native/stdafx.cpp b/Source/Robock.Background.Native/stdafx.cpp new file mode 100644 index 0000000..fd4f341 --- /dev/null +++ b/Source/Robock.Background.Native/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/Source/Robock.Background.Native/stdafx.h b/Source/Robock.Background.Native/stdafx.h new file mode 100644 index 0000000..eeca3ca --- /dev/null +++ b/Source/Robock.Background.Native/stdafx.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include +#include +#define DirectX_NS DirectX diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 14651c3..4e7593d 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -6,6 +6,7 @@ using Microsoft.Wpf.Interop.DirectX; +using Robock.Background.Native; using Robock.Shared.Win32; // ReSharper disable LocalizableElement @@ -121,7 +122,7 @@ public void StopRender() public void Release() { - _renderer?.Dispose(); + _renderer?.Release(); _dxImage.Dispose(); } @@ -156,7 +157,8 @@ private IntPtr FindWorkerW() return workerW; } - private delegate bool DGetDxSharedSurface(IntPtr hWnd, out IntPtr phSurface, out long pAdapterLuid, out int pFmtWindow, out int pPresentFlgs, out long pWin32KUpdateId); + private delegate bool DGetDxSharedSurface( + IntPtr hWnd, out IntPtr phSurface, out long pAdapterLuid, out int pFmtWindow, out int pPresentFlgs, out long pWin32KUpdateId); #region Singleton diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index d6e658c..5395abb 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -163,6 +163,10 @@ + + {5c90987b-36b8-44b1-a3b1-018a0a44bba1} + Robock.Background.Native + {07becf0b-6e07-4ac5-b0c2-3eae0539d9a2} Robock.Shared diff --git a/Source/Robock.sln b/Source/Robock.sln index af4b6d8..c7ec6fe 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -18,24 +18,48 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Robock.Background", "Robock.Background\Robock.Background.csproj", "{F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Robock.Background.Native", "Robock.Background.Native\Robock.Background.Native.vcxproj", "{5C90987B-36B8-44B1-A3B1-018A0A44BBA1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.ActiveCfg = Debug|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.Build.0 = Debug|x64 + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x86.ActiveCfg = Debug|Any CPU + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x86.Build.0 = Debug|Any CPU {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.ActiveCfg = Release|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.Build.0 = Release|x64 + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x86.ActiveCfg = Release|Any CPU + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x86.Build.0 = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.ActiveCfg = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.Build.0 = Debug|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x86.ActiveCfg = Debug|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x86.Build.0 = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.ActiveCfg = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.Build.0 = Release|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x86.ActiveCfg = Release|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x86.Build.0 = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|x64 + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x86.Build.0 = Debug|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x86.ActiveCfg = Release|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x86.Build.0 = Release|Any CPU + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x64.ActiveCfg = Debug|x64 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x64.Build.0 = Debug|x64 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x86.ActiveCfg = Debug|Win32 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x86.Build.0 = Debug|Win32 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x64.ActiveCfg = Release|x64 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x64.Build.0 = Release|x64 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x86.ActiveCfg = Release|Win32 + {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 8b0cc779793abe23d510941567fc02a3118decc4 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 30 Jul 2018 19:39:28 +0900 Subject: [PATCH 096/167] feat(core): Ignore UWP invisible windows. --- Source/Robock.Shared/Robock.Shared.csproj | 1 + .../Robock.Shared/Win32/DWMWINDOWATTRIBUTE.cs | 25 +++++++++++++++++++ Source/Robock.Shared/Win32/NativeMethods.cs | 3 +++ Source/Robock/Models/WindowManager.cs | 6 +++++ 4 files changed, 35 insertions(+) create mode 100644 Source/Robock.Shared/Win32/DWMWINDOWATTRIBUTE.cs diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index b80898f..fbcefad 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -67,6 +67,7 @@ + diff --git a/Source/Robock.Shared/Win32/DWMWINDOWATTRIBUTE.cs b/Source/Robock.Shared/Win32/DWMWINDOWATTRIBUTE.cs new file mode 100644 index 0000000..d025f99 --- /dev/null +++ b/Source/Robock.Shared/Win32/DWMWINDOWATTRIBUTE.cs @@ -0,0 +1,25 @@ +// ReSharper disable FieldCanBeMadeReadOnly.Global +// ReSharper disable InconsistentNaming +// ReSharper disable MemberCanBePrivate.Global + +namespace Robock.Shared.Win32 +{ + public enum DWMWINDOWATTRIBUTE + { + NCRenderingEnabled = 1, + NCRenderingPolicy, + TransitionsForceDisabled, + AllowNCPaint, + CaptionButtonBounds, + NonClientRtlLayout, + ForceIconicRepresentation, + Flip3DPolicy, + ExtendedFrameBounds, + HasIconicBitmap, + DisallowPeek, + ExcludedFromPeek, + Cloak, + Cloaked, + FreezeRepresentation + } +} \ No newline at end of file diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index 4150aef..53fc0d7 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -58,6 +58,9 @@ public static class NativeMethods [DllImport("dwmapi.dll", PreserveSig = true)] public static extern int DwmUpdateThumbnailProperties(IntPtr hThumbnail, ref DWM_THUMBNAIL_PROPERTIES props); + [DllImport("dwmapi.dll")] + public static extern int DwmGetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE dwAttribute, out bool pvAttribute, int cbAttribute); + #endregion #region User32 diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs index 1dd7187..63a6bb1 100644 --- a/Source/Robock/Models/WindowManager.cs +++ b/Source/Robock/Models/WindowManager.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Linq; using System.Reactive.Linq; +using System.Runtime.InteropServices; using System.Text; using Robock.Shared.Win32; @@ -50,6 +51,11 @@ private void FindWindows() if (string.IsNullOrWhiteSpace(title.ToString())) return true; // Skipped + // Universal Windows (invisible / background) + NativeMethods.DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.Cloaked, out var isCloaked, Marshal.SizeOf(typeof(bool))); + if (isCloaked) + return true; + if (Ignores.IgnoreWindowTitles.Contains(title.ToString())) return true; windows.Add(new Window {Handle = hWnd, Title = title.ToString()}); From ff0a6f85d26b70a82a72bf0d93596c7063cf4cb4 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 31 Jul 2018 20:15:46 +0900 Subject: [PATCH 097/167] fix: Previewed previous window. --- Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index c2050c0..6f798fd 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -130,14 +130,14 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin PreviewAreaTop, PreviewAreaHeight, PreviewAreaWidth - }.CombineLatest().Subscribe(w => + }.CombineLatest().Where(w => IsSelected.Value).Subscribe(w => { // Render(1); }); desktopWindowManager.Thumbnails[0] .ObserveProperty(w => w.IsRendering) - .Where(w => w) + .Where(w => w && IsSelected.Value) .Subscribe(w => { // From 15b40a6801fe12c35b8b7f91e79782e8db04e7b1 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 31 Jul 2018 21:11:33 +0900 Subject: [PATCH 098/167] fix: Tab is virtualization --- Source/Robock/Behaviors/ControlPositionBindingBehavior.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs index a5c9ab5..6f668dc 100644 --- a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs +++ b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs @@ -51,10 +51,17 @@ protected override void OnAttached() if (Application.Current.MainWindow != null) Application.Current.MainWindow.SizeChanged += MainWindowOnSizeChanged; AssociatedObject.SizeChanged += AssociatedObjectSizeChanged; + AssociatedObject.DataContextChanged += AssociatedObjectOnDataContextChanged; + } + + private void AssociatedObjectOnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) + { + AssociatedObjectSizeChanged(null, null); } protected override void OnDetaching() { + AssociatedObject.DataContextChanged -= AssociatedObjectOnDataContextChanged; AssociatedObject.SizeChanged -= AssociatedObjectSizeChanged; if (Application.Current.MainWindow != null) Application.Current.MainWindow.SizeChanged -= MainWindowOnSizeChanged; From 3a46d7b77edd4180fd48f2733729ef797e038853 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 2 Aug 2018 00:07:01 +0900 Subject: [PATCH 099/167] fix: f**k virtualization --- .../Robock/Behaviors/ControlPositionBindingBehavior.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs index 6f668dc..e59c050 100644 --- a/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs +++ b/Source/Robock/Behaviors/ControlPositionBindingBehavior.cs @@ -1,4 +1,6 @@ -using System.Windows; +using System; +using System.Reactive.Linq; +using System.Windows; using System.Windows.Interactivity; using System.Windows.Media; @@ -56,7 +58,10 @@ protected override void OnAttached() private void AssociatedObjectOnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { - AssociatedObjectSizeChanged(null, null); + // XXX: DataContext が変わったら強制的に変更を通知する + // なんとかしたい気持ち + Height = Width = Left = Top = -1; + Observable.Return(0).Delay(TimeSpan.FromMilliseconds(1)).Subscribe(w => { Dispatcher.Invoke(() => { AssociatedObjectSizeChanged(null, null); }); }); } protected override void OnDetaching() From d1690ef377e7ee23dd2ad4ea746df2f6599aac19 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 2 Aug 2018 00:41:48 +0900 Subject: [PATCH 100/167] fix: Fix some bugs. --- Source/Robock/Models/IgnoreComparator.cs | 20 --------- Source/Robock/Robock.csproj | 1 - .../ViewModels/Tabs/DesktopViewModel.cs | 43 +++++++++++-------- 3 files changed, 24 insertions(+), 40 deletions(-) delete mode 100644 Source/Robock/Models/IgnoreComparator.cs diff --git a/Source/Robock/Models/IgnoreComparator.cs b/Source/Robock/Models/IgnoreComparator.cs deleted file mode 100644 index 42a9798..0000000 --- a/Source/Robock/Models/IgnoreComparator.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Robock.Models -{ - internal class IgnoreComparator : IEqualityComparer - { - public bool Equals(int x, int y) - { - if (x != 0 && y == 0) - return true; // なぜか新しい値に0が降ってきて、それを通知すると死ぬ - return x == y; - } - - public int GetHashCode(int obj) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 56dfc10..7c803be 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -146,7 +146,6 @@ - diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 6f798fd..71b5edd 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -75,7 +75,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin IsSelected = new ReactiveProperty(false); IsSelected.Subscribe(w => { - if (w) + if (w && CanRender()) { Render(0); } @@ -98,7 +98,8 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin EditorAreaTop, EditorAreaHeight, EditorAreaWidth - }.CombineLatest().Where(w => IsSelected.Value).Subscribe(w => Render(0)).AddTo(this); + }.CombineLatest().Throttle(TimeSpan.FromMilliseconds(50)) + .Where(w => CanRender()).Subscribe(w => Render(0)).AddTo(this); desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.Size).Subscribe(w => { // @@ -116,28 +117,30 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedAreaTop, SelectedAreaHeight, SelectedAreaWidth - }.CombineLatest().Where(w => IsSelected.Value).Subscribe(w => Render(1)).AddTo(this); + }.CombineLatest().Throttle(TimeSpan.FromMilliseconds(50)) + .Where(w => CanRender()).Subscribe(w => Render(1)).AddTo(this); // プレビュー AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; - PreviewAreaLeft = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); - PreviewAreaTop = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); - PreviewAreaHeight = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); - PreviewAreaWidth = new ReactiveProperty(1, equalityComparer: new IgnoreComparator()); + PreviewAreaLeft = new ReactiveProperty(); + PreviewAreaTop = new ReactiveProperty(); + PreviewAreaHeight = new ReactiveProperty(); + PreviewAreaWidth = new ReactiveProperty(); new[] { PreviewAreaLeft, PreviewAreaTop, PreviewAreaHeight, PreviewAreaWidth - }.CombineLatest().Where(w => IsSelected.Value).Subscribe(w => - { - // - Render(1); - }); + }.CombineLatest().Throttle(TimeSpan.FromMilliseconds(50)) + .Where(w => CanRender()).Subscribe(w => + { + // + Render(1); + }); desktopWindowManager.Thumbnails[0] .ObserveProperty(w => w.IsRendering) - .Where(w => w && IsSelected.Value) + .Where(w => w && CanRender()) .Subscribe(w => { // @@ -151,7 +154,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin // 他 Windows = windowManager.Windows.ToReadOnlyReactiveCollection(w => new WindowViewModel(w)); SelectedWindow = new ReactiveProperty(); - SelectedWindow.Where(w => w != null && IsSelected.Value).Subscribe(w => + SelectedWindow.Where(w => w != null && CanRender()).Subscribe(w => { _desktopWindowManager.Stop(0); _desktopWindowManager.Stop(1); @@ -184,8 +187,6 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin private void Render(int index) { - if (SelectedWindow?.Value == null) - return; var handle = SelectedWindow.Value.Handle; if (index == 0) @@ -201,9 +202,6 @@ private void Render(int index) if (SelectedAreaHeight.Value != 0) rect = CalcRenderingRect(); - if (PreviewAreaHeight.Value == 0) - throw new InvalidOperationException("Fucking "); - if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) _desktopWindowManager.Rerender(1, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, rect); else @@ -211,6 +209,13 @@ private void Render(int index) } } + private bool CanRender() + { + if (!IsSelected.Value || SelectedWindow.Value == null) + return false; + return PreviewAreaHeight.Value != 0 && PreviewAreaWidth.Value != 0; + } + private RECT CalcRenderingRect() { // 描画サイズから、縮小された割合を計算 From 60b937e7f87e4f8d31ff3520858a4901008440c2 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 2 Aug 2018 08:34:28 +0900 Subject: [PATCH 101/167] feat(core): Save/Restore select area --- .../Behaviors/RectangleSelectorBehavior.cs | 84 +++++++++++++++++-- Source/Robock/Views/Tabs/DesktopTab.xaml | 10 +-- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/Source/Robock/Behaviors/RectangleSelectorBehavior.cs b/Source/Robock/Behaviors/RectangleSelectorBehavior.cs index 1bc2c21..2898ea2 100644 --- a/Source/Robock/Behaviors/RectangleSelectorBehavior.cs +++ b/Source/Robock/Behaviors/RectangleSelectorBehavior.cs @@ -1,4 +1,7 @@ -using System.Windows; +using System; +using System.Reactive.Linq; +using System.Reactive.Subjects; +using System.Windows; using System.Windows.Input; using System.Windows.Interactivity; using System.Windows.Shapes; @@ -8,24 +11,27 @@ namespace Robock.Behaviors public class RectangleSelectorBehavior : Behavior { public static readonly DependencyProperty LeftProperty = - DependencyProperty.Register(nameof(Left), typeof(int), typeof(RectangleSelectorBehavior)); + DependencyProperty.Register(nameof(Left), typeof(int), typeof(RectangleSelectorBehavior), new FrameworkPropertyMetadata(LeftPropertyChanged)); public static readonly DependencyProperty TopProperty = - DependencyProperty.Register(nameof(Top), typeof(int), typeof(RectangleSelectorBehavior)); + DependencyProperty.Register(nameof(Top), typeof(int), typeof(RectangleSelectorBehavior), new FrameworkPropertyMetadata(TopPropertyChanged)); public static readonly DependencyProperty HeightProperty = - DependencyProperty.Register(nameof(Height), typeof(int), typeof(RectangleSelectorBehavior)); + DependencyProperty.Register(nameof(Height), typeof(int), typeof(RectangleSelectorBehavior), new FrameworkPropertyMetadata(HeightPropertyChanged)); public static readonly DependencyProperty WidthProperty = - DependencyProperty.Register(nameof(Width), typeof(int), typeof(RectangleSelectorBehavior)); + DependencyProperty.Register(nameof(Width), typeof(int), typeof(RectangleSelectorBehavior), new FrameworkPropertyMetadata(WidthPropertyChanged)); public static readonly DependencyProperty RectangleProperty = DependencyProperty.Register(nameof(Rectangle), typeof(Rectangle), typeof(RectangleSelectorBehavior)); + private IDisposable _disposable; + private double _fromPosX; private double _fromPosY; private bool _isSelecting; + private Subject _subject; public int Left { @@ -57,14 +63,72 @@ public Rectangle Rectangle set => SetValue(RectangleProperty, value); } + private static void LeftPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (!(d is RectangleSelectorBehavior behavior)) + return; + behavior._subject.OnNext((int) e.NewValue); + } + + private static void TopPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (!(d is RectangleSelectorBehavior behavior)) + return; + behavior._subject.OnNext((int) e.NewValue); + } + + private static void HeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (!(d is RectangleSelectorBehavior behavior)) + return; + behavior.Rectangle.Height = (int) e.NewValue; + behavior.UpdateRenderStatus(); + } + + private static void WidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (!(d is RectangleSelectorBehavior behavior)) + return; + behavior.Rectangle.Width = (int) e.NewValue; + behavior.UpdateRenderStatus(); + } + protected override void OnAttached() { base.OnAttached(); + _subject = new Subject(); + _disposable = _subject.Throttle(TimeSpan.FromMilliseconds(100)).Subscribe(_ => + { + Dispatcher.Invoke(() => + { + Rectangle.Margin = new Thickness(Left, Top, 0, 0); + UpdateRenderStatus(); + }); + }); + AssociatedObject.DataContextChanged += AssociatedObjectOnDataContextChanged; AssociatedObject.MouseLeftButtonDown += AssociatedObjectOnMouseLeftButtonDown; AssociatedObject.MouseLeftButtonUp += AssociatedObjectOnMouseLeftButtonUp; AssociatedObject.MouseMove += AssociatedObjectOnMouseMove; } + protected override void OnDetaching() + { + AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove; + AssociatedObject.MouseLeftButtonUp -= AssociatedObjectOnMouseLeftButtonUp; + AssociatedObject.MouseLeftButtonDown -= AssociatedObjectOnMouseLeftButtonDown; + AssociatedObject.DataContextChanged -= AssociatedObjectOnDataContextChanged; + _subject.Dispose(); + _disposable.Dispose(); + base.OnDetaching(); + } + + private void AssociatedObjectOnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if (Rectangle == null) + return; + UpdateRenderStatus(); + } + private void AssociatedObjectOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { _isSelecting = true; @@ -118,5 +182,15 @@ private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs e) Rectangle.Height = _fromPosY - pos.Y; } } + + private bool IsSelected() + { + return Math.Abs(Rectangle.Width) > 0 && Math.Abs(Rectangle.Height) > 0; + } + + private void UpdateRenderStatus() + { + Rectangle.Visibility = IsSelected() ? Visibility.Visible : Visibility.Hidden; + } } } \ No newline at end of file diff --git a/Source/Robock/Views/Tabs/DesktopTab.xaml b/Source/Robock/Views/Tabs/DesktopTab.xaml index ea64137..b2d87ee 100644 --- a/Source/Robock/Views/Tabs/DesktopTab.xaml +++ b/Source/Robock/Views/Tabs/DesktopTab.xaml @@ -86,11 +86,11 @@ - + Top="{Binding SelectedAreaTop.Value, Mode=TwoWay}" /> + Visibility="{Binding IsSelected.Value, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}" /> From 305c142605b1ee219c3bbaac2cf10f32f0fe4bc4 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 2 Aug 2018 20:28:21 +0900 Subject: [PATCH 102/167] docs: Fix requirements. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 410c86e..5da2800 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,9 @@ ## Requirements -* Windows 7 SP1 以降 (64-bit) - * Windows 7 については DWM を有効にする必要があり - * Windows 8.1 以前についてはサポート、 Pull Request 共に受け付けていません +* Windows 10 10.0.17134.0 * .NET Framework 4.7.2 以降 -* Dirext3D 9.0Ex および HLSL 2.0 に対応したビデオカード +* DirectX 11 ~ * Windows Display Driver Model に対応したビデオカード * インターネット接続 * YouTube で 1080p 動画をフルスクリーンで見てもカクつかない程度のスペック From e3e902d817eb6c1e4987966e6a3d7f0707df35b3 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 3 Aug 2018 01:04:43 +0900 Subject: [PATCH 103/167] feat(background): Change lifecycle and params --- .../Models/BackgroundService.cs | 55 ++++++++++++------- .../Robock.Background.csproj | 4 -- Source/Robock.Shared/Win32/NativeMethods.cs | 13 +++++ 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 4e7593d..aaf3e41 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -6,7 +6,6 @@ using Microsoft.Wpf.Interop.DirectX; -using Robock.Background.Native; using Robock.Shared.Win32; // ReSharper disable LocalizableElement @@ -17,15 +16,20 @@ namespace Robock.Background.Models // 様々な理由から Singleton にせざるを得ない (RobockService への注入不可) public class BackgroundService { + private int _clientHeight; + private int _clientWidth; + private int _clientX; + private int _clientY; + private D3D11Image _dxImage; - private int _height; private IntPtr _hWnd; private TimeSpan _lastRender; - private DxRenderer _renderer; private IntPtr _srcWindowHandle; - private int _width; - private int _x; - private int _y; + + private int _windowHeight; + private int _windowWidth; + private int _windowX; + private int _windowY; private DGetDxSharedSurface GetDxSharedSurface { get; set; } public void Initialize(IntPtr hWnd, D3D11Image dxImage) @@ -49,13 +53,13 @@ public void MoveToOutsideOfVirtualScreen() public void SetupRenderer(int x, int y, int width, int height) { - _x = x; - _y = y; - _width = width; - _height = height; + _windowX = x; + _windowY = y; + _windowWidth = width; + _windowHeight = height; // Initialize DirectX devices. - _renderer = new DxRenderer(); + NativeMethods.Init(width, height); var funcPtr = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("user32"), "DwmGetDxSharedSurface"); GetDxSharedSurface = Marshal.GetDelegateForFunctionPointer(funcPtr); @@ -66,11 +70,15 @@ public void SetupRenderer(int x, int y, int width, int height) public void StartRender(IntPtr hWnd, int x, int y, int width, int height) { _srcWindowHandle = hWnd; + _clientX = x; + _clientY = y; + _clientWidth = width; + _clientHeight = height; // 1st, change DirectX rendering size and register composition event. _dxImage.Dispatcher.Invoke(() => { - _dxImage.SetPixelSize(_width, _height); + _dxImage.SetPixelSize(_windowWidth, _windowHeight); CompositionTarget.Rendering += CompositionTargetOnRendering; }); @@ -81,10 +89,10 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) var progman = NativeMethods.FindWindow("Progman", null); // 3rd, stick myself to progman - NativeMethods.SetParent(_hWnd, progman); + // NativeMethods.SetParent(_hWnd, progman); // 4th, move self to rendering position - NativeMethods.MoveWindow(_hWnd, _x, _y, _width, _height, true); + NativeMethods.MoveWindow(_hWnd, _windowX, _windowY, _windowWidth, _windowHeight, true); } private void CompositionTargetOnRendering(object sender, EventArgs e) @@ -102,27 +110,33 @@ private void Render(IntPtr hSurface, bool isNewSurface) if (_srcWindowHandle == IntPtr.Zero) return; + // 1st, Get DWM DirectX shared handle. GetDxSharedSurface(_srcWindowHandle, out var phSurface, out var pAdapterLuid, out var pFmtWindow, out var pPresentFlgs, out var pWin32KUpdateId); - _renderer.Render(hSurface, phSurface, _width, _height, isNewSurface); + + // 2nd, render window using shared handle + NativeMethods.Render(hSurface, phSurface, _clientX, _clientY, _clientWidth, _clientHeight, isNewSurface); } public void StopRender() { _srcWindowHandle = IntPtr.Zero; - // 1st, unregister composition rendering event. + // 1st, release DirectX resources. + NativeMethods.Release(); + + // 2nd, unregister composition rendering event. _dxImage.Dispatcher.Invoke(() => { CompositionTarget.Rendering -= CompositionTargetOnRendering; }); - // 2nd, set parent to desktop (nullptr) + // 3rd, set parent to desktop (nullptr) NativeMethods.SetParent(_hWnd, (IntPtr) null); - // 3rd, move self to outside of desktop + // 4th, move self to outside of desktop MoveToOutsideOfVirtualScreen(); } public void Release() { - _renderer?.Release(); + NativeMethods.Release(); _dxImage.Dispose(); } @@ -157,8 +171,7 @@ private IntPtr FindWorkerW() return workerW; } - private delegate bool DGetDxSharedSurface( - IntPtr hWnd, out IntPtr phSurface, out long pAdapterLuid, out int pFmtWindow, out int pPresentFlgs, out long pWin32KUpdateId); + private delegate bool DGetDxSharedSurface(IntPtr hWnd, out IntPtr phSurface, out long pAdapterLuid, out int pFmtWindow, out int pPresentFlgs, out long pWin32KUpdateId); #region Singleton diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 5395abb..d6e658c 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -163,10 +163,6 @@ - - {5c90987b-36b8-44b1-a3b1-018a0a44bba1} - Robock.Background.Native - {07becf0b-6e07-4ac5-b0c2-3eae0539d9a2} Robock.Shared diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index 53fc0d7..edbadf1 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -108,5 +108,18 @@ public static class NativeMethods public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags uFlags); #endregion + + #region Robock.Background.Native + + [DllImport("Robock.Background.Native.dll")] + public static extern void Init(int width, int height); + + [DllImport("Robock.Background.Native.dll")] + public static extern void Render(IntPtr hWindowSurface, IntPtr hDwmSurface, int x, int y, int width, int height, bool isNewSurface); + + [DllImport("Robock.Background.Native.dll")] + public static extern void Release(); + + #endregion } } \ No newline at end of file From 229b569386910c42597295ac7a7e4066b5d5e970 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 3 Aug 2018 01:09:18 +0900 Subject: [PATCH 104/167] feat(native): Rendering clear foreground. --- .../Robock.Background.Native/AssemblyInfo.cpp | 22 -- .../Robock.Background.Native/DxRenderer.cpp | 259 ++++++++++++++++++ Source/Robock.Background.Native/DxRenderer.h | 41 +++ Source/Robock.Background.Native/Resource.h | 3 - .../Robock.Background.Native.cpp | 9 - .../Robock.Background.Native.h | 18 -- .../Robock.Background.Native.vcxproj | 80 +++--- .../Robock.Background.Native.vcxproj.filters | 25 +- Source/Robock.Background.Native/app.ico | Bin 41395 -> 0 bytes Source/Robock.Background.Native/app.rc | Bin 2520 -> 0 bytes Source/Robock.Background.Native/dllmain.cpp | Bin 0 -> 1482 bytes Source/Robock.Background.Native/dllmain.h | 12 + Source/Robock.Background.Native/stdafx.cpp | Bin 20 -> 454 bytes Source/Robock.Background.Native/stdafx.h | Bin 139 -> 1390 bytes Source/Robock.Background.Native/targetver.h | Bin 0 -> 500 bytes Source/Robock.sln | 18 +- 16 files changed, 376 insertions(+), 111 deletions(-) delete mode 100644 Source/Robock.Background.Native/AssemblyInfo.cpp create mode 100644 Source/Robock.Background.Native/DxRenderer.cpp create mode 100644 Source/Robock.Background.Native/DxRenderer.h delete mode 100644 Source/Robock.Background.Native/Resource.h delete mode 100644 Source/Robock.Background.Native/Robock.Background.Native.cpp delete mode 100644 Source/Robock.Background.Native/Robock.Background.Native.h delete mode 100644 Source/Robock.Background.Native/app.ico delete mode 100644 Source/Robock.Background.Native/app.rc create mode 100644 Source/Robock.Background.Native/dllmain.cpp create mode 100644 Source/Robock.Background.Native/dllmain.h create mode 100644 Source/Robock.Background.Native/targetver.h diff --git a/Source/Robock.Background.Native/AssemblyInfo.cpp b/Source/Robock.Background.Native/AssemblyInfo.cpp deleted file mode 100644 index e04cca7..0000000 --- a/Source/Robock.Background.Native/AssemblyInfo.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "stdafx.h" - -using namespace System; -using namespace System::Reflection; -using namespace System::Runtime::CompilerServices; -using namespace System::Runtime::InteropServices; -using namespace System::Security::Permissions; - -[assembly:AssemblyTitleAttribute(L"Robock.Background.Native")]; -[assembly:AssemblyDescriptionAttribute(L"Robock Background Worker (Native DirectX)")]; -[assembly:AssemblyConfigurationAttribute(L"")]; -[assembly:AssemblyCompanyAttribute(L"")]; -[assembly:AssemblyProductAttribute(L"Robock.Background.Native")]; -[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2018 Mikazuki")]; -[assembly:AssemblyTrademarkAttribute(L"")]; -[assembly:AssemblyCultureAttribute(L"")]; - -[assembly:AssemblyVersionAttribute("1.0.*")]; - -[assembly:ComVisible(false)]; - -[assembly:CLSCompliantAttribute(true)]; diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp new file mode 100644 index 0000000..931ab76 --- /dev/null +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -0,0 +1,259 @@ +#include "stdafx.h" +#include "DxRenderer.h" + +using namespace DirectX; +using namespace PackedVector; + +DxRenderer::DxRenderer() +{ + this->_width = 0; + this->_height = 0; + this->_driverType = D3D_DRIVER_TYPE_NULL; + this->_featureLevel = D3D_FEATURE_LEVEL_11_0; + this->_device = nullptr; + this->_deviceContext = nullptr; + this->_renderTargetView = nullptr; + this->_vertexLayout = nullptr; + this->_vertexBuffer = nullptr; + this->_vertexShader = nullptr; + this->_pixelShader = nullptr; + this->_samplerState = nullptr; + this->_shaderResourceView = nullptr; +} + +HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int x, const int y, const int width, const int height, const bool isNewSurface) +{ + auto hr = S_OK; + + if (isNewSurface) + { + this->_deviceContext->OMSetRenderTargets(0, nullptr, nullptr); + hr = this->InitRenderTarget(phWindowSurface); + + if (FAILED(hr)) + { + MessageBoxW(nullptr, L"Failed to initialize a render target", L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); + return hr; + } + } + return hr; +} + +HRESULT DxRenderer::Release() +{ + this->_width = 0; + this->_height = 0; + this->_driverType = D3D_DRIVER_TYPE_NULL; + this->_featureLevel = D3D_FEATURE_LEVEL_11_0; + SAFE_RELEASE(this->_device); + SAFE_RELEASE(this->_deviceContext); + SAFE_RELEASE(this->_renderTargetView); + SAFE_RELEASE(this->_vertexLayout); + SAFE_RELEASE(this->_vertexBuffer); + SAFE_RELEASE(this->_vertexShader); + SAFE_RELEASE(this->_pixelShader); + SAFE_RELEASE(this->_samplerState); + SAFE_RELEASE(this->_shaderResourceView); + + return S_OK; +} + +HRESULT DxRenderer::Init() +{ + const auto hr = this->InitDevice(); + if (FAILED(hr)) + { + MessageBoxW(nullptr, L"Failed to create a new device", L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); + return hr; + } + + return hr; +} + +HRESULT DxRenderer::SetViewport(const int width, const int height) +{ + this->_width = width; + this->_height = height; + + return S_OK; +} + +HRESULT DxRenderer::InitDevice() +{ + auto hr = S_OK; + + const UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + + D3D_DRIVER_TYPE driverTypes[] = { + D3D_DRIVER_TYPE_HARDWARE, + D3D_DRIVER_TYPE_WARP, + D3D_DRIVER_TYPE_REFERENCE, + }; + + D3D_FEATURE_LEVEL featureLevels[] = { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + + for (UINT i = 0; i < 3; i++) + { + hr = D3D11CreateDevice(nullptr, driverTypes[i], nullptr, flags, featureLevels, 3, D3D11_SDK_VERSION, &this->_device, &this->_featureLevel, &this->_deviceContext); + if (SUCCEEDED(hr)) + { + this->_driverType = driverTypes[i]; + break; + } + } + + if (FAILED(hr)) + return hr; + + hr = this->LoadShader(); + if (FAILED(hr)) + { + MessageBoxW(nullptr, L"Failed to load a shader", L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); + return hr; + } + + SimpleVertex vertices[] = { + }; + + D3D11_BUFFER_DESC bufferDesc; + ZeroMemory(&bufferDesc, sizeof bufferDesc); + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.ByteWidth = sizeof(SimpleVertex) * 4; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + + D3D11_SUBRESOURCE_DATA initData; + ZeroMemory(&initData, sizeof initData); + initData.pSysMem = vertices; + + hr = this->_device->CreateBuffer(&bufferDesc, &initData, &this->_vertexBuffer); + if (FAILED(hr)) + return hr; + + UINT stride = sizeof(SimpleVertex); + UINT offset = 0; + this->_deviceContext->IASetVertexBuffers(0, 1, &this->_vertexBuffer, &stride, &offset); + + this->_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + D3D11_SAMPLER_DESC samplerDesc; + ZeroMemory(&samplerDesc, sizeof samplerDesc); + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + + this->_device->CreateSamplerState(&samplerDesc, &this->_samplerState); + + return hr; +} + +HRESULT DxRenderer::InitRenderTarget(void* pResource) +{ + auto pUnk = static_cast(pResource); + IDXGIResource* pDXGIResource; + auto hr = pUnk->QueryInterface(__uuidof(IDXGIResource), reinterpret_cast(&pDXGIResource)); + if (FAILED(hr)) + return hr; + + HANDLE sharedHandle; + hr = pDXGIResource->GetSharedHandle(&sharedHandle); + if (FAILED(hr)) + return hr; + + IUnknown* resource; + hr = this->_device->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), reinterpret_cast(&resource)); + if (FAILED(hr)) + return hr; + + ID3D11Texture2D* output; + hr = resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast(&output)); + if (FAILED(hr)) + return hr; + + resource->Release(); + + D3D11_RENDER_TARGET_VIEW_DESC renderTargetDesc; + renderTargetDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + renderTargetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + renderTargetDesc.Texture2D.MipSlice = 0; + + hr = this->_device->CreateRenderTargetView(output, &renderTargetDesc, &this->_renderTargetView); + if (FAILED(hr)) + return hr; + + D3D11_TEXTURE2D_DESC resourceDesc; + output->GetDesc(&resourceDesc); + if (resourceDesc.Width != this->_width || resourceDesc.Height != this->_height) + { + this->SetViewport(resourceDesc.Width, resourceDesc.Height); + + D3D11_VIEWPORT viewport; + viewport.Width = this->_width; + viewport.Height = this->_height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + this->_deviceContext->RSSetViewports(1, &viewport); + } + + this->_deviceContext->OMSetRenderTargets(1, &this->_renderTargetView, nullptr); + if (output != nullptr) + output->Release(); + + return hr; +} + +HRESULT DxRenderer::LoadShader() +{ + ID3DBlob* vsBlob = nullptr; + auto hr = this->CompileShaderFromFile(L"shader.hlsl", "VS", "vs_5_0", &vsBlob); + if (FAILED(hr)) + return hr; + + hr = this->_device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &this->_vertexShader); + if (FAILED(hr)) + { + vsBlob->Release(); + return hr; + } + + ID3DBlob* psBlob = nullptr; + hr = this->CompileShaderFromFile(L"shader.hlsl", "PS", "ps_5_0", &psBlob); + if (FAILED(hr)) + return hr; + + hr = this->_device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &this->_pixelShader); + psBlob->Release(); + if (FAILED(hr)) + return hr; + + D3D11_INPUT_ELEMENT_DESC layout[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + + hr = this->_device->CreateInputLayout(layout, 2, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &this->_vertexLayout); + vsBlob->Release(); + if (FAILED(hr)) + return hr; + + this->_deviceContext->IASetInputLayout(this->_vertexLayout); + return hr; +} + +HRESULT DxRenderer::CompileShaderFromFile(const LPCWSTR pFileName, const LPCSTR pEntrypoint, const LPCSTR pTarget, ID3D10Blob** ppCode) +{ + ID3D10Blob* pErrorBlob; + const auto hr = D3DCompileFromFile(pFileName, nullptr, nullptr, pEntrypoint, pTarget, 0, 0, ppCode, &pErrorBlob); + SAFE_RELEASE(pErrorBlob); + + return hr; +} \ No newline at end of file diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h new file mode 100644 index 0000000..b0dbcac --- /dev/null +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -0,0 +1,41 @@ +#pragma once +class DxRenderer +{ +public: + DxRenderer(); + HRESULT Render(void* phWindowSurface, void* phDwmSurface, int x, int y, int width, int height, bool isNewSurface); + HRESULT Release(); + + // internal + HRESULT Init(); + HRESULT SetViewport(int width, int height); + +private: + HRESULT InitDevice(); + HRESULT InitRenderTarget(void* pResource); + HRESULT LoadShader(); + + static HRESULT CompileShaderFromFile(LPCWSTR pFileName, LPCSTR pEntrypoint, LPCSTR pTarget, ID3D10Blob** ppCode); + + int _width; + int _height; + + D3D_DRIVER_TYPE _driverType{}; + D3D_FEATURE_LEVEL _featureLevel{}; + + ID3D11Device* _device{}; + ID3D11DeviceContext* _deviceContext{}; + ID3D11RenderTargetView* _renderTargetView{}; + ID3D11InputLayout* _vertexLayout{}; + ID3D11Buffer* _vertexBuffer{}; + ID3D11VertexShader* _vertexShader{}; + ID3D11PixelShader* _pixelShader{}; + ID3D11SamplerState* _samplerState{}; + ID3D11ShaderResourceView* _shaderResourceView{}; +}; + +struct SimpleVertex +{ + DirectX::XMFLOAT3 Pos; + DirectX::XMFLOAT2 UV; +}; diff --git a/Source/Robock.Background.Native/Resource.h b/Source/Robock.Background.Native/Resource.h deleted file mode 100644 index 16e656e..0000000 --- a/Source/Robock.Background.Native/Resource.h +++ /dev/null @@ -1,3 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ で生成されたインクルード ファイル。 -// 使用 app.rc diff --git a/Source/Robock.Background.Native/Robock.Background.Native.cpp b/Source/Robock.Background.Native/Robock.Background.Native.cpp deleted file mode 100644 index 8ef4dd7..0000000 --- a/Source/Robock.Background.Native/Robock.Background.Native.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "stdafx.h" - -#include "Robock.Background.Native.h" - -using namespace DirectX; -using namespace DirectX::PackedVector; - -using namespace Robock::Background::Native; - diff --git a/Source/Robock.Background.Native/Robock.Background.Native.h b/Source/Robock.Background.Native/Robock.Background.Native.h deleted file mode 100644 index 0ab3215..0000000 --- a/Source/Robock.Background.Native/Robock.Background.Native.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -using namespace System; - -namespace Robock -{ - namespace Background - { - namespace Native - { - public ref class DxRenderer - { - // TODO: このクラスのメソッドをここに追加します。 - public: - }; - } // namespace Native - } // namespace Background -} // namespace Robock diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index ac873c5..faf11ec 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -20,9 +20,8 @@ 15.0 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1} - v4.7.2 - ManagedCProj + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3} + Win32Proj RobockBackgroundNative 10.0.17134.0 @@ -31,28 +30,26 @@ DynamicLibrary true v141 - true Unicode DynamicLibrary false v141 - true + true Unicode DynamicLibrary true v141 - true Unicode DynamicLibrary false v141 - true + true Unicode @@ -75,6 +72,7 @@ true + ..\Robock\bin\x64\Debug true @@ -84,63 +82,83 @@ false + ..\Robock\bin\x64\Release + Use Level3 Disabled - _DEBUG;%(PreprocessorDefinitions) - Use + true + _DEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Windows + true d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies) + Use Level3 Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) - Use + true + WIN32;_DEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true - + Windows + true - Level3 - WIN32;NDEBUG;%(PreprocessorDefinitions) Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true - + Windows + true + true + true - Level3 - NDEBUG;%(PreprocessorDefinitions) Use + Level3 + MaxSpeed + true + true + true + NDEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true - + Windows + true + true + true + d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies) - - - - - - - - + + + - - + + Create Create @@ -148,12 +166,6 @@ Create - - - - - - diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters index 7312942..11378a9 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters @@ -15,35 +15,28 @@ - + ヘッダー ファイル - + ヘッダー ファイル - + + ヘッダー ファイル + + ヘッダー ファイル - + ソース ファイル - + ソース ファイル - + ソース ファイル - - - リソース ファイル - - - - - リソース ファイル - - \ No newline at end of file diff --git a/Source/Robock.Background.Native/app.ico b/Source/Robock.Background.Native/app.ico deleted file mode 100644 index 789d7ccbb56ed92f1bb005054ec7e67257ddc37e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41395 zcmeHQZA=_R7=DjCkZTKK8e`L%_DrfaQ35q-NU0yk2`Okwv@x+7+O*QNL}I~`Y8$Mc zweceoTVpWz1KLD?5Tj6HjAC->RZTH5(3+Y^qR}Q*QIUg61#Btj%&kM`7H)6nj+0&P zne4DLH}A~6^UO0d@9xgBL=JKjcMi&?At%w>EL>Qq#oKdt>C$N+(Rua|At$Lyk0H7#>diEi}F0wek;+HU7|b|XXU)xB+Bzp4Xf+HR-)G) zs@#~fX!#;mY)(aa>1JM9q{b|Es@mJmiXcbB=8Zn;=)3uM7IEz^*;GQ*b!7464yF^i z>&qW&Ajxqo~ z`o$M|S6|Ksp*!JynDLQBBox`-#bTKXNNLW6@ zgkx${f)e9J7HU zW>BoNwY0UbHnH&K*Qp-nz06Nvr^+meah=M<;eY@TNCN~S6LgB(nf&r-v~=^*=c0n&Ojh75tz+RnK5HVPvXohh+3)UAs(fW-b|Sp*ELAr(aAhg;CWNC zNg-csQaH8gOTI~A>mQ?;HLt$xf4z2e-!~6*cy1{Dt+(p06<@t|uzZicMMS~oQ0<3D z0x!1grj?D(wFOt)E;k)Ed9+Tg3NEWIIN#a3e!Td!+uXBZlaG*-5o1m2`SF#ewPVG* z`nqqrRCRT#YNfyP4BvY&bah{6bzfHSM$0IhOhc`lceYNT^Phg?sL%8lI?Ns?&V`*c zRdBocy$a9gPIeW|Bs$T^;GR!b6_sshE;@YY_gp~UPvB*7Kl6N3QpB;1NN_*^2mk>f zpdrBaQ2Eo`hgtjKfdM$cIKcK+E@&TbtfT$t|Aou}RsOSm)?qt)eP5#e#_0u9G5^8-Gva`rFPQ&e|Jj)XdOjO*ANC*YKRsXU%zfB@ z$=iQ=KG;33I{(?dy?Xu8el`17kDuM+=zsLT5eMwf?|AwfwVkKM%WwB|v>)T&hy!-# zcRc-#+K%yWJT~HChjicv4%m(ZY5o2e-U9>zKp=e)5dSYJ-Z^~{vUkhl^=tHZCp?kH z`q>9+;D7)SxP}0;>rdL;uu&S+@th^rgWXn^{AFF=V`xmP6 zLQm8mZTksaRPj`m7xe&t;4gDP@IsYOs`8>9xo#d7zpIv~Dlh6m{oudM0l^DZKB>x! zdgQug{)_ZfpHctp{7*IRqI}>VjlUj`bctK)VsIXmk>B_FKdTq@^7|D0wuFay@!ess zi$&(x%>|#u+@X3Fb@P0QtXIgd%~cBlKUMBUn?5AqRsh+Gt>a9)^4aj3_&%Y=|+=(c!3oH9iI{G|}Zd zpnSyklCl9?tsAq~VBc^gYi;zYlf^QYxJ%BqX-d1C?NIyD>ZW4rv$#UaYHMZM>IHV4 zY;R*9H5}pyMU=6JGaSIDw8;K0DmbO2#%~pQN-FHjit|B!B<~6195XY@N$`)ORPGI) zo0-)xni6lN_$c7GCBZi1ILiB)45!ZU` z8QfAbBK8gSdK`&Wnk^IC1~-<8W6PNfezo7V)iIpuTkB%6c-gkT7`9WdD&)v6O61Kp zzdkLlV+$GE%G-7JW<6zcU(AZnrJ{Ya(LSF!+h%<8v0SFTV_MyzAH_+|lE=%>XFNU8 zLwbF}3Zy6stT3uX{v-y!iBMO8Yi%_-D5t`qO!ng8z7=E6SBi!x2@t6mCeZvU{l#BYc=-jt_g;>}@B z9=ccO68v~O#3M|0bS_G@hAfExRRlzsDx9%3Q8)iQObc7z|3SX~b+|kxJ16rI-DM_p I6Z{p~AG16luK)l5 diff --git a/Source/Robock.Background.Native/dllmain.cpp b/Source/Robock.Background.Native/dllmain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9a211d0bb899fe9c652c676b727fe5aa3cc5220 GIT binary patch literal 1482 zcmb7EPfG$p9DQ^Q`VLcFG%Dv@6a*SYQjnEIhcN%-g09P|X-M@QI(Cc>b?nqv=o@tE z9CYm()tgzD-Pv{(8FXjI-=Ft;?~T7d8Dt<(L4&J_5-iwQMi~y5zzRQE-lb7-T(eF-)6 z*{jZzq{u8I_L*htT$ej{Oh$APzq;zM#acNOaL9QMh-8~}En-P=-WK-?m(Y0Cv&UV9 zCv`0HEiR%?JQmIw(Lq|zFwozE@oFi&VdMg9Jhge+<1=oy)sgv2SSR`_yB)Ews^Sp0 z%lA|St%+=W)qsgK{zrGHolD$;-A}QHong$CMjOX$ShEx^h*EL6zzPo8D)LS7(jw}D zu3e)W%A80s9gWU1su>d(r$|3htINb+Ceu0Ug)>gkqPvxE+St{qm@~yW!=m>ERf}_o z=aH_ykq)(Whu-pC@#N~F>g;&uK!OE#$aX!(}!yWdPi^K EAMSJX5dZ)H literal 0 HcmV?d00001 diff --git a/Source/Robock.Background.Native/dllmain.h b/Source/Robock.Background.Native/dllmain.h new file mode 100644 index 0000000..e8821a1 --- /dev/null +++ b/Source/Robock.Background.Native/dllmain.h @@ -0,0 +1,12 @@ +#pragma once + +#define DllExport __declspec( dllexport ) +#include "DxRenderer.h" + +DxRenderer* renderer; + +extern "C" { +DllExport HRESULT Init(int width, int height); +DllExport HRESULT Render(void* phWindowSurface, void* phDwmSurface, int x, int y, int width, int height, bool isNewSurface); +DllExport HRESULT Release(); +} diff --git a/Source/Robock.Background.Native/stdafx.cpp b/Source/Robock.Background.Native/stdafx.cpp index fd4f341c7b247a19f9f24bba29582643f79a0751..855b2000caf77420bbfc1f7da406756b91ed9da3 100644 GIT binary patch literal 454 zcmZvYJ4?f07=@3WMDPc=MID9qxVouPMAS+WX+@;1txZiNjaQsnI(h-2gR??+2mgR5 z9UL7*e}j&$-cABy6bWzm65j7Qm(Pz3GBB`%T~ts)6$eP8j8Kn(G0lK?7IgT^OTO@p zcQmkqLDaFQ8)5u5um}rT%wh_Ya8SSk#xbw2Rk1?RYT^WJvdw< zLdTBPEefLk0I5@W6e1AnDAnh^nRQ3o)r1({d%W-O&*$^z_pg5R!@&aT@KHdBC7i{y zECX7nW>?E)zTz8x;07J6@dsb>8@KsMw{z7?d)BA$UG}Nj$`U!y1W}N&3~P& z1{t3A#@NMC`n;^DWghi@h7)|kS-P@+=6Am43-$WQ?pvuwrw*;kD?GWp^)#ni9=mrs z8oya*P(@AXO1P`tK?P+L5m;a3pRtxXG{i!nh#v7#P)IrL@^*K1UX3k|BHMovLpfW|*My7G#K9N7=UeeT%Ex>(mTDM|LUCkx z+I)5-yF!2UgqOtK;-pipmU06zJA2U&3XQQf=P)ngQpZ?dsC}H%w||_gI9I$^q(W8o z=XO}_T-#M#O>sr3a8oQ6bWR`GCz*3yIYr!24Ih(nrAn-3)VKKpLW|gF>R?>TU6E#a zO+0M%yrDCS+^u{2$dnNF?os-_?lZP}(`ziInqi`@a|K74#^+k<@)q%uC5HFV@SjLlR6ePBAn@6>`ZeN=+__ n@J%eqz$y`tn4F!O5(ZS0Uj$Z=lA4y8m#P5O7w;DgV{!oiqFOGh diff --git a/Source/Robock.Background.Native/targetver.h b/Source/Robock.Background.Native/targetver.h new file mode 100644 index 0000000000000000000000000000000000000000..3dd3ac101968116cab2e1aee95f0bc9eef7bd23c GIT binary patch literal 500 zcmezWPnn^Bp@<=oA)O%?NGdSoGvqNOGo&)`GH`*hK7&3`G?>AK!5fG{WEfDkh(V7b z11LVpV2QzJgY^cl4gMIMG>A0lHpnnwG|&vvC`~u;1@aiun+&-8eEstb6d1x8GJ$5N z0BtB|CF?R|Xq_rfxTQ4s_ongUdh{LfmH(!4Z-VbR)zy5P#wJQ8-W~$Q`7Hf^SeZQ0G>I zyFfRbF!&dp*pmSc9dtiWGO((QH0UsJGsp&pP&_bk1{x1lNoXtN`ax93RG=_BfjjwF$w^Mbcjd* literal 0 HcmV?d00001 diff --git a/Source/Robock.sln b/Source/Robock.sln index c7ec6fe..905e4ca 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -18,7 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Robock.Background", "Robock.Background\Robock.Background.csproj", "{F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Robock.Background.Native", "Robock.Background.Native\Robock.Background.Native.vcxproj", "{5C90987B-36B8-44B1-A3B1-018A0A44BBA1}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Robock.Background.Native", "Robock.Background.Native\Robock.Background.Native.vcxproj", "{9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -52,14 +52,14 @@ Global {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x86.ActiveCfg = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x86.Build.0 = Release|Any CPU - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x64.ActiveCfg = Debug|x64 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x64.Build.0 = Debug|x64 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x86.ActiveCfg = Debug|Win32 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Debug|x86.Build.0 = Debug|Win32 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x64.ActiveCfg = Release|x64 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x64.Build.0 = Release|x64 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x86.ActiveCfg = Release|Win32 - {5C90987B-36B8-44B1-A3B1-018A0A44BBA1}.Release|x86.Build.0 = Release|Win32 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.ActiveCfg = Debug|x64 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.Build.0 = Debug|x64 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x86.ActiveCfg = Debug|Win32 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x86.Build.0 = Debug|Win32 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.ActiveCfg = Release|x64 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.Build.0 = Release|x64 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x86.ActiveCfg = Release|Win32 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 717ab8af2f62e7bfec856716c1db7aed34b09df4 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 3 Aug 2018 07:54:12 +0900 Subject: [PATCH 105/167] fix(background): Background --- Source/Robock.Background/Models/BackgroundService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index aaf3e41..4779f8b 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -89,7 +89,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) var progman = NativeMethods.FindWindow("Progman", null); // 3rd, stick myself to progman - // NativeMethods.SetParent(_hWnd, progman); + NativeMethods.SetParent(_hWnd, progman); // 4th, move self to rendering position NativeMethods.MoveWindow(_hWnd, _windowX, _windowY, _windowWidth, _windowHeight, true); From e303b56173cb47fa6e99e8c10e56747bbc321870 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 3 Aug 2018 07:54:38 +0900 Subject: [PATCH 106/167] fix(native): Flush --- Source/Robock.Background.Native/DxRenderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 931ab76..30f7333 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -36,6 +36,8 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int return hr; } } + if (this->_deviceContext != nullptr) + this->_deviceContext->Flush(); return hr; } From 8f55e1dbd36b8547d137c152fc85b5432084e387 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 3 Aug 2018 07:55:35 +0900 Subject: [PATCH 107/167] fix(native): hmm.... --- Source/Robock.Background.Native/DxRenderer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 30f7333..33394a1 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -36,6 +36,9 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int return hr; } } + + const float clearColor[4] = {1, 0, 1, 1}; // RGBA + this->_deviceContext->ClearRenderTargetView(this->_renderTargetView, clearColor); if (this->_deviceContext != nullptr) this->_deviceContext->Flush(); return hr; From 9a35fd3a590c540ca583f539452a255350c00e40 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 01:48:13 +0900 Subject: [PATCH 108/167] fix(native/background): Remove params --- Source/Robock.Background.Native/dllmain.cpp | Bin 1482 -> 1330 bytes Source/Robock.Background.Native/dllmain.h | 2 +- .../Models/BackgroundService.cs | 2 +- Source/Robock.Shared/Win32/NativeMethods.cs | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Robock.Background.Native/dllmain.cpp b/Source/Robock.Background.Native/dllmain.cpp index f9a211d0bb899fe9c652c676b727fe5aa3cc5220..9e21e0d9efff4a47875b0c29bd110ee62dc4abe6 100644 GIT binary patch delta 16 XcmX@by@_iB2jgTf#*EDzOox~OFH;2* delta 72 zcmdnQb&7if2jk=jCa1|9j2Xtk45v; SnF{2m1L+b5&CR}yPniL73=muZ diff --git a/Source/Robock.Background.Native/dllmain.h b/Source/Robock.Background.Native/dllmain.h index e8821a1..b7ae805 100644 --- a/Source/Robock.Background.Native/dllmain.h +++ b/Source/Robock.Background.Native/dllmain.h @@ -6,7 +6,7 @@ DxRenderer* renderer; extern "C" { -DllExport HRESULT Init(int width, int height); +DllExport HRESULT Init(); DllExport HRESULT Render(void* phWindowSurface, void* phDwmSurface, int x, int y, int width, int height, bool isNewSurface); DllExport HRESULT Release(); } diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 4779f8b..be69d3d 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -59,7 +59,7 @@ public void SetupRenderer(int x, int y, int width, int height) _windowHeight = height; // Initialize DirectX devices. - NativeMethods.Init(width, height); + NativeMethods.Init(); var funcPtr = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("user32"), "DwmGetDxSharedSurface"); GetDxSharedSurface = Marshal.GetDelegateForFunctionPointer(funcPtr); diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index edbadf1..cd12ca2 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -112,7 +112,7 @@ public static class NativeMethods #region Robock.Background.Native [DllImport("Robock.Background.Native.dll")] - public static extern void Init(int width, int height); + public static extern void Init(); [DllImport("Robock.Background.Native.dll")] public static extern void Render(IntPtr hWindowSurface, IntPtr hDwmSurface, int x, int y, int width, int height, bool isNewSurface); From 818ea69b5ed283325684f45d6b32397efb82f949 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 01:50:51 +0900 Subject: [PATCH 109/167] fix(native): Change encoding --- Source/Robock.Background.Native/dllmain.cpp | Bin 1330 -> 684 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Source/Robock.Background.Native/dllmain.cpp b/Source/Robock.Background.Native/dllmain.cpp index 9e21e0d9efff4a47875b0c29bd110ee62dc4abe6..84f0cbeead2800d9800f2dd6b2cd2f6eb2631e71 100644 GIT binary patch literal 684 zcmZXR%}T>S6ovPBifi4p(x1J>f{=>EpwKEVOH8I_Af1F{Vk#n-$;P#tqTogZe-;IC z;YRv07x6Vrn@p3`tmdAZd*^&}S}ibbd#qE|G+Y<9LDe)s@r3ad<98Gv7=NSq!uSQ_ zPmE?LUKfY>Ht7P!k0_qATHO829)9O<7)>#nV|0%{vnY!Ni;fwYL1ui1-9*SueJnB*_RmI;ofdfE0M{uMkho12jf~rjKq9mIWsEl rl{~GzlTCD=tU@R`-B@#)=2XmT;VN5@x-K>sL8hQ-FNvqXnnm^pm1gm} literal 1330 zcma)5O-sW-6dXJX{)bgBRn+cTQ4m^DEDC;5#DmndwShJ*X=*D){SO{JiU&P<@-O%g zJb4zpdKGnc)6gW{wX!5xHuL7aH?!~OJBus?%BXWSP=X5&OK{NQ5?JPwLxD@+PQJ?*@1x$@Y@A^SOCC0pcmSxW|Ux`Mub3;t0{WsBz( zSmmk5(=NZJ%2xi2U&LA><0v|yMm{qL)_8(lY$L>6YF<+Zacwdv|It^)4xP! Date: Sat, 4 Aug 2018 03:52:11 +0900 Subject: [PATCH 110/167] chore(native): Rendering capture window --- .../Robock.Background.Native/DxRenderer.cpp | 194 ++++++++++-------- Source/Robock.Background.Native/DxRenderer.h | 5 +- Source/Robock.Background.Native/dllmain.cpp | 3 +- 3 files changed, 112 insertions(+), 90 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 33394a1..9813e21 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -17,6 +17,7 @@ DxRenderer::DxRenderer() this->_vertexBuffer = nullptr; this->_vertexShader = nullptr; this->_pixelShader = nullptr; + this->_indexBuffer = nullptr; this->_samplerState = nullptr; this->_shaderResourceView = nullptr; } @@ -31,14 +32,44 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int hr = this->InitRenderTarget(phWindowSurface); if (FAILED(hr)) - { - MessageBoxW(nullptr, L"Failed to initialize a render target", L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); - return hr; - } + return this->MsgBox(hr, L"Render#InitRenderTarget"); } - const float clearColor[4] = {1, 0, 1, 1}; // RGBA + if (this->_shaderResourceView == nullptr) + { + IUnknown* resource; + hr = this->_device->OpenSharedResource(phDwmSurface, __uuidof(ID3D11Resource), reinterpret_cast(&resource)); + if (FAILED(hr)) + return this->MsgBox(hr, L"Render#OpenSharedResource"); + + ID3D11Texture2D* texture2D; + D3D11_TEXTURE2D_DESC textureDesc; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = resource; + hr = this->_device->CreateTexture2D(&textureDesc, &initData, &texture2D); + if (FAILED(hr)) + return this->MsgBox(hr, L"Render#CreateTexture2D"); + + hr = this->_device->CreateShaderResourceView(texture2D, nullptr, &this->_shaderResourceView); + if (FAILED(hr)) + return this->MsgBox(hr, L"Render#CreateShaderResourceView"); + } + + const float clearColor[4] = {0, 0, 0, 1}; // RGBA this->_deviceContext->ClearRenderTargetView(this->_renderTargetView, clearColor); + + this->_deviceContext->VSSetShader(this->_vertexShader, nullptr, 0); + this->_deviceContext->PSSetShader(this->_pixelShader, nullptr, 0); + + this->_deviceContext->PSSetSamplers(0, 1, &this->_samplerState); + this->_deviceContext->PSSetShaderResources(0, 1, &this->_shaderResourceView); + + this->_deviceContext->Draw(4, 0); + if (this->_deviceContext != nullptr) this->_deviceContext->Flush(); return hr; @@ -57,6 +88,7 @@ HRESULT DxRenderer::Release() SAFE_RELEASE(this->_vertexBuffer); SAFE_RELEASE(this->_vertexShader); SAFE_RELEASE(this->_pixelShader); + SAFE_RELEASE(this->_indexBuffer); SAFE_RELEASE(this->_samplerState); SAFE_RELEASE(this->_shaderResourceView); @@ -65,22 +97,7 @@ HRESULT DxRenderer::Release() HRESULT DxRenderer::Init() { - const auto hr = this->InitDevice(); - if (FAILED(hr)) - { - MessageBoxW(nullptr, L"Failed to create a new device", L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); - return hr; - } - - return hr; -} - -HRESULT DxRenderer::SetViewport(const int width, const int height) -{ - this->_width = width; - this->_height = height; - - return S_OK; + return this->InitDevice(); } HRESULT DxRenderer::InitDevice() @@ -100,60 +117,23 @@ HRESULT DxRenderer::InitDevice() D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; + const UINT drivers = sizeof featureLevels / sizeof featureLevels[0]; for (UINT i = 0; i < 3; i++) { - hr = D3D11CreateDevice(nullptr, driverTypes[i], nullptr, flags, featureLevels, 3, D3D11_SDK_VERSION, &this->_device, &this->_featureLevel, &this->_deviceContext); + hr = D3D11CreateDevice(nullptr, driverTypes[i], nullptr, flags, featureLevels, drivers, D3D11_SDK_VERSION, &this->_device, &this->_featureLevel, &this->_deviceContext); if (SUCCEEDED(hr)) { this->_driverType = driverTypes[i]; break; } } - if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"InitDevice#D3D11CreateDevice"); hr = this->LoadShader(); if (FAILED(hr)) - { - MessageBoxW(nullptr, L"Failed to load a shader", L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); - return hr; - } - - SimpleVertex vertices[] = { - }; - - D3D11_BUFFER_DESC bufferDesc; - ZeroMemory(&bufferDesc, sizeof bufferDesc); - bufferDesc.Usage = D3D11_USAGE_DEFAULT; - bufferDesc.ByteWidth = sizeof(SimpleVertex) * 4; - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufferDesc.CPUAccessFlags = 0; - bufferDesc.MiscFlags = 0; - - D3D11_SUBRESOURCE_DATA initData; - ZeroMemory(&initData, sizeof initData); - initData.pSysMem = vertices; - - hr = this->_device->CreateBuffer(&bufferDesc, &initData, &this->_vertexBuffer); - if (FAILED(hr)) - return hr; - - UINT stride = sizeof(SimpleVertex); - UINT offset = 0; - this->_deviceContext->IASetVertexBuffers(0, 1, &this->_vertexBuffer, &stride, &offset); - - this->_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - D3D11_SAMPLER_DESC samplerDesc; - ZeroMemory(&samplerDesc, sizeof samplerDesc); - samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - - this->_device->CreateSamplerState(&samplerDesc, &this->_samplerState); + return this->MsgBox(hr, L"InitDevice#LoadShader"); return hr; } @@ -164,22 +144,22 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) IDXGIResource* pDXGIResource; auto hr = pUnk->QueryInterface(__uuidof(IDXGIResource), reinterpret_cast(&pDXGIResource)); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"InitRenderTarget#QueryInterface"); HANDLE sharedHandle; hr = pDXGIResource->GetSharedHandle(&sharedHandle); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"InitRenderTarget#GetSharedHandle"); IUnknown* resource; hr = this->_device->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), reinterpret_cast(&resource)); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"InitRenderTarget#OpenSharedResource"); ID3D11Texture2D* output; hr = resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast(&output)); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"InitRenderTarget#QueryInterface"); resource->Release(); @@ -196,11 +176,11 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) output->GetDesc(&resourceDesc); if (resourceDesc.Width != this->_width || resourceDesc.Height != this->_height) { - this->SetViewport(resourceDesc.Width, resourceDesc.Height); - D3D11_VIEWPORT viewport; - viewport.Width = this->_width; - viewport.Height = this->_height; + this->_width = resourceDesc.Width; + this->_height = resourceDesc.Height; + viewport.Width = static_cast(this->_width); + viewport.Height = static_cast(this->_height); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0; @@ -217,41 +197,77 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) HRESULT DxRenderer::LoadShader() { - ID3DBlob* vsBlob = nullptr; + ID3DBlob* vsBlob; auto hr = this->CompileShaderFromFile(L"shader.hlsl", "VS", "vs_5_0", &vsBlob); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); hr = this->_device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &this->_vertexShader); if (FAILED(hr)) { - vsBlob->Release(); - return hr; + SAFE_RELEASE(vsBlob); + return this->MsgBox(hr, L"LoadShader#CreateVertexShader"); } - ID3DBlob* psBlob = nullptr; + D3D11_INPUT_ELEMENT_DESC layout[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + const UINT elements = sizeof layout / sizeof layout[0]; + + hr = this->_device->CreateInputLayout(layout, elements, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &this->_vertexLayout); + if (FAILED(hr)) + return this->MsgBox(hr, L"LoadShader#CreateInputLayout"); + + this->_deviceContext->IASetInputLayout(this->_vertexLayout); + + ID3DBlob* psBlob; hr = this->CompileShaderFromFile(L"shader.hlsl", "PS", "ps_5_0", &psBlob); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); hr = this->_device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &this->_pixelShader); - psBlob->Release(); + SAFE_RELEASE(vsBlob); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"LoadShader#CreatePixelShader"); - D3D11_INPUT_ELEMENT_DESC layout[] = + SimpleVertex vertices[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT2(0, 1)}, + {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0, 0)}, + {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(1, 1)}, + {XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(1, 0)} }; - hr = this->_device->CreateInputLayout(layout, 2, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &this->_vertexLayout); - vsBlob->Release(); + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.ByteWidth = sizeof(SimpleVertex) * 4; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = vertices; + + hr = this->_device->CreateBuffer(&bufferDesc, &InitData, &this->_vertexBuffer); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"LoadShader#CreateBuffer"); - this->_deviceContext->IASetInputLayout(this->_vertexLayout); - return hr; + const UINT stride = sizeof(SimpleVertex); + const UINT offset = 0; + this->_deviceContext->IASetVertexBuffers(0, 1, &this->_vertexBuffer, &stride, &offset); + + this->_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + D3D11_SAMPLER_DESC samplerDesc; + ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC)); + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + this->_device->CreateSamplerState(&samplerDesc, &this->_samplerState); + + return S_OK; } HRESULT DxRenderer::CompileShaderFromFile(const LPCWSTR pFileName, const LPCSTR pEntrypoint, const LPCSTR pTarget, ID3D10Blob** ppCode) @@ -260,5 +276,11 @@ HRESULT DxRenderer::CompileShaderFromFile(const LPCWSTR pFileName, const LPCSTR const auto hr = D3DCompileFromFile(pFileName, nullptr, nullptr, pEntrypoint, pTarget, 0, 0, ppCode, &pErrorBlob); SAFE_RELEASE(pErrorBlob); + return hr; +} + +HRESULT DxRenderer::MsgBox(const HRESULT hr, const LPCWSTR lpText) +{ + MessageBoxW(nullptr, lpText, L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); return hr; } \ No newline at end of file diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index b0dbcac..1deaca9 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -8,7 +8,6 @@ class DxRenderer // internal HRESULT Init(); - HRESULT SetViewport(int width, int height); private: HRESULT InitDevice(); @@ -16,6 +15,7 @@ class DxRenderer HRESULT LoadShader(); static HRESULT CompileShaderFromFile(LPCWSTR pFileName, LPCSTR pEntrypoint, LPCSTR pTarget, ID3D10Blob** ppCode); + static HRESULT MsgBox(HRESULT hr, LPCWSTR lpText); int _width; int _height; @@ -30,6 +30,7 @@ class DxRenderer ID3D11Buffer* _vertexBuffer{}; ID3D11VertexShader* _vertexShader{}; ID3D11PixelShader* _pixelShader{}; + ID3D11Buffer* _indexBuffer{}; ID3D11SamplerState* _samplerState{}; ID3D11ShaderResourceView* _shaderResourceView{}; }; @@ -37,5 +38,5 @@ class DxRenderer struct SimpleVertex { DirectX::XMFLOAT3 Pos; - DirectX::XMFLOAT2 UV; + DirectX::XMFLOAT2 Uv; }; diff --git a/Source/Robock.Background.Native/dllmain.cpp b/Source/Robock.Background.Native/dllmain.cpp index 84f0cbe..862d52d 100644 --- a/Source/Robock.Background.Native/dllmain.cpp +++ b/Source/Robock.Background.Native/dllmain.cpp @@ -1,4 +1,3 @@ -// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。 #include "stdafx.h" #include "DxRenderer.h" #include "dllmain.h" @@ -10,7 +9,7 @@ HRESULT Init() return S_OK; } -HRESULT Render(void *phWindowSurface, void *phDwmSurface, const int x, const int y, const int width, const int height, const bool isNewSurface) +HRESULT Render(void* phWindowSurface, void* phDwmSurface, const int x, const int y, const int width, const int height, const bool isNewSurface) { if (renderer == nullptr) return E_FAIL; From 3aad5da632cf62cb37c8d6e6ae02a42b1d75411f Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 04:26:43 +0900 Subject: [PATCH 111/167] fix(native): return S_OK --- Source/Robock.Background.Native/DxRenderer.cpp | 8 +++++--- Source/Robock.Background.Native/dllmain.cpp | Bin 589 -> 1584 bytes 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 9813e21..641c40d 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -46,6 +46,8 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int D3D11_TEXTURE2D_DESC textureDesc; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + textureDesc.Width = width; + textureDesc.Height = height; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; D3D11_SUBRESOURCE_DATA initData; @@ -72,7 +74,7 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int if (this->_deviceContext != nullptr) this->_deviceContext->Flush(); - return hr; + return S_OK; } HRESULT DxRenderer::Release() @@ -135,7 +137,7 @@ HRESULT DxRenderer::InitDevice() if (FAILED(hr)) return this->MsgBox(hr, L"InitDevice#LoadShader"); - return hr; + return S_OK; } HRESULT DxRenderer::InitRenderTarget(void* pResource) @@ -192,7 +194,7 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) if (output != nullptr) output->Release(); - return hr; + return S_OK; } HRESULT DxRenderer::LoadShader() diff --git a/Source/Robock.Background.Native/dllmain.cpp b/Source/Robock.Background.Native/dllmain.cpp index 862d52dc79fdf6d92b298ba3fd1cbaf9fff20470..c81de23bbbc39403981b84b0e15b10079b989360 100644 GIT binary patch literal 1584 zcma)+y>1gh6oro{k$8t8G!6nXH3%fYK}0x?lz^g$0-3dgSJ>-ly^hWQJ5W+03Mi>~ z1>S&)8i|$`0pHAcmEHBOf<`kQ&)j?Nx%Zx(zkfEgA)~%VjInx(mFS8h9WjiqGTZ7f zjNaRC_NV=9f7>tihy7&}`;ql4XGY)c2fu%7-#z^FX5YTH2lk9Tr?a}?5hKuNL>Yjy zrl~UaJsoO6tRW{&mTfF{@k+dJ$}T;{qnb&M?jqa;Yg2oAKtA_jvITAomzLH&gBN}^ z+_>SQ72_IR=QQDT&Tk#FYb*X4S*Q4{qFvUFQvBfi$|KZqEmonWV@+V*2lpa<8fxEH zxzFjG{9MdK>KnoJ5;j%qHdf;ry9ocpcgJ|V4Bv%EsJnUAcr*9hGI+V@b-qKG#d?B8 zwqo-b78CU1I84>`^)BaB*R7b04V|p(TIk!%Yy60a>9XH>r^|iMPq&FYW%S@V&@DJE zsB?=76_H$q9Ta@P{fzyX)#*D_(5Wj1VZ{0z6oUdMav4T?ijuqBIg4ZN)_f%#RM?VJ*Z$z`|&M#k!qE>=# j^NQ80uBmcmCe59zd$Ecf%AP0hP0p&^{k^4<@>=}^T?hem literal 589 zcmZXR(Q3jl6o&8f6lZ!2%Sw`c<%5M48)LKG%dfhL{?|8FiNWK)(dnow_N~)T)) Date: Sat, 4 Aug 2018 04:37:28 +0900 Subject: [PATCH 112/167] fix: Require rect --- Source/Robock.Background/Models/RobockServer.cs | 4 ++-- Source/Robock.Shared/Communication/IRobockDuplex.cs | 2 +- Source/Robock/Models/Desktop.cs | 2 +- Source/Robock/Models/RobockClient.cs | 2 +- Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 5 ++++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 3086e8e..d9dc8b0 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -36,9 +36,9 @@ public void Handshake(int x, int y, int height, int width) Callback.HandshakeCallback(); } - public void ApplyWallpaper(IntPtr src, RECT? rect) + public void ApplyWallpaper(IntPtr src, RECT rect) { - _backgroundService.StartRender(src, rect?.left ?? 0, rect?.top ?? 0, rect?.right - rect?.left ?? 0, rect?.bottom - rect?.top ?? 0); + _backgroundService.StartRender(src, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); Callback.ApplyWallpaperCallback(true); } diff --git a/Source/Robock.Shared/Communication/IRobockDuplex.cs b/Source/Robock.Shared/Communication/IRobockDuplex.cs index a8cc4fd..c3fbbd7 100644 --- a/Source/Robock.Shared/Communication/IRobockDuplex.cs +++ b/Source/Robock.Shared/Communication/IRobockDuplex.cs @@ -24,7 +24,7 @@ public interface IRobockDuplex /// hWnd of source window /// [OperationContract(IsOneWay = true)] - void ApplyWallpaper(IntPtr src, RECT? rect); + void ApplyWallpaper(IntPtr src, RECT rect); /// /// Discard wallpaper diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 5dc00f7..1ef5dc8 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -54,7 +54,7 @@ public void Handshake() _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width); } - public void ApplyWallpaper(IntPtr hWnd, RECT? rect) + public void ApplyWallpaper(IntPtr hWnd, RECT rect) { _client.ApplyWallpaper(hWnd, rect); } diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 7ea371e..922ceb8 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -43,7 +43,7 @@ public void Handshake(int x, int y, int height, int width) _channel.Handshake(x, y, height, width); } - public void ApplyWallpaper(IntPtr src, RECT? rect) + public void ApplyWallpaper(IntPtr src, RECT rect) { _channel.ApplyWallpaper(src, rect); } diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 71b5edd..e021cd6 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -170,7 +170,10 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin // タイミングどこが良いか問題 _desktop.Handshake(); - _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : (RECT?) null); + var rect = SelectedAreaHeight.Value != 0 + ? CalcRenderingRect() + : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; + _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); }).AddTo(this); DiscardWallpaperCommand = new[] { From 0a744939554dc105e06e4802c587235dca8d9f27 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 04:58:13 +0900 Subject: [PATCH 113/167] fix(core): BackgroundService life time --- Source/Robock/Models/Desktop.cs | 17 +++++++++++++---- Source/Robock/Models/RobockClient.cs | 24 ++++++++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 1ef5dc8..87d312a 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -13,8 +13,9 @@ namespace Robock.Models public class Desktop : IDisposable { private readonly RobockClient _client; - private readonly Process _process; private readonly Screen _screen; + private readonly string _uuid; + private Process _process; public int No { get; } public bool IsPrimary => _screen.Primary; @@ -27,9 +28,8 @@ public Desktop(Screen screen, int index) { _screen = screen; No = index; - var uuid = $"Background.Desktop{index}"; - _client = new RobockClient(uuid); - _process = Process.Start("Robock.Background.exe", $"{uuid}"); + _uuid = $"Background.Desktop{index}"; + _client = new RobockClient(_uuid); } public void Dispose() @@ -48,6 +48,11 @@ public void Dispose() public void Handshake() { + _process = Process.Start("Robock.Background.exe", $"{_uuid}"); + if (_process == null) + return; + _process.WaitForInputIdle(); + var offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; var offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; @@ -62,6 +67,10 @@ public void ApplyWallpaper(IntPtr hWnd, RECT rect) public void DiscardWallpaper() { _client.DiscardWallpaper(); + _client.Close(); + _process?.CloseMainWindow(); + _process?.WaitForExit(); + _process?.Dispose(); } } } \ No newline at end of file diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 922ceb8..796f659 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.ServiceModel; +using System.Threading.Tasks; using Robock.Shared.Communication; using Robock.Shared.Win32; @@ -9,15 +10,19 @@ namespace Robock.Models { public class RobockClient : IRobockDuplexCallback { - private readonly IRobockDuplex _channel; + private readonly string _uuid; + private IRobockDuplex _channel; + private bool _connecting; public RobockClient(string uuid) { - _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{uuid}").CreateChannel(); + _uuid = uuid; + _connecting = false; } public void HandshakeCallback() { + _connecting = true; Debug.WriteLine("Handshake ended"); } @@ -36,11 +41,21 @@ public void CloseCallback() // throw new NotImplementedException(); } - #region IRobockDuples + #region IRobockDuplex public void Handshake(int x, int y, int height, int width) { - _channel.Handshake(x, y, height, width); + while (!_connecting) + try + { + _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}").CreateChannel(); + _channel.Handshake(x, y, height, width); + _connecting = true; + } + catch + { + Task.Delay(TimeSpan.FromMilliseconds(100)).Wait(); + } } public void ApplyWallpaper(IntPtr src, RECT rect) @@ -58,6 +73,7 @@ public void Close() try { _channel.Close(); + _connecting = false; } catch { From 441bfb2e913df8343a79ba86b7bb0212f7ee80b7 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 16:39:34 +0900 Subject: [PATCH 114/167] feat(native): Show error message. --- Source/Robock.Background.Native/DxRenderer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 641c40d..8a3a282 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include "DxRenderer.h" +#include "comdef.h" +#include using namespace DirectX; using namespace PackedVector; @@ -283,6 +285,9 @@ HRESULT DxRenderer::CompileShaderFromFile(const LPCWSTR pFileName, const LPCSTR HRESULT DxRenderer::MsgBox(const HRESULT hr, const LPCWSTR lpText) { - MessageBoxW(nullptr, lpText, L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); + _com_error err(hr); + const std::wstring base(lpText); + const auto message = base + L"\r\nMessage: " + err.ErrorMessage(); + MessageBoxW(nullptr, message.c_str(), L"Robock.Native Internal Error", MB_OK | MB_ICONEXCLAMATION); return hr; } \ No newline at end of file From ecd797aa96c5568b174ac640eee4f8b455986614 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 16:39:51 +0900 Subject: [PATCH 115/167] feat(core): throw exception --- Source/Robock/Models/RobockClient.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 796f659..ae22714 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -60,11 +60,15 @@ public void Handshake(int x, int y, int height, int width) public void ApplyWallpaper(IntPtr src, RECT rect) { + if (_channel == null) + throw new InvalidOperationException("Invalid connection"); _channel.ApplyWallpaper(src, rect); } public void DiscardWallpaper() { + if (_channel == null) + throw new InvalidOperationException("Invalid connection"); _channel.DiscardWallpaper(); } From 5cbaec1823435e2fccd778f3831bfac1ddb417ad Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 18:02:41 +0900 Subject: [PATCH 116/167] feat(native): Rendering --- Source/Robock.Background.Native/DxRenderer.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 8a3a282..817d387 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -44,19 +44,10 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int if (FAILED(hr)) return this->MsgBox(hr, L"Render#OpenSharedResource"); - ID3D11Texture2D* texture2D; - D3D11_TEXTURE2D_DESC textureDesc; - textureDesc.Usage = D3D11_USAGE_DEFAULT; - textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - textureDesc.Width = width; - textureDesc.Height = height; - textureDesc.CPUAccessFlags = 0; - textureDesc.MiscFlags = 0; - D3D11_SUBRESOURCE_DATA initData; - initData.pSysMem = resource; - hr = this->_device->CreateTexture2D(&textureDesc, &initData, &texture2D); + ID3D11Texture2D* texture2D = nullptr; + hr = resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast(&texture2D)); if (FAILED(hr)) - return this->MsgBox(hr, L"Render#CreateTexture2D"); + return this->MsgBox(hr, L"Render#QueryInterface"); hr = this->_device->CreateShaderResourceView(texture2D, nullptr, &this->_shaderResourceView); if (FAILED(hr)) From c285fcc9dbe78a3d7372ab601aad3ffd3dd29901 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 18:09:51 +0900 Subject: [PATCH 117/167] feat(native): Maximize --- Source/Robock.Background.Native/DxRenderer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 817d387..8bd769b 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -229,10 +229,10 @@ HRESULT DxRenderer::LoadShader() SimpleVertex vertices[] = { - {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT2(0, 1)}, - {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT2(0, 0)}, - {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT2(1, 1)}, - {XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT2(1, 0)} + {XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0, 1)}, + {XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0, 0)}, + {XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1, 1)}, + {XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1, 0)} }; D3D11_BUFFER_DESC bufferDesc; From 2838a38c55b3e22f31721fb3bea09816743ef0e4 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 20:12:53 +0900 Subject: [PATCH 118/167] docs: Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5da2800..99be785 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Robock -ロボ子さんをデスクトップに住ませて無限に癒やされたかった +Window Capture + Dynamic Wallpaper = Good Experience ## Requirements @@ -17,6 +17,7 @@ * Robock * Robock.Background +* Robock.Background.Native * Robock.Shared From 7f704b0b359949c831bb44e4611e822ef7b7f824 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 20:40:22 +0900 Subject: [PATCH 119/167] docs: Update README.md --- README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 99be785..f8f8ce6 100644 --- a/README.md +++ b/README.md @@ -5,24 +5,21 @@ Window Capture + Dynamic Wallpaper = Good Experience ## Requirements -* Windows 10 10.0.17134.0 -* .NET Framework 4.7.2 以降 +* Windows 10 (1804 ~) +* .NET Framework 4.7.2 ~ * DirectX 11 ~ -* Windows Display Driver Model に対応したビデオカード -* インターネット接続 -* YouTube で 1080p 動画をフルスクリーンで見てもカクつかない程度のスペック +* Video Card that supports Windows Display Driver Model +* Internet Connection ## Components -* Robock -* Robock.Background -* Robock.Background.Native -* Robock.Shared +* Robock (C#) +* Robock.Background (C# + DirectX Host) +* Robock.Background.Native (C++) +* Robock.Shared (C#) ## Donation -* BTC : `1NFcYczriqTEzVgzfurTMJNbhxPY1vyki9` -* ETH : `0x3cd67f16c2d7fe518e924930f645dd73aadaaf39` -* MONA : `MC4x87u1ffmhsRhHof1sHz8UAtNtKCTQut` +https://mochizuki.moe/donation From fe6d56ca332e9a5ca2e7b18f5a7c7a95a3095be1 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 23:22:16 +0900 Subject: [PATCH 120/167] feat(core): Improve discard --- .../Robock.Background/Models/RobockServer.cs | 1 - .../Communication/IRobockDuplex.cs | 1 + Source/Robock/Models/Desktop.cs | 27 ++++++----- Source/Robock/Models/RobockClient.cs | 45 ++++++++++++++++--- .../ViewModels/Tabs/DesktopViewModel.cs | 13 +++--- 5 files changed, 63 insertions(+), 24 deletions(-) diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index d9dc8b0..0f5b64f 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -54,7 +54,6 @@ public void Close() { DiscardWallpaper(); Callback.CloseCallback(); - _serviceHost.Close(); } // diff --git a/Source/Robock.Shared/Communication/IRobockDuplex.cs b/Source/Robock.Shared/Communication/IRobockDuplex.cs index c3fbbd7..a517eff 100644 --- a/Source/Robock.Shared/Communication/IRobockDuplex.cs +++ b/Source/Robock.Shared/Communication/IRobockDuplex.cs @@ -35,6 +35,7 @@ public interface IRobockDuplex /// /// Close communication pipe /// + [OperationContract(IsOneWay = true)] void Close(); } } \ No newline at end of file diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 87d312a..a0989c1 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -36,9 +36,11 @@ public void Dispose() { try { - _client.Close(); - _process?.CloseMainWindow(); - _process?.Dispose(); + _client.Close(() => + { + _process?.CloseMainWindow(); + _process?.Dispose(); + }); } catch (Exception e) { @@ -46,7 +48,7 @@ public void Dispose() } } - public void Handshake() + public void Handshake(Action action = null) { _process = Process.Start("Robock.Background.exe", $"{_uuid}"); if (_process == null) @@ -56,7 +58,7 @@ public void Handshake() var offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; var offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; - _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width); + _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width, action); } public void ApplyWallpaper(IntPtr hWnd, RECT rect) @@ -66,11 +68,16 @@ public void ApplyWallpaper(IntPtr hWnd, RECT rect) public void DiscardWallpaper() { - _client.DiscardWallpaper(); - _client.Close(); - _process?.CloseMainWindow(); - _process?.WaitForExit(); - _process?.Dispose(); + // なんかつらい + _client.DiscardWallpaper(() => + { + _client.Close(() => + { + _process?.CloseMainWindow(); + _process?.WaitForExit(); + _process?.Dispose(); + }); + }); } } } \ No newline at end of file diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index ae22714..01e7796 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.ServiceModel; using System.Threading.Tasks; @@ -10,6 +11,7 @@ namespace Robock.Models { public class RobockClient : IRobockDuplexCallback { + private readonly Dictionary _callbacks; private readonly string _uuid; private IRobockDuplex _channel; private bool _connecting; @@ -18,37 +20,60 @@ public RobockClient(string uuid) { _uuid = uuid; _connecting = false; + _callbacks = new Dictionary(); } public void HandshakeCallback() { _connecting = true; Debug.WriteLine("Handshake ended"); + InvokeCallback(nameof(Handshake)); } public void ApplyWallpaperCallback(bool isSucceed) { Debug.WriteLine(isSucceed ? "Rendering Success" : "Rendering Failed"); + InvokeCallback(nameof(ApplyWallpaper)); } public void DiscardWallpaperCallback() { Debug.WriteLine("Discard finished."); + InvokeCallback(nameof(DiscardWallpaper)); } public void CloseCallback() { - // throw new NotImplementedException(); + InvokeCallback(nameof(Close)); + } + + private void InvokeCallback(string key) + { + if (!_callbacks.ContainsKey(key)) + return; + _callbacks[key]?.Invoke(); + _callbacks.Remove(key); + } + + private void RegisterCallback(string key, Action action) + { + if (action == null) + return; + + if (_callbacks.ContainsKey(key)) + _callbacks.Remove(key); + _callbacks.Add(key, action); } #region IRobockDuplex - public void Handshake(int x, int y, int height, int width) + public void Handshake(int x, int y, int height, int width, Action action = null) { while (!_connecting) try { _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}").CreateChannel(); + RegisterCallback(nameof(Handshake), action); _channel.Handshake(x, y, height, width); _connecting = true; } @@ -58,30 +83,36 @@ public void Handshake(int x, int y, int height, int width) } } - public void ApplyWallpaper(IntPtr src, RECT rect) + public void ApplyWallpaper(IntPtr src, RECT rect, Action action = null) { if (_channel == null) throw new InvalidOperationException("Invalid connection"); + RegisterCallback(nameof(ApplyWallpaper), action); _channel.ApplyWallpaper(src, rect); } - public void DiscardWallpaper() + public void DiscardWallpaper(Action action = null) { if (_channel == null) throw new InvalidOperationException("Invalid connection"); + RegisterCallback(nameof(DiscardWallpaper), action); _channel.DiscardWallpaper(); } - public void Close() + public void Close(Action action = null) { + if (_channel == null) + throw new InvalidOperationException("Invalid connection"); + try { + RegisterCallback(nameof(Close), action); _channel.Close(); _connecting = false; } - catch + catch (Exception e) { - // ignored + Debug.WriteLine(e.Message); } } diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index e021cd6..a4926dd 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -168,12 +168,13 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin ApplyWallpaperCommand.Subscribe(_ => { // タイミングどこが良いか問題 - _desktop.Handshake(); - - var rect = SelectedAreaHeight.Value != 0 - ? CalcRenderingRect() - : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; - _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); + _desktop.Handshake(() => + { + var rect = SelectedAreaHeight.Value != 0 + ? CalcRenderingRect() + : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; + _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); + }); }).AddTo(this); DiscardWallpaperCommand = new[] { From c6c8cd22cafcbf63dbb82e94d32df700301d85e1 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 4 Aug 2018 23:58:24 +0900 Subject: [PATCH 121/167] feat(core): Update status texts --- Source/Robock/Models/RobockClient.cs | 12 +++++++--- Source/Robock/Models/WindowManager.cs | 4 ++++ Source/Robock/Robock.csproj | 1 + Source/Robock/Services/StatusTextService.cs | 23 +++++++++++++++++++ Source/Robock/ViewModels/AppShellViewModel.cs | 5 ++++ Source/Robock/Views/AppShell.xaml | 2 +- 6 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 Source/Robock/Services/StatusTextService.cs diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 01e7796..2319364 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -4,6 +4,7 @@ using System.ServiceModel; using System.Threading.Tasks; +using Robock.Services; using Robock.Shared.Communication; using Robock.Shared.Win32; @@ -26,24 +27,25 @@ public RobockClient(string uuid) public void HandshakeCallback() { _connecting = true; - Debug.WriteLine("Handshake ended"); + StatusTextService.Instance.Status = "Handshake success, Connected to background process"; InvokeCallback(nameof(Handshake)); } public void ApplyWallpaperCallback(bool isSucceed) { - Debug.WriteLine(isSucceed ? "Rendering Success" : "Rendering Failed"); + StatusTextService.Instance.Status = isSucceed ? "Rendering success, Start rendering" : "Rendering failed"; InvokeCallback(nameof(ApplyWallpaper)); } public void DiscardWallpaperCallback() { - Debug.WriteLine("Discard finished."); + StatusTextService.Instance.Status = "Discard wallpaper finished"; InvokeCallback(nameof(DiscardWallpaper)); } public void CloseCallback() { + StatusTextService.Instance.Status = "Closed connection to background process"; InvokeCallback(nameof(Close)); } @@ -69,6 +71,7 @@ private void RegisterCallback(string key, Action action) public void Handshake(int x, int y, int height, int width, Action action = null) { + StatusTextService.Instance.Status = "Start handshaking between Robock and background process... It may take a little time"; while (!_connecting) try { @@ -87,6 +90,7 @@ public void ApplyWallpaper(IntPtr src, RECT rect, Action action = null) { if (_channel == null) throw new InvalidOperationException("Invalid connection"); + StatusTextService.Instance.Status = "Applying wallpeper..."; RegisterCallback(nameof(ApplyWallpaper), action); _channel.ApplyWallpaper(src, rect); } @@ -95,6 +99,7 @@ public void DiscardWallpaper(Action action = null) { if (_channel == null) throw new InvalidOperationException("Invalid connection"); + StatusTextService.Instance.Status = "Discarding wallpeper..."; RegisterCallback(nameof(DiscardWallpaper), action); _channel.DiscardWallpaper(); } @@ -106,6 +111,7 @@ public void Close(Action action = null) try { + StatusTextService.Instance.Status = "Closing connection to background process... It may take a little time"; RegisterCallback(nameof(Close), action); _channel.Close(); _connecting = false; diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs index 63a6bb1..9e09010 100644 --- a/Source/Robock/Models/WindowManager.cs +++ b/Source/Robock/Models/WindowManager.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using System.Text; +using Robock.Services; using Robock.Shared.Win32; namespace Robock.Models @@ -38,6 +39,7 @@ public void ForceUpdate() private void FindWindows() { var windows = new List(); + StatusTextService.Instance.Status = "Synchronizing visible windows..."; NativeMethods.EnumWindows((hWnd, lParam) => { @@ -83,6 +85,8 @@ private void FindWindows() // Remove killed windows. foreach (var window in Windows.ToArray().Where(w => !w.IsMarked)) Windows.Remove(window); + + StatusTextService.Instance.Status = "Synchronizied windows"; } } } \ No newline at end of file diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 7c803be..a30d269 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -153,6 +153,7 @@ + diff --git a/Source/Robock/Services/StatusTextService.cs b/Source/Robock/Services/StatusTextService.cs new file mode 100644 index 0000000..4b8e8df --- /dev/null +++ b/Source/Robock/Services/StatusTextService.cs @@ -0,0 +1,23 @@ +using Prism.Mvvm; + +namespace Robock.Services +{ + public class StatusTextService : BindableBase + { + private static StatusTextService _instance; + + private string _status; + public static StatusTextService Instance => _instance ?? (_instance = new StatusTextService()); + + public string Status + { + get => _status; + set => SetProperty(ref _status, value); + } + + private StatusTextService() + { + // + } + } +} \ No newline at end of file diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index 48f1003..c29a0f4 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Specialized; +using System.Reactive.Linq; using Reactive.Bindings; using Reactive.Bindings.Extensions; using Robock.Models; +using Robock.Services; using Robock.Shared.Extensions; using Robock.Shared.Models; using Robock.Shared.Mvvm; @@ -16,6 +18,7 @@ public class AppShellViewModel : ViewModel { private readonly DesktopWindowManager _desktopWindowManager; public ReactiveProperty Title { get; } + public ReactiveProperty Status { get; } public ReactiveCollection Tabs { get; } public VirtualScreenViewModel VirtualScreen { get; } @@ -26,6 +29,8 @@ public AppShellViewModel() _desktopWindowManager = new DesktopWindowManager().AddTo(this); Title = new ReactiveProperty("Robock"); + Status = StatusTextService.Instance.ObserveProperty(w => w.Status).ToReactiveProperty(); + Status.Throttle(TimeSpan.FromSeconds(10)).Subscribe(_ => StatusTextService.Instance.Status = "Ready").AddTo(this); Tabs = new ReactiveCollection { new AboutTabViewModel() diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index 5aee0c5..e52d98b 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -128,7 +128,7 @@ + Text="{Binding Status.Value, Mode=OneWay}" /> From efb85b85cced3ae2e605610ecfa6a6e8a0aacd58 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 5 Aug 2018 02:08:52 +0900 Subject: [PATCH 122/167] feat(core): Threading --- Source/Robock/Models/Desktop.cs | 21 +++++++++++++-- Source/Robock/ViewModels/AppShellViewModel.cs | 2 +- .../ViewModels/Tabs/DesktopViewModel.cs | 27 ++++++++++--------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index a0989c1..d8c7931 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -3,6 +3,9 @@ using System.Windows; using System.Windows.Forms; +using Prism.Mvvm; + +using Robock.Services; using Robock.Shared.Win32; namespace Robock.Models @@ -10,7 +13,7 @@ namespace Robock.Models /// /// Desktop is equals to Monitor, Monitor has a one Desktop. /// - public class Desktop : IDisposable + public class Desktop : BindableBase, IDisposable { private readonly RobockClient _client; private readonly Screen _screen; @@ -63,7 +66,7 @@ public void Handshake(Action action = null) public void ApplyWallpaper(IntPtr hWnd, RECT rect) { - _client.ApplyWallpaper(hWnd, rect); + _client.ApplyWallpaper(hWnd, rect, () => { IsConnecting = true; }); } public void DiscardWallpaper() @@ -73,11 +76,25 @@ public void DiscardWallpaper() { _client.Close(() => { + StatusTextService.Instance.Status = "Waiting for shutting down of background process..."; _process?.CloseMainWindow(); _process?.WaitForExit(); _process?.Dispose(); + IsConnecting = false; }); }); } + + #region IsConnecting + + private bool _isConnecting; + + public bool IsConnecting + { + get => _isConnecting; + set => SetProperty(ref _isConnecting, value); + } + + #endregion } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index c29a0f4..8a5e213 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -30,7 +30,7 @@ public AppShellViewModel() Title = new ReactiveProperty("Robock"); Status = StatusTextService.Instance.ObserveProperty(w => w.Status).ToReactiveProperty(); - Status.Throttle(TimeSpan.FromSeconds(10)).Subscribe(_ => StatusTextService.Instance.Status = "Ready").AddTo(this); + Status.Throttle(TimeSpan.FromSeconds(30)).Subscribe(_ => StatusTextService.Instance.Status = "Ready").AddTo(this); Tabs = new ReactiveCollection { new AboutTabViewModel() diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index a4926dd..eeea96d 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reactive.Linq; +using System.Threading.Tasks; using System.Windows; using Reactive.Bindings; @@ -163,28 +164,28 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin ApplyWallpaperCommand = new[] { SelectedWindow.Select(w => w != null), - _desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.IsRendering) + _desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.IsRendering), + desktop.ObserveProperty(w => w.IsConnecting).Select(w => !w) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); ApplyWallpaperCommand.Subscribe(_ => { - // タイミングどこが良いか問題 - _desktop.Handshake(() => + Task.Run(() => { - var rect = SelectedAreaHeight.Value != 0 - ? CalcRenderingRect() - : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; - _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); + _desktop.Handshake(() => + { + var rect = SelectedAreaHeight.Value != 0 + ? CalcRenderingRect() + : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; + _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); + }); }); }).AddTo(this); DiscardWallpaperCommand = new[] { - SelectedWindow.Select(w => w != null) + SelectedWindow.Select(w => w != null), + desktop.ObserveProperty(w => w.IsConnecting) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); - DiscardWallpaperCommand.Subscribe(_ => - { - // - _desktop.DiscardWallpaper(); - }).AddTo(this); + DiscardWallpaperCommand.Subscribe(_ => Task.Run(() => _desktop.DiscardWallpaper())).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); ReloadWindowsCommand.Subscribe(_ => windowManager.ForceUpdate()).AddTo(this); } From f030ec2e2649b49f7867afc06c1551c3c8397731 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 5 Aug 2018 14:56:07 +0900 Subject: [PATCH 123/167] refactor(shared): Remove unused class --- .../Robock.Shared/Refrection/RefrectionHelper.cs | 14 -------------- Source/Robock.Shared/Robock.Shared.csproj | 1 - 2 files changed, 15 deletions(-) delete mode 100644 Source/Robock.Shared/Refrection/RefrectionHelper.cs diff --git a/Source/Robock.Shared/Refrection/RefrectionHelper.cs b/Source/Robock.Shared/Refrection/RefrectionHelper.cs deleted file mode 100644 index c4e0ce4..0000000 --- a/Source/Robock.Shared/Refrection/RefrectionHelper.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Reflection; - -namespace Robock.Shared.Refrection -{ - public static class RefrectionHelper - { - public static T GetPrivateField(this object instance, string fieldName) - { - var type = instance.GetType(); - var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField); - return (T) field?.GetValue(instance); - } - } -} \ No newline at end of file diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index fbcefad..b84dd94 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -65,7 +65,6 @@ - From 260df58fd9d72d56ddc2f05d349f555f7361c14a Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 6 Aug 2018 19:49:14 +0900 Subject: [PATCH 124/167] refactor(core): Unused variables --- Source/Robock.Background/Models/BackgroundService.cs | 2 +- Source/Robock.Shared/Models/DesktopWindowManager.cs | 9 +-------- Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index be69d3d..ce872d2 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -111,7 +111,7 @@ private void Render(IntPtr hSurface, bool isNewSurface) return; // 1st, Get DWM DirectX shared handle. - GetDxSharedSurface(_srcWindowHandle, out var phSurface, out var pAdapterLuid, out var pFmtWindow, out var pPresentFlgs, out var pWin32KUpdateId); + GetDxSharedSurface(_srcWindowHandle, out var phSurface, out _, out _, out _, out _); // 2nd, render window using shared handle NativeMethods.Render(hSurface, phSurface, _clientX, _clientY, _clientWidth, _clientHeight, isNewSurface); diff --git a/Source/Robock.Shared/Models/DesktopWindowManager.cs b/Source/Robock.Shared/Models/DesktopWindowManager.cs index 19ec1dc..64af08a 100644 --- a/Source/Robock.Shared/Models/DesktopWindowManager.cs +++ b/Source/Robock.Shared/Models/DesktopWindowManager.cs @@ -86,7 +86,7 @@ private void Render(int index, int left, int top, int height, int width, RECT? r { fVisible = true, dwFlags = (int) (DWM_TNP.DWM_TNP_VISIBLE | DWM_TNP.DWM_TNP_OPACITY | DWM_TNP.DWM_TNP_RECTDESTINATION | DWM_TNP.DWM_TNP_SOURCECLIENTAREAONLY), - opacity = (byte) (255 / (index == EditorIndex ? 2 : 1)), + opacity = (byte) (255 / (index == 0 ? 2 : 1)), rcDestination = new RECT {left = left, top = top, right = left + width, bottom = top + height}, fSourceClientAreaOnly = true }; @@ -99,12 +99,5 @@ private void Render(int index, int left, int top, int height, int width, RECT? r NativeMethods.DwmUpdateThumbnailProperties(Thumbnails[index].Handle, ref props); } - - #region Constants - - public const int EditorIndex = 0; - public const int PreviewIndex = 1; - - #endregion } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index eeea96d..b90cee0 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -207,7 +207,7 @@ private void Render(int index) if (SelectedAreaHeight.Value != 0) rect = CalcRenderingRect(); - if (_desktopWindowManager.Thumbnails[DesktopWindowManager.PreviewIndex].IsRendering) + if (_desktopWindowManager.Thumbnails[1].IsRendering) _desktopWindowManager.Rerender(1, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, rect); else _desktopWindowManager.Start(1, handle, PreviewAreaLeft.Value, PreviewAreaTop.Value, PreviewAreaHeight.Value, PreviewAreaWidth.Value, rect); From ac3ac0390e44f947f00f7fde5b0486b0322a813e Mon Sep 17 00:00:00 2001 From: mika-f Date: Tue, 7 Aug 2018 09:27:46 +0900 Subject: [PATCH 125/167] docs(readme): Add licesne badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f8f8ce6..587167f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Robock +[![License](https://img.shields.io/github/license/mika-f/robock.svg?style=flat-square)](./blob/develop/LICENSE) + Window Capture + Dynamic Wallpaper = Good Experience From d1d0c048dc394c2c42927211580da02f7fe805ff Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 7 Aug 2018 22:55:24 +0900 Subject: [PATCH 126/167] chore(build): Drop x86 build --- Source/Robock.sln | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Source/Robock.sln b/Source/Robock.sln index 905e4ca..7ffbe56 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -23,43 +23,25 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.ActiveCfg = Debug|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.Build.0 = Debug|x64 - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x86.ActiveCfg = Debug|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x86.Build.0 = Debug|Any CPU {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.ActiveCfg = Release|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.Build.0 = Release|x64 - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x86.ActiveCfg = Release|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x86.Build.0 = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.ActiveCfg = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.Build.0 = Debug|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x86.ActiveCfg = Debug|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x86.Build.0 = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.ActiveCfg = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.Build.0 = Release|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x86.ActiveCfg = Release|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x86.Build.0 = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|x64 - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x86.ActiveCfg = Debug|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x86.Build.0 = Debug|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x86.ActiveCfg = Release|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x86.Build.0 = Release|Any CPU {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.ActiveCfg = Debug|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.Build.0 = Debug|x64 - {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x86.ActiveCfg = Debug|Win32 - {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x86.Build.0 = Debug|Win32 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.ActiveCfg = Release|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.Build.0 = Release|x64 - {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x86.ActiveCfg = Release|Win32 - {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From af7e1a74b40ebce5705186b2d4ae722e515e037c Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 7 Aug 2018 23:17:15 +0900 Subject: [PATCH 127/167] feat: Async/Await WCF --- .../Models/BackgroundService.cs | 8 ++ .../Robock.Background/Models/RobockServer.cs | 27 +++---- .../Communication/IRobockDuplexCallback.cs | 34 -------- .../IRobockBackgroundConnection.cs} | 23 +++--- Source/Robock.Shared/Robock.Shared.csproj | 7 +- Source/Robock/Models/Desktop.cs | 46 +++++------ Source/Robock/Models/RobockClient.cs | 78 ++++--------------- .../ViewModels/Tabs/DesktopViewModel.cs | 18 ++--- 8 files changed, 85 insertions(+), 156 deletions(-) delete mode 100644 Source/Robock.Shared/Communication/IRobockDuplexCallback.cs rename Source/Robock.Shared/{Communication/IRobockDuplex.cs => Models/IRobockBackgroundConnection.cs} (60%) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index ce872d2..3fa8cbb 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Reactive.Linq; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Windows.Media; @@ -8,6 +9,8 @@ using Robock.Shared.Win32; +using Application = System.Windows.Application; + // ReSharper disable LocalizableElement namespace Robock.Background.Models @@ -140,6 +143,11 @@ public void Release() _dxImage.Dispose(); } + public void Kill() + { + Observable.Return(0).Delay(TimeSpan.FromSeconds(5)).Subscribe(_ => _dxImage.Dispatcher.Invoke(() => Application.Current.Shutdown())); + } + private (int, int) GetPreviewWindowPosition() { var rect = SystemInformation.VirtualScreen; diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 0f5b64f..45bc50c 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -1,21 +1,20 @@ using System; using System.ServiceModel; +using System.Threading.Tasks; using System.Windows; -using Robock.Shared.Communication; +using Robock.Shared.Models; using Robock.Shared.Win32; namespace Robock.Background.Models { [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] - public class RobockServer : IRobockDuplex, IDisposable + public class RobockServer : IRobockBackgroundConnection, IDisposable { private readonly BackgroundService _backgroundService; private readonly string _uuid; private ServiceHost _serviceHost; - private IRobockDuplexCallback Callback => OperationContext.Current.GetCallbackChannel(); - public RobockServer() { var args = Environment.GetCommandLineArgs(); @@ -29,31 +28,33 @@ public void Dispose() ((IDisposable) _serviceHost)?.Dispose(); } - public void Handshake(int x, int y, int height, int width) + public Task Handshake(int x, int y, int height, int width) { _backgroundService.SetupRenderer(x, y, width, height); - Callback.HandshakeCallback(); + return Task.CompletedTask; } - public void ApplyWallpaper(IntPtr src, RECT rect) + public Task ApplyWallpaper(IntPtr src, RECT rect) { _backgroundService.StartRender(src, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - Callback.ApplyWallpaperCallback(true); + return Task.CompletedTask; } - public void DiscardWallpaper() + public Task DiscardWallpaper() { _backgroundService.StopRender(); - Callback.DiscardWallpaperCallback(); + return Task.CompletedTask; } - public void Close() + public Task Close() { DiscardWallpaper(); - Callback.CloseCallback(); + _backgroundService.Kill(); + + return Task.CompletedTask; } // @@ -65,7 +66,7 @@ public void Start() try { _serviceHost = new ServiceHost(typeof(RobockServer)); - _serviceHost.AddServiceEndpoint(typeof(IRobockDuplex), new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}"); + _serviceHost.AddServiceEndpoint(typeof(IRobockBackgroundConnection), new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}"); _serviceHost.Open(); } catch (Exception e) diff --git a/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs b/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs deleted file mode 100644 index f202cdf..0000000 --- a/Source/Robock.Shared/Communication/IRobockDuplexCallback.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.ServiceModel; - -// ReSharper disable OperationContractWithoutServiceContract - -namespace Robock.Shared.Communication -{ - public interface IRobockDuplexCallback - { - /// - /// Handshake() callback - /// - [OperationContract(IsOneWay = true)] - void HandshakeCallback(); - - /// - /// ApplyWallpaper() callback - /// - /// If wallpaper applied to background, returns true - [OperationContract(IsOneWay = true)] - void ApplyWallpaperCallback(bool isSucceed); - - /// - /// DiscardWallpaper() callback - /// - [OperationContract(IsOneWay = true)] - void DiscardWallpaperCallback(); - - /// - /// Close() callback - /// - [OperationContract(IsOneWay = true)] - void CloseCallback(); - } -} \ No newline at end of file diff --git a/Source/Robock.Shared/Communication/IRobockDuplex.cs b/Source/Robock.Shared/Models/IRobockBackgroundConnection.cs similarity index 60% rename from Source/Robock.Shared/Communication/IRobockDuplex.cs rename to Source/Robock.Shared/Models/IRobockBackgroundConnection.cs index a517eff..ba94232 100644 --- a/Source/Robock.Shared/Communication/IRobockDuplex.cs +++ b/Source/Robock.Shared/Models/IRobockBackgroundConnection.cs @@ -1,12 +1,13 @@ using System; using System.ServiceModel; +using System.Threading.Tasks; using Robock.Shared.Win32; -namespace Robock.Shared.Communication +namespace Robock.Shared.Models { - [ServiceContract(Namespace = "robock://localhost", SessionMode = SessionMode.Required, CallbackContract = typeof(IRobockDuplexCallback))] - public interface IRobockDuplex + [ServiceContract(Namespace = "robock://localhost", SessionMode = SessionMode.Required)] + public interface IRobockBackgroundConnection { /// /// Handshake between Robock and Robock.Background @@ -15,27 +16,27 @@ public interface IRobockDuplex /// Y /// Height /// Width - [OperationContract(IsOneWay = true)] - void Handshake(int x, int y, int height, int width); + [OperationContract] + Task Handshake(int x, int y, int height, int width); /// /// Apply wallpaper /// /// hWnd of source window /// - [OperationContract(IsOneWay = true)] - void ApplyWallpaper(IntPtr src, RECT rect); + [OperationContract] + Task ApplyWallpaper(IntPtr src, RECT rect); /// /// Discard wallpaper /// - [OperationContract(IsOneWay = true)] - void DiscardWallpaper(); + [OperationContract] + Task DiscardWallpaper(); /// /// Close communication pipe /// - [OperationContract(IsOneWay = true)] - void Close(); + [OperationContract] + Task Close(); } } \ No newline at end of file diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index b84dd94..0e79105 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -57,8 +57,7 @@ - - + @@ -81,6 +80,8 @@ - + + + \ No newline at end of file diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index d8c7931..a22da71 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; @@ -39,11 +40,7 @@ public void Dispose() { try { - _client.Close(() => - { - _process?.CloseMainWindow(); - _process?.Dispose(); - }); + Close().Wait(); } catch (Exception e) { @@ -51,7 +48,7 @@ public void Dispose() } } - public void Handshake(Action action = null) + public async Task Handshake(Action action = null) { _process = Process.Start("Robock.Background.exe", $"{_uuid}"); if (_process == null) @@ -61,28 +58,33 @@ public void Handshake(Action action = null) var offsetX = (SystemParameters.VirtualScreenLeft < 0 ? -1 : 1) * SystemParameters.VirtualScreenLeft; var offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; - _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width, action); + await _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width); } - public void ApplyWallpaper(IntPtr hWnd, RECT rect) + public async Task ApplyWallpaper(IntPtr hWnd, RECT rect) { - _client.ApplyWallpaper(hWnd, rect, () => { IsConnecting = true; }); + await _client.ApplyWallpaper(hWnd, rect); + IsConnecting = true; } - public void DiscardWallpaper() + public async Task DiscardWallpaper() { - // なんかつらい - _client.DiscardWallpaper(() => - { - _client.Close(() => - { - StatusTextService.Instance.Status = "Waiting for shutting down of background process..."; - _process?.CloseMainWindow(); - _process?.WaitForExit(); - _process?.Dispose(); - IsConnecting = false; - }); - }); + await _client.DiscardWallpaper(); + await Close(); + IsConnecting = false; + } + + private async Task Close() + { + StatusTextService.Instance.Status = "Waiting for shutting down of background process..."; + await _client.Close(); + if (_process == null) + return; + + _process.CloseMainWindow(); + _process.WaitForExit(); + _process.Dispose(); + StatusTextService.Instance.Status = "Shutdown successful"; } #region IsConnecting diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 2319364..0f3face 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -1,84 +1,38 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.ServiceModel; using System.Threading.Tasks; using Robock.Services; -using Robock.Shared.Communication; +using Robock.Shared.Models; using Robock.Shared.Win32; namespace Robock.Models { - public class RobockClient : IRobockDuplexCallback + public class RobockClient : IRobockBackgroundConnection { - private readonly Dictionary _callbacks; private readonly string _uuid; - private IRobockDuplex _channel; + private IRobockBackgroundConnection _channel; private bool _connecting; public RobockClient(string uuid) { _uuid = uuid; _connecting = false; - _callbacks = new Dictionary(); - } - - public void HandshakeCallback() - { - _connecting = true; - StatusTextService.Instance.Status = "Handshake success, Connected to background process"; - InvokeCallback(nameof(Handshake)); - } - - public void ApplyWallpaperCallback(bool isSucceed) - { - StatusTextService.Instance.Status = isSucceed ? "Rendering success, Start rendering" : "Rendering failed"; - InvokeCallback(nameof(ApplyWallpaper)); - } - - public void DiscardWallpaperCallback() - { - StatusTextService.Instance.Status = "Discard wallpaper finished"; - InvokeCallback(nameof(DiscardWallpaper)); - } - - public void CloseCallback() - { - StatusTextService.Instance.Status = "Closed connection to background process"; - InvokeCallback(nameof(Close)); - } - - private void InvokeCallback(string key) - { - if (!_callbacks.ContainsKey(key)) - return; - _callbacks[key]?.Invoke(); - _callbacks.Remove(key); - } - - private void RegisterCallback(string key, Action action) - { - if (action == null) - return; - - if (_callbacks.ContainsKey(key)) - _callbacks.Remove(key); - _callbacks.Add(key, action); } #region IRobockDuplex - public void Handshake(int x, int y, int height, int width, Action action = null) + public async Task Handshake(int x, int y, int height, int width) { StatusTextService.Instance.Status = "Start handshaking between Robock and background process... It may take a little time"; while (!_connecting) try { - _channel = new DuplexChannelFactory(this, new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}").CreateChannel(); - RegisterCallback(nameof(Handshake), action); - _channel.Handshake(x, y, height, width); + _channel = new ChannelFactory(new NetNamedPipeBinding(), $"net.pipe://localhost/Robock.{_uuid}").CreateChannel(); + await _channel.Handshake(x, y, height, width); _connecting = true; + StatusTextService.Instance.Status = "Handshake success, Connected to background process"; } catch { @@ -86,34 +40,32 @@ public void Handshake(int x, int y, int height, int width, Action action = null) } } - public void ApplyWallpaper(IntPtr src, RECT rect, Action action = null) + public async Task ApplyWallpaper(IntPtr src, RECT rect) { if (_channel == null) throw new InvalidOperationException("Invalid connection"); StatusTextService.Instance.Status = "Applying wallpeper..."; - RegisterCallback(nameof(ApplyWallpaper), action); - _channel.ApplyWallpaper(src, rect); + await _channel.ApplyWallpaper(src, rect); + StatusTextService.Instance.Status = "Rendering success, Start rendering"; } - public void DiscardWallpaper(Action action = null) + public async Task DiscardWallpaper() { if (_channel == null) throw new InvalidOperationException("Invalid connection"); StatusTextService.Instance.Status = "Discarding wallpeper..."; - RegisterCallback(nameof(DiscardWallpaper), action); - _channel.DiscardWallpaper(); + await _channel.DiscardWallpaper(); + StatusTextService.Instance.Status = "Discard wallpaper finished"; } - public void Close(Action action = null) + public async Task Close() { if (_channel == null) throw new InvalidOperationException("Invalid connection"); try { - StatusTextService.Instance.Status = "Closing connection to background process... It may take a little time"; - RegisterCallback(nameof(Close), action); - _channel.Close(); + await _channel.Close(); _connecting = false; } catch (Exception e) diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index b90cee0..d22e637 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -167,17 +167,15 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin _desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.IsRendering), desktop.ObserveProperty(w => w.IsConnecting).Select(w => !w) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); - ApplyWallpaperCommand.Subscribe(_ => + ApplyWallpaperCommand.Subscribe(() => { - Task.Run(() => + Task.Run(async () => { - _desktop.Handshake(() => - { - var rect = SelectedAreaHeight.Value != 0 - ? CalcRenderingRect() - : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; - _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); - }); + await _desktop.Handshake(); + var rect = SelectedAreaHeight.Value != 0 + ? CalcRenderingRect() + : new RECT {top = 0, left = 0, bottom = _desktopWindowManager.Thumbnails[0].Size.Height, right = _desktopWindowManager.Thumbnails[0].Size.Width}; + await _desktop.ApplyWallpaper(SelectedWindow.Value.Handle, SelectedAreaHeight.Value != 0 ? CalcRenderingRect() : rect); }); }).AddTo(this); DiscardWallpaperCommand = new[] @@ -185,7 +183,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin SelectedWindow.Select(w => w != null), desktop.ObserveProperty(w => w.IsConnecting) }.CombineLatest().Select(w => w.All(v => v)).ToReactiveCommand(); - DiscardWallpaperCommand.Subscribe(_ => Task.Run(() => _desktop.DiscardWallpaper())).AddTo(this); + DiscardWallpaperCommand.Subscribe(() => Task.Run(async () => await _desktop.DiscardWallpaper())).AddTo(this); ReloadWindowsCommand = new ReactiveCommand(); ReloadWindowsCommand.Subscribe(_ => windowManager.ForceUpdate()).AddTo(this); } From e019dcacb10b7824a1a385aa89a8142430f0780b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 8 Aug 2018 07:53:02 +0900 Subject: [PATCH 128/167] feat(core): Show process name --- Source/Robock.Shared/Win32/NativeMethods.cs | 3 +++ Source/Robock/Models/Window.cs | 1 + Source/Robock/Models/WindowManager.cs | 10 +++++++++- Source/Robock/ViewModels/WindowViewModel.cs | 5 ++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index cd12ca2..960f7bc 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -107,6 +107,9 @@ public static class NativeMethods [DllImport("user32.dll", SetLastError = true)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags uFlags); + [DllImport("user32.dll", SetLastError = true)] + public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + #endregion #region Robock.Background.Native diff --git a/Source/Robock/Models/Window.cs b/Source/Robock/Models/Window.cs index 3727453..c5f26f6 100644 --- a/Source/Robock/Models/Window.cs +++ b/Source/Robock/Models/Window.cs @@ -9,6 +9,7 @@ public class Window : BindableBase { public IntPtr Handle { get; set; } public bool IsMarked { get; set; } + public string ProcessName { get; set; } #region Title diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs index 9e09010..03bcf8f 100644 --- a/Source/Robock/Models/WindowManager.cs +++ b/Source/Robock/Models/WindowManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics; using System.Linq; using System.Reactive.Linq; using System.Runtime.InteropServices; @@ -60,7 +61,14 @@ private void FindWindows() if (Ignores.IgnoreWindowTitles.Contains(title.ToString())) return true; - windows.Add(new Window {Handle = hWnd, Title = title.ToString()}); + + NativeMethods.GetWindowThreadProcessId(hWnd, out var processId); + windows.Add(new Window + { + Handle = hWnd, + Title = title.ToString(), + ProcessName = Process.GetProcessById((int) processId).ProcessName + }); return true; }, IntPtr.Zero); diff --git a/Source/Robock/ViewModels/WindowViewModel.cs b/Source/Robock/ViewModels/WindowViewModel.cs index fb2910e..4477138 100644 --- a/Source/Robock/ViewModels/WindowViewModel.cs +++ b/Source/Robock/ViewModels/WindowViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Reactive.Linq; using Reactive.Bindings; using Reactive.Bindings.Extensions; @@ -18,7 +19,9 @@ public class WindowViewModel : ViewModel public WindowViewModel(Window window) { _window = window; - Title = window.ObserveProperty(w => w.Title).ToReactiveProperty().AddTo(this); + + // .exe 決め打ちでも問題無かろう + Title = window.ObserveProperty(w => w.Title).Select(w => $"{w} ({window.ProcessName}.exe)").ToReactiveProperty().AddTo(this); } } } \ No newline at end of file From 34a81c94622da9ea3b66b116d66f7455f64567f8 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 8 Aug 2018 21:00:28 +0900 Subject: [PATCH 129/167] docs(readme): Add note and attention --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 587167f..afe371d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Robock [![License](https://img.shields.io/github/license/mika-f/robock.svg?style=flat-square)](./blob/develop/LICENSE) +> Robock is experimental software. Please use it at your own risk. Window Capture + Dynamic Wallpaper = Good Experience @@ -14,6 +15,12 @@ Window Capture + Dynamic Wallpaper = Good Experience * Internet Connection +## Note + +If you want to capture Google Chrome and other applications, please disable "hardware acceleration". +I would like to deal with this problem, but I don't know how to fix it. + + ## Components * Robock (C#) From 96bd0c7b102cdf81fe49cb911c23c7fc50d66adf Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 8 Aug 2018 21:49:51 +0900 Subject: [PATCH 130/167] feat(native): Compile HLSL shaders. --- .../Robock.Background.Native/DxRenderer.cpp | 21 +++---------- .../Robock.Background.Native/PixelShader.hlsl | 13 ++++++++ .../Robock.Background.Native.rc | Bin 0 -> 2520 bytes .../Robock.Background.Native.vcxproj | 29 ++++++++++++++++++ .../Robock.Background.Native.vcxproj.filters | 12 ++++++++ .../VertexShader.hlsl | 14 +++++++++ Source/Robock.Background.Native/resource.h | 14 +++++++++ Source/Robock.Background.Native/stdafx.h | Bin 1390 -> 1500 bytes 8 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 Source/Robock.Background.Native/PixelShader.hlsl create mode 100644 Source/Robock.Background.Native/Robock.Background.Native.rc create mode 100644 Source/Robock.Background.Native/VertexShader.hlsl create mode 100644 Source/Robock.Background.Native/resource.h diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 8bd769b..ffda774 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -192,17 +192,10 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) HRESULT DxRenderer::LoadShader() { - ID3DBlob* vsBlob; - auto hr = this->CompileShaderFromFile(L"shader.hlsl", "VS", "vs_5_0", &vsBlob); + auto size = ARRAYSIZE(g_VS); + auto hr = this->_device->CreateVertexShader(g_VS, size, nullptr, &this->_vertexShader); if (FAILED(hr)) - return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); - - hr = this->_device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &this->_vertexShader); - if (FAILED(hr)) - { - SAFE_RELEASE(vsBlob); return this->MsgBox(hr, L"LoadShader#CreateVertexShader"); - } D3D11_INPUT_ELEMENT_DESC layout[] = { @@ -211,19 +204,15 @@ HRESULT DxRenderer::LoadShader() }; const UINT elements = sizeof layout / sizeof layout[0]; - hr = this->_device->CreateInputLayout(layout, elements, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &this->_vertexLayout); + hr = this->_device->CreateInputLayout(layout, elements, g_VS, size, &this->_vertexLayout); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreateInputLayout"); this->_deviceContext->IASetInputLayout(this->_vertexLayout); - ID3DBlob* psBlob; - hr = this->CompileShaderFromFile(L"shader.hlsl", "PS", "ps_5_0", &psBlob); - if (FAILED(hr)) - return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); + size = ARRAYSIZE(g_PS); + hr = this->_device->CreatePixelShader(g_PS, size, nullptr, &this->_pixelShader); - hr = this->_device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &this->_pixelShader); - SAFE_RELEASE(vsBlob); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreatePixelShader"); diff --git a/Source/Robock.Background.Native/PixelShader.hlsl b/Source/Robock.Background.Native/PixelShader.hlsl new file mode 100644 index 0000000..caff704 --- /dev/null +++ b/Source/Robock.Background.Native/PixelShader.hlsl @@ -0,0 +1,13 @@ +Texture2D tex2D : register (t0); +SamplerState sampleLinear : register(s0); + +struct VS_INPUT +{ + float4 Pos: SV_POSITION; + float2 Tex: TEXCOORD; +}; + +float4 PS(VS_INPUT input) : SV_TARGET +{ + return tex2D.Sample(sampleLinear, input.Tex); +} \ No newline at end of file diff --git a/Source/Robock.Background.Native/Robock.Background.Native.rc b/Source/Robock.Background.Native/Robock.Background.Native.rc new file mode 100644 index 0000000000000000000000000000000000000000..791d83f2ef870dc513849aa997aa062fe5c0e36c GIT binary patch literal 2520 zcmds3OG*Pl5Pi53LGT8)aibVaMFrQI#1M=hOhyd^f}bQRqM!yh;$HC#Uct2s_ujx0 zxbY04zM4+!gv`XxYLKSWJvCjw*RLw`{+2=t220q-4o+~4Q_cp?C|jrO6fJDwkWU#* za2PaYxHYux$&J+HMIPi;?#19fG7j@c5&{N&_ z)Z%W3`$_Cks;8}no@@AedVUV8D4`4wSro8>8rG1bG|T-mil|Uh;_njXDJgRA{A&#H z8!kGx8s?V6CVvaeC&LUh(;PFO;&do4%GD?Km$E_pzsLF9$IznPiE;c;aS>Stw8$CD zg1_FsL)Y1j*Xp7(c&;a#x7P+^{%$;Q<9f!TvCnES7-=J-^;GA6j5V-8-q?C5k^3Gi zBSYrY$e$vITD#ydk(y=NSVNu~IdadVhI%Ygx=g9ZHSaSqjaejVC+)xgiYoe!l*{Xk zX_5Nbe^QZ}xAI6=ooONxUc35so|)(Un${=N9^u`u3Tbyhy$6ezYH0@u_n`KAc?s*g z33PXa1gh-9RdUL9;IBBNVw(PQOuzLsN}g*Uu>7}?DgI$Sp_^}tPPB#Ibr-L05sXH& z3QoP}M$c~9jZDy9y!M)zM&#CL_A3j2`rqjAidU||Xf(oTu6BO`b>69dmmNq}W;XlF GYUu-QXf`nb literal 0 HcmV?d00001 diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index faf11ec..68df08c 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -92,6 +92,7 @@ true _DEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true + $(OutDir);%(AdditionalIncludeDirectories) Windows @@ -153,6 +154,7 @@ + @@ -166,6 +168,33 @@ Create + + + + + + Pixel + Pixel + Pixel + Pixel + PS + $(OutDir)%(Filename).h + 5.0 + + + + + Vertex + Vertex + Vertex + Vertex + VS + 5.0 + $(OutDir)%(Filename).h + + + + diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters index 11378a9..d074764 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters @@ -27,6 +27,9 @@ ヘッダー ファイル + + ヘッダー ファイル + @@ -39,4 +42,13 @@ ソース ファイル + + + リソース ファイル + + + + + + \ No newline at end of file diff --git a/Source/Robock.Background.Native/VertexShader.hlsl b/Source/Robock.Background.Native/VertexShader.hlsl new file mode 100644 index 0000000..0e277d7 --- /dev/null +++ b/Source/Robock.Background.Native/VertexShader.hlsl @@ -0,0 +1,14 @@ +struct VS_OUTPUT +{ + float4 Pos: SV_POSITION; + float2 Tex: TEXCOORD; +}; + +VS_OUTPUT VS(float Pos : POSITION, float2 Tex : TEXCOORD) +{ + VS_OUTPUT vertex = (VS_OUTPUT)0; + vertex.Pos = Pos; + vertex.Tex = Tex; + + return vertex; +} \ No newline at end of file diff --git a/Source/Robock.Background.Native/resource.h b/Source/Robock.Background.Native/resource.h new file mode 100644 index 0000000..8c4dcc2 --- /dev/null +++ b/Source/Robock.Background.Native/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Robock.Background.Native.rc + +// 新しいオブジェクトの次の既定値 +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Source/Robock.Background.Native/stdafx.h b/Source/Robock.Background.Native/stdafx.h index ec4e98302d5162d8789637faac586c65ce5326a4..e7d8cd9276bb74c4471b7fca51652cd91fe7d264 100644 GIT binary patch delta 78 zcmaFIb%%Qc5A$R$Mgi#nhD?SEhE#?ehG2#ahD3%GAiIb`56D)U%*ZGy8wTc=0LcnW L6`TJv Date: Wed, 8 Aug 2018 22:34:56 +0900 Subject: [PATCH 131/167] Revert "feat(native): Compile HLSL shaders." This reverts commit 96bd0c7b102cdf81fe49cb911c23c7fc50d66adf. --- .../Robock.Background.Native/DxRenderer.cpp | 21 ++++++++++--- .../Robock.Background.Native/PixelShader.hlsl | 13 -------- .../Robock.Background.Native.rc | Bin 2520 -> 0 bytes .../Robock.Background.Native.vcxproj | 29 ------------------ .../Robock.Background.Native.vcxproj.filters | 12 -------- .../VertexShader.hlsl | 14 --------- Source/Robock.Background.Native/resource.h | 14 --------- Source/Robock.Background.Native/stdafx.h | Bin 1500 -> 1390 bytes 8 files changed, 16 insertions(+), 87 deletions(-) delete mode 100644 Source/Robock.Background.Native/PixelShader.hlsl delete mode 100644 Source/Robock.Background.Native/Robock.Background.Native.rc delete mode 100644 Source/Robock.Background.Native/VertexShader.hlsl delete mode 100644 Source/Robock.Background.Native/resource.h diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index ffda774..8bd769b 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -192,10 +192,17 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) HRESULT DxRenderer::LoadShader() { - auto size = ARRAYSIZE(g_VS); - auto hr = this->_device->CreateVertexShader(g_VS, size, nullptr, &this->_vertexShader); + ID3DBlob* vsBlob; + auto hr = this->CompileShaderFromFile(L"shader.hlsl", "VS", "vs_5_0", &vsBlob); if (FAILED(hr)) + return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); + + hr = this->_device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &this->_vertexShader); + if (FAILED(hr)) + { + SAFE_RELEASE(vsBlob); return this->MsgBox(hr, L"LoadShader#CreateVertexShader"); + } D3D11_INPUT_ELEMENT_DESC layout[] = { @@ -204,15 +211,19 @@ HRESULT DxRenderer::LoadShader() }; const UINT elements = sizeof layout / sizeof layout[0]; - hr = this->_device->CreateInputLayout(layout, elements, g_VS, size, &this->_vertexLayout); + hr = this->_device->CreateInputLayout(layout, elements, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &this->_vertexLayout); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreateInputLayout"); this->_deviceContext->IASetInputLayout(this->_vertexLayout); - size = ARRAYSIZE(g_PS); - hr = this->_device->CreatePixelShader(g_PS, size, nullptr, &this->_pixelShader); + ID3DBlob* psBlob; + hr = this->CompileShaderFromFile(L"shader.hlsl", "PS", "ps_5_0", &psBlob); + if (FAILED(hr)) + return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); + hr = this->_device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &this->_pixelShader); + SAFE_RELEASE(vsBlob); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreatePixelShader"); diff --git a/Source/Robock.Background.Native/PixelShader.hlsl b/Source/Robock.Background.Native/PixelShader.hlsl deleted file mode 100644 index caff704..0000000 --- a/Source/Robock.Background.Native/PixelShader.hlsl +++ /dev/null @@ -1,13 +0,0 @@ -Texture2D tex2D : register (t0); -SamplerState sampleLinear : register(s0); - -struct VS_INPUT -{ - float4 Pos: SV_POSITION; - float2 Tex: TEXCOORD; -}; - -float4 PS(VS_INPUT input) : SV_TARGET -{ - return tex2D.Sample(sampleLinear, input.Tex); -} \ No newline at end of file diff --git a/Source/Robock.Background.Native/Robock.Background.Native.rc b/Source/Robock.Background.Native/Robock.Background.Native.rc deleted file mode 100644 index 791d83f2ef870dc513849aa997aa062fe5c0e36c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2520 zcmds3OG*Pl5Pi53LGT8)aibVaMFrQI#1M=hOhyd^f}bQRqM!yh;$HC#Uct2s_ujx0 zxbY04zM4+!gv`XxYLKSWJvCjw*RLw`{+2=t220q-4o+~4Q_cp?C|jrO6fJDwkWU#* za2PaYxHYux$&J+HMIPi;?#19fG7j@c5&{N&_ z)Z%W3`$_Cks;8}no@@AedVUV8D4`4wSro8>8rG1bG|T-mil|Uh;_njXDJgRA{A&#H z8!kGx8s?V6CVvaeC&LUh(;PFO;&do4%GD?Km$E_pzsLF9$IznPiE;c;aS>Stw8$CD zg1_FsL)Y1j*Xp7(c&;a#x7P+^{%$;Q<9f!TvCnES7-=J-^;GA6j5V-8-q?C5k^3Gi zBSYrY$e$vITD#ydk(y=NSVNu~IdadVhI%Ygx=g9ZHSaSqjaejVC+)xgiYoe!l*{Xk zX_5Nbe^QZ}xAI6=ooONxUc35so|)(Un${=N9^u`u3Tbyhy$6ezYH0@u_n`KAc?s*g z33PXa1gh-9RdUL9;IBBNVw(PQOuzLsN}g*Uu>7}?DgI$Sp_^}tPPB#Ibr-L05sXH& z3QoP}M$c~9jZDy9y!M)zM&#CL_A3j2`rqjAidU||Xf(oTu6BO`b>69dmmNq}W;XlF GYUu-QXf`nb diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index 68df08c..faf11ec 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -92,7 +92,6 @@ true _DEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true - $(OutDir);%(AdditionalIncludeDirectories) Windows @@ -154,7 +153,6 @@ - @@ -168,33 +166,6 @@ Create - - - - - - Pixel - Pixel - Pixel - Pixel - PS - $(OutDir)%(Filename).h - 5.0 - - - - - Vertex - Vertex - Vertex - Vertex - VS - 5.0 - $(OutDir)%(Filename).h - - - - diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters index d074764..11378a9 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters @@ -27,9 +27,6 @@ ヘッダー ファイル - - ヘッダー ファイル - @@ -42,13 +39,4 @@ ソース ファイル - - - リソース ファイル - - - - - - \ No newline at end of file diff --git a/Source/Robock.Background.Native/VertexShader.hlsl b/Source/Robock.Background.Native/VertexShader.hlsl deleted file mode 100644 index 0e277d7..0000000 --- a/Source/Robock.Background.Native/VertexShader.hlsl +++ /dev/null @@ -1,14 +0,0 @@ -struct VS_OUTPUT -{ - float4 Pos: SV_POSITION; - float2 Tex: TEXCOORD; -}; - -VS_OUTPUT VS(float Pos : POSITION, float2 Tex : TEXCOORD) -{ - VS_OUTPUT vertex = (VS_OUTPUT)0; - vertex.Pos = Pos; - vertex.Tex = Tex; - - return vertex; -} \ No newline at end of file diff --git a/Source/Robock.Background.Native/resource.h b/Source/Robock.Background.Native/resource.h deleted file mode 100644 index 8c4dcc2..0000000 --- a/Source/Robock.Background.Native/resource.h +++ /dev/null @@ -1,14 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Robock.Background.Native.rc - -// 新しいオブジェクトの次の既定値 -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Source/Robock.Background.Native/stdafx.h b/Source/Robock.Background.Native/stdafx.h index e7d8cd9276bb74c4471b7fca51652cd91fe7d264..ec4e98302d5162d8789637faac586c65ce5326a4 100644 GIT binary patch delta 12 Tcmcb^{f=t`5A)_K<|HNnAeRI) delta 78 zcmaFIb%%Qc5A$R$Mgi#nhD?SEhE#?ehG2#ahD3%GAiIb`56D)U%*ZGy8wTc=0LcnW L6`TJv Date: Wed, 8 Aug 2018 22:41:51 +0900 Subject: [PATCH 132/167] Revert "Revert "feat(native): Compile HLSL shaders."" This reverts commit 2a990ffc5ec39f68e569de5a42959e244d26f9ef. --- .../Robock.Background.Native/DxRenderer.cpp | 21 +++---------- .../Robock.Background.Native/PixelShader.hlsl | 13 ++++++++ .../Robock.Background.Native.rc | Bin 0 -> 2520 bytes .../Robock.Background.Native.vcxproj | 29 ++++++++++++++++++ .../Robock.Background.Native.vcxproj.filters | 12 ++++++++ .../VertexShader.hlsl | 14 +++++++++ Source/Robock.Background.Native/resource.h | 14 +++++++++ Source/Robock.Background.Native/stdafx.h | Bin 1390 -> 1500 bytes 8 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 Source/Robock.Background.Native/PixelShader.hlsl create mode 100644 Source/Robock.Background.Native/Robock.Background.Native.rc create mode 100644 Source/Robock.Background.Native/VertexShader.hlsl create mode 100644 Source/Robock.Background.Native/resource.h diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 8bd769b..ffda774 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -192,17 +192,10 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) HRESULT DxRenderer::LoadShader() { - ID3DBlob* vsBlob; - auto hr = this->CompileShaderFromFile(L"shader.hlsl", "VS", "vs_5_0", &vsBlob); + auto size = ARRAYSIZE(g_VS); + auto hr = this->_device->CreateVertexShader(g_VS, size, nullptr, &this->_vertexShader); if (FAILED(hr)) - return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); - - hr = this->_device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &this->_vertexShader); - if (FAILED(hr)) - { - SAFE_RELEASE(vsBlob); return this->MsgBox(hr, L"LoadShader#CreateVertexShader"); - } D3D11_INPUT_ELEMENT_DESC layout[] = { @@ -211,19 +204,15 @@ HRESULT DxRenderer::LoadShader() }; const UINT elements = sizeof layout / sizeof layout[0]; - hr = this->_device->CreateInputLayout(layout, elements, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &this->_vertexLayout); + hr = this->_device->CreateInputLayout(layout, elements, g_VS, size, &this->_vertexLayout); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreateInputLayout"); this->_deviceContext->IASetInputLayout(this->_vertexLayout); - ID3DBlob* psBlob; - hr = this->CompileShaderFromFile(L"shader.hlsl", "PS", "ps_5_0", &psBlob); - if (FAILED(hr)) - return this->MsgBox(hr, L"LoadShader#CompileShaderFromFile"); + size = ARRAYSIZE(g_PS); + hr = this->_device->CreatePixelShader(g_PS, size, nullptr, &this->_pixelShader); - hr = this->_device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &this->_pixelShader); - SAFE_RELEASE(vsBlob); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreatePixelShader"); diff --git a/Source/Robock.Background.Native/PixelShader.hlsl b/Source/Robock.Background.Native/PixelShader.hlsl new file mode 100644 index 0000000..caff704 --- /dev/null +++ b/Source/Robock.Background.Native/PixelShader.hlsl @@ -0,0 +1,13 @@ +Texture2D tex2D : register (t0); +SamplerState sampleLinear : register(s0); + +struct VS_INPUT +{ + float4 Pos: SV_POSITION; + float2 Tex: TEXCOORD; +}; + +float4 PS(VS_INPUT input) : SV_TARGET +{ + return tex2D.Sample(sampleLinear, input.Tex); +} \ No newline at end of file diff --git a/Source/Robock.Background.Native/Robock.Background.Native.rc b/Source/Robock.Background.Native/Robock.Background.Native.rc new file mode 100644 index 0000000000000000000000000000000000000000..791d83f2ef870dc513849aa997aa062fe5c0e36c GIT binary patch literal 2520 zcmds3OG*Pl5Pi53LGT8)aibVaMFrQI#1M=hOhyd^f}bQRqM!yh;$HC#Uct2s_ujx0 zxbY04zM4+!gv`XxYLKSWJvCjw*RLw`{+2=t220q-4o+~4Q_cp?C|jrO6fJDwkWU#* za2PaYxHYux$&J+HMIPi;?#19fG7j@c5&{N&_ z)Z%W3`$_Cks;8}no@@AedVUV8D4`4wSro8>8rG1bG|T-mil|Uh;_njXDJgRA{A&#H z8!kGx8s?V6CVvaeC&LUh(;PFO;&do4%GD?Km$E_pzsLF9$IznPiE;c;aS>Stw8$CD zg1_FsL)Y1j*Xp7(c&;a#x7P+^{%$;Q<9f!TvCnES7-=J-^;GA6j5V-8-q?C5k^3Gi zBSYrY$e$vITD#ydk(y=NSVNu~IdadVhI%Ygx=g9ZHSaSqjaejVC+)xgiYoe!l*{Xk zX_5Nbe^QZ}xAI6=ooONxUc35so|)(Un${=N9^u`u3Tbyhy$6ezYH0@u_n`KAc?s*g z33PXa1gh-9RdUL9;IBBNVw(PQOuzLsN}g*Uu>7}?DgI$Sp_^}tPPB#Ibr-L05sXH& z3QoP}M$c~9jZDy9y!M)zM&#CL_A3j2`rqjAidU||Xf(oTu6BO`b>69dmmNq}W;XlF GYUu-QXf`nb literal 0 HcmV?d00001 diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index faf11ec..68df08c 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -92,6 +92,7 @@ true _DEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true + $(OutDir);%(AdditionalIncludeDirectories) Windows @@ -153,6 +154,7 @@ + @@ -166,6 +168,33 @@ Create + + + + + + Pixel + Pixel + Pixel + Pixel + PS + $(OutDir)%(Filename).h + 5.0 + + + + + Vertex + Vertex + Vertex + Vertex + VS + 5.0 + $(OutDir)%(Filename).h + + + + diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters index 11378a9..d074764 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj.filters @@ -27,6 +27,9 @@ ヘッダー ファイル + + ヘッダー ファイル + @@ -39,4 +42,13 @@ ソース ファイル + + + リソース ファイル + + + + + + \ No newline at end of file diff --git a/Source/Robock.Background.Native/VertexShader.hlsl b/Source/Robock.Background.Native/VertexShader.hlsl new file mode 100644 index 0000000..0e277d7 --- /dev/null +++ b/Source/Robock.Background.Native/VertexShader.hlsl @@ -0,0 +1,14 @@ +struct VS_OUTPUT +{ + float4 Pos: SV_POSITION; + float2 Tex: TEXCOORD; +}; + +VS_OUTPUT VS(float Pos : POSITION, float2 Tex : TEXCOORD) +{ + VS_OUTPUT vertex = (VS_OUTPUT)0; + vertex.Pos = Pos; + vertex.Tex = Tex; + + return vertex; +} \ No newline at end of file diff --git a/Source/Robock.Background.Native/resource.h b/Source/Robock.Background.Native/resource.h new file mode 100644 index 0000000..8c4dcc2 --- /dev/null +++ b/Source/Robock.Background.Native/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Robock.Background.Native.rc + +// 新しいオブジェクトの次の既定値 +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Source/Robock.Background.Native/stdafx.h b/Source/Robock.Background.Native/stdafx.h index ec4e98302d5162d8789637faac586c65ce5326a4..e7d8cd9276bb74c4471b7fca51652cd91fe7d264 100644 GIT binary patch delta 78 zcmaFIb%%Qc5A$R$Mgi#nhD?SEhE#?ehG2#ahD3%GAiIb`56D)U%*ZGy8wTc=0LcnW L6`TJv Date: Wed, 8 Aug 2018 23:02:34 +0900 Subject: [PATCH 133/167] fix(shader): Fix HLSL shader --- Source/Robock.Background.Native/PixelShader.hlsl | 2 +- Source/Robock.Background.Native/VertexShader.hlsl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Robock.Background.Native/PixelShader.hlsl b/Source/Robock.Background.Native/PixelShader.hlsl index caff704..46b6c7b 100644 --- a/Source/Robock.Background.Native/PixelShader.hlsl +++ b/Source/Robock.Background.Native/PixelShader.hlsl @@ -7,7 +7,7 @@ struct VS_INPUT float2 Tex: TEXCOORD; }; -float4 PS(VS_INPUT input) : SV_TARGET +float4 PS(VS_INPUT input) : SV_Target { return tex2D.Sample(sampleLinear, input.Tex); } \ No newline at end of file diff --git a/Source/Robock.Background.Native/VertexShader.hlsl b/Source/Robock.Background.Native/VertexShader.hlsl index 0e277d7..4a91fdd 100644 --- a/Source/Robock.Background.Native/VertexShader.hlsl +++ b/Source/Robock.Background.Native/VertexShader.hlsl @@ -4,11 +4,11 @@ struct VS_OUTPUT float2 Tex: TEXCOORD; }; -VS_OUTPUT VS(float Pos : POSITION, float2 Tex : TEXCOORD) +VS_OUTPUT VS(float4 Pos : POSITION, float2 Tex : TEXCOORD) { - VS_OUTPUT vertex = (VS_OUTPUT)0; - vertex.Pos = Pos; - vertex.Tex = Tex; + VS_OUTPUT vs_output = (VS_OUTPUT)0; + vs_output.Pos = Pos; + vs_output.Tex = Tex; - return vertex; + return vs_output; } \ No newline at end of file From 3ea61b067e472ecd794d139570e7aecc1f8a40f4 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 8 Aug 2018 23:05:32 +0900 Subject: [PATCH 134/167] refactor(native): Remove unused func --- Source/Robock.Background.Native/DxRenderer.cpp | 9 --------- Source/Robock.Background.Native/DxRenderer.h | 1 - 2 files changed, 10 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index ffda774..3b08f4d 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -254,15 +254,6 @@ HRESULT DxRenderer::LoadShader() return S_OK; } -HRESULT DxRenderer::CompileShaderFromFile(const LPCWSTR pFileName, const LPCSTR pEntrypoint, const LPCSTR pTarget, ID3D10Blob** ppCode) -{ - ID3D10Blob* pErrorBlob; - const auto hr = D3DCompileFromFile(pFileName, nullptr, nullptr, pEntrypoint, pTarget, 0, 0, ppCode, &pErrorBlob); - SAFE_RELEASE(pErrorBlob); - - return hr; -} - HRESULT DxRenderer::MsgBox(const HRESULT hr, const LPCWSTR lpText) { _com_error err(hr); diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index 1deaca9..16fdc0b 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -14,7 +14,6 @@ class DxRenderer HRESULT InitRenderTarget(void* pResource); HRESULT LoadShader(); - static HRESULT CompileShaderFromFile(LPCWSTR pFileName, LPCSTR pEntrypoint, LPCSTR pTarget, ID3D10Blob** ppCode); static HRESULT MsgBox(HRESULT hr, LPCWSTR lpText); int _width; From 96c9c80348981b59bcca91a2f268071f79123c10 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 9 Aug 2018 08:40:55 +0900 Subject: [PATCH 135/167] fix(native): phDwmSurface is not constant value --- Source/Robock.Background.Native/DxRenderer.cpp | 5 ++++- Source/Robock.Background.Native/DxRenderer.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 3b08f4d..9cd2cf7 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -8,6 +8,7 @@ using namespace PackedVector; DxRenderer::DxRenderer() { + this->_currentDwnSurface = nullptr; this->_width = 0; this->_height = 0; this->_driverType = D3D_DRIVER_TYPE_NULL; @@ -37,7 +38,7 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int return this->MsgBox(hr, L"Render#InitRenderTarget"); } - if (this->_shaderResourceView == nullptr) + if (this->_shaderResourceView == nullptr || this->_currentDwnSurface != phDwmSurface) { IUnknown* resource; hr = this->_device->OpenSharedResource(phDwmSurface, __uuidof(ID3D11Resource), reinterpret_cast(&resource)); @@ -52,6 +53,7 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int hr = this->_device->CreateShaderResourceView(texture2D, nullptr, &this->_shaderResourceView); if (FAILED(hr)) return this->MsgBox(hr, L"Render#CreateShaderResourceView"); + this->_currentDwnSurface = phDwmSurface; } const float clearColor[4] = {0, 0, 0, 1}; // RGBA @@ -72,6 +74,7 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int HRESULT DxRenderer::Release() { + this->_currentDwnSurface = nullptr; this->_width = 0; this->_height = 0; this->_driverType = D3D_DRIVER_TYPE_NULL; diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index 16fdc0b..44a8959 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -16,6 +16,7 @@ class DxRenderer static HRESULT MsgBox(HRESULT hr, LPCWSTR lpText); + void* _currentDwnSurface; int _width; int _height; From 6d8c84b5e15c3de0b05c0ee74a478c8ddeeff140 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 9 Aug 2018 20:02:48 +0900 Subject: [PATCH 136/167] docs(readme): Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index afe371d..d7111b9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Window Capture + Dynamic Wallpaper = Good Experience * .NET Framework 4.7.2 ~ * DirectX 11 ~ * Video Card that supports Windows Display Driver Model -* Internet Connection +* Internet Connection (Robock will connect to placehold.mochizuki.moe) ## Note From 9d547f7cddd1d011bc77327e67adbd47deaa19f2 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 9 Aug 2018 23:31:43 +0900 Subject: [PATCH 137/167] fix(background): Short --- Source/Robock.Background/Models/BackgroundService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 3fa8cbb..86e51e6 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -145,7 +145,7 @@ public void Release() public void Kill() { - Observable.Return(0).Delay(TimeSpan.FromSeconds(5)).Subscribe(_ => _dxImage.Dispatcher.Invoke(() => Application.Current.Shutdown())); + Observable.Return(0).Delay(TimeSpan.FromSeconds(1.5)).Subscribe(_ => _dxImage.Dispatcher.Invoke(() => Application.Current.Shutdown())); } private (int, int) GetPreviewWindowPosition() From 4eeb8cb30848aa041de48867fd39f55ec252431f Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Thu, 9 Aug 2018 23:36:38 +0900 Subject: [PATCH 138/167] chore(native): Remove unused variable --- Source/Robock.Background.Native/DxRenderer.cpp | 10 ++++------ Source/Robock.Background.Native/DxRenderer.h | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 9cd2cf7..3feb28c 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -20,14 +20,13 @@ DxRenderer::DxRenderer() this->_vertexBuffer = nullptr; this->_vertexShader = nullptr; this->_pixelShader = nullptr; - this->_indexBuffer = nullptr; this->_samplerState = nullptr; this->_shaderResourceView = nullptr; } HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int x, const int y, const int width, const int height, const bool isNewSurface) { - auto hr = S_OK; + HRESULT hr; if (isNewSurface) { @@ -86,7 +85,6 @@ HRESULT DxRenderer::Release() SAFE_RELEASE(this->_vertexBuffer); SAFE_RELEASE(this->_vertexShader); SAFE_RELEASE(this->_pixelShader); - SAFE_RELEASE(this->_indexBuffer); SAFE_RELEASE(this->_samplerState); SAFE_RELEASE(this->_shaderResourceView); @@ -233,10 +231,10 @@ HRESULT DxRenderer::LoadShader() bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufferDesc.CPUAccessFlags = 0; bufferDesc.MiscFlags = 0; - D3D11_SUBRESOURCE_DATA InitData; - InitData.pSysMem = vertices; + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = vertices; - hr = this->_device->CreateBuffer(&bufferDesc, &InitData, &this->_vertexBuffer); + hr = this->_device->CreateBuffer(&bufferDesc, &initData, &this->_vertexBuffer); if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreateBuffer"); diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index 44a8959..9089c75 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -30,7 +30,6 @@ class DxRenderer ID3D11Buffer* _vertexBuffer{}; ID3D11VertexShader* _vertexShader{}; ID3D11PixelShader* _pixelShader{}; - ID3D11Buffer* _indexBuffer{}; ID3D11SamplerState* _samplerState{}; ID3D11ShaderResourceView* _shaderResourceView{}; }; From bbd013fdb5c08f00a21210d52d9f39316165a753 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 10 Aug 2018 08:28:43 +0900 Subject: [PATCH 139/167] chore: Heartbeating --- .../Robock.Background/Models/RobockServer.cs | 6 +++++ .../Models/IRobockBackgroundConnection.cs | 7 ++++++ Source/Robock.Shared/Robock.Shared.csproj | 4 +--- Source/Robock.Shared/Win32/NativeMethods.cs | 6 ++--- Source/Robock/Models/Desktop.cs | 23 +++++++++++++++++++ Source/Robock/Models/RobockClient.cs | 7 ++++++ 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/Source/Robock.Background/Models/RobockServer.cs b/Source/Robock.Background/Models/RobockServer.cs index 45bc50c..8f6c575 100644 --- a/Source/Robock.Background/Models/RobockServer.cs +++ b/Source/Robock.Background/Models/RobockServer.cs @@ -42,6 +42,12 @@ public Task ApplyWallpaper(IntPtr src, RECT rect) return Task.CompletedTask; } + // 通信できればそれでよい + public Task Heartbeat() + { + return Task.CompletedTask; + } + public Task DiscardWallpaper() { _backgroundService.StopRender(); diff --git a/Source/Robock.Shared/Models/IRobockBackgroundConnection.cs b/Source/Robock.Shared/Models/IRobockBackgroundConnection.cs index ba94232..6d433c2 100644 --- a/Source/Robock.Shared/Models/IRobockBackgroundConnection.cs +++ b/Source/Robock.Shared/Models/IRobockBackgroundConnection.cs @@ -27,6 +27,13 @@ public interface IRobockBackgroundConnection [OperationContract] Task ApplyWallpaper(IntPtr src, RECT rect); + /// + /// + /// + /// + [OperationContract] + Task Heartbeat(); + /// /// Discard wallpaper /// diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 0e79105..9868eaa 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -80,8 +80,6 @@ - - - + \ No newline at end of file diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index 960f7bc..ba33e63 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -115,13 +115,13 @@ public static class NativeMethods #region Robock.Background.Native [DllImport("Robock.Background.Native.dll")] - public static extern void Init(); + public static extern int Init(); [DllImport("Robock.Background.Native.dll")] - public static extern void Render(IntPtr hWindowSurface, IntPtr hDwmSurface, int x, int y, int width, int height, bool isNewSurface); + public static extern int Render(IntPtr hWindowSurface, IntPtr hDwmSurface, int x, int y, int width, int height, bool isNewSurface); [DllImport("Robock.Background.Native.dll")] - public static extern void Release(); + public static extern int Release(); #endregion } diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index a22da71..11f8eb2 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Reactive.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; @@ -19,6 +20,7 @@ public class Desktop : BindableBase, IDisposable private readonly RobockClient _client; private readonly Screen _screen; private readonly string _uuid; + private IDisposable _disposable; private Process _process; public int No { get; } @@ -59,6 +61,9 @@ public async Task Handshake(Action action = null) var offsetY = (SystemParameters.VirtualScreenTop < 0 ? -1 : 1) * SystemParameters.VirtualScreenTop; await _client.Handshake((int) (offsetX + X), (int) (offsetY + Y), (int) Height, (int) Width); + + // 生存確認 + _disposable = Observable.Timer(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)).Subscribe(async _ => await Heartbeat()); } public async Task ApplyWallpaper(IntPtr hWnd, RECT rect) @@ -74,6 +79,23 @@ public async Task DiscardWallpaper() IsConnecting = false; } + private async Task Heartbeat() + { + try + { + await _client.Heartbeat(); + } + catch (Exception) + { + if (_process == null) + return; + _disposable.Dispose(); + _process.WaitForExit(); + _process.Dispose(); + IsConnecting = false; + } + } + private async Task Close() { StatusTextService.Instance.Status = "Waiting for shutting down of background process..."; @@ -81,6 +103,7 @@ private async Task Close() if (_process == null) return; + _disposable?.Dispose(); _process.CloseMainWindow(); _process.WaitForExit(); _process.Dispose(); diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 0f3face..0ce94e7 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -49,6 +49,13 @@ public async Task ApplyWallpaper(IntPtr src, RECT rect) StatusTextService.Instance.Status = "Rendering success, Start rendering"; } + public async Task Heartbeat() + { + if (_channel == null) + throw new InvalidOperationException("Invalid connection"); + await _channel.Heartbeat(); + } + public async Task DiscardWallpaper() { if (_channel == null) From fcdbf51a8b93c29261cde0f3fec4142332b7cb3b Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 10 Aug 2018 08:33:10 +0900 Subject: [PATCH 140/167] chore: Remove submodule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit いつからあった...? --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index ed58488..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "Source/PyxisControls"] - path = Source/PyxisControls - url = https://github.com/mika-f/PyxisControls.git From 10c466961ae089241fd000f3ed8c877a9c865fc7 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Fri, 10 Aug 2018 08:42:09 +0900 Subject: [PATCH 141/167] feat(background): fail --- Source/Robock.Background/Models/BackgroundService.cs | 9 ++++++++- Source/Robock/Models/Desktop.cs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 86e51e6..55249f0 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -117,7 +117,14 @@ private void Render(IntPtr hSurface, bool isNewSurface) GetDxSharedSurface(_srcWindowHandle, out var phSurface, out _, out _, out _, out _); // 2nd, render window using shared handle - NativeMethods.Render(hSurface, phSurface, _clientX, _clientY, _clientWidth, _clientHeight, isNewSurface); + var hr = NativeMethods.Render(hSurface, phSurface, _clientX, _clientY, _clientWidth, _clientHeight, isNewSurface); + if (hr == 0) + return; + + // たまに phSurface でのリソース共有に失敗することがあるらしい + StopRender(); + Release(); + Kill(); } public void StopRender() diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index 11f8eb2..b187fde 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -87,6 +87,7 @@ private async Task Heartbeat() } catch (Exception) { + StatusTextService.Instance.Status = "Heartbeat failed, disconnect from background process."; if (_process == null) return; _disposable.Dispose(); From 044e559d0058f6f9ae1ec0d2942e5b43cc74ff49 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 11 Aug 2018 15:45:35 +0900 Subject: [PATCH 142/167] docs(readme): Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7111b9..c6bb64f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Robock -[![License](https://img.shields.io/github/license/mika-f/robock.svg?style=flat-square)](./blob/develop/LICENSE) + +[![License](https://img.shields.io/github/license/mika-f/robock.svg?style=flat-square)](LICENSE) > Robock is experimental software. Please use it at your own risk. @@ -31,4 +32,5 @@ I would like to deal with this problem, but I don't know how to fix it. ## Donation +If you want to support me, you can donate cryptocurrencies here. https://mochizuki.moe/donation From 5a96a274ad3f5132733af6480bf15057ce533900 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 12 Aug 2018 03:11:03 +0900 Subject: [PATCH 143/167] style(native): PS/VS --- Source/Robock.Background.Native/DxRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 3feb28c..5bb1c00 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -59,8 +59,8 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int this->_deviceContext->ClearRenderTargetView(this->_renderTargetView, clearColor); this->_deviceContext->VSSetShader(this->_vertexShader, nullptr, 0); - this->_deviceContext->PSSetShader(this->_pixelShader, nullptr, 0); + this->_deviceContext->PSSetShader(this->_pixelShader, nullptr, 0); this->_deviceContext->PSSetSamplers(0, 1, &this->_samplerState); this->_deviceContext->PSSetShaderResources(0, 1, &this->_shaderResourceView); From 3c9599fb3e688f6d097a59a84b46494a08a5d516 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 12 Aug 2018 17:58:23 +0900 Subject: [PATCH 144/167] feat(native): Coords --- .../Robock.Background.Native/DxRenderer.cpp | 36 +++++++++++++++++++ Source/Robock.Background.Native/DxRenderer.h | 9 +++++ .../Robock.Background.Native/PixelShader.hlsl | 10 +++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index 5bb1c00..bf5c97b 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -22,6 +22,7 @@ DxRenderer::DxRenderer() this->_pixelShader = nullptr; this->_samplerState = nullptr; this->_shaderResourceView = nullptr; + this->_constantBuffer = nullptr; } HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int x, const int y, const int width, const int height, const bool isNewSurface) @@ -58,9 +59,34 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int const float clearColor[4] = {0, 0, 0, 1}; // RGBA this->_deviceContext->ClearRenderTargetView(this->_renderTargetView, clearColor); + // Transform Coords + ConstantBuffer buffer{}; + if (height == 0) + { + buffer.Top = 0.0f; + buffer.Height = 3.0f; + } + else + { + buffer.Top = float(y) / this->_height; + buffer.Height = float(height) / this->_height; + } + if (width == 0) + { + buffer.Left = 0.0f; + buffer.Width = 3.0f; + } + else + { + buffer.Width = float(width) / this->_width; + buffer.Left = float(x) / this->_width; + } + this->_deviceContext->UpdateSubresource(this->_constantBuffer, 0, nullptr, &buffer, 0, 0); + this->_deviceContext->VSSetShader(this->_vertexShader, nullptr, 0); this->_deviceContext->PSSetShader(this->_pixelShader, nullptr, 0); + this->_deviceContext->PSSetConstantBuffers(0, 1, &this->_constantBuffer); this->_deviceContext->PSSetSamplers(0, 1, &this->_samplerState); this->_deviceContext->PSSetShaderResources(0, 1, &this->_shaderResourceView); @@ -87,6 +113,7 @@ HRESULT DxRenderer::Release() SAFE_RELEASE(this->_pixelShader); SAFE_RELEASE(this->_samplerState); SAFE_RELEASE(this->_shaderResourceView); + SAFE_RELEASE(this->_constantBuffer); return S_OK; } @@ -244,6 +271,15 @@ HRESULT DxRenderer::LoadShader() this->_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.ByteWidth = sizeof ConstantBuffer; + bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bufferDesc.CPUAccessFlags = 0; + + hr = this->_device->CreateBuffer(&bufferDesc, nullptr, &this->_constantBuffer); + if (FAILED(hr)) + return this->MsgBox(hr, L"LoadShader#CreateBuffer"); + D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC)); samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index 9089c75..8a5b992 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -32,6 +32,7 @@ class DxRenderer ID3D11PixelShader* _pixelShader{}; ID3D11SamplerState* _samplerState{}; ID3D11ShaderResourceView* _shaderResourceView{}; + ID3D11Buffer* _constantBuffer{}; }; struct SimpleVertex @@ -39,3 +40,11 @@ struct SimpleVertex DirectX::XMFLOAT3 Pos; DirectX::XMFLOAT2 Uv; }; + +struct ConstantBuffer +{ + float Top; + float Left; + float Width; + float Height; +}; diff --git a/Source/Robock.Background.Native/PixelShader.hlsl b/Source/Robock.Background.Native/PixelShader.hlsl index 46b6c7b..a5017f8 100644 --- a/Source/Robock.Background.Native/PixelShader.hlsl +++ b/Source/Robock.Background.Native/PixelShader.hlsl @@ -1,6 +1,14 @@ Texture2D tex2D : register (t0); SamplerState sampleLinear : register(s0); +cbuffer ConstantBuffer : register(b0) +{ + float Top; + float Left; + float Width; + float Height; +}; + struct VS_INPUT { float4 Pos: SV_POSITION; @@ -9,5 +17,5 @@ struct VS_INPUT float4 PS(VS_INPUT input) : SV_Target { - return tex2D.Sample(sampleLinear, input.Tex); + return tex2D.Sample(sampleLinear, input.Tex * float2(Width, Height) + float2(Left, Top)); } \ No newline at end of file From 28d6cd3c9e877539900e27c58ad2c660e3be040e Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 12 Aug 2018 18:39:46 +0900 Subject: [PATCH 145/167] feat(native): Fix rendering coords. --- .../Robock.Background.Native/DxRenderer.cpp | 51 ++++++++----------- Source/Robock.Background.Native/DxRenderer.h | 6 ++- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index bf5c97b..a1cfb87 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -9,8 +9,10 @@ using namespace PackedVector; DxRenderer::DxRenderer() { this->_currentDwnSurface = nullptr; - this->_width = 0; - this->_height = 0; + this->_screenWidth = 0; + this->_screenHeight = 0; + this->_textureWidth = 0; + this->_textureHeight = 0; this->_driverType = D3D_DRIVER_TYPE_NULL; this->_featureLevel = D3D_FEATURE_LEVEL_11_0; this->_device = nullptr; @@ -50,9 +52,15 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int if (FAILED(hr)) return this->MsgBox(hr, L"Render#QueryInterface"); + D3D11_TEXTURE2D_DESC texture2DDesc; + texture2D->GetDesc(&texture2DDesc); + this->_textureWidth = texture2DDesc.Width; + this->_textureHeight = texture2DDesc.Height; + hr = this->_device->CreateShaderResourceView(texture2D, nullptr, &this->_shaderResourceView); if (FAILED(hr)) return this->MsgBox(hr, L"Render#CreateShaderResourceView"); + this->_currentDwnSurface = phDwmSurface; } @@ -61,26 +69,11 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int // Transform Coords ConstantBuffer buffer{}; - if (height == 0) - { - buffer.Top = 0.0f; - buffer.Height = 3.0f; - } - else - { - buffer.Top = float(y) / this->_height; - buffer.Height = float(height) / this->_height; - } - if (width == 0) - { - buffer.Left = 0.0f; - buffer.Width = 3.0f; - } - else - { - buffer.Width = float(width) / this->_width; - buffer.Left = float(x) / this->_width; - } + buffer.Top = float(y) / this->_textureHeight; + buffer.Height = float(height) / this->_textureHeight; + buffer.Width = float(width) / this->_textureWidth; + buffer.Left = float(x) / this->_textureWidth; + this->_deviceContext->UpdateSubresource(this->_constantBuffer, 0, nullptr, &buffer, 0, 0); this->_deviceContext->VSSetShader(this->_vertexShader, nullptr, 0); @@ -100,8 +93,8 @@ HRESULT DxRenderer::Render(void* phWindowSurface, void* phDwmSurface, const int HRESULT DxRenderer::Release() { this->_currentDwnSurface = nullptr; - this->_width = 0; - this->_height = 0; + this->_screenWidth = 0; + this->_screenHeight = 0; this->_driverType = D3D_DRIVER_TYPE_NULL; this->_featureLevel = D3D_FEATURE_LEVEL_11_0; SAFE_RELEASE(this->_device); @@ -197,13 +190,13 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) D3D11_TEXTURE2D_DESC resourceDesc; output->GetDesc(&resourceDesc); - if (resourceDesc.Width != this->_width || resourceDesc.Height != this->_height) + if (resourceDesc.Width != this->_screenWidth || resourceDesc.Height != this->_screenHeight) { D3D11_VIEWPORT viewport; - this->_width = resourceDesc.Width; - this->_height = resourceDesc.Height; - viewport.Width = static_cast(this->_width); - viewport.Height = static_cast(this->_height); + this->_screenWidth = resourceDesc.Width; + this->_screenHeight = resourceDesc.Height; + viewport.Width = static_cast(this->_screenWidth); + viewport.Height = static_cast(this->_screenHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0; diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index 8a5b992..5540acb 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -17,8 +17,10 @@ class DxRenderer static HRESULT MsgBox(HRESULT hr, LPCWSTR lpText); void* _currentDwnSurface; - int _width; - int _height; + int _screenWidth; + int _screenHeight; + int _textureWidth; + int _textureHeight; D3D_DRIVER_TYPE _driverType{}; D3D_FEATURE_LEVEL _featureLevel{}; From fcd31d87130a88ef24c6ca6a666f086dac3c99c9 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 12 Aug 2018 19:05:56 +0900 Subject: [PATCH 146/167] chore(build): Configure for x64 release build --- .../Robock.Background.Native.vcxproj | 11 +++++++++++ Source/Robock.sln | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index 68df08c..d26cf57 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -142,6 +142,7 @@ true NDEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true + $(OutDir);%(AdditionalIncludeDirectories) Windows @@ -182,6 +183,11 @@ 5.0 + PS + 5.0 + $(OutDir)%(Filename).h + + Vertex @@ -193,6 +199,11 @@ $(OutDir)%(Filename).h + VS + 5.0 + + + $(OutDir)%(Filename).h diff --git a/Source/Robock.sln b/Source/Robock.sln index 7ffbe56..d375aaf 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -36,8 +36,8 @@ Global {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.Build.0 = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|x64 - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|x64 + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.ActiveCfg = Debug|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.Build.0 = Debug|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.ActiveCfg = Release|x64 From 087f62c3201d8976670c26a8494ce85e95ac7706 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 12 Aug 2018 22:51:18 +0900 Subject: [PATCH 147/167] chore(background): Fix dist path --- Source/Robock.Background/Robock.Background.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index d6e658c..8a4a01f 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -47,7 +47,7 @@ true - bin\x64\Release\ + ..\Robock\bin\x64\Release\ TRACE true pdbonly From faa1bc251f861c45ee81182282a0acab4b9c12e9 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sun, 12 Aug 2018 23:23:11 +0900 Subject: [PATCH 148/167] docs(readme): Add video link --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c6bb64f..3a31394 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ Window Capture + Dynamic Wallpaper = Good Experience +## Video + +[![](https://img.youtube.com/vi/3HdT_-mdNBM/0.jpg)](https://www.youtube.com/watch?v=3HdT_-mdNBM) + + ## Requirements * Windows 10 (1804 ~) From 5bdbad6c43808473f8b2aa4a7c6c27c4479534c5 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 13 Aug 2018 08:48:20 +0900 Subject: [PATCH 149/167] chore(native): Error dialog --- Source/Robock.Background.Native/DxRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index a1cfb87..d586cfb 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -186,7 +186,7 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) hr = this->_device->CreateRenderTargetView(output, &renderTargetDesc, &this->_renderTargetView); if (FAILED(hr)) - return hr; + return this->MsgBox(hr, L"InitRenderTarget#CreateRenderTargetView"); D3D11_TEXTURE2D_DESC resourceDesc; output->GetDesc(&resourceDesc); From 843de3c2cfb15af3b90f0ce1b80607d0e7724d33 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 13 Aug 2018 23:47:06 +0900 Subject: [PATCH 150/167] chore(background): Fix typo --- Source/Robock.Background/Models/BackgroundService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 55249f0..5e19434 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -85,7 +85,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) CompositionTarget.Rendering += CompositionTargetOnRendering; }); - // 2st, find WorkerW and send 0x052C (undocumented) message to progman + // 2nd, find WorkerW and send 0x052C (undocumented) message to progman var workerW = FindWorkerW(); if (workerW == IntPtr.Zero) Debug.WriteLine("WARNING: Unknown desktop structure"); // SHELLDLL_DefView だとか WorkerW なくても動くが、ログだけ残しとく From ff3cce10c0a8e47708748ce342dddc49b78449e3 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 14 Aug 2018 08:21:12 +0900 Subject: [PATCH 151/167] chore: async --- Source/Robock/Models/RobockClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 0ce94e7..5e86ce0 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -36,7 +36,7 @@ public async Task Handshake(int x, int y, int height, int width) } catch { - Task.Delay(TimeSpan.FromMilliseconds(100)).Wait(); + await Task.Delay(TimeSpan.FromMilliseconds(100)); } } From 5cde502f3aea0f8da999c61b5feb3ef3d04f75d9 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 14 Aug 2018 19:25:15 +0900 Subject: [PATCH 152/167] feat(core): Close #4 --- Source/Robock/ViewModels/AppShellViewModel.cs | 7 +++++++ Source/Robock/ViewModels/Tabs/DesktopViewModel.cs | 1 + Source/Robock/Views/AppShell.xaml | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Robock/ViewModels/AppShellViewModel.cs b/Source/Robock/ViewModels/AppShellViewModel.cs index 8a5e213..e1de233 100644 --- a/Source/Robock/ViewModels/AppShellViewModel.cs +++ b/Source/Robock/ViewModels/AppShellViewModel.cs @@ -35,6 +35,13 @@ public AppShellViewModel() { new AboutTabViewModel() }; + Tabs.ToCollectionChanged().Subscribe(w => + { + if (!(w.Value is DesktopViewModel model) || !model.IsPrimary) + return; + VirtualScreen.SelectedIndex.Value = w.Index; + model.IsSelected.Value = true; + }); VirtualScreen = new VirtualScreenViewModel(); // Subscribe diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index d22e637..75840ee 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -57,6 +57,7 @@ public class DesktopViewModel : TabViewModel public string DesktopName => $"Desktop {_desktop.No}"; public string Resolution => $"{_desktop.Width}x{_desktop.Height}"; + public bool IsPrimary => _desktop.IsPrimary; public double VirtualScreenX => (_offsetX + _desktop.X) / Scale; public double VirtualScreenY => (_offsetY + _desktop.Y) / Scale; diff --git a/Source/Robock/Views/AppShell.xaml b/Source/Robock/Views/AppShell.xaml index e52d98b..fdb4ef3 100644 --- a/Source/Robock/Views/AppShell.xaml +++ b/Source/Robock/Views/AppShell.xaml @@ -77,7 +77,7 @@ Background="{DynamicResource BackgroundBrushKey}" BorderThickness="0" ItemsSource="{Binding Tabs}" - SelectedIndex="{Binding VirtualScreen.SelectedIndex.Value, Mode=OneWayToSource}"> + SelectedIndex="{Binding VirtualScreen.SelectedIndex.Value, Mode=TwoWay}"> From 901b9a99f462d06c8a7b91ce6837eef5c34d46f6 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 14 Aug 2018 21:25:16 +0900 Subject: [PATCH 153/167] refactor(core): Placeholder image to FakeImg class * placehold.mochizuki.moe is obsoleted. --- Source/Robock.Shared/Models/RectUtil.cs | 18 --------- Source/Robock.Shared/Models/RobockUtil.cs | 38 +++++++++++++++++++ Source/Robock/Models/AspectHelper.cs | 22 ----------- Source/Robock/Models/FakeImg.cs | 19 ++++++++++ .../ViewModels/Tabs/DesktopViewModel.cs | 10 ++--- .../ViewModels/VirtualScreenViewModel.cs | 2 +- 6 files changed, 63 insertions(+), 46 deletions(-) delete mode 100644 Source/Robock.Shared/Models/RectUtil.cs create mode 100644 Source/Robock.Shared/Models/RobockUtil.cs create mode 100644 Source/Robock/Models/FakeImg.cs diff --git a/Source/Robock.Shared/Models/RectUtil.cs b/Source/Robock.Shared/Models/RectUtil.cs deleted file mode 100644 index d0a05c8..0000000 --- a/Source/Robock.Shared/Models/RectUtil.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Robock.Shared.Win32; - -namespace Robock.Shared.Models -{ - public static class RectUtil - { - public static RECT AsRect(double top, double left, double height, double width, double multi = 1) - { - return new RECT - { - top = (int) (top * multi), - left = (int) (left * multi), - bottom = (int) ((top + height) * multi), - right = (int) ((left + width) * multi) - }; - } - } -} \ No newline at end of file diff --git a/Source/Robock.Shared/Models/RobockUtil.cs b/Source/Robock.Shared/Models/RobockUtil.cs new file mode 100644 index 0000000..704b55d --- /dev/null +++ b/Source/Robock.Shared/Models/RobockUtil.cs @@ -0,0 +1,38 @@ +using System; + +using Robock.Shared.Win32; + +namespace Robock.Shared.Models +{ + public static class RobockUtil + { + public static RECT AsRect(double top, double left, double height, double width, double multi = 1) + { + return new RECT + { + top = (int) (top * multi), + left = (int) (left * multi), + bottom = (int) ((top + height) * multi), + right = (int) ((left + width) * multi) + }; + } + + /// + /// height, width におけるアスペクト比を求めます。 + /// + /// + /// + /// WxH + public static (double, double) AspectRatio(double width, double height) + { + // ReSharper disable once RedundantAssignment + var (a, b, remainder) = (height, width, .0); + do + { + remainder = a % b; + (a, b) = (b, remainder); + } while (Math.Abs(remainder) > 0); + return (width / a, height / a); + } + } +} \ No newline at end of file diff --git a/Source/Robock/Models/AspectHelper.cs b/Source/Robock/Models/AspectHelper.cs index 9843c7b..5f8d600 100644 --- a/Source/Robock/Models/AspectHelper.cs +++ b/Source/Robock/Models/AspectHelper.cs @@ -5,27 +5,5 @@ namespace Robock.Models { public static class AspectHelper { - /// - /// height, width におけるアスペクト比を求めます。 - /// - /// - /// - /// WxH - public static string Calc(double height, double width) - { - // ReSharper disable once RedundantAssignment - var (a, b, remainder) = (height, width, .0); - do - { - remainder = a % b; - (a, b) = (b, remainder); - } while (Math.Abs(remainder) > 0); - return $"{width / a}x{height / a}"; - } - - public static Size AsSize(string aspectRatio) - { - return new Size {Height = int.Parse(aspectRatio.Split('x')[1]), Width = int.Parse(aspectRatio.Split('x')[0])}; - } } } \ No newline at end of file diff --git a/Source/Robock/Models/FakeImg.cs b/Source/Robock/Models/FakeImg.cs new file mode 100644 index 0000000..e81a308 --- /dev/null +++ b/Source/Robock/Models/FakeImg.cs @@ -0,0 +1,19 @@ +namespace Robock.Models +{ + public static class FakeImg + { + private const string Domain = "https://fakeimg.mochizuki.moe"; + + public static string Default => HxW(1, 1); + + public static string HxW(int height, int width) + { + return $"{Domain}/{height}x{width}/000000%2C000/000000%2C000/"; + } + + public static string HxW((double, double) tuple) + { + return HxW((int) tuple.Item1, (int) tuple.Item2); + } + } +} \ No newline at end of file diff --git a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs index 75840ee..faeaea3 100644 --- a/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs +++ b/Source/Robock/ViewModels/Tabs/DesktopViewModel.cs @@ -89,7 +89,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin }).AddTo(this); // エディター - EditorAspectRatio = new ReactiveProperty("https://placehold.mochizuki.moe/1x1/"); + EditorAspectRatio = new ReactiveProperty(FakeImg.Default); EditorAreaLeft = new ReactiveProperty(); EditorAreaTop = new ReactiveProperty(); EditorAreaHeight = new ReactiveProperty(); @@ -105,7 +105,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin desktopWindowManager.Thumbnails[0].ObserveProperty(w => w.Size).Subscribe(w => { // - EditorAspectRatio.Value = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(w.Height, w.Width)}/000000%2C000/000000%2C000/"; + EditorAspectRatio.Value = FakeImg.HxW(RobockUtil.AspectRatio(w.Width, w.Height)); }).AddTo(this); // 選択範囲 @@ -123,7 +123,7 @@ public DesktopViewModel(Desktop desktop, WindowManager windowManager, DesktopWin .Where(w => CanRender()).Subscribe(w => Render(1)).AddTo(this); // プレビュー - AspectRatio = $"https://placehold.mochizuki.moe/{AspectHelper.Calc(_desktop.Height, _desktop.Width)}/000000%2C000/000000%2C000/"; + AspectRatio = FakeImg.HxW(RobockUtil.AspectRatio(_desktop.Width, _desktop.Height)); PreviewAreaLeft = new ReactiveProperty(); PreviewAreaTop = new ReactiveProperty(); PreviewAreaHeight = new ReactiveProperty(); @@ -202,7 +202,7 @@ private void Render(int index) } else { - var rect = RectUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[0].Size.Height, _desktopWindowManager.Thumbnails[0].Size.Width); + var rect = RobockUtil.AsRect(0, 0, _desktopWindowManager.Thumbnails[0].Size.Height, _desktopWindowManager.Thumbnails[0].Size.Width); if (SelectedAreaHeight.Value != 0) rect = CalcRenderingRect(); @@ -227,7 +227,7 @@ private RECT CalcRenderingRect() // Grid と Image のズレが大きいと、描画領域がずれてしまうので、補正する var diff = new Size(EditorAreaLeft.Value - GridAreaLeft.Value, EditorAreaTop.Value - GridAreaTop.Value); - return RectUtil.AsRect(SelectedAreaTop.Value - diff.Height, SelectedAreaLeft.Value - diff.Width, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi); + return RobockUtil.AsRect(SelectedAreaTop.Value - diff.Height, SelectedAreaLeft.Value - diff.Width, SelectedAreaHeight.Value, SelectedAreaWidth.Value, multi); } } } \ No newline at end of file diff --git a/Source/Robock/ViewModels/VirtualScreenViewModel.cs b/Source/Robock/ViewModels/VirtualScreenViewModel.cs index b0c62d7..9e412ad 100644 --- a/Source/Robock/ViewModels/VirtualScreenViewModel.cs +++ b/Source/Robock/ViewModels/VirtualScreenViewModel.cs @@ -24,7 +24,7 @@ public VirtualScreenViewModel() { Desktops = new ObservableCollection(); SelectedIndex = new ReactiveProperty(0); - SelectedIndex.Where(w => w >= 0).Subscribe(w => + SelectedIndex.Where(w => 0 <= w).Subscribe(w => { foreach (var desktop in Desktops) desktop.IsSelected.Value = false; From a80227397035afad27d2dd05368372385d9547a1 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 14 Aug 2018 21:28:06 +0900 Subject: [PATCH 154/167] chore(build): Fix --- Source/Robock.Shared/Robock.Shared.csproj | 2 +- Source/Robock/Robock.csproj | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 9868eaa..8e34de5 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -60,7 +60,7 @@ - + diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index a30d269..925b0af 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -146,6 +146,7 @@ + From b0e11cd482dd618759d9726f12a76a393d1db5e7 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 15 Aug 2018 07:49:39 +0900 Subject: [PATCH 155/167] refactor(core): Remove unused param/class. --- Source/Robock/Models/AspectHelper.cs | 9 --------- Source/Robock/Models/Desktop.cs | 4 ++-- Source/Robock/Robock.csproj | 1 - 3 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 Source/Robock/Models/AspectHelper.cs diff --git a/Source/Robock/Models/AspectHelper.cs b/Source/Robock/Models/AspectHelper.cs deleted file mode 100644 index 5f8d600..0000000 --- a/Source/Robock/Models/AspectHelper.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Drawing; - -namespace Robock.Models -{ - public static class AspectHelper - { - } -} \ No newline at end of file diff --git a/Source/Robock/Models/Desktop.cs b/Source/Robock/Models/Desktop.cs index b187fde..7626b4e 100644 --- a/Source/Robock/Models/Desktop.cs +++ b/Source/Robock/Models/Desktop.cs @@ -33,9 +33,9 @@ public class Desktop : BindableBase, IDisposable public Desktop(Screen screen, int index) { _screen = screen; - No = index; _uuid = $"Background.Desktop{index}"; _client = new RobockClient(_uuid); + No = index; } public void Dispose() @@ -50,7 +50,7 @@ public void Dispose() } } - public async Task Handshake(Action action = null) + public async Task Handshake() { _process = Process.Start("Robock.Background.exe", $"{_uuid}"); if (_process == null) diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 925b0af..259c5ea 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -149,7 +149,6 @@ - From 34a7e22e7d66c9a8e5ed999195e1679065009fbc Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 15 Aug 2018 21:55:21 +0900 Subject: [PATCH 156/167] chore(myst): Add submodule --- .gitmodules | 3 ++ Source/Myst | 1 + Source/Robock.sln | 26 ++++++++++ Source/Robock/App.xaml | 2 +- Source/Robock/Robock.csproj | 13 ++--- Source/Robock/Styles/Controls.TabControl.xaml | 51 ------------------- Source/Robock/Styles/Controls.xaml | 5 -- 7 files changed, 35 insertions(+), 66 deletions(-) create mode 100644 .gitmodules create mode 160000 Source/Myst delete mode 100644 Source/Robock/Styles/Controls.TabControl.xaml delete mode 100644 Source/Robock/Styles/Controls.xaml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6a22a2b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Source\\Myst"] + path = Source\\Myst + url = git@github.com:mika-f/Myst.git diff --git a/Source/Myst b/Source/Myst new file mode 160000 index 0000000..0ff6195 --- /dev/null +++ b/Source/Myst @@ -0,0 +1 @@ +Subproject commit 0ff61954259e424f7bb70a027208d0f35f91c22d diff --git a/Source/Robock.sln b/Source/Robock.sln index d375aaf..f91e423 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -20,28 +20,54 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Robock.Background", "Robock EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Robock.Background.Native", "Robock.Background.Native\Robock.Background.Native.vcxproj", "{9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Myst", "Myst\Source\Myst\Myst.csproj", "{07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|Any CPU.Build.0 = Debug|Any CPU {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.ActiveCfg = Debug|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.Build.0 = Debug|x64 + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|Any CPU.Build.0 = Release|Any CPU {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.ActiveCfg = Release|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.Build.0 = Release|x64 + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.ActiveCfg = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.Build.0 = Debug|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|Any CPU.Build.0 = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.ActiveCfg = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.Build.0 = Release|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|Any CPU.Build.0 = Debug|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|x64 + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|Any CPU.Build.0 = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|x64 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|Any CPU.ActiveCfg = Debug|Win32 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.ActiveCfg = Debug|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.Build.0 = Debug|x64 + {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|Any CPU.ActiveCfg = Release|Win32 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.ActiveCfg = Release|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.Build.0 = Release|x64 + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|x64.ActiveCfg = Debug|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|x64.Build.0 = Debug|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|Any CPU.Build.0 = Release|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|x64.ActiveCfg = Release|Any CPU + {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Source/Robock/App.xaml b/Source/Robock/App.xaml index dc92e53..80d8048 100644 --- a/Source/Robock/App.xaml +++ b/Source/Robock/App.xaml @@ -8,7 +8,7 @@ - + diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 259c5ea..06af36f 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -178,15 +178,6 @@ DesktopTab.xaml - - Designer - MSBuild:Compile - Controls.xaml - - - Designer - MSBuild:Compile - Designer MSBuild:Compile @@ -236,6 +227,10 @@ + + {07b370e8-a053-4d3e-b3a1-a205e5f7cccd} + Myst + {07becf0b-6e07-4ac5-b0c2-3eae0539d9a2} Robock.Shared diff --git a/Source/Robock/Styles/Controls.TabControl.xaml b/Source/Robock/Styles/Controls.TabControl.xaml deleted file mode 100644 index 5bbdd10..0000000 --- a/Source/Robock/Styles/Controls.TabControl.xaml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Source/Robock/Styles/Controls.xaml b/Source/Robock/Styles/Controls.xaml deleted file mode 100644 index 7e6926a..0000000 --- a/Source/Robock/Styles/Controls.xaml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file From 9a6d7ab9ecf1e6cc61ebed30077acb111b669d58 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Wed, 15 Aug 2018 21:59:25 +0900 Subject: [PATCH 157/167] chore(build): Remove "Any CPU" --- .../Robock.Background.Native.vcxproj | 71 ------------------- .../Robock.Background.csproj | 19 ----- Source/Robock.sln | 20 ------ Source/Robock/Robock.csproj | 19 ----- 4 files changed, 129 deletions(-) diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index d26cf57..4454728 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -1,14 +1,6 @@ - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -26,19 +18,6 @@ 10.0.17134.0 - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - DynamicLibrary true @@ -57,12 +36,6 @@ - - - - - - @@ -74,12 +47,6 @@ true ..\Robock\bin\x64\Debug - - true - - - false - false ..\Robock\bin\x64\Release @@ -100,38 +67,6 @@ d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies) - - - Use - Level3 - Disabled - true - WIN32;_DEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - - - Windows - true - - - - - Use - Level3 - MaxSpeed - true - true - true - WIN32;NDEBUG;ROBOCKBACKGROUNDNATIVE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - Use @@ -164,8 +99,6 @@ Create - Create - Create Create @@ -175,8 +108,6 @@ Pixel - Pixel - Pixel Pixel PS $(OutDir)%(Filename).h @@ -191,8 +122,6 @@ Vertex - Vertex - Vertex Vertex VS 5.0 diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index 8a4a01f..b73258a 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -14,25 +14,6 @@ 4 true - - AnyCPU - true - full - false - ..\Robock\bin\x64\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - ..\Robock\bin\x64\Release\ - TRACE - prompt - 4 - app.manifest diff --git a/Source/Robock.sln b/Source/Robock.sln index f91e423..eb945db 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -24,48 +24,28 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Myst", "Myst\Source\Myst\My EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|Any CPU.Build.0 = Debug|Any CPU {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.ActiveCfg = Debug|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Debug|x64.Build.0 = Debug|x64 - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|Any CPU.Build.0 = Release|Any CPU {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.ActiveCfg = Release|x64 {829FE68D-DA01-4FFA-9992-032CCEE00BEF}.Release|x64.Build.0 = Release|x64 - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.ActiveCfg = Debug|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Debug|x64.Build.0 = Debug|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|Any CPU.Build.0 = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.ActiveCfg = Release|Any CPU {07BECF0B-6E07-4AC5-B0C2-3EAE0539D9A2}.Release|x64.Build.0 = Release|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|Any CPU.Build.0 = Debug|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.ActiveCfg = Debug|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Debug|x64.Build.0 = Debug|x64 - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|Any CPU.Build.0 = Release|Any CPU {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.ActiveCfg = Release|x64 {F3D75D1B-A861-44A9-A88B-BFAA4D5E77AD}.Release|x64.Build.0 = Release|x64 - {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|Any CPU.ActiveCfg = Debug|Win32 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.ActiveCfg = Debug|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Debug|x64.Build.0 = Debug|x64 - {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|Any CPU.ActiveCfg = Release|Win32 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.ActiveCfg = Release|x64 {9EA33D1B-E569-4E0C-BB36-1BCC899FF1E3}.Release|x64.Build.0 = Release|x64 - {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|Any CPU.Build.0 = Debug|Any CPU {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|x64.ActiveCfg = Debug|Any CPU {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Debug|x64.Build.0 = Debug|Any CPU - {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|Any CPU.Build.0 = Release|Any CPU {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|x64.ActiveCfg = Release|Any CPU {07B370E8-A053-4D3E-B3A1-A205E5F7CCCD}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 06af36f..827e8d0 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -14,25 +14,6 @@ 4 true - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true bin\x64\Debug\ From 703757958bf70fac7b3100b6b2306c3db46b86c8 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Sat, 18 Aug 2018 01:36:45 +0900 Subject: [PATCH 158/167] docs(readme): Update README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a31394..53be6af 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Window Capture + Dynamic Wallpaper = Good Experience * .NET Framework 4.7.2 ~ * DirectX 11 ~ * Video Card that supports Windows Display Driver Model -* Internet Connection (Robock will connect to placehold.mochizuki.moe) +* Internet Connection (Robock will connect to https://fakeimg.mochizuki.moe) ## Note From 1a4320fc058cc65d733e42be23de305743d5e403 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 27 Aug 2018 22:19:11 +0900 Subject: [PATCH 159/167] fix(background): If exists WorkerW process, use it. --- .../Models/BackgroundService.cs | 14 +++- Source/Robock.Background/app.manifest | 5 +- Source/Robock.Shared/Models/RobockUtil.cs | 15 ++++ Source/Robock.Shared/Robock.Shared.csproj | 4 + Source/Robock.Shared/app.manifest | 73 +++++++++++++++++++ Source/Robock/app.manifest | 4 +- 6 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 Source/Robock.Shared/app.manifest diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 5e19434..9ccdf94 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -7,6 +7,7 @@ using Microsoft.Wpf.Interop.DirectX; +using Robock.Shared.Models; using Robock.Shared.Win32; using Application = System.Windows.Application; @@ -92,7 +93,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) var progman = NativeMethods.FindWindow("Progman", null); // 3rd, stick myself to progman - NativeMethods.SetParent(_hWnd, progman); + NativeMethods.SetParent(_hWnd, workerW == IntPtr.Zero ? progman : workerW); // 4th, move self to rendering position NativeMethods.MoveWindow(_hWnd, _windowX, _windowY, _windowWidth, _windowHeight, true); @@ -172,8 +173,15 @@ public void Kill() private IntPtr FindWorkerW() { var progman = NativeMethods.FindWindow("Progman", null); - NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out _); - + if (RobockUtil.IsOldWindows()) + { + NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0), IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out _); + } + else + { + NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0x0000000D), new IntPtr(0), SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out _); + NativeMethods.SendMessageTimeout(progman, 0x052C, new IntPtr(0x0000000D), new IntPtr(1), SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out _); + } var workerW = IntPtr.Zero; NativeMethods.EnumWindows((hWnd, lParam) => { diff --git a/Source/Robock.Background/app.manifest b/Source/Robock.Background/app.manifest index b6cdff5..19173b4 100644 --- a/Source/Robock.Background/app.manifest +++ b/Source/Robock.Background/app.manifest @@ -1,4 +1,5 @@  + @@ -37,10 +38,10 @@ - + - + diff --git a/Source/Robock.Shared/Models/RobockUtil.cs b/Source/Robock.Shared/Models/RobockUtil.cs index 704b55d..8b09ed8 100644 --- a/Source/Robock.Shared/Models/RobockUtil.cs +++ b/Source/Robock.Shared/Models/RobockUtil.cs @@ -1,5 +1,7 @@ using System; +using Microsoft.Win32; + using Robock.Shared.Win32; namespace Robock.Shared.Models @@ -34,5 +36,18 @@ public static (double, double) AspectRatio(double width, double height) } while (Math.Abs(remainder) > 0); return (width / a, height / a); } + + /// + /// Windows 10 1703 (Creators Update) 以前の場合は true を返します。 + /// + /// + public static bool IsOldWindows() + { + if (Environment.OSVersion.Version.Major < 10) + return true; + + var release = int.Parse(Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ReleaseId", "1000").ToString()); + return release < 1709; + } } } \ No newline at end of file diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 8e34de5..5c12c19 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -30,6 +30,9 @@ prompt 4 + + app.manifest + @@ -78,6 +81,7 @@ + diff --git a/Source/Robock.Shared/app.manifest b/Source/Robock.Shared/app.manifest new file mode 100644 index 0000000..059a9a0 --- /dev/null +++ b/Source/Robock.Shared/app.manifest @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Robock/app.manifest b/Source/Robock/app.manifest index 3b0c66e..19173b4 100644 --- a/Source/Robock/app.manifest +++ b/Source/Robock/app.manifest @@ -38,10 +38,10 @@ - + - + From 3972abb9645bc59b6328c08806de3ee7d0e6b592 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 27 Aug 2018 22:23:08 +0900 Subject: [PATCH 160/167] fix(background): revert --- Source/Robock.Background/Models/BackgroundService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 9ccdf94..38597b9 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -93,7 +93,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) var progman = NativeMethods.FindWindow("Progman", null); // 3rd, stick myself to progman - NativeMethods.SetParent(_hWnd, workerW == IntPtr.Zero ? progman : workerW); + NativeMethods.SetParent(_hWnd, progman); // 4th, move self to rendering position NativeMethods.MoveWindow(_hWnd, _windowX, _windowY, _windowWidth, _windowHeight, true); From fa9ca5491541c142c5af583aabb9bb7773942540 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 27 Aug 2018 22:26:32 +0900 Subject: [PATCH 161/167] fix(text): Fix typo --- Source/Robock.sln.DotSettings | 2 ++ Source/Robock/Models/RobockClient.cs | 4 ++-- Source/Robock/Models/WindowManager.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 Source/Robock.sln.DotSettings diff --git a/Source/Robock.sln.DotSettings b/Source/Robock.sln.DotSettings new file mode 100644 index 0000000..6ccfa19 --- /dev/null +++ b/Source/Robock.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/Source/Robock/Models/RobockClient.cs b/Source/Robock/Models/RobockClient.cs index 5e86ce0..18c5950 100644 --- a/Source/Robock/Models/RobockClient.cs +++ b/Source/Robock/Models/RobockClient.cs @@ -44,7 +44,7 @@ public async Task ApplyWallpaper(IntPtr src, RECT rect) { if (_channel == null) throw new InvalidOperationException("Invalid connection"); - StatusTextService.Instance.Status = "Applying wallpeper..."; + StatusTextService.Instance.Status = "Applying wallpaper..."; await _channel.ApplyWallpaper(src, rect); StatusTextService.Instance.Status = "Rendering success, Start rendering"; } @@ -60,7 +60,7 @@ public async Task DiscardWallpaper() { if (_channel == null) throw new InvalidOperationException("Invalid connection"); - StatusTextService.Instance.Status = "Discarding wallpeper..."; + StatusTextService.Instance.Status = "Discarding wallpaper..."; await _channel.DiscardWallpaper(); StatusTextService.Instance.Status = "Discard wallpaper finished"; } diff --git a/Source/Robock/Models/WindowManager.cs b/Source/Robock/Models/WindowManager.cs index 03bcf8f..fd8835c 100644 --- a/Source/Robock/Models/WindowManager.cs +++ b/Source/Robock/Models/WindowManager.cs @@ -94,7 +94,7 @@ private void FindWindows() foreach (var window in Windows.ToArray().Where(w => !w.IsMarked)) Windows.Remove(window); - StatusTextService.Instance.Status = "Synchronizied windows"; + StatusTextService.Instance.Status = "Synchronized windows"; } } } \ No newline at end of file From 5cd0b6262a94e21b991788316e7ad24fc4fe982c Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Mon, 27 Aug 2018 22:37:41 +0900 Subject: [PATCH 162/167] fix(background): reset workerw --- Source/Robock.Background/Models/BackgroundService.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/Robock.Background/Models/BackgroundService.cs b/Source/Robock.Background/Models/BackgroundService.cs index 38597b9..7b767e0 100644 --- a/Source/Robock.Background/Models/BackgroundService.cs +++ b/Source/Robock.Background/Models/BackgroundService.cs @@ -93,7 +93,7 @@ public void StartRender(IntPtr hWnd, int x, int y, int width, int height) var progman = NativeMethods.FindWindow("Progman", null); // 3rd, stick myself to progman - NativeMethods.SetParent(_hWnd, progman); + NativeMethods.SetParent(_hWnd, workerW != IntPtr.Zero ? workerW : progman); // 4th, move self to rendering position NativeMethods.MoveWindow(_hWnd, _windowX, _windowY, _windowWidth, _windowHeight, true); @@ -138,10 +138,13 @@ public void StopRender() // 2nd, unregister composition rendering event. _dxImage.Dispatcher.Invoke(() => { CompositionTarget.Rendering -= CompositionTargetOnRendering; }); - // 3rd, set parent to desktop (nullptr) + // 3rd, reset workerW + FindWorkerW(); + + // 4th, set parent to desktop (nullptr) NativeMethods.SetParent(_hWnd, (IntPtr) null); - // 4th, move self to outside of desktop + // 5th, move self to outside of desktop MoveToOutsideOfVirtualScreen(); } From 4e49f3fa1d9f43cf9da623895bd4a29fc30bc0c5 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 28 Aug 2018 21:29:13 +0900 Subject: [PATCH 163/167] fix(native): Close #6 --- .../Robock.Background.Native/DxRenderer.cpp | 31 +++++++++--------- Source/Robock.Background.Native/DxRenderer.h | 2 +- Source/Robock.Background.Native/dllmain.cpp | Bin 1584 -> 1676 bytes Source/Robock.Background.Native/dllmain.h | 2 +- .../Models/BackgroundService.cs | 2 +- Source/Robock.Shared/Win32/NativeMethods.cs | 4 +-- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Source/Robock.Background.Native/DxRenderer.cpp b/Source/Robock.Background.Native/DxRenderer.cpp index d586cfb..9dea90d 100644 --- a/Source/Robock.Background.Native/DxRenderer.cpp +++ b/Source/Robock.Background.Native/DxRenderer.cpp @@ -111,8 +111,10 @@ HRESULT DxRenderer::Release() return S_OK; } -HRESULT DxRenderer::Init() +HRESULT DxRenderer::Init(const int width, const int height) { + this->_screenWidth = width; + this->_screenHeight = height; return this->InitDevice(); } @@ -190,19 +192,17 @@ HRESULT DxRenderer::InitRenderTarget(void* pResource) D3D11_TEXTURE2D_DESC resourceDesc; output->GetDesc(&resourceDesc); - if (resourceDesc.Width != this->_screenWidth || resourceDesc.Height != this->_screenHeight) - { - D3D11_VIEWPORT viewport; - this->_screenWidth = resourceDesc.Width; - this->_screenHeight = resourceDesc.Height; - viewport.Width = static_cast(this->_screenWidth); - viewport.Height = static_cast(this->_screenHeight); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - this->_deviceContext->RSSetViewports(1, &viewport); - } + + D3D11_VIEWPORT viewport; + this->_screenWidth = resourceDesc.Width; + this->_screenHeight = resourceDesc.Height; + viewport.Width = static_cast(this->_screenWidth); + viewport.Height = static_cast(this->_screenHeight); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + this->_deviceContext->RSSetViewports(1, &viewport); this->_deviceContext->OMSetRenderTargets(1, &this->_renderTargetView, nullptr); if (output != nullptr) @@ -237,10 +237,11 @@ HRESULT DxRenderer::LoadShader() if (FAILED(hr)) return this->MsgBox(hr, L"LoadShader#CreatePixelShader"); + const auto width = static_cast(this->_screenWidth); SimpleVertex vertices[] = { {XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT2(0, 1)}, - {XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT2(0, 0)}, + {XMFLOAT3(-1.0f - (20 / width), 1.0f, 1.0f), XMFLOAT2(0, 0)}, {XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1, 1)}, {XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT2(1, 0)} }; diff --git a/Source/Robock.Background.Native/DxRenderer.h b/Source/Robock.Background.Native/DxRenderer.h index 5540acb..7293be4 100644 --- a/Source/Robock.Background.Native/DxRenderer.h +++ b/Source/Robock.Background.Native/DxRenderer.h @@ -7,7 +7,7 @@ class DxRenderer HRESULT Release(); // internal - HRESULT Init(); + HRESULT Init(int width, int height); private: HRESULT InitDevice(); diff --git a/Source/Robock.Background.Native/dllmain.cpp b/Source/Robock.Background.Native/dllmain.cpp index c81de23bbbc39403981b84b0e15b10079b989360..665daccc23b64ad45ae33f8d6e6474f35472ac6e 100644 GIT binary patch delta 74 zcmdnM)5E)ggK@GGlhb4l#s(funcPtr); diff --git a/Source/Robock.Shared/Win32/NativeMethods.cs b/Source/Robock.Shared/Win32/NativeMethods.cs index ba33e63..9f8df39 100644 --- a/Source/Robock.Shared/Win32/NativeMethods.cs +++ b/Source/Robock.Shared/Win32/NativeMethods.cs @@ -29,7 +29,7 @@ public static class NativeMethods public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); [DllImport("gdi32.dll")] - public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); + public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hGdiObj); [DllImport("gdi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -115,7 +115,7 @@ public static class NativeMethods #region Robock.Background.Native [DllImport("Robock.Background.Native.dll")] - public static extern int Init(); + public static extern int Init(int width, int height); [DllImport("Robock.Background.Native.dll")] public static extern int Render(IntPtr hWindowSurface, IntPtr hDwmSurface, int x, int y, int width, int height, bool isNewSurface); From 806e5c4976b8b4ec4a3a5680aee7653e9a81a012 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 28 Aug 2018 21:45:27 +0900 Subject: [PATCH 164/167] chore(ci): Fix url of submodule --- .gitmodules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6a22a2b..db3c738 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "Source\\Myst"] - path = Source\\Myst - url = git@github.com:mika-f/Myst.git +[submodule "Source/Myst"] + path = Source/Myst + url = https://github.com/mika-f/Myst.git From b7032e90b999b10651e88b3c9c990392606200a3 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 28 Aug 2018 22:04:01 +0900 Subject: [PATCH 165/167] chore: Remove unused properties --- Source/Robock.Background/App.config | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Source/Robock.Background/App.config b/Source/Robock.Background/App.config index 4aa637f..a801cbd 100644 --- a/Source/Robock.Background/App.config +++ b/Source/Robock.Background/App.config @@ -10,14 +10,6 @@ - - - - - - - - \ No newline at end of file From 63dd131301ae2ccf56b8db7231bf893439cb7b56 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 28 Aug 2018 22:48:22 +0900 Subject: [PATCH 166/167] chore(build): for release --- Source/Myst | 2 +- .../Robock.Background.Native/Robock.Background.Native.vcxproj | 3 ++- Source/Robock.Background/Robock.Background.csproj | 2 +- Source/Robock.Shared/Robock.Shared.csproj | 2 +- Source/Robock/Robock.csproj | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Myst b/Source/Myst index 0ff6195..0366a53 160000 --- a/Source/Myst +++ b/Source/Myst @@ -1 +1 @@ -Subproject commit 0ff61954259e424f7bb70a027208d0f35f91c22d +Subproject commit 0366a5337fbb7f11b0fd12ecbb28bfd6e0af153f diff --git a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj index 4454728..0db5943 100644 --- a/Source/Robock.Background.Native/Robock.Background.Native.vcxproj +++ b/Source/Robock.Background.Native/Robock.Background.Native.vcxproj @@ -83,8 +83,9 @@ Windows true true - true + false d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies) + Default diff --git a/Source/Robock.Background/Robock.Background.csproj b/Source/Robock.Background/Robock.Background.csproj index b73258a..ce7c89b 100644 --- a/Source/Robock.Background/Robock.Background.csproj +++ b/Source/Robock.Background/Robock.Background.csproj @@ -31,7 +31,7 @@ ..\Robock\bin\x64\Release\ TRACE true - pdbonly + none x64 prompt MinimumRecommendedRules.ruleset diff --git a/Source/Robock.Shared/Robock.Shared.csproj b/Source/Robock.Shared/Robock.Shared.csproj index 5c12c19..8dc0b75 100644 --- a/Source/Robock.Shared/Robock.Shared.csproj +++ b/Source/Robock.Shared/Robock.Shared.csproj @@ -23,7 +23,7 @@ x64 - pdbonly + none true bin\Release\ TRACE diff --git a/Source/Robock/Robock.csproj b/Source/Robock/Robock.csproj index 827e8d0..eaccd5c 100644 --- a/Source/Robock/Robock.csproj +++ b/Source/Robock/Robock.csproj @@ -28,7 +28,7 @@ bin\x64\Release\ TRACE true - pdbonly + none x64 prompt MinimumRecommendedRules.ruleset From c4e0c8af60758966825859ab82dc132f4e25da02 Mon Sep 17 00:00:00 2001 From: Mikazuki Date: Tue, 28 Aug 2018 22:52:51 +0900 Subject: [PATCH 167/167] chore(ci): Setup for AppVeyor ci skip --- Source/Robock.sln | 1 + appveyor.yml | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 appveyor.yml diff --git a/Source/Robock.sln b/Source/Robock.sln index eb945db..e98f52b 100644 --- a/Source/Robock.sln +++ b/Source/Robock.sln @@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\.gitattributes = ..\.gitattributes ..\.gitignore = ..\.gitignore ..\.gitmodules = ..\.gitmodules + ..\appveyor.yml = ..\appveyor.yml ..\LICENSE = ..\LICENSE ..\README.md = ..\README.md EndProjectSection diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..f017fdf --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,24 @@ +version: 1.0.0.{build} +image: Visual Studio 2017 +configuration: Release +platform: x64 +clone_script: +- cmd: >- + git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/%APPVEYOR_REPO_NAME%.git %APPVEYOR_BUILD_FOLDER% + && cd %APPVEYOR_BUILD_FOLDER% + && git checkout -qf %APPVEYOR_REPO_COMMIT% + && git submodule update --init --recursive +assembly_info: + patch: true + file: '**\AssemblyInfo.*' + assembly_version: '{version}' + assembly_file_version: '{version}' + assembly_informational_version: '{version}' +before_build: +- cmd: nuget restore .\Source\ +build: + project: Source/Robock.sln + verbosity: minimal +artifacts: +- path: Source\Robock\bin\x64\Release\ + name: Robock \ No newline at end of file