mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-06-03 11:04:32 +12:00
Mergedown.
This commit is contained in:
commit
8ad4e78ac5
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<UpdateInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<latestVersion>3.1.0.0</latestVersion>
|
||||
<latestVersionRelease>2010-09-09T00:00:00Z</latestVersionRelease>
|
||||
<latestVersion>3.2.0.0</latestVersion>
|
||||
<latestVersionRelease>2010-10-15T00:00:00Z</latestVersionRelease>
|
||||
<downloadPage>http://www.klopfenstein.net/lorenz.aspx/ontopreplica</downloadPage>
|
||||
</UpdateInformation>
|
15
OnTopReplica/Actions.cs
Normal file
15
OnTopReplica/Actions.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
public delegate void Action();
|
||||
|
||||
public delegate void Action<T1>(T1 arg1);
|
||||
|
||||
public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
|
||||
|
||||
public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
|
||||
|
||||
}
|
BIN
OnTopReplica/Assets/pos_center.png
Normal file
BIN
OnTopReplica/Assets/pos_center.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 231 B |
|
@ -7,6 +7,7 @@ namespace OnTopReplica {
|
|||
public class CloseRequestEventArgs : EventArgs {
|
||||
|
||||
public WindowHandle LastWindowHandle { get; set; }
|
||||
|
||||
public Rectangle? LastRegion { get; set; }
|
||||
|
||||
}
|
||||
|
|
27
OnTopReplica/EnumerableExtensions.cs
Normal file
27
OnTopReplica/EnumerableExtensions.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
/// <summary>
|
||||
/// Extension methods for IEnumerable.
|
||||
/// </summary>
|
||||
static class EnumerableExtensions {
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first element of an enumeration of a default value.
|
||||
/// </summary>
|
||||
public static T FirstOrDefault<T>(this IEnumerable<T> collection) {
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
using (var enumerator = collection.GetEnumerator()) {
|
||||
if (!enumerator.MoveNext())
|
||||
return default(T);
|
||||
else
|
||||
return enumerator.Current;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
OnTopReplica/ExtensionAttribute.cs
Normal file
11
OnTopReplica/ExtensionAttribute.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Runtime.CompilerServices {
|
||||
/// <summary>
|
||||
/// Fake extension attribute that adds extension method support to C# 2 (without System.Core.dll reference).
|
||||
/// </summary>
|
||||
class ExtensionAttribute : Attribute {
|
||||
}
|
||||
}
|
61
OnTopReplica/MainForm.Designer.cs
generated
61
OnTopReplica/MainForm.Designer.cs
generated
|
@ -52,9 +52,13 @@
|
|||
this.quarterToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.fullscreenToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.restorePositionAndSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.dockToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.disabledToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.topLeftToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.topRightToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.centerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.bottomLeftToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.bottomRightToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.chromeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -115,6 +119,7 @@
|
|||
this.menuWindows.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.noneToolStripMenuItem});
|
||||
this.menuWindows.Name = "menuWindows";
|
||||
this.menuWindows.OwnerItem = this.menuContextWindows;
|
||||
this.menuWindows.Size = new System.Drawing.Size(118, 26);
|
||||
this.menuWindows.Opening += new System.ComponentModel.CancelEventHandler(this.Menu_Windows_opening);
|
||||
//
|
||||
|
@ -206,6 +211,7 @@
|
|||
this.toolStripMenuItem3,
|
||||
this.toolStripMenuItem4});
|
||||
this.menuOpacity.Name = "menuOpacity";
|
||||
this.menuOpacity.OwnerItem = this.fullOpacityToolStripMenuItem;
|
||||
this.menuOpacity.ShowCheckMargin = true;
|
||||
this.menuOpacity.ShowImageMargin = false;
|
||||
this.menuOpacity.Size = new System.Drawing.Size(154, 92);
|
||||
|
@ -265,58 +271,75 @@
|
|||
this.halfToolStripMenuItem1,
|
||||
this.quarterToolStripMenuItem1,
|
||||
this.toolStripSeparator3,
|
||||
this.fullscreenToolStripMenuItem1});
|
||||
this.fullscreenToolStripMenuItem1,
|
||||
this.toolStripSeparator2,
|
||||
this.restorePositionAndSizeToolStripMenuItem});
|
||||
this.menuResize.Name = "menuResize";
|
||||
this.menuResize.OwnerItem = this.resizeToolStripMenuItem;
|
||||
this.menuResize.Size = new System.Drawing.Size(165, 120);
|
||||
this.menuResize.Size = new System.Drawing.Size(218, 170);
|
||||
this.menuResize.Opening += new System.ComponentModel.CancelEventHandler(this.Menu_Resize_opening);
|
||||
//
|
||||
// doubleToolStripMenuItem1
|
||||
//
|
||||
this.doubleToolStripMenuItem1.Name = "doubleToolStripMenuItem1";
|
||||
this.doubleToolStripMenuItem1.Size = new System.Drawing.Size(164, 22);
|
||||
this.doubleToolStripMenuItem1.Size = new System.Drawing.Size(217, 22);
|
||||
this.doubleToolStripMenuItem1.Text = global::OnTopReplica.Strings.MenuFitDouble;
|
||||
this.doubleToolStripMenuItem1.Click += new System.EventHandler(this.Menu_Resize_Double);
|
||||
//
|
||||
// fitToWindowToolStripMenuItem1
|
||||
//
|
||||
this.fitToWindowToolStripMenuItem1.Name = "fitToWindowToolStripMenuItem1";
|
||||
this.fitToWindowToolStripMenuItem1.Size = new System.Drawing.Size(164, 22);
|
||||
this.fitToWindowToolStripMenuItem1.Size = new System.Drawing.Size(217, 22);
|
||||
this.fitToWindowToolStripMenuItem1.Text = global::OnTopReplica.Strings.MenuFitOriginal;
|
||||
this.fitToWindowToolStripMenuItem1.Click += new System.EventHandler(this.Menu_Resize_FitToWindow);
|
||||
//
|
||||
// halfToolStripMenuItem1
|
||||
//
|
||||
this.halfToolStripMenuItem1.Name = "halfToolStripMenuItem1";
|
||||
this.halfToolStripMenuItem1.Size = new System.Drawing.Size(164, 22);
|
||||
this.halfToolStripMenuItem1.Size = new System.Drawing.Size(217, 22);
|
||||
this.halfToolStripMenuItem1.Text = global::OnTopReplica.Strings.MenuFitHalf;
|
||||
this.halfToolStripMenuItem1.Click += new System.EventHandler(this.Menu_Resize_Half);
|
||||
//
|
||||
// quarterToolStripMenuItem1
|
||||
//
|
||||
this.quarterToolStripMenuItem1.Name = "quarterToolStripMenuItem1";
|
||||
this.quarterToolStripMenuItem1.Size = new System.Drawing.Size(164, 22);
|
||||
this.quarterToolStripMenuItem1.Size = new System.Drawing.Size(217, 22);
|
||||
this.quarterToolStripMenuItem1.Text = global::OnTopReplica.Strings.MenuFitQuarter;
|
||||
this.quarterToolStripMenuItem1.Click += new System.EventHandler(this.Menu_Resize_Quarter);
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
this.toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
this.toolStripSeparator3.Size = new System.Drawing.Size(161, 6);
|
||||
this.toolStripSeparator3.Size = new System.Drawing.Size(214, 6);
|
||||
//
|
||||
// fullscreenToolStripMenuItem1
|
||||
//
|
||||
this.fullscreenToolStripMenuItem1.Image = global::OnTopReplica.Properties.Resources.fullscreen;
|
||||
this.fullscreenToolStripMenuItem1.Name = "fullscreenToolStripMenuItem1";
|
||||
this.fullscreenToolStripMenuItem1.Size = new System.Drawing.Size(164, 22);
|
||||
this.fullscreenToolStripMenuItem1.Size = new System.Drawing.Size(217, 22);
|
||||
this.fullscreenToolStripMenuItem1.Text = global::OnTopReplica.Strings.MenuFitFullscreen;
|
||||
this.fullscreenToolStripMenuItem1.Click += new System.EventHandler(this.Menu_Resize_Fullscreen);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(214, 6);
|
||||
//
|
||||
// restorePositionAndSizeToolStripMenuItem
|
||||
//
|
||||
this.restorePositionAndSizeToolStripMenuItem.Name = "restorePositionAndSizeToolStripMenuItem";
|
||||
this.restorePositionAndSizeToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
|
||||
this.restorePositionAndSizeToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuRecall;
|
||||
this.restorePositionAndSizeToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuRecallTT;
|
||||
this.restorePositionAndSizeToolStripMenuItem.Click += new System.EventHandler(this.Menu_Resize_RecallPosition_click);
|
||||
//
|
||||
// dockToolStripMenuItem
|
||||
//
|
||||
this.dockToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.disabledToolStripMenuItem,
|
||||
this.topLeftToolStripMenuItem,
|
||||
this.topRightToolStripMenuItem,
|
||||
this.centerToolStripMenuItem,
|
||||
this.bottomLeftToolStripMenuItem,
|
||||
this.bottomRightToolStripMenuItem});
|
||||
this.dockToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.pos_null;
|
||||
|
@ -324,6 +347,16 @@
|
|||
this.dockToolStripMenuItem.Size = new System.Drawing.Size(168, 22);
|
||||
this.dockToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuPosition;
|
||||
this.dockToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuPositionTT;
|
||||
this.dockToolStripMenuItem.DropDownOpening += new System.EventHandler(this.Menu_Position_Opening);
|
||||
//
|
||||
// disabledToolStripMenuItem
|
||||
//
|
||||
this.disabledToolStripMenuItem.Checked = true;
|
||||
this.disabledToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.disabledToolStripMenuItem.Name = "disabledToolStripMenuItem";
|
||||
this.disabledToolStripMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.disabledToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuPosDisabled;
|
||||
this.disabledToolStripMenuItem.Click += new System.EventHandler(this.Menu_Position_Disable);
|
||||
//
|
||||
// topLeftToolStripMenuItem
|
||||
//
|
||||
|
@ -341,6 +374,14 @@
|
|||
this.topRightToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuPosTopRight;
|
||||
this.topRightToolStripMenuItem.Click += new System.EventHandler(this.Menu_Position_TopRight);
|
||||
//
|
||||
// centerToolStripMenuItem
|
||||
//
|
||||
this.centerToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.pos_center;
|
||||
this.centerToolStripMenuItem.Name = "centerToolStripMenuItem";
|
||||
this.centerToolStripMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.centerToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuPosCenter;
|
||||
this.centerToolStripMenuItem.Click += new System.EventHandler(this.Menu_Position_Center);
|
||||
//
|
||||
// bottomLeftToolStripMenuItem
|
||||
//
|
||||
this.bottomLeftToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.pos_bottomleft;
|
||||
|
@ -568,6 +609,10 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem clickThroughToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem groupSwitchModeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem enableClickthroughToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem centerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem disabledToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem restorePositionAndSizeToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ using VistaControls.TaskDialog;
|
|||
using System.Collections.Generic;
|
||||
using OnTopReplica.Native;
|
||||
using OnTopReplica.Update;
|
||||
using OnTopReplica.StartupOptions;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
@ -19,18 +21,23 @@ namespace OnTopReplica {
|
|||
Panel _sidePanelContainer;
|
||||
|
||||
//Managers
|
||||
WindowManager _windowManager = new WindowManager();
|
||||
BaseWindowSeeker _windowSeeker = new TaskWindowSeeker {
|
||||
SkipNotVisibleWindows = true
|
||||
};
|
||||
MessagePumpManager _msgPumpManager = new MessagePumpManager();
|
||||
UpdateManager _updateManager = new UpdateManager();
|
||||
|
||||
FormBorderStyle _defaultBorderStyle;
|
||||
Options _startupOptions;
|
||||
|
||||
public MainForm() {
|
||||
public MainForm(Options startupOptions) {
|
||||
_startupOptions = startupOptions;
|
||||
|
||||
//WinForms init pass
|
||||
InitializeComponent();
|
||||
KeepAspectRatio = false;
|
||||
GlassEnabled = true;
|
||||
|
||||
//Store default values
|
||||
_defaultBorderStyle = FormBorderStyle;
|
||||
_nonClickThroughKey = TransparencyKey;
|
||||
|
||||
//Thumbnail panel
|
||||
|
@ -97,18 +104,20 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e) {
|
||||
base.OnShown(e);
|
||||
protected override void OnHandleCreated(EventArgs e){
|
||||
base.OnHandleCreated(e);
|
||||
|
||||
_windowSeeker.OwnerHandle = this.Handle;
|
||||
|
||||
//Platform specific form initialization
|
||||
Program.Platform.InitForm(this);
|
||||
|
||||
//Glassify window
|
||||
GlassEnabled = true;
|
||||
}
|
||||
|
||||
protected override void OnHandleCreated(EventArgs e) {
|
||||
base.OnHandleCreated(e);
|
||||
protected override void OnShown(EventArgs e) {
|
||||
base.OnShown(e);
|
||||
|
||||
//Apply startup options
|
||||
_startupOptions.Apply(this);
|
||||
|
||||
//Check for updates
|
||||
_updateManager.UpdateCheckCompleted += new EventHandler<UpdateCheckCompletedEventArgs>(UpdateManager_CheckCompleted);
|
||||
|
@ -131,10 +140,19 @@ namespace OnTopReplica {
|
|||
fullMargins;
|
||||
}
|
||||
|
||||
protected override void OnResizeEnd(EventArgs e) {
|
||||
base.OnResizeEnd(e);
|
||||
|
||||
//If locked in position, move accordingly
|
||||
if (PositionLock.HasValue) {
|
||||
this.SetScreenPosition(PositionLock.Value);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivated(EventArgs e) {
|
||||
base.OnActivated(e);
|
||||
|
||||
//Deactivate click-through if reactivated
|
||||
//Deactivate click-through if form is reactivated
|
||||
if (ClickThroughEnabled) {
|
||||
ClickThroughEnabled = false;
|
||||
}
|
||||
|
@ -146,7 +164,7 @@ namespace OnTopReplica {
|
|||
base.OnDeactivate(e);
|
||||
|
||||
//HACK: sometimes, even if TopMost is true, the window loses its "always on top" status.
|
||||
// This is an attempt of a fix that probably won't work...
|
||||
// This is a fix attempt that probably won't work...
|
||||
if (!IsFullscreen) { //fullscreen mode doesn't use TopMost
|
||||
TopMost = false;
|
||||
TopMost = true;
|
||||
|
@ -269,8 +287,8 @@ namespace OnTopReplica {
|
|||
IsFullscreen = false;
|
||||
}
|
||||
//Disable click forwarding
|
||||
else if (_thumbnailPanel.ReportThumbnailClicks) {
|
||||
_thumbnailPanel.ReportThumbnailClicks = false;
|
||||
else if (ClickForwardingEnabled) {
|
||||
ClickForwardingEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,6 +320,7 @@ namespace OnTopReplica {
|
|||
bool _isFullscreen = false;
|
||||
Point _preFullscreenLocation;
|
||||
Size _preFullscreenSize;
|
||||
FormBorderStyle _preFullscreenBorderStyle;
|
||||
|
||||
public bool IsFullscreen {
|
||||
get {
|
||||
|
@ -314,26 +333,30 @@ namespace OnTopReplica {
|
|||
return;
|
||||
|
||||
CloseSidePanel(); //on switch, always hide side panels
|
||||
GlassEnabled = !value;
|
||||
FormBorderStyle = (value) ? FormBorderStyle.None : _defaultBorderStyle;
|
||||
TopMost = !value;
|
||||
HandleMouseMove = !value;
|
||||
|
||||
//Location and size
|
||||
if (value) {
|
||||
_preFullscreenLocation = Location;
|
||||
_preFullscreenSize = Size;
|
||||
_preFullscreenSize = ClientSize;
|
||||
_preFullscreenBorderStyle = FormBorderStyle;
|
||||
|
||||
var currentScreen = Screen.FromControl(this);
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
Size = currentScreen.WorkingArea.Size;
|
||||
Location = currentScreen.WorkingArea.Location;
|
||||
}
|
||||
else {
|
||||
FormBorderStyle = _preFullscreenBorderStyle;
|
||||
Location = _preFullscreenLocation;
|
||||
Size = _preFullscreenSize;
|
||||
ClientSize = _preFullscreenSize;
|
||||
RefreshAspectRatio();
|
||||
}
|
||||
|
||||
//Common
|
||||
GlassEnabled = !value;
|
||||
TopMost = !value;
|
||||
HandleMouseMove = !value;
|
||||
|
||||
_isFullscreen = value;
|
||||
|
||||
Program.Platform.OnFormStateChange(this);
|
||||
|
@ -349,13 +372,18 @@ namespace OnTopReplica {
|
|||
/// </summary>
|
||||
/// <param name="handle">Handle to the window to clone.</param>
|
||||
/// <param name="region">Region of the window to clone.</param>
|
||||
public void SetThumbnail(WindowHandle handle, StoredRegion region) {
|
||||
public void SetThumbnail(WindowHandle handle, Rectangle? region) {
|
||||
try {
|
||||
CurrentThumbnailWindowHandle = handle;
|
||||
_thumbnailPanel.SetThumbnailHandle(handle);
|
||||
|
||||
if (region != null)
|
||||
_thumbnailPanel.SelectedRegion = region.Rect;
|
||||
#if DEBUG
|
||||
string windowClass = WindowMethods.GetWindowClass(handle.Handle);
|
||||
Console.WriteLine("Cloning window HWND {0} of class {1}.", handle.Handle, windowClass);
|
||||
#endif
|
||||
|
||||
if (region.HasValue)
|
||||
_thumbnailPanel.SelectedRegion = region.Value;
|
||||
else
|
||||
_thumbnailPanel.ConstrainToRegion = false;
|
||||
|
||||
|
@ -470,33 +498,6 @@ namespace OnTopReplica {
|
|||
|
||||
#endregion
|
||||
|
||||
#region Click-through
|
||||
|
||||
bool _clickThrough = false;
|
||||
Color _nonClickThroughKey;
|
||||
|
||||
public bool ClickThroughEnabled {
|
||||
get {
|
||||
return _clickThrough;
|
||||
}
|
||||
set {
|
||||
//Adjust opacity if fully opaque
|
||||
if (value && Opacity == 1.0)
|
||||
Opacity = 0.75;
|
||||
if (!value)
|
||||
Opacity = 1.0;
|
||||
|
||||
//Enable transparency and force as top-most
|
||||
TransparencyKey = (value) ? Color.Black : _nonClickThroughKey;
|
||||
if (value)
|
||||
TopMost = true;
|
||||
|
||||
_clickThrough = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accessors
|
||||
|
||||
/// <summary>
|
||||
|
|
114
OnTopReplica/MainForm_Features.cs
Normal file
114
OnTopReplica/MainForm_Features.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Properties;
|
||||
using VistaControls.TaskDialog;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OnTopReplica {
|
||||
//Contains some feature implementations of MainForm
|
||||
partial class MainForm {
|
||||
|
||||
#region Click forwarding
|
||||
|
||||
public bool ClickForwardingEnabled {
|
||||
get {
|
||||
return _thumbnailPanel.ReportThumbnailClicks;
|
||||
}
|
||||
set {
|
||||
if (value && Settings.Default.FirstTimeClickForwarding) {
|
||||
TaskDialog dlg = new TaskDialog(Strings.InfoClickForwarding, Strings.InfoClickForwardingTitle, Strings.InfoClickForwardingContent) {
|
||||
CommonButtons = TaskDialogButton.Yes | TaskDialogButton.No
|
||||
};
|
||||
if (dlg.Show(this).CommonButton == Result.No)
|
||||
return;
|
||||
|
||||
Settings.Default.FirstTimeClickForwarding = false;
|
||||
}
|
||||
|
||||
_thumbnailPanel.ReportThumbnailClicks = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Click-through
|
||||
|
||||
bool _clickThrough = false;
|
||||
Color _nonClickThroughKey;
|
||||
|
||||
public bool ClickThroughEnabled {
|
||||
get {
|
||||
return _clickThrough;
|
||||
}
|
||||
set {
|
||||
//Adjust opacity if fully opaque
|
||||
/*if (value && Opacity == 1.0)
|
||||
Opacity = 0.75;
|
||||
if (!value)
|
||||
Opacity = 1.0;*/
|
||||
|
||||
//Enable transparency and force as top-most
|
||||
TransparencyKey = (value) ? Color.Black : _nonClickThroughKey;
|
||||
if (value)
|
||||
TopMost = true;
|
||||
|
||||
_clickThrough = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Chrome
|
||||
|
||||
public bool IsChromeVisible {
|
||||
get {
|
||||
return (FormBorderStyle == FormBorderStyle.SizableToolWindow);
|
||||
}
|
||||
set {
|
||||
if (!value) {
|
||||
Location = new Point {
|
||||
X = Location.X + SystemInformation.FrameBorderSize.Width,
|
||||
Y = Location.Y + SystemInformation.FrameBorderSize.Height
|
||||
};
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
}
|
||||
else if(value) {
|
||||
Location = new Point {
|
||||
X = Location.X - SystemInformation.FrameBorderSize.Width,
|
||||
Y = Location.Y - SystemInformation.FrameBorderSize.Height
|
||||
};
|
||||
FormBorderStyle = FormBorderStyle.SizableToolWindow;
|
||||
}
|
||||
|
||||
Program.Platform.OnFormStateChange(this);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Position lock
|
||||
|
||||
ScreenPosition? _positionLock = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the screen position where the window is currently locked in.
|
||||
/// </summary>
|
||||
public ScreenPosition? PositionLock {
|
||||
get {
|
||||
return _positionLock;
|
||||
}
|
||||
set {
|
||||
if (value != null)
|
||||
this.SetScreenPosition(value.Value);
|
||||
|
||||
_positionLock = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
|
@ -38,18 +38,24 @@ namespace OnTopReplica {
|
|||
return new Point(finX, finY);
|
||||
}
|
||||
|
||||
private int ChromeBorderVertical {
|
||||
/// <summary>
|
||||
/// Gets the window's vertical chrome size.
|
||||
/// </summary>
|
||||
public int ChromeBorderVertical {
|
||||
get {
|
||||
if (FormBorderStyle == _defaultBorderStyle)
|
||||
if (IsChromeVisible)
|
||||
return SystemInformation.FrameBorderSize.Height;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int ChromeBorderHorizontal {
|
||||
/// <summary>
|
||||
/// Gets the window's horizontal chrome size.
|
||||
/// </summary>
|
||||
public int ChromeBorderHorizontal {
|
||||
get {
|
||||
if (FormBorderStyle == _defaultBorderStyle)
|
||||
if (IsChromeVisible)
|
||||
return SystemInformation.FrameBorderSize.Width;
|
||||
else
|
||||
return 0;
|
||||
|
|
|
@ -20,8 +20,8 @@ namespace OnTopReplica {
|
|||
selectRegionToolStripMenuItem.Enabled = showing;
|
||||
switchToWindowToolStripMenuItem.Enabled = showing;
|
||||
resizeToolStripMenuItem.Enabled = showing;
|
||||
chromeToolStripMenuItem.Checked = (FormBorderStyle == _defaultBorderStyle);
|
||||
clickForwardingToolStripMenuItem.Checked = _thumbnailPanel.ReportThumbnailClicks;
|
||||
chromeToolStripMenuItem.Checked = IsChromeVisible;
|
||||
clickForwardingToolStripMenuItem.Checked = ClickForwardingEnabled;
|
||||
chromeToolStripMenuItem.Enabled = showing;
|
||||
clickThroughToolStripMenuItem.Enabled = showing;
|
||||
clickForwardingToolStripMenuItem.Enabled = showing;
|
||||
|
@ -29,8 +29,9 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
private void Menu_Windows_opening(object sender, CancelEventArgs e) {
|
||||
_windowManager.Refresh(WindowManager.EnumerationMode.TaskWindows);
|
||||
WindowListHelper.PopulateMenu(this, _windowManager, (ToolStrip)sender,
|
||||
_windowSeeker.Refresh();
|
||||
var menu = (ToolStrip)sender;
|
||||
menu.PopulateMenu(this, _windowSeeker,
|
||||
CurrentThumbnailWindowHandle, new EventHandler(Menu_Windows_itemclick));
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,9 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
var selectionData = (WindowListHelper.WindowSelectionData)tsi.Tag;
|
||||
SetThumbnail(selectionData.Handle, selectionData.Region);
|
||||
Rectangle? bounds = (selectionData.Region != null)
|
||||
? (Rectangle?)selectionData.Region.Bounds : null;
|
||||
SetThumbnail(selectionData.Handle, bounds);
|
||||
}
|
||||
|
||||
private void Menu_Switch_click(object sender, EventArgs e) {
|
||||
|
@ -66,17 +69,7 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
private void Menu_ClickForwarding_click(object sender, EventArgs e) {
|
||||
if (Settings.Default.FirstTimeClickForwarding && !_thumbnailPanel.ReportThumbnailClicks) {
|
||||
TaskDialog dlg = new TaskDialog(Strings.InfoClickForwarding, Strings.InfoClickForwardingTitle, Strings.InfoClickForwardingContent) {
|
||||
CommonButtons = TaskDialogButton.Yes | TaskDialogButton.No
|
||||
};
|
||||
if (dlg.Show(this).CommonButton == Result.No)
|
||||
return;
|
||||
|
||||
Settings.Default.FirstTimeClickForwarding = false;
|
||||
}
|
||||
|
||||
_thumbnailPanel.ReportThumbnailClicks = !_thumbnailPanel.ReportThumbnailClicks;
|
||||
ClickForwardingEnabled = !ClickForwardingEnabled;
|
||||
}
|
||||
|
||||
private void Menu_ClickThrough_click(object sender, EventArgs e) {
|
||||
|
@ -116,6 +109,8 @@ namespace OnTopReplica {
|
|||
private void Menu_Resize_opening(object sender, CancelEventArgs e) {
|
||||
if (!_thumbnailPanel.IsShowingThumbnail)
|
||||
e.Cancel = true;
|
||||
|
||||
restorePositionAndSizeToolStripMenuItem.Checked = Settings.Default.RestoreSizeAndPosition;
|
||||
}
|
||||
|
||||
private void Menu_Resize_Double(object sender, EventArgs e) {
|
||||
|
@ -138,40 +133,41 @@ namespace OnTopReplica {
|
|||
IsFullscreen = true;
|
||||
}
|
||||
|
||||
private void Menu_Position_TopLeft(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
private void Menu_Resize_RecallPosition_click(object sender, EventArgs e) {
|
||||
Settings.Default.RestoreSizeAndPosition = !Settings.Default.RestoreSizeAndPosition;
|
||||
}
|
||||
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Left - ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Top - ChromeBorderVertical
|
||||
);
|
||||
private void Menu_Position_Opening(object sender, EventArgs e) {
|
||||
disabledToolStripMenuItem.Checked = (PositionLock == null);
|
||||
topLeftToolStripMenuItem.Checked = (PositionLock == ScreenPosition.TopLeft);
|
||||
topRightToolStripMenuItem.Checked = (PositionLock == ScreenPosition.TopRight);
|
||||
centerToolStripMenuItem.Checked = (PositionLock == ScreenPosition.Center);
|
||||
bottomLeftToolStripMenuItem.Checked = (PositionLock == ScreenPosition.BottomLeft);
|
||||
bottomRightToolStripMenuItem.Checked = (PositionLock == ScreenPosition.BottomRight);
|
||||
}
|
||||
|
||||
private void Menu_Position_Disable(object sender, EventArgs e) {
|
||||
PositionLock = null;
|
||||
}
|
||||
|
||||
private void Menu_Position_TopLeft(object sender, EventArgs e) {
|
||||
PositionLock = ScreenPosition.TopLeft;
|
||||
}
|
||||
|
||||
private void Menu_Position_TopRight(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
PositionLock = ScreenPosition.TopRight;
|
||||
}
|
||||
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Width - Size.Width + ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Top - ChromeBorderVertical
|
||||
);
|
||||
private void Menu_Position_Center(object sender, EventArgs e) {
|
||||
PositionLock = ScreenPosition.Center;
|
||||
}
|
||||
|
||||
private void Menu_Position_BottomLeft(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Left - ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Height - Size.Height + ChromeBorderVertical
|
||||
);
|
||||
PositionLock = ScreenPosition.BottomLeft;
|
||||
}
|
||||
|
||||
private void Menu_Position_BottomRight(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Width - Size.Width + ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Height - Size.Height + ChromeBorderVertical
|
||||
);
|
||||
PositionLock = ScreenPosition.BottomRight;
|
||||
}
|
||||
|
||||
private void Menu_Reduce_click(object sender, EventArgs e) {
|
||||
|
@ -180,23 +176,7 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
private void Menu_Chrome_click(object sender, EventArgs e) {
|
||||
if (FormBorderStyle == _defaultBorderStyle) {
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
Location = new Point {
|
||||
X = Location.X + SystemInformation.FrameBorderSize.Width,
|
||||
Y = Location.Y + SystemInformation.FrameBorderSize.Height
|
||||
};
|
||||
}
|
||||
else {
|
||||
FormBorderStyle = _defaultBorderStyle;
|
||||
Location = new Point {
|
||||
X = Location.X - SystemInformation.FrameBorderSize.Width,
|
||||
Y = Location.Y - SystemInformation.FrameBorderSize.Height
|
||||
};
|
||||
}
|
||||
|
||||
Program.Platform.OnFormStateChange(this);
|
||||
Invalidate();
|
||||
IsChromeVisible = !IsChromeVisible;
|
||||
}
|
||||
|
||||
private void Menu_Language_click(object sender, EventArgs e) {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.MessagePumpProcessors;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
@ -12,6 +11,15 @@ namespace OnTopReplica {
|
|||
|
||||
public MainForm Form { get; private set; }
|
||||
|
||||
private void Register(IMessagePumpProcessor processor, MainForm form) {
|
||||
_processors[processor.GetType()] = processor;
|
||||
processor.Initialize(form);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Registered message pump processor: {0}", processor.GetType());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates all message pump processors and registers them on the main form.
|
||||
/// </summary>
|
||||
|
@ -29,18 +37,10 @@ namespace OnTopReplica {
|
|||
#endif
|
||||
}
|
||||
|
||||
foreach (var t in Assembly.GetExecutingAssembly().GetTypes()) {
|
||||
if (typeof(IMessagePumpProcessor).IsAssignableFrom(t) && !t.IsAbstract) {
|
||||
var instance = (IMessagePumpProcessor)Activator.CreateInstance(t);
|
||||
instance.Initialize(form);
|
||||
|
||||
_processors[t] = instance;
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Registered message pump processor: {0}", t);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//Register message pump processors
|
||||
Register(new WindowKeeper(), form);
|
||||
Register(new HotKeyManager(), form);
|
||||
Register(new GroupSwitchManager(), form);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Native;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.MessagePumpProcessors {
|
||||
class TitleSetter : BaseMessagePumpProcessor {
|
||||
|
||||
const string Title = "OnTopReplica";
|
||||
|
||||
public override bool Process(ref Message msg) {
|
||||
switch (msg.Msg) {
|
||||
case WM.GETTEXT: {
|
||||
Console.WriteLine("GetText");
|
||||
int maxLen = msg.WParam.ToInt32();
|
||||
byte[] strBytes = Encoding.UTF8.GetBytes(Title);
|
||||
byte[] termBytes = new byte[strBytes.Length + 1];
|
||||
strBytes.CopyTo(termBytes, 0);
|
||||
termBytes[strBytes.Length] = 0;
|
||||
|
||||
Marshal.Copy(termBytes, 0, msg.LParam, Math.Min(maxLen, Title.Length + 1));
|
||||
}
|
||||
goto case WM.GETTEXTLENGTH;
|
||||
|
||||
case WM.GETTEXTLENGTH:
|
||||
Console.WriteLine("GetTextLength");
|
||||
msg.Result = (IntPtr)Title.Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void Shutdown() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
1103
OnTopReplica/NDesk/Options/Options.cs
Normal file
1103
OnTopReplica/NDesk/Options/Options.cs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -37,6 +37,17 @@ namespace OnTopReplica.Native {
|
|||
return String.Empty;
|
||||
}
|
||||
|
||||
const int MaxClassLength = 255;
|
||||
|
||||
public static string GetWindowClass(IntPtr hwnd) {
|
||||
var sb = new StringBuilder(MaxClassLength + 1);
|
||||
RealGetWindowClass(hwnd, sb, MaxClassLength);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern uint RealGetWindowClass(IntPtr hwnd, [Out] StringBuilder lpString, uint maxCount);
|
||||
|
||||
public enum WindowLong {
|
||||
WndProc = (-4),
|
||||
HInstance = (-6),
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<WebPage>publish.htm</WebPage>
|
||||
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>3.0.2.%2a</ApplicationVersion>
|
||||
<ApplicationVersion>3.2.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
|
@ -106,11 +106,17 @@
|
|||
<Compile Include="AboutForm.Designer.cs">
|
||||
<DependentUpon>AboutForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Actions.cs" />
|
||||
<Compile Include="AspectRatioForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CloneClickEventArgs.cs" />
|
||||
<Compile Include="CloseRequestEventArgs.cs" />
|
||||
<Compile Include="EnumerableExtensions.cs" />
|
||||
<Compile Include="ExtensionAttribute.cs" />
|
||||
<Compile Include="MainForm_Features.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm_Gui.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -124,12 +130,16 @@
|
|||
<Compile Include="MessagePumpProcessors\GroupSwitchManager.cs" />
|
||||
<Compile Include="IMessagePumpProcessor.cs" />
|
||||
<Compile Include="MessagePumpProcessors\BaseMessagePumpProcessor.cs" />
|
||||
<None Include="MessagePumpProcessors\TitleSetter.cs" />
|
||||
<Compile Include="MessagePumpProcessors\WindowKeeper.cs" />
|
||||
<Compile Include="Native\ErrorMethods.cs" />
|
||||
<Compile Include="Native\HookMethods.cs" />
|
||||
<Compile Include="Native\HotKeyMethods.cs" />
|
||||
<Compile Include="Native\HT.cs" />
|
||||
<Compile Include="Pair.cs" />
|
||||
<Compile Include="WindowSeekers\BaseWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\ByClassWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\ByTitleWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\TaskWindowSeeker.cs" />
|
||||
<None Include="Native\ITaskBarList.cs" />
|
||||
<Compile Include="Native\InputMethods.cs" />
|
||||
<Compile Include="Native\MessagingMethods.cs" />
|
||||
|
@ -141,7 +151,9 @@
|
|||
<Compile Include="Native\WindowMethods.cs" />
|
||||
<Compile Include="Native\WM.cs" />
|
||||
<Compile Include="Native\WMSZ.cs" />
|
||||
<Compile Include="NDesk\Options\Options.cs" />
|
||||
<Compile Include="NotificationIcon.cs" />
|
||||
<Compile Include="ScreenPosition.cs" />
|
||||
<Compile Include="SidePanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -151,6 +163,18 @@
|
|||
<Compile Include="SidePanels\GroupSwitchPanel.Designer.cs">
|
||||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StartupOptions\CliStatus.cs" />
|
||||
<Compile Include="StartupOptions\CommandLineReportForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="StartupOptions\CommandLineReportForm.Designer.cs">
|
||||
<DependentUpon>CommandLineReportForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StartupOptions\RectangleConverter.cs" />
|
||||
<Compile Include="StartupOptions\Factory.cs" />
|
||||
<Compile Include="StartupOptions\Options.cs" />
|
||||
<Compile Include="StartupOptions\ScreenPositionConverter.cs" />
|
||||
<Compile Include="StartupOptions\SizeConverter.cs" />
|
||||
<Compile Include="StoredRegionComparer.cs" />
|
||||
<Compile Include="Native\WindowsSevenMethods.cs" />
|
||||
<None Include="Native\CommonControls.cs" />
|
||||
|
@ -186,6 +210,9 @@
|
|||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="StartupOptions\CommandLineReportForm.resx">
|
||||
<DependentUpon>CommandLineReportForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Strings.cs.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.cs.Designer.cs</LastGenOutput>
|
||||
|
@ -240,6 +267,11 @@
|
|||
</Compile>
|
||||
<Compile Include="StoredRegion.cs" />
|
||||
<Compile Include="StoredRegionArray.cs" />
|
||||
<Compile Include="Strings.it.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Strings.it.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ThumbnailPanel.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
@ -249,7 +281,6 @@
|
|||
<Compile Include="Win32Helper.cs" />
|
||||
<Compile Include="WindowHandle.cs" />
|
||||
<Compile Include="WindowListHelper.cs" />
|
||||
<Compile Include="WindowManager.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Assets\windows.png" />
|
||||
|
@ -273,6 +304,7 @@
|
|||
<None Include="Assets\fullscreen.png" />
|
||||
<None Include="Assets\clickforwarding.png" />
|
||||
<None Include="Assets\groupmode.png" />
|
||||
<None Include="Assets\pos_center.png" />
|
||||
<Content Include="Assets\xiao_arrow.png" />
|
||||
<None Include="Assets\xiao_help.png" />
|
||||
<None Include="Assets\window_opacity_new.png" />
|
||||
|
|
|
@ -15,4 +15,8 @@
|
|||
<PropertyGroup>
|
||||
<EnableSecurityDebugging>false</EnableSecurityDebugging>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
15
OnTopReplica/Pair.cs
Normal file
15
OnTopReplica/Pair.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
/// <summary>
|
||||
/// Simple tuple with two values.
|
||||
/// </summary>
|
||||
struct Pair<T1, T2> {
|
||||
public T1 Item1;
|
||||
public T2 Item2;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ using System.IO;
|
|||
using VistaControls.TaskDialog;
|
||||
using OnTopReplica.Update;
|
||||
using System.Reflection;
|
||||
using OnTopReplica.StartupOptions;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
@ -26,7 +27,7 @@ namespace OnTopReplica {
|
|||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main() {
|
||||
static void Main(string[] args) {
|
||||
//Hook abort handler
|
||||
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||||
|
||||
|
@ -45,6 +46,16 @@ namespace OnTopReplica {
|
|||
Settings.Default.MustUpdate = false;
|
||||
}
|
||||
|
||||
//Load startup options
|
||||
var options = StartupOptions.Factory.CreateOptions(args);
|
||||
string optionsMessage = options.DebugMessage;
|
||||
if (!string.IsNullOrEmpty(optionsMessage)) { //show dialog if debug message present or if parsing failed
|
||||
var dlg = new CommandLineReportForm(options.Status, optionsMessage);
|
||||
dlg.ShowDialog();
|
||||
}
|
||||
if (options.Status == CliStatus.Information || options.Status == CliStatus.Error)
|
||||
return;
|
||||
|
||||
bool mustReloadForm = false;
|
||||
Point reloadLocation = new Point();
|
||||
Size reloadSize = new Size();
|
||||
|
@ -55,7 +66,7 @@ namespace OnTopReplica {
|
|||
Settings.Default.Language = _languageChangeCode;
|
||||
_languageChangeCode = null;
|
||||
|
||||
_mainForm = new MainForm();
|
||||
_mainForm = new MainForm(options);
|
||||
if (mustReloadForm) {
|
||||
_mainForm.Location = reloadLocation;
|
||||
_mainForm.Size = reloadSize;
|
||||
|
@ -71,6 +82,8 @@ namespace OnTopReplica {
|
|||
while (_languageChangeCode != null);
|
||||
|
||||
//Persist settings
|
||||
Settings.Default.RestoreLastPosition = reloadLocation;
|
||||
Settings.Default.RestoreLastSize = reloadSize;
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("3.1.1.0")]
|
||||
[assembly: AssemblyFileVersion("3.1.1.0")]
|
||||
[assembly: AssemblyVersion("3.2.0.0")]
|
||||
[assembly: AssemblyFileVersion("3.2.0.0")]
|
||||
|
|
7
OnTopReplica/Properties/Resources.Designer.cs
generated
7
OnTopReplica/Properties/Resources.Designer.cs
generated
|
@ -165,6 +165,13 @@ namespace OnTopReplica.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap pos_center {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("pos_center", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap pos_null {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("pos_null", resourceCulture);
|
||||
|
|
|
@ -223,8 +223,11 @@
|
|||
<data name="flag_usa" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Assets\flag_usa.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="groupmode" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Assets\groupmode.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="pos_center" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Assets\pos_center.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
28
OnTopReplica/Properties/Settings.Designer.cs
generated
28
OnTopReplica/Properties/Settings.Designer.cs
generated
|
@ -132,25 +132,37 @@ namespace OnTopReplica.Properties {
|
|||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string Setting {
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool RestoreSizeAndPosition {
|
||||
get {
|
||||
return ((string)(this["Setting"]));
|
||||
return ((bool)(this["RestoreSizeAndPosition"]));
|
||||
}
|
||||
set {
|
||||
this["Setting"] = value;
|
||||
this["RestoreSizeAndPosition"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string Setting1 {
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0, 0")]
|
||||
public global::System.Drawing.Size RestoreLastSize {
|
||||
get {
|
||||
return ((string)(this["Setting1"]));
|
||||
return ((global::System.Drawing.Size)(this["RestoreLastSize"]));
|
||||
}
|
||||
set {
|
||||
this["Setting1"] = value;
|
||||
this["RestoreLastSize"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0, 0")]
|
||||
public global::System.Drawing.Point RestoreLastPosition {
|
||||
get {
|
||||
return ((global::System.Drawing.Point)(this["RestoreLastPosition"]));
|
||||
}
|
||||
set {
|
||||
this["RestoreLastPosition"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,11 +29,14 @@
|
|||
<Setting Name="FullscreenAlwaysOnTop" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="Setting" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
<Setting Name="RestoreSizeAndPosition" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="Setting1" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
<Setting Name="RestoreLastSize" Type="System.Drawing.Size" Scope="User">
|
||||
<Value Profile="(Default)">0, 0</Value>
|
||||
</Setting>
|
||||
<Setting Name="RestoreLastPosition" Type="System.Drawing.Point" Scope="User">
|
||||
<Value Profile="(Default)">0, 0</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
77
OnTopReplica/ScreenPosition.cs
Normal file
77
OnTopReplica/ScreenPosition.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OnTopReplica {
|
||||
/// <summary>
|
||||
/// Describes a resolution independent position.
|
||||
/// </summary>
|
||||
enum ScreenPosition {
|
||||
TopLeft,
|
||||
TopRight,
|
||||
BottomLeft,
|
||||
BottomRight,
|
||||
Center
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for ScreenPositions.
|
||||
/// </summary>
|
||||
static class ScreenPositionExtensions {
|
||||
|
||||
/// <summary>
|
||||
/// Sets the form's screen position in independent coordinates.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Position is set relative to the form's current screen.
|
||||
/// </remarks>
|
||||
public static void SetScreenPosition(this MainForm form, ScreenPosition position) {
|
||||
var screen = Screen.FromControl(form);
|
||||
var wa = screen.WorkingArea;
|
||||
|
||||
Point p = new Point();
|
||||
switch (position) {
|
||||
case ScreenPosition.TopLeft:
|
||||
p = new Point(
|
||||
wa.Left - form.ChromeBorderHorizontal,
|
||||
wa.Top - form.ChromeBorderVertical
|
||||
);
|
||||
break;
|
||||
|
||||
case ScreenPosition.TopRight:
|
||||
p = new Point(
|
||||
wa.Right - form.Width + form.ChromeBorderHorizontal,
|
||||
wa.Top - form.ChromeBorderVertical
|
||||
);
|
||||
break;
|
||||
|
||||
case ScreenPosition.BottomLeft:
|
||||
p = new Point(
|
||||
wa.Left - form.ChromeBorderHorizontal,
|
||||
wa.Bottom - form.Height + form.ChromeBorderVertical
|
||||
);
|
||||
break;
|
||||
|
||||
case ScreenPosition.BottomRight:
|
||||
p = new Point(
|
||||
wa.Right - form.Width + form.ChromeBorderHorizontal,
|
||||
wa.Bottom - form.Height + form.ChromeBorderVertical
|
||||
);
|
||||
break;
|
||||
|
||||
case ScreenPosition.Center:
|
||||
p = new Point(
|
||||
wa.X + (wa.Width / 2) - (form.Width / 2) - (form.ChromeBorderHorizontal / 2),
|
||||
wa.Y + (wa.Height / 2) - (form.Height / 2) - (form.ChromeBorderVertical / 2)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
form.Location = p;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ using System.Windows.Forms;
|
|||
using OnTopReplica.Properties;
|
||||
using System.Collections.Generic;
|
||||
using OnTopReplica.MessagePumpProcessors;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
|
||||
namespace OnTopReplica.SidePanels {
|
||||
partial class GroupSwitchPanel : SidePanel {
|
||||
|
@ -23,8 +24,8 @@ namespace OnTopReplica.SidePanels {
|
|||
}
|
||||
|
||||
private void LoadWindowList() {
|
||||
var manager = new WindowManager();
|
||||
manager.Refresh(WindowManager.EnumerationMode.TaskWindows);
|
||||
var manager = new TaskWindowSeeker();
|
||||
manager.Refresh();
|
||||
|
||||
var imageList = new ImageList();
|
||||
imageList.ColorDepth = ColorDepth.Depth32Bit;
|
||||
|
@ -46,7 +47,7 @@ namespace OnTopReplica.SidePanels {
|
|||
public override void OnClosing(MainForm form) {
|
||||
base.OnClosing(form);
|
||||
|
||||
if (_enableOnClose) {
|
||||
if (_enableOnClose && listWindows.SelectedItems.Count > 0) {
|
||||
List<WindowHandle> ret = new List<WindowHandle>();
|
||||
foreach (ListViewItem i in listWindows.SelectedItems) {
|
||||
ret.Add((WindowHandle)i.Tag);
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace OnTopReplica.SidePanels {
|
|||
return;
|
||||
}
|
||||
|
||||
SetRegion(region.Rect);
|
||||
SetRegion(region.Bounds);
|
||||
|
||||
//Select right combobox
|
||||
if (comboRegions.Items.Contains(region)) {
|
||||
|
@ -207,7 +207,7 @@ namespace OnTopReplica.SidePanels {
|
|||
if (region == null)
|
||||
return;
|
||||
|
||||
SetRegion(region.Rect);
|
||||
SetRegion(region.Bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
21
OnTopReplica/StartupOptions/CliStatus.cs
Normal file
21
OnTopReplica/StartupOptions/CliStatus.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
public enum CliStatus {
|
||||
/// <summary>
|
||||
/// No errors while parsing.
|
||||
/// </summary>
|
||||
Ok,
|
||||
/// <summary>
|
||||
/// User asked for help.
|
||||
/// </summary>
|
||||
Information,
|
||||
/// <summary>
|
||||
/// Error while parsing.
|
||||
/// </summary>
|
||||
Error
|
||||
}
|
||||
|
||||
}
|
116
OnTopReplica/StartupOptions/CommandLineReportForm.Designer.cs
generated
Normal file
116
OnTopReplica/StartupOptions/CommandLineReportForm.Designer.cs
generated
Normal file
|
@ -0,0 +1,116 @@
|
|||
namespace OnTopReplica.StartupOptions {
|
||||
partial class CommandLineReportForm {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CommandLineReportForm));
|
||||
this.buttonOk = new System.Windows.Forms.Button();
|
||||
this.labelInstruction = new System.Windows.Forms.Label();
|
||||
this.txtDescription = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.txtCliArgs = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// buttonOk
|
||||
//
|
||||
this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.buttonOk.Location = new System.Drawing.Point(440, 200);
|
||||
this.buttonOk.Name = "buttonOk";
|
||||
this.buttonOk.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonOk.TabIndex = 0;
|
||||
this.buttonOk.Text = "OK";
|
||||
this.buttonOk.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelInstruction
|
||||
//
|
||||
this.labelInstruction.AutoSize = true;
|
||||
this.labelInstruction.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.labelInstruction.ForeColor = System.Drawing.SystemColors.HotTrack;
|
||||
this.labelInstruction.Location = new System.Drawing.Point(12, 10);
|
||||
this.labelInstruction.Name = "labelInstruction";
|
||||
this.labelInstruction.Size = new System.Drawing.Size(112, 21);
|
||||
this.labelInstruction.TabIndex = 1;
|
||||
this.labelInstruction.Text = "Command line";
|
||||
//
|
||||
// txtDescription
|
||||
//
|
||||
this.txtDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtDescription.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.txtDescription.Location = new System.Drawing.Point(12, 42);
|
||||
this.txtDescription.Multiline = true;
|
||||
this.txtDescription.Name = "txtDescription";
|
||||
this.txtDescription.ReadOnly = true;
|
||||
this.txtDescription.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.txtDescription.Size = new System.Drawing.Size(503, 152);
|
||||
this.txtDescription.TabIndex = 2;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(13, 205);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(60, 13);
|
||||
this.label1.TabIndex = 3;
|
||||
this.label1.Text = "Arguments:";
|
||||
//
|
||||
// txtCliArgs
|
||||
//
|
||||
this.txtCliArgs.Location = new System.Drawing.Point(79, 202);
|
||||
this.txtCliArgs.Name = "txtCliArgs";
|
||||
this.txtCliArgs.ReadOnly = true;
|
||||
this.txtCliArgs.Size = new System.Drawing.Size(355, 20);
|
||||
this.txtCliArgs.TabIndex = 4;
|
||||
//
|
||||
// CommandLineReportForm
|
||||
//
|
||||
this.AcceptButton = this.buttonOk;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
this.ClientSize = new System.Drawing.Size(527, 235);
|
||||
this.Controls.Add(this.txtCliArgs);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.txtDescription);
|
||||
this.Controls.Add(this.labelInstruction);
|
||||
this.Controls.Add(this.buttonOk);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "CommandLineReportForm";
|
||||
this.Text = "Command line parameters";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button buttonOk;
|
||||
private System.Windows.Forms.Label labelInstruction;
|
||||
private System.Windows.Forms.TextBox txtDescription;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox txtCliArgs;
|
||||
}
|
||||
}
|
31
OnTopReplica/StartupOptions/CommandLineReportForm.cs
Normal file
31
OnTopReplica/StartupOptions/CommandLineReportForm.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
public partial class CommandLineReportForm : Form {
|
||||
|
||||
public CommandLineReportForm(CliStatus status, string message) {
|
||||
InitializeComponent();
|
||||
|
||||
switch (status) {
|
||||
case CliStatus.Information:
|
||||
labelInstruction.Text = "Command line help";
|
||||
break;
|
||||
|
||||
case CliStatus.Error:
|
||||
labelInstruction.Text = "Command line parsing error";
|
||||
break;
|
||||
}
|
||||
|
||||
txtDescription.Text = message;
|
||||
|
||||
txtCliArgs.Text = Environment.CommandLine;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
1574
OnTopReplica/StartupOptions/CommandLineReportForm.resx
Normal file
1574
OnTopReplica/StartupOptions/CommandLineReportForm.resx
Normal file
File diff suppressed because it is too large
Load diff
92
OnTopReplica/StartupOptions/Factory.cs
Normal file
92
OnTopReplica/StartupOptions/Factory.cs
Normal file
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using OnTopReplica.Properties;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
class Factory {
|
||||
|
||||
static Factory() {
|
||||
//Custom type conversion attributes
|
||||
TypeDescriptor.AddAttributes(typeof(Size), new TypeConverterAttribute(typeof(SizeConverter)));
|
||||
TypeDescriptor.AddAttributes(typeof(ScreenPosition), new TypeConverterAttribute(typeof(ScreenPositionConverter)));
|
||||
TypeDescriptor.AddAttributes(typeof(Rectangle), new TypeConverterAttribute(typeof(RectangleConverter)));
|
||||
}
|
||||
|
||||
public static Options CreateOptions(string[] args) {
|
||||
var options = new Options();
|
||||
|
||||
LoadSettings(options);
|
||||
|
||||
ParseCommandLine(args, options);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private static void LoadSettings(Options options) {
|
||||
if (Settings.Default.RestoreSizeAndPosition) {
|
||||
options.StartLocation = Settings.Default.RestoreLastPosition;
|
||||
options.StartSize = Settings.Default.RestoreLastSize;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseCommandLine(string[] args, Options options) {
|
||||
var cmdOptions = new NDesk.Options.OptionSet()
|
||||
.Add<long>("windowId=", "Window handle ({HWND}) to be cloned.", id => {
|
||||
options.WindowId = new IntPtr(id);
|
||||
})
|
||||
.Add<string>("windowTitle=", "{TITLE} of the window to be cloned.", s => {
|
||||
options.WindowTitle = s;
|
||||
})
|
||||
.Add<string>("windowClass=", "{CLASS} of the window to be cloned.", s => {
|
||||
options.WindowClass = s;
|
||||
})
|
||||
.Add("v|visible", "If set, only clones windows that are visible.", s => {
|
||||
options.MustBeVisible = true;
|
||||
})
|
||||
.Add<Size>("size=", "Target {SIZE} of the cloned thumbnail.", s => {
|
||||
options.StartSize = s;
|
||||
})
|
||||
.Add<Size>("position=", "Target {COORDINATES} of the OnTopReplica window.", s => {
|
||||
options.StartLocation = new Point(s.Width, s.Height);
|
||||
options.StartScreenPosition = null;
|
||||
})
|
||||
.Add<ScreenPosition>("screenPosition=", "Resolution independent window position on current screen, with locking (TR|TL|C|BR|BL).", pos => {
|
||||
options.StartLocation = null;
|
||||
options.StartScreenPosition = pos;
|
||||
})
|
||||
.Add<Rectangle>("r|region=", "Region {BOUNDS} of the original window.", region => {
|
||||
options.Region = region;
|
||||
})
|
||||
.Add<byte>("o|opacity=", "Opacity of the window (0-255).", opacity => {
|
||||
options.Opacity = opacity;
|
||||
})
|
||||
.Add("clickForwarding", "Enables click forwarding.", s => {
|
||||
options.EnableClickForwarding = true;
|
||||
})
|
||||
.Add("chromeOff", "Disables the window's chrome (border).", s => {
|
||||
options.DisableChrome = true;
|
||||
})
|
||||
.Add("h|help|?", "Show command line help.", s => {
|
||||
options.Status = CliStatus.Information;
|
||||
});
|
||||
|
||||
List<string> values;
|
||||
try {
|
||||
values = cmdOptions.Parse(args);
|
||||
}
|
||||
catch (NDesk.Options.OptionException ex) {
|
||||
options.DebugMessageWriter.WriteLine(ex.Message);
|
||||
options.DebugMessageWriter.WriteLine("Try 'OnTopReplica /help' for more information.");
|
||||
options.Status = CliStatus.Error;
|
||||
}
|
||||
|
||||
if (options.Status == CliStatus.Information) {
|
||||
cmdOptions.WriteOptionDescriptions(options.DebugMessageWriter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
145
OnTopReplica/StartupOptions/Options.cs
Normal file
145
OnTopReplica/StartupOptions/Options.cs
Normal file
|
@ -0,0 +1,145 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
|
||||
/// <summary>
|
||||
/// Represents startup options that can be set via CLI scripting (or other stuff).
|
||||
/// </summary>
|
||||
class Options {
|
||||
|
||||
public Options() {
|
||||
Status = CliStatus.Ok;
|
||||
Opacity = 255;
|
||||
DisableChrome = false;
|
||||
MustBeVisible = false;
|
||||
}
|
||||
|
||||
#region Position and size
|
||||
|
||||
public Point? StartLocation { get; set; }
|
||||
|
||||
public ScreenPosition? StartScreenPosition { get; set; }
|
||||
|
||||
public Size? StartSize { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Window cloning
|
||||
|
||||
public IntPtr? WindowId { get; set; }
|
||||
|
||||
public string WindowTitle { get; set; }
|
||||
|
||||
public string WindowClass { get; set; }
|
||||
|
||||
public Rectangle? Region { get; set; }
|
||||
|
||||
public bool MustBeVisible { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Options
|
||||
|
||||
public bool EnableClickForwarding { get; set; }
|
||||
|
||||
public byte Opacity { get; set; }
|
||||
|
||||
public bool DisableChrome { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Debug info
|
||||
|
||||
StringBuilder _sb = new StringBuilder();
|
||||
TextWriter _sbWriter;
|
||||
|
||||
public CliStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a debug message writer.
|
||||
/// </summary>
|
||||
public TextWriter DebugMessageWriter {
|
||||
get {
|
||||
if (_sbWriter == null) {
|
||||
_sbWriter = new StringWriter(_sb);
|
||||
}
|
||||
return _sbWriter;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the debug message.
|
||||
/// </summary>
|
||||
public string DebugMessage {
|
||||
get {
|
||||
if(_sbWriter != null)
|
||||
_sbWriter.Flush();
|
||||
return _sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Application
|
||||
|
||||
public void Apply(MainForm form) {
|
||||
//GUI
|
||||
form.IsChromeVisible = !DisableChrome;
|
||||
form.Opacity = (double)Opacity / 255.0;
|
||||
|
||||
//Thumbnail cloning
|
||||
WindowHandle handle = null;
|
||||
if (WindowId.HasValue) {
|
||||
handle = WindowHandle.FromHandle(WindowId.Value);
|
||||
}
|
||||
else if (WindowTitle != null) {
|
||||
var seeker = new ByTitleWindowSeeker(WindowTitle) {
|
||||
OwnerHandle = form.Handle,
|
||||
SkipNotVisibleWindows = MustBeVisible
|
||||
};
|
||||
seeker.Refresh();
|
||||
|
||||
handle = seeker.Windows.FirstOrDefault();
|
||||
}
|
||||
else if (WindowClass != null) {
|
||||
var seeker = new ByClassWindowSeeker(WindowClass) {
|
||||
OwnerHandle = form.Handle,
|
||||
SkipNotVisibleWindows = MustBeVisible
|
||||
};
|
||||
seeker.Refresh();
|
||||
|
||||
handle = seeker.Windows.FirstOrDefault();
|
||||
}
|
||||
if (handle != null) {
|
||||
form.SetThumbnail(handle, Region);
|
||||
}
|
||||
|
||||
//Size
|
||||
if (StartSize.HasValue) {
|
||||
form.ClientSize = StartSize.Value;
|
||||
}
|
||||
|
||||
//Position
|
||||
if (StartLocation.HasValue) {
|
||||
form.Location = StartLocation.Value;
|
||||
}
|
||||
else if (StartScreenPosition.HasValue) {
|
||||
form.PositionLock = StartScreenPosition.Value;
|
||||
}
|
||||
|
||||
//Other features
|
||||
if (EnableClickForwarding) {
|
||||
form.ClickForwardingEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
61
OnTopReplica/StartupOptions/RectangleConverter.cs
Normal file
61
OnTopReplica/StartupOptions/RectangleConverter.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
class RectangleConverter : TypeConverter {
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
|
||||
if (value != null) {
|
||||
var sVal = value.ToString();
|
||||
return Convert(sVal);
|
||||
}
|
||||
else
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
|
||||
return sourceType == typeof(string);
|
||||
}
|
||||
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
|
||||
return destinationType == typeof(Rectangle);
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
|
||||
if (value != null && destinationType == typeof(Rectangle)) {
|
||||
var sVal = value.ToString();
|
||||
return Convert(sVal);
|
||||
}
|
||||
else
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
static Regex _sizeRegex = new Regex("^\\D*(?<x>\\d*)\\s*,\\s*(?<y>\\d*)\\s*,\\s*(?<width>\\d*)\\s*,\\s*(?<height>\\d*)\\D*$",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.Singleline);
|
||||
|
||||
private Rectangle Convert(string s) {
|
||||
var match = _sizeRegex.Match(s);
|
||||
|
||||
var x = match.Groups["x"];
|
||||
var y = match.Groups["y"];
|
||||
var width = match.Groups["width"];
|
||||
var height = match.Groups["height"];
|
||||
|
||||
if (match.Success && x.Success && y.Success && width.Success && height.Success) {
|
||||
var xVal = int.Parse(x.Value);
|
||||
var yVal = int.Parse(y.Value);
|
||||
var widthVal = int.Parse(width.Value);
|
||||
var heightVal = int.Parse(height.Value);
|
||||
|
||||
return new Rectangle(xVal, yVal, widthVal, heightVal);
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("Cannot convert '" + s + "' to rectangle.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
50
OnTopReplica/StartupOptions/ScreenPositionConverter.cs
Normal file
50
OnTopReplica/StartupOptions/ScreenPositionConverter.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
class ScreenPositionConverter : TypeConverter {
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
|
||||
if (sourceType == typeof(string))
|
||||
return true;
|
||||
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
|
||||
if (destinationType == typeof(ScreenPosition))
|
||||
return true;
|
||||
|
||||
return base.CanConvertTo(context, destinationType);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
|
||||
var sValue = value.ToString();
|
||||
|
||||
switch (sValue) {
|
||||
case "TL":
|
||||
return ScreenPosition.TopLeft;
|
||||
case "TR":
|
||||
return ScreenPosition.TopRight;
|
||||
case "BL":
|
||||
return ScreenPosition.BottomLeft;
|
||||
case "BR":
|
||||
return ScreenPosition.BottomRight;
|
||||
case "C":
|
||||
return ScreenPosition.Center;
|
||||
default:
|
||||
throw new ArgumentException("Invalid screen position value '" + sValue + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
|
||||
if (destinationType == typeof(ScreenPosition))
|
||||
return ConvertFrom(context, culture, value);
|
||||
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
69
OnTopReplica/StartupOptions/SizeConverter.cs
Normal file
69
OnTopReplica/StartupOptions/SizeConverter.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace OnTopReplica.StartupOptions {
|
||||
|
||||
class SizeConverter : TypeConverter {
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
|
||||
if (value != null) {
|
||||
var sVal = value.ToString();
|
||||
return StringToSize(sVal);
|
||||
}
|
||||
else
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
|
||||
return (sourceType == typeof(string) || sourceType == typeof(Size));
|
||||
}
|
||||
|
||||
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
|
||||
return (destinationType == typeof(Size) || destinationType == typeof(string));
|
||||
}
|
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
|
||||
if (value == null)
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
|
||||
if (destinationType == typeof(Size)) {
|
||||
var sVal = value.ToString();
|
||||
return StringToSize(sVal);
|
||||
}
|
||||
else if (destinationType == typeof(string)) {
|
||||
if (value is Size) {
|
||||
Size sValue = (Size)value;
|
||||
return string.Format("{0}, {1}", sValue.Width, sValue.Height);
|
||||
}
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
else
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
|
||||
static Regex _sizeRegex = new Regex("^\\D*(?<x>\\d*)\\s*,\\s*(?<y>\\d*)\\D*$",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.Singleline);
|
||||
|
||||
private Size StringToSize(string s) {
|
||||
var match = _sizeRegex.Match(s);
|
||||
|
||||
var x = match.Groups["x"];
|
||||
var y = match.Groups["y"];
|
||||
|
||||
if (!match.Success || !x.Success || !y.Success)
|
||||
throw new ArgumentException("Cannot convert '" + s + "' to coordinates pair.");
|
||||
|
||||
var xVal = Int32.Parse(x.Value);
|
||||
var yVal = Int32.Parse(y.Value);
|
||||
|
||||
return new Size(xVal, yVal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -13,11 +13,11 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
public StoredRegion(Rectangle r, string n) {
|
||||
Rect = r;
|
||||
Bounds = r;
|
||||
Name = n;
|
||||
}
|
||||
|
||||
public Rectangle Rect {
|
||||
public Rectangle Bounds {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
@ -47,14 +47,14 @@ namespace OnTopReplica {
|
|||
reader.Read();
|
||||
|
||||
XmlSerializer x = new XmlSerializer(typeof(Rectangle));
|
||||
Rect = (Rectangle)x.Deserialize(reader);
|
||||
Bounds = (Rectangle)x.Deserialize(reader);
|
||||
}
|
||||
|
||||
public void WriteXml(System.Xml.XmlWriter writer) {
|
||||
writer.WriteAttributeString("name", Name);
|
||||
|
||||
XmlSerializer x = new XmlSerializer(typeof(Rectangle));
|
||||
x.Serialize(writer, Rect);
|
||||
x.Serialize(writer, Bounds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
20
OnTopReplica/Strings.Designer.cs
generated
20
OnTopReplica/Strings.Designer.cs
generated
|
@ -1025,7 +1025,25 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Position.
|
||||
/// Looks up a localized string similar to Center.
|
||||
/// </summary>
|
||||
internal static string MenuPosCenter {
|
||||
get {
|
||||
return ResourceManager.GetString("MenuPosCenter", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Disabled.
|
||||
/// </summary>
|
||||
internal static string MenuPosDisabled {
|
||||
get {
|
||||
return ResourceManager.GetString("MenuPosDisabled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Position lock.
|
||||
/// </summary>
|
||||
internal static string MenuPosition {
|
||||
get {
|
||||
|
|
|
@ -171,7 +171,7 @@ Dette program kræver Windows Vista Home Premium eller bedre.</value>
|
|||
<value>Ingen miniature indlæst.</value>
|
||||
</data>
|
||||
<data name="ErrorUnableToCreateThumbnail" xml:space="preserve">
|
||||
<value>Kan ikke lave miniature.</value>
|
||||
<value>Kan ikke lave miniature</value>
|
||||
</data>
|
||||
<data name="ErrorUnableToFit" xml:space="preserve">
|
||||
<value>Kunne ikke passes til vinduet.</value>
|
||||
|
|
0
OnTopReplica/Strings.it.Designer.cs
generated
Normal file
0
OnTopReplica/Strings.it.Designer.cs
generated
Normal file
|
@ -1,5 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
|
@ -176,7 +281,7 @@ Per farlo, clicca col tasto destro del mouse sul desktop e poi su Personalizza.<
|
|||
<value>Nessuna finestra clonata al momento.</value>
|
||||
</data>
|
||||
<data name="ErrorUnableToCreateThumbnail" xml:space="preserve">
|
||||
<value>Impossibile clonare la finestra.</value>
|
||||
<value>Impossibile clonare la finestra</value>
|
||||
</data>
|
||||
<data name="ErrorUnableToFit" xml:space="preserve">
|
||||
<value>Impossibile adattare la finestra.</value>
|
||||
|
@ -386,7 +491,7 @@ Puoi abilitare il Click-Through in futuro</value>
|
|||
<value>In basso a destra</value>
|
||||
</data>
|
||||
<data name="MenuPosition" xml:space="preserve">
|
||||
<value>Posizione</value>
|
||||
<value>Blocco posizione</value>
|
||||
</data>
|
||||
<data name="MenuPositionTT" xml:space="preserve">
|
||||
<value>Posiziona automaticamente OnTopReplica sul monitor corrente.</value>
|
||||
|
@ -484,4 +589,7 @@ Puoi abilitare il Click-Through in futuro</value>
|
|||
<data name="UpdateNow" xml:space="preserve">
|
||||
<value>Aggiorna!</value>
|
||||
</data>
|
||||
<data name="MenuPosDisabled" xml:space="preserve">
|
||||
<value>Disabilitato</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,5 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
|
@ -176,7 +281,7 @@ You must run this application on Windows Vista Home Premium or better.</value>
|
|||
<value>No thumbnail loaded.</value>
|
||||
</data>
|
||||
<data name="ErrorUnableToCreateThumbnail" xml:space="preserve">
|
||||
<value>Unable to create thumbnail.</value>
|
||||
<value>Unable to create thumbnail</value>
|
||||
</data>
|
||||
<data name="ErrorUnableToFit" xml:space="preserve">
|
||||
<value>Unable to fit window.</value>
|
||||
|
@ -386,7 +491,7 @@ You can enable click-through later</value>
|
|||
<value>Bottom Right</value>
|
||||
</data>
|
||||
<data name="MenuPosition" xml:space="preserve">
|
||||
<value>Position</value>
|
||||
<value>Position lock</value>
|
||||
</data>
|
||||
<data name="MenuPositionTT" xml:space="preserve">
|
||||
<value>Automatically position OnTopReplica on the current screen.</value>
|
||||
|
@ -484,4 +589,10 @@ You can enable click-through later</value>
|
|||
<data name="UpdateNow" xml:space="preserve">
|
||||
<value>Update now!</value>
|
||||
</data>
|
||||
<data name="MenuPosCenter" xml:space="preserve">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="MenuPosDisabled" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
</root>
|
|
@ -8,6 +8,7 @@ namespace OnTopReplica {
|
|||
|
||||
/// <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;
|
||||
|
||||
|
@ -81,5 +82,13 @@ namespace OnTopReplica {
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new windowHandle instance from a given IntPtr handle.
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle value.</param>
|
||||
public static WindowHandle FromHandle(IntPtr handle) {
|
||||
return new WindowHandle(handle, string.Empty);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,12 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Properties;
|
||||
using OnTopReplica.WindowSeekers;
|
||||
|
||||
namespace OnTopReplica {
|
||||
/// <summary>
|
||||
/// Extension methods used to apply a window list to a menu.
|
||||
/// </summary>
|
||||
static class WindowListHelper {
|
||||
|
||||
public class WindowSelectionData {
|
||||
|
@ -14,7 +18,15 @@ namespace OnTopReplica {
|
|||
|
||||
const int MaxWindowTitleLength = 55;
|
||||
|
||||
public static void PopulateMenu(Form ownerForm, WindowManager windowManager, ToolStrip menu,
|
||||
/// <summary>
|
||||
/// Populates the menu with a list of windows.
|
||||
/// </summary>
|
||||
/// <param name="menu">The menu to populate.</param>
|
||||
/// <param name="ownerForm">The owning form.</param>
|
||||
/// <param name="windowManager">The window manager that provides the windows list.</param>
|
||||
/// <param name="currentHandle">The currently used window (will be checked in the list).</param>
|
||||
/// <param name="clickHandler">Event handler for clicks on window items.</param>
|
||||
public static void PopulateMenu(this ToolStrip menu, Form ownerForm, BaseWindowSeeker windowManager,
|
||||
WindowHandle currentHandle, EventHandler clickHandler) {
|
||||
var regions = GetRegions();
|
||||
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
/// <summary>A helper class that allows you to easily build and keep a list of Windows (in the form of WindowHandle objects).</summary>
|
||||
public class WindowManager {
|
||||
|
||||
List<WindowHandle> _windows = new List<WindowHandle>();
|
||||
|
||||
public enum EnumerationMode {
|
||||
/// <summary>All windows with 'Visible' flag.</summary>
|
||||
AllVisible,
|
||||
|
||||
/// <summary>All top level windows.</summary>
|
||||
AllTopLevel,
|
||||
|
||||
/// <summary>Windows of a task (like Alt+Tab).</summary>
|
||||
TaskWindows
|
||||
}
|
||||
|
||||
/// <summary>Refreshes the window list.</summary>
|
||||
public void Refresh(EnumerationMode mode) {
|
||||
_windows = new List<WindowHandle>();
|
||||
|
||||
WindowManagerMethods.EnumWindowsProc proc = null;
|
||||
switch (mode) {
|
||||
case EnumerationMode.AllVisible:
|
||||
proc = new WindowManagerMethods.EnumWindowsProc(EnumWindowProcAll);
|
||||
break;
|
||||
|
||||
case EnumerationMode.AllTopLevel:
|
||||
proc = new WindowManagerMethods.EnumWindowsProc(EnumWindowProcTopLevel);
|
||||
break;
|
||||
|
||||
case EnumerationMode.TaskWindows:
|
||||
proc = new WindowManagerMethods.EnumWindowsProc(EnumWindowProcTask);
|
||||
break;
|
||||
}
|
||||
|
||||
WindowManagerMethods.EnumWindows(proc, IntPtr.Zero);
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<WindowHandle> Windows {
|
||||
get {
|
||||
return _windows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool EnumWindowProcAll(IntPtr hwnd, IntPtr lParam) {
|
||||
if (WindowManagerMethods.IsWindowVisible(hwnd)) {
|
||||
string title = WindowMethods.GetWindowText(hwnd);
|
||||
_windows.Add( new WindowHandle(hwnd, title));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnumWindowProcTopLevel(IntPtr hwnd, IntPtr lParam) {
|
||||
if (WindowManagerMethods.IsWindowVisible(hwnd)) {
|
||||
//Check if window has no parent
|
||||
if ((long)WindowManagerMethods.GetParent(hwnd) == 0 && WindowManagerMethods.GetDesktopWindow() != hwnd) {
|
||||
string title = WindowMethods.GetWindowText(hwnd);
|
||||
_windows.Add( new WindowHandle(hwnd, title));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnumWindowProcTask(IntPtr hwnd, IntPtr lParam) {
|
||||
//Code taken from: http://www.thescarms.com/VBasic/alttab.aspx
|
||||
|
||||
//Accept windows that
|
||||
// - are visible
|
||||
// - do not have a parent
|
||||
// - have no owner and are not Tool windows OR
|
||||
// - have an owner and are App windows
|
||||
|
||||
//Reject empty titles
|
||||
|
||||
string title = WindowMethods.GetWindowText(hwnd);
|
||||
if (string.IsNullOrEmpty(title))
|
||||
return true;
|
||||
|
||||
if (WindowManagerMethods.IsWindowVisible(hwnd)) {
|
||||
if ((long)WindowManagerMethods.GetParent(hwnd) == 0) {
|
||||
bool hasOwner = (long)WindowManagerMethods.GetWindow(hwnd, WindowManagerMethods.GetWindowMode.GW_OWNER) != 0;
|
||||
WindowMethods.WindowExStyles exStyle = (WindowMethods.WindowExStyles)WindowMethods.GetWindowLong(hwnd, WindowMethods.WindowLong.ExStyle);
|
||||
|
||||
if (((exStyle & WindowMethods.WindowExStyles.ToolWindow) == 0 && !hasOwner) || //unowned non-tool window
|
||||
((exStyle & WindowMethods.WindowExStyles.AppWindow) == WindowMethods.WindowExStyles.AppWindow && hasOwner)) { //owned application window
|
||||
_windows.Add(new WindowHandle(hwnd, title));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
80
OnTopReplica/WindowSeekers/BaseWindowSeeker.cs
Normal file
80
OnTopReplica/WindowSeekers/BaseWindowSeeker.cs
Normal file
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.WindowSeekers {
|
||||
|
||||
/// <summary>
|
||||
/// Base class for window seekers that can populate a list of window handles based on some criteria.
|
||||
/// </summary>
|
||||
abstract class BaseWindowSeeker {
|
||||
|
||||
List<WindowHandle> _list = new List<WindowHandle>();
|
||||
|
||||
/// <summary>
|
||||
/// Get the matching windows from the last refresh.
|
||||
/// </summary>
|
||||
public IEnumerable<WindowHandle> Windows {
|
||||
get {
|
||||
return _list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces a window list refresh.
|
||||
/// </summary>
|
||||
public virtual void Refresh() {
|
||||
_list.Clear();
|
||||
|
||||
WindowManagerMethods.EnumWindows(
|
||||
new WindowManagerMethods.EnumWindowsProc(RefreshCallback),
|
||||
IntPtr.Zero);
|
||||
}
|
||||
|
||||
private bool RefreshCallback(IntPtr hwnd, IntPtr lParam) {
|
||||
bool cont = true;
|
||||
|
||||
//Skip owner
|
||||
if (hwnd == OwnerHandle)
|
||||
return true;
|
||||
|
||||
if (SkipNotVisibleWindows && !WindowManagerMethods.IsWindowVisible(hwnd))
|
||||
return true;
|
||||
|
||||
//Extract basic properties
|
||||
string title = WindowMethods.GetWindowText(hwnd);
|
||||
|
||||
if (InspectWindow(hwnd, title, ref cont)) {
|
||||
//Window has been picked
|
||||
_list.Add(new WindowHandle(hwnd, title));
|
||||
}
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inspects a window and returns whether the window should be listed or not.
|
||||
/// </summary>
|
||||
/// <param name="hwnd">Handle of the window.</param>
|
||||
/// <param name="title">Title of the window (if any).</param>
|
||||
/// <param name="terminate">Indicates whether the inspection loop should terminate after this window.</param>
|
||||
/// <returns>True if the window should be listed.</returns>
|
||||
protected abstract bool InspectWindow(IntPtr hwnd, string title, ref bool terminate);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the window handle of the owner.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Windows with this handle will be automatically skipped.
|
||||
/// </remarks>
|
||||
public IntPtr OwnerHandle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether not visible windows should be skipped.
|
||||
/// </summary>
|
||||
public bool SkipNotVisibleWindows { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
35
OnTopReplica/WindowSeekers/ByClassWindowSeeker.cs
Normal file
35
OnTopReplica/WindowSeekers/ByClassWindowSeeker.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.WindowSeekers {
|
||||
/// <summary>
|
||||
/// Seeks a single window by matching its window class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Class matching is exact and case-sensititve.
|
||||
/// </remarks>
|
||||
class ByClassWindowSeeker : BaseWindowSeeker {
|
||||
|
||||
public ByClassWindowSeeker(string className) {
|
||||
if (className == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
ClassName = className;
|
||||
}
|
||||
|
||||
public string ClassName { get; private set; }
|
||||
|
||||
protected override bool InspectWindow(IntPtr hwnd, string title, ref bool terminate) {
|
||||
var wndClass = WindowMethods.GetWindowClass(hwnd);
|
||||
|
||||
if (ClassName.Equals(wndClass, StringComparison.CurrentCulture)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
45
OnTopReplica/WindowSeekers/ByTitleWindowSeeker.cs
Normal file
45
OnTopReplica/WindowSeekers/ByTitleWindowSeeker.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.WindowSeekers {
|
||||
/// <summary>
|
||||
/// Seeks a single window by approximately matching its title.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Title search is case-insensitive and matches only the beginning of the windows' titles.
|
||||
/// </remarks>
|
||||
class ByTitleWindowSeeker : BaseWindowSeeker {
|
||||
|
||||
public ByTitleWindowSeeker(string titleSeekString) {
|
||||
if (titleSeekString == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
TitleMatch = titleSeekString.Trim().ToLower();
|
||||
}
|
||||
|
||||
public string TitleMatch { get; private set; }
|
||||
|
||||
protected override bool InspectWindow(IntPtr hwnd, string title, ref bool terminate) {
|
||||
//Skip empty titles
|
||||
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)
|
||||
return false;
|
||||
|
||||
var modTitle = title.Trim().ToLower();
|
||||
if (modTitle.StartsWith(TitleMatch)) {
|
||||
terminate = true; //only one needed
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
37
OnTopReplica/WindowSeekers/TaskWindowSeeker.cs
Normal file
37
OnTopReplica/WindowSeekers/TaskWindowSeeker.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.WindowSeekers {
|
||||
class TaskWindowSeeker : BaseWindowSeeker {
|
||||
|
||||
protected override bool InspectWindow(IntPtr hwnd, string title, ref bool terminate) {
|
||||
//Code taken from: http://www.thescarms.com/VBasic/alttab.aspx
|
||||
|
||||
//Accept windows that
|
||||
// - are visible
|
||||
// - do not have a parent
|
||||
// - have no owner and are not Tool windows OR
|
||||
// - have an owner and are App windows
|
||||
|
||||
//Reject empty titles
|
||||
|
||||
if (string.IsNullOrEmpty(title))
|
||||
return false;
|
||||
|
||||
if ((long)WindowManagerMethods.GetParent(hwnd) == 0) {
|
||||
bool hasOwner = (long)WindowManagerMethods.GetWindow(hwnd, WindowManagerMethods.GetWindowMode.GW_OWNER) != 0;
|
||||
WindowMethods.WindowExStyles exStyle = (WindowMethods.WindowExStyles)WindowMethods.GetWindowLong(hwnd, WindowMethods.WindowLong.ExStyle);
|
||||
|
||||
if (((exStyle & WindowMethods.WindowExStyles.ToolWindow) == 0 && !hasOwner) || //unowned non-tool window
|
||||
((exStyle & WindowMethods.WindowExStyles.AppWindow) == WindowMethods.WindowExStyles.AppWindow && hasOwner)) { //owned application window
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -31,11 +31,14 @@
|
|||
<setting name="FullscreenAlwaysOnTop" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="Setting" serializeAs="String">
|
||||
<value />
|
||||
<setting name="RestoreSizeAndPosition" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="Setting1" serializeAs="String">
|
||||
<value />
|
||||
<setting name="RestoreLastSize" serializeAs="String">
|
||||
<value>0, 0</value>
|
||||
</setting>
|
||||
<setting name="RestoreLastPosition" serializeAs="String">
|
||||
<value>0, 0</value>
|
||||
</setting>
|
||||
</OnTopReplica.Properties.Settings>
|
||||
</userSettings>
|
||||
|
|
Loading…
Reference in a new issue