mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-05-21 04:43:55 +12:00
Window restoring option added (by window class, window title and window HWND).
This commit is contained in:
parent
4cfd61ba28
commit
c2347b25a5
42
OnTopReplica/MainForm.Designer.cs
generated
42
OnTopReplica/MainForm.Designer.cs
generated
|
@ -37,6 +37,7 @@
|
|||
this.clickForwardingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.clickThroughToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.groupSwitchModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.restoreLastClonedWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuContextOpacity = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuOpacity = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -69,6 +70,7 @@
|
|||
this.englishToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.cestinaToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.danskToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.espanolToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.italianoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuContextClose = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -77,7 +79,6 @@
|
|||
this.menuFullscreenContext = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.enableClickthroughToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.fullExitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.espanolToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuContext.SuspendLayout();
|
||||
this.menuWindows.SuspendLayout();
|
||||
this.menuOpacity.SuspendLayout();
|
||||
|
@ -154,17 +155,19 @@
|
|||
this.advancedToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.clickForwardingToolStripMenuItem,
|
||||
this.clickThroughToolStripMenuItem,
|
||||
this.groupSwitchModeToolStripMenuItem});
|
||||
this.groupSwitchModeToolStripMenuItem,
|
||||
this.restoreLastClonedWindowToolStripMenuItem});
|
||||
this.advancedToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.xiao_wrench;
|
||||
this.advancedToolStripMenuItem.Name = "advancedToolStripMenuItem";
|
||||
this.advancedToolStripMenuItem.Size = new System.Drawing.Size(168, 22);
|
||||
this.advancedToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuAdvanced;
|
||||
this.advancedToolStripMenuItem.DropDownOpening += new System.EventHandler(this.Menu_Advanced_opening);
|
||||
//
|
||||
// clickForwardingToolStripMenuItem
|
||||
//
|
||||
this.clickForwardingToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.clickforwarding;
|
||||
this.clickForwardingToolStripMenuItem.Name = "clickForwardingToolStripMenuItem";
|
||||
this.clickForwardingToolStripMenuItem.Size = new System.Drawing.Size(199, 22);
|
||||
this.clickForwardingToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
|
||||
this.clickForwardingToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuClickForwarding;
|
||||
this.clickForwardingToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuClickForwardingTT;
|
||||
this.clickForwardingToolStripMenuItem.Click += new System.EventHandler(this.Menu_ClickForwarding_click);
|
||||
|
@ -173,7 +176,7 @@
|
|||
//
|
||||
this.clickThroughToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.window_opacity;
|
||||
this.clickThroughToolStripMenuItem.Name = "clickThroughToolStripMenuItem";
|
||||
this.clickThroughToolStripMenuItem.Size = new System.Drawing.Size(199, 22);
|
||||
this.clickThroughToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
|
||||
this.clickThroughToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuClickThrough;
|
||||
this.clickThroughToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuClickThroughTT;
|
||||
this.clickThroughToolStripMenuItem.Click += new System.EventHandler(this.Menu_ClickThrough_click);
|
||||
|
@ -182,11 +185,18 @@
|
|||
//
|
||||
this.groupSwitchModeToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.groupmode;
|
||||
this.groupSwitchModeToolStripMenuItem.Name = "groupSwitchModeToolStripMenuItem";
|
||||
this.groupSwitchModeToolStripMenuItem.Size = new System.Drawing.Size(199, 22);
|
||||
this.groupSwitchModeToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
|
||||
this.groupSwitchModeToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuGroupSwitch;
|
||||
this.groupSwitchModeToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuGroupSwitchTT;
|
||||
this.groupSwitchModeToolStripMenuItem.Click += new System.EventHandler(this.Menu_GroupSwitchMode_click);
|
||||
//
|
||||
// restoreLastClonedWindowToolStripMenuItem
|
||||
//
|
||||
this.restoreLastClonedWindowToolStripMenuItem.Name = "restoreLastClonedWindowToolStripMenuItem";
|
||||
this.restoreLastClonedWindowToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
|
||||
this.restoreLastClonedWindowToolStripMenuItem.Text = "Restore last cloned window";
|
||||
this.restoreLastClonedWindowToolStripMenuItem.Click += new System.EventHandler(this.Menu_RestoreLastWindow_click);
|
||||
//
|
||||
// menuContextOpacity
|
||||
//
|
||||
this.menuContextOpacity.DropDown = this.menuOpacity;
|
||||
|
@ -467,6 +477,15 @@
|
|||
this.danskToolStripMenuItem1.Text = "Dansk";
|
||||
this.danskToolStripMenuItem1.Click += new System.EventHandler(this.Menu_Language_click);
|
||||
//
|
||||
// espanolToolStripMenuItem
|
||||
//
|
||||
this.espanolToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.flag_spanish;
|
||||
this.espanolToolStripMenuItem.Name = "espanolToolStripMenuItem";
|
||||
this.espanolToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.espanolToolStripMenuItem.Tag = "es-ES";
|
||||
this.espanolToolStripMenuItem.Text = "Español";
|
||||
this.espanolToolStripMenuItem.Click += new System.EventHandler(this.Menu_Language_click);
|
||||
//
|
||||
// italianoToolStripMenuItem
|
||||
//
|
||||
this.italianoToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.flag_ita;
|
||||
|
@ -538,15 +557,6 @@
|
|||
this.fullExitToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuQuitFullscreen;
|
||||
this.fullExitToolStripMenuItem.Click += new System.EventHandler(this.Menu_Fullscreen_ExitFullscreen_click);
|
||||
//
|
||||
// espanolToolStripMenuItem
|
||||
//
|
||||
this.espanolToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.flag_spanish;
|
||||
this.espanolToolStripMenuItem.Name = "espanolToolStripMenuItem";
|
||||
this.espanolToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.espanolToolStripMenuItem.Text = "Español";
|
||||
this.espanolToolStripMenuItem.Tag = "es-ES";
|
||||
this.espanolToolStripMenuItem.Click += new System.EventHandler(this.Menu_Language_click);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -554,11 +564,10 @@
|
|||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.ClientSize = new System.Drawing.Size(264, 204);
|
||||
this.ControlBox = false;
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable; //.SizableToolWindow;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(20, 34);
|
||||
this.MinimumSize = new System.Drawing.Size(20, 38);
|
||||
this.Name = "MainForm";
|
||||
this.Text = "OnTopReplica";
|
||||
this.TopMost = true;
|
||||
|
@ -625,6 +634,7 @@
|
|||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem restorePositionAndSizeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem espanolToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem restoreLastClonedWindowToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Native;
|
||||
using OnTopReplica.Properties;
|
||||
using OnTopReplica.StartupOptions;
|
||||
using OnTopReplica.Update;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
using VistaControls.Dwm;
|
||||
using VistaControls.TaskDialog;
|
||||
using System.Collections.Generic;
|
||||
using OnTopReplica.Native;
|
||||
using OnTopReplica.Update;
|
||||
using OnTopReplica.StartupOptions;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
@ -52,7 +52,7 @@ namespace OnTopReplica {
|
|||
|
||||
//Side panel
|
||||
_sidePanelContainer = new Panel {
|
||||
Location = new Point(ClientSize.Width, 0),
|
||||
Location = new Point(ClientSize.Width + 5, 0),
|
||||
Anchor = AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom,
|
||||
Enabled = false,
|
||||
Visible = false,
|
||||
|
@ -126,6 +126,13 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e) {
|
||||
//Store last thumbnail, if any
|
||||
if (_thumbnailPanel.IsShowingThumbnail && CurrentThumbnailWindowHandle != null) {
|
||||
Settings.Default.RestoreLastWindowTitle = CurrentThumbnailWindowHandle.Title;
|
||||
Settings.Default.RestoreLastWindowHwnd = CurrentThumbnailWindowHandle.Handle.ToInt64();
|
||||
Settings.Default.RestoreLastWindowClass = CurrentThumbnailWindowHandle.Class;
|
||||
}
|
||||
|
||||
_msgPumpManager.Dispose();
|
||||
Program.Platform.CloseForm(this);
|
||||
|
||||
|
@ -262,7 +269,8 @@ namespace OnTopReplica {
|
|||
FitToThumbnail(0.5);
|
||||
}
|
||||
|
||||
else if (e.KeyCode == Keys.D3 || e.KeyCode == Keys.NumPad3 || e.KeyCode == Keys.D0 || e.KeyCode == Keys.NumPad0) {
|
||||
else if (e.KeyCode == Keys.D3 || e.KeyCode == Keys.NumPad3 ||
|
||||
e.KeyCode == Keys.D0 || e.KeyCode == Keys.NumPad0) {
|
||||
FitToThumbnail(1.0);
|
||||
}
|
||||
|
||||
|
@ -340,8 +348,8 @@ namespace OnTopReplica {
|
|||
_preFullscreenSize = ClientSize;
|
||||
_preFullscreenBorderStyle = FormBorderStyle;
|
||||
|
||||
var currentScreen = Screen.FromControl(this);
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
var currentScreen = Screen.FromControl(this);
|
||||
Size = currentScreen.WorkingArea.Size;
|
||||
Location = currentScreen.WorkingArea.Location;
|
||||
}
|
||||
|
|
|
@ -64,10 +64,18 @@ namespace OnTopReplica {
|
|||
Native.WindowManagerMethods.SetForegroundWindow(CurrentThumbnailWindowHandle.Handle);
|
||||
}
|
||||
|
||||
private void Menu_Advanced_opening(object sender, EventArgs e) {
|
||||
restoreLastClonedWindowToolStripMenuItem.Checked = Settings.Default.RestoreLastWindow;
|
||||
}
|
||||
|
||||
private void Menu_GroupSwitchMode_click(object sender, EventArgs e) {
|
||||
SetSidePanel(new SidePanels.GroupSwitchPanel());
|
||||
}
|
||||
|
||||
private void Menu_RestoreLastWindow_click(object sender, EventArgs e) {
|
||||
Settings.Default.RestoreLastWindow = !Settings.Default.RestoreLastWindow;
|
||||
}
|
||||
|
||||
private void Menu_ClickForwarding_click(object sender, EventArgs e) {
|
||||
ClickForwardingEnabled = !ClickForwardingEnabled;
|
||||
}
|
||||
|
|
|
@ -84,5 +84,16 @@ namespace OnTopReplica.Native {
|
|||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetWindow(IntPtr hwnd, GetWindowMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a window is a top-level window (has no owner nor parent window).
|
||||
/// </summary>
|
||||
/// <param name="hwnd">Handle to the window to check.</param>
|
||||
public static bool IsTopLevel(IntPtr hwnd) {
|
||||
bool hasParent = WindowManagerMethods.GetParent(hwnd).ToInt64() != 0;
|
||||
bool hasOwner = WindowManagerMethods.GetWindow(hwnd, WindowManagerMethods.GetWindowMode.GW_OWNER).ToInt64() != 0;
|
||||
|
||||
return (!hasParent && !hasOwner);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
<Compile Include="CloseRequestEventArgs.cs" />
|
||||
<Compile Include="EnumerableExtensions.cs" />
|
||||
<Compile Include="ExtensionAttribute.cs" />
|
||||
<Compile Include="GeometryExtensions.cs" />
|
||||
<Compile Include="MainForm_Features.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -138,9 +139,22 @@
|
|||
<Compile Include="Native\HT.cs" />
|
||||
<Compile Include="Pair.cs" />
|
||||
<Compile Include="Platforms\DebugPlatform.cs" />
|
||||
<Compile Include="SidePanels\OptionsPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\OptionsPanel.Designer.cs">
|
||||
<DependentUpon>OptionsPanel.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\GroupSwitchPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\GroupSwitchPanel.Designer.cs">
|
||||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WindowSeekers\BaseWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\ByClassWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\ByTitleWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\RestoreWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\TaskWindowSeeker.cs" />
|
||||
<None Include="Native\ITaskBarList.cs" />
|
||||
<Compile Include="Native\InputMethods.cs" />
|
||||
|
@ -159,12 +173,6 @@
|
|||
<Compile Include="SidePanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\GroupSwitchPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\GroupSwitchPanel.Designer.cs">
|
||||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StartupOptions\CliStatus.cs" />
|
||||
<Compile Include="StartupOptions\CommandLineReportForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
@ -210,7 +218,9 @@
|
|||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SidePanels\GroupSwitchPanel.resx">
|
||||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SidePanels\OptionsPanel.resx">
|
||||
<DependentUpon>OptionsPanel.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="StartupOptions\CommandLineReportForm.resx">
|
||||
<DependentUpon>CommandLineReportForm.cs</DependentUpon>
|
||||
|
@ -378,72 +388,72 @@
|
|||
<ItemGroup>
|
||||
<PublishFile Include="Assets\icon.ico">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>File</FileType>
|
||||
</PublishFile>
|
||||
<PublishFile Include="Assets\screenshot-icon.ico">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>File</FileType>
|
||||
</PublishFile>
|
||||
<PublishFile Include="Assets\window_multiple16.ico">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>File</FileType>
|
||||
</PublishFile>
|
||||
<PublishFile Include="Assets\xiao_arrow.png">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Exclude</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>File</FileType>
|
||||
</PublishFile>
|
||||
<PublishFile Include="cs\OnTopReplica.resources">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Include</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Include</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>Satellite</FileType>
|
||||
</PublishFile>
|
||||
<PublishFile Include="da\OnTopReplica.resources">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Include</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Include</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>Satellite</FileType>
|
||||
</PublishFile>
|
||||
<PublishFile Include="it\OnTopReplica.resources">
|
||||
<Visible>False</Visible>
|
||||
<PublishState>Include</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<Group>
|
||||
</Group>
|
||||
<TargetPath>
|
||||
</TargetPath>
|
||||
<PublishState>Include</PublishState>
|
||||
<IncludeHash>True</IncludeHash>
|
||||
<FileType>Satellite</FileType>
|
||||
</PublishFile>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
<ErrorReportUrlHistory>
|
||||
</ErrorReportUrlHistory>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<EnableSecurityDebugging>false</EnableSecurityDebugging>
|
||||
|
|
60
OnTopReplica/Properties/Settings.Designer.cs
generated
60
OnTopReplica/Properties/Settings.Designer.cs
generated
|
@ -34,18 +34,6 @@ namespace OnTopReplica.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool AutoFitOnResize {
|
||||
get {
|
||||
return ((bool)(this["AutoFitOnResize"]));
|
||||
}
|
||||
set {
|
||||
this["AutoFitOnResize"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("255")]
|
||||
|
@ -165,5 +153,53 @@ namespace OnTopReplica.Properties {
|
|||
this["RestoreLastPosition"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool RestoreLastWindow {
|
||||
get {
|
||||
return ((bool)(this["RestoreLastWindow"]));
|
||||
}
|
||||
set {
|
||||
this["RestoreLastWindow"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string RestoreLastWindowClass {
|
||||
get {
|
||||
return ((string)(this["RestoreLastWindowClass"]));
|
||||
}
|
||||
set {
|
||||
this["RestoreLastWindowClass"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string RestoreLastWindowTitle {
|
||||
get {
|
||||
return ((string)(this["RestoreLastWindowTitle"]));
|
||||
}
|
||||
set {
|
||||
this["RestoreLastWindowTitle"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public long RestoreLastWindowHwnd {
|
||||
get {
|
||||
return ((long)(this["RestoreLastWindowHwnd"]));
|
||||
}
|
||||
set {
|
||||
this["RestoreLastWindowHwnd"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
<Setting Name="SavedRegions" Type="OnTopReplica.StoredRegionArray" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="AutoFitOnResize" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="Opacity" Type="System.Byte" Scope="User">
|
||||
<Value Profile="(Default)">255</Value>
|
||||
</Setting>
|
||||
|
@ -38,5 +35,17 @@
|
|||
<Setting Name="RestoreLastPosition" Type="System.Drawing.Point" Scope="User">
|
||||
<Value Profile="(Default)">0, 0</Value>
|
||||
</Setting>
|
||||
<Setting Name="RestoreLastWindow" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="RestoreLastWindowClass" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="RestoreLastWindowTitle" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="RestoreLastWindowHwnd" Type="System.Int64" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
|
@ -4,6 +4,7 @@ using System.Text;
|
|||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using OnTopReplica.Properties;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
class Factory {
|
||||
|
@ -30,6 +31,27 @@ namespace OnTopReplica.StartupOptions {
|
|||
options.StartLocation = Settings.Default.RestoreLastPosition;
|
||||
options.StartSize = Settings.Default.RestoreLastSize;
|
||||
}
|
||||
|
||||
if (Settings.Default.RestoreLastWindow) {
|
||||
var handle = Settings.Default.RestoreLastWindowHwnd;
|
||||
var title = Settings.Default.RestoreLastWindowTitle;
|
||||
var className = Settings.Default.RestoreLastWindowClass;
|
||||
|
||||
var seeker = new RestoreWindowSeeker(new IntPtr(handle), title, className);
|
||||
seeker.SkipNotVisibleWindows = true;
|
||||
seeker.Refresh();
|
||||
var resultHandle = seeker.Windows.FirstOrDefault();
|
||||
|
||||
if (resultHandle != null) {
|
||||
//Load window
|
||||
options.WindowId = resultHandle.Handle;
|
||||
}
|
||||
#if DEBUG
|
||||
else {
|
||||
Console.WriteLine("Couldn't find window to restore.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseCommandLine(string[] args, Options options) {
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace OnTopReplica {
|
|||
if (handle == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
return new WindowHandle(handle, string.Empty);
|
||||
return new WindowHandle(handle, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,12 +6,19 @@ using OnTopReplica.Native;
|
|||
|
||||
namespace OnTopReplica {
|
||||
|
||||
/// <summary>Helper class that keeps a window handle (HWND), the title of the window and can load its icon.</summary>
|
||||
/// <summary>
|
||||
/// Helper class that keeps a window handle (HWND),
|
||||
/// the title of the window and can load its icon.
|
||||
/// </summary>
|
||||
public class WindowHandle : System.Windows.Forms.IWin32Window {
|
||||
|
||||
IntPtr _handle;
|
||||
string _title;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new WindowHandle instance. The handle pointer must be valid, the title
|
||||
/// may be null or empty and will be updated as requested.
|
||||
/// </summary>
|
||||
public WindowHandle(IntPtr p, string title) {
|
||||
_handle = p;
|
||||
_title = title;
|
||||
|
@ -19,6 +26,10 @@ namespace OnTopReplica {
|
|||
|
||||
public string Title {
|
||||
get {
|
||||
if (_title == null) {
|
||||
_title = WindowMethods.GetWindowText(_handle) ?? string.Empty;
|
||||
}
|
||||
|
||||
return _title;
|
||||
}
|
||||
}
|
||||
|
@ -32,10 +43,11 @@ namespace OnTopReplica {
|
|||
IntPtr hIcon;
|
||||
|
||||
if (MessagingMethods.SendMessageTimeout(_handle, WM.GETICON, new IntPtr(2), new IntPtr(0),
|
||||
MessagingMethods.SendMessageTimeoutFlags.AbortIfHung | MessagingMethods.SendMessageTimeoutFlags.Block, 500, out hIcon) == IntPtr.Zero)
|
||||
hIcon = IntPtr.Zero;
|
||||
MessagingMethods.SendMessageTimeoutFlags.AbortIfHung | MessagingMethods.SendMessageTimeoutFlags.Block, 500, out hIcon) == IntPtr.Zero) {
|
||||
hIcon = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (hIcon.ToInt64() != 0) {
|
||||
if (hIcon != IntPtr.Zero) {
|
||||
_icon = Icon.FromHandle(hIcon);
|
||||
}
|
||||
else {
|
||||
|
@ -54,7 +66,26 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
string _class = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the window's class name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This value is cached and is never null.
|
||||
/// </remarks>
|
||||
public string Class {
|
||||
get {
|
||||
if (_class == null) {
|
||||
_class = Native.WindowMethods.GetWindowClass(Handle) ?? string.Empty;
|
||||
}
|
||||
return _class;
|
||||
}
|
||||
}
|
||||
|
||||
#region Object override
|
||||
|
||||
public override string ToString() {
|
||||
return _title;
|
||||
}
|
||||
|
||||
|
@ -74,9 +105,11 @@ namespace OnTopReplica {
|
|||
return _handle.GetHashCode();
|
||||
}
|
||||
|
||||
#region IWin32Window Members
|
||||
#endregion
|
||||
|
||||
public IntPtr Handle {
|
||||
#region IWin32Window Members
|
||||
|
||||
public IntPtr Handle {
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
|
@ -87,7 +120,7 @@ namespace OnTopReplica {
|
|||
/// </summary>
|
||||
/// <param name="handle">Handle value.</param>
|
||||
public static WindowHandle FromHandle(IntPtr handle) {
|
||||
return new WindowHandle(handle, string.Empty);
|
||||
return new WindowHandle(handle, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,15 +10,18 @@ namespace OnTopReplica.WindowSeekers {
|
|||
/// </summary>
|
||||
abstract class BaseWindowSeeker {
|
||||
|
||||
List<WindowHandle> _list = new List<WindowHandle>();
|
||||
IList<WindowHandle> _list = new List<WindowHandle>();
|
||||
|
||||
/// <summary>
|
||||
/// Get the matching windows from the last refresh.
|
||||
/// </summary>
|
||||
public IEnumerable<WindowHandle> Windows {
|
||||
public virtual IList<WindowHandle> Windows {
|
||||
get {
|
||||
return _list;
|
||||
}
|
||||
protected set {
|
||||
_list = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -26,10 +26,8 @@ namespace OnTopReplica.WindowSeekers {
|
|||
if (string.IsNullOrEmpty(title))
|
||||
return false;
|
||||
|
||||
//Skip non-top-level windows (skips most internal controls)
|
||||
bool hasParent = (long)WindowManagerMethods.GetParent(hwnd) != 0;
|
||||
bool hasOwner = (long)WindowManagerMethods.GetWindow(hwnd, WindowManagerMethods.GetWindowMode.GW_OWNER) != 0;
|
||||
if (hasParent || hasOwner)
|
||||
//Skip non top-level windows
|
||||
if (!WindowManagerMethods.IsTopLevel(hwnd))
|
||||
return false;
|
||||
|
||||
var modTitle = title.Trim().ToLower();
|
||||
|
|
112
OnTopReplica/WindowSeekers/RestoreWindowSeeker.cs
Normal file
112
OnTopReplica/WindowSeekers/RestoreWindowSeeker.cs
Normal file
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.WindowSeekers {
|
||||
|
||||
/// <summary>
|
||||
/// Window seeker that attempts to locate a window to restore (by class, title and ID).
|
||||
/// </summary>
|
||||
class RestoreWindowSeeker : BaseWindowSeeker {
|
||||
|
||||
public RestoreWindowSeeker(IntPtr handle, string title, string className){
|
||||
Handle = handle;
|
||||
Title = title;
|
||||
Class = className;
|
||||
}
|
||||
|
||||
public IntPtr Handle { get; private set; }
|
||||
|
||||
public string Title { get; private set; }
|
||||
|
||||
public string Class { get; private set; }
|
||||
|
||||
bool _mustBeOrdered = true;
|
||||
|
||||
public override void Refresh() {
|
||||
//Whenever the window list is refreshed, the list must be reordered
|
||||
_mustBeOrdered = true;
|
||||
_points = new Dictionary<long, int>();
|
||||
|
||||
base.Refresh();
|
||||
}
|
||||
|
||||
Dictionary<long, int> _points = new Dictionary<long, int>();
|
||||
|
||||
protected override bool InspectWindow(IntPtr hwnd, string title, ref bool terminate) {
|
||||
if (!WindowManagerMethods.IsTopLevel(hwnd))
|
||||
return false;
|
||||
|
||||
int points = 0;
|
||||
|
||||
//Class exact match
|
||||
if (!string.IsNullOrEmpty(Class)) {
|
||||
string wndClass = WindowMethods.GetWindowClass(hwnd);
|
||||
if (Class.Equals(wndClass, StringComparison.InvariantCulture)) {
|
||||
points += 10;
|
||||
}
|
||||
}
|
||||
|
||||
//Title match (may not be exact, but let's try)
|
||||
if (!string.IsNullOrEmpty(Title) && !string.IsNullOrEmpty(title)) {
|
||||
if (title.StartsWith(Title, StringComparison.InvariantCultureIgnoreCase)) {
|
||||
points += 10;
|
||||
}
|
||||
}
|
||||
|
||||
//Handle match (will probably not work, but anyhow)
|
||||
if (Handle != IntPtr.Zero) {
|
||||
if (Handle == hwnd) {
|
||||
points += 5;
|
||||
}
|
||||
}
|
||||
|
||||
//Store handle if it matches
|
||||
if (points > 0) {
|
||||
_points.Add(hwnd.ToInt64(), points);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override IList<WindowHandle> Windows {
|
||||
get {
|
||||
if (_mustBeOrdered) {
|
||||
WindowHandle[] arr = new WindowHandle[base.Windows.Count];
|
||||
base.Windows.CopyTo(arr, 0);
|
||||
Array.Sort<WindowHandle>(arr, new PointComparer(_points));
|
||||
|
||||
//Store ordered array
|
||||
base.Windows = arr;
|
||||
|
||||
_mustBeOrdered = false;
|
||||
}
|
||||
|
||||
return base.Windows;
|
||||
}
|
||||
}
|
||||
|
||||
private class PointComparer : IComparer<WindowHandle> {
|
||||
|
||||
public PointComparer(IDictionary<long, int> pointDict) {
|
||||
_pointDict = pointDict;
|
||||
}
|
||||
|
||||
IDictionary<long, int> _pointDict;
|
||||
|
||||
public int Compare(WindowHandle x, WindowHandle y) {
|
||||
int px = 0;
|
||||
_pointDict.TryGetValue(x.Handle.ToInt64(), out px);
|
||||
int py = 0;
|
||||
_pointDict.TryGetValue(y.Handle.ToInt64(), out py);
|
||||
|
||||
return py.CompareTo(px); //inverse comparison (from max points to min)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -7,9 +7,6 @@
|
|||
</configSections>
|
||||
<userSettings>
|
||||
<OnTopReplica.Properties.Settings>
|
||||
<setting name="AutoFitOnResize" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="Opacity" serializeAs="String">
|
||||
<value>255</value>
|
||||
</setting>
|
||||
|
@ -40,6 +37,18 @@
|
|||
<setting name="RestoreLastPosition" serializeAs="String">
|
||||
<value>0, 0</value>
|
||||
</setting>
|
||||
<setting name="RestoreLastWindow" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="RestoreLastWindowClass" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="RestoreLastWindowTitle" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="RestoreLastWindowHwnd" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
</OnTopReplica.Properties.Settings>
|
||||
</userSettings>
|
||||
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
|
||||
|
|
Loading…
Reference in a new issue