Fixed ALT+TAB display on Windows Seven and altered hide/show mechanism.

Added CTRL+SHIFT+C hotkey that clones the active foreground window.
This commit is contained in:
Lorenz Cuno Klopfenstein 2010-07-18 12:45:53 +02:00
parent f5e4231cf9
commit cfe39c713c
8 changed files with 114 additions and 41 deletions

View file

@ -31,6 +31,7 @@
this.menuContextWindows = new System.Windows.Forms.ToolStripMenuItem();
this.menuWindows = new System.Windows.Forms.ContextMenuStrip(this.components);
this.noneToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.fullSelectWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.switchToWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.selectRegionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.advancedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -43,6 +44,7 @@
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem();
this.fullOpacityToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.resizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuResize = new System.Windows.Forms.ContextMenuStrip(this.components);
this.doubleToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
@ -67,8 +69,6 @@
this.italianoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuContextClose = new System.Windows.Forms.ToolStripMenuItem();
this.fullSelectWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.fullOpacityToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.danskToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuFullscreenContext = new System.Windows.Forms.ContextMenuStrip(this.components);
this.enableClickthroughToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -115,7 +115,7 @@
this.menuWindows.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.noneToolStripMenuItem});
this.menuWindows.Name = "menuWindows";
this.menuWindows.OwnerItem = this.fullSelectWindowToolStripMenuItem;
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);
//
@ -125,6 +125,15 @@
this.noneToolStripMenuItem.Size = new System.Drawing.Size(117, 22);
this.noneToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuWindowsNone;
//
// fullSelectWindowToolStripMenuItem
//
this.fullSelectWindowToolStripMenuItem.DropDown = this.menuWindows;
this.fullSelectWindowToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.list;
this.fullSelectWindowToolStripMenuItem.Name = "fullSelectWindowToolStripMenuItem";
this.fullSelectWindowToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
this.fullSelectWindowToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuWindows;
this.fullSelectWindowToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuWindowsTT;
//
// switchToWindowToolStripMenuItem
//
this.switchToWindowToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.window_switch;
@ -195,7 +204,7 @@
this.toolStripMenuItem3,
this.toolStripMenuItem4});
this.menuOpacity.Name = "menuOpacity";
this.menuOpacity.OwnerItem = this.fullOpacityToolStripMenuItem;
this.menuOpacity.OwnerItem = this.menuContextOpacity;
this.menuOpacity.ShowCheckMargin = true;
this.menuOpacity.ShowImageMargin = false;
this.menuOpacity.Size = new System.Drawing.Size(154, 92);
@ -239,6 +248,14 @@
this.toolStripMenuItem4.ToolTipText = global::OnTopReplica.Strings.MenuOp25TT;
this.toolStripMenuItem4.Click += new System.EventHandler(this.Menu_Opacity_click);
//
// fullOpacityToolStripMenuItem
//
this.fullOpacityToolStripMenuItem.DropDown = this.menuOpacity;
this.fullOpacityToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.window_opacity;
this.fullOpacityToolStripMenuItem.Name = "fullOpacityToolStripMenuItem";
this.fullOpacityToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
this.fullOpacityToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuOpacity;
//
// resizeToolStripMenuItem
//
this.resizeToolStripMenuItem.DropDown = this.menuResize;
@ -439,23 +456,6 @@
this.menuContextClose.Text = global::OnTopReplica.Strings.MenuClose;
this.menuContextClose.Click += new System.EventHandler(this.Menu_Close_click);
//
// fullSelectWindowToolStripMenuItem
//
this.fullSelectWindowToolStripMenuItem.DropDown = this.menuWindows;
this.fullSelectWindowToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.list;
this.fullSelectWindowToolStripMenuItem.Name = "fullSelectWindowToolStripMenuItem";
this.fullSelectWindowToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
this.fullSelectWindowToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuWindows;
this.fullSelectWindowToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuWindowsTT;
//
// fullOpacityToolStripMenuItem
//
this.fullOpacityToolStripMenuItem.DropDown = this.menuOpacity;
this.fullOpacityToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.window_opacity;
this.fullOpacityToolStripMenuItem.Name = "fullOpacityToolStripMenuItem";
this.fullOpacityToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
this.fullOpacityToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuOpacity;
//
// danskToolStripMenuItem
//
this.danskToolStripMenuItem.Image = global::OnTopReplica.Properties.Resources.flag_danish;

View file

@ -69,6 +69,8 @@ namespace OnTopReplica {
var hotKeyMgr = _msgPumpManager.Get<MessagePumpProcessors.HotKeyManager>();
hotKeyMgr.RegisterHotKey(Native.HotKeyModifiers.Control | Native.HotKeyModifiers.Shift,
Keys.O, new Native.HotKeyMethods.HotKeyHandler(HotKeyOpenHandler));
hotKeyMgr.RegisterHotKey(Native.HotKeyModifiers.Control | Native.HotKeyModifiers.Shift,
Keys.C, new Native.HotKeyMethods.HotKeyHandler(HotKeyCloneHandler));
}
#region Event override
@ -114,6 +116,8 @@ namespace OnTopReplica {
if (ClickThroughEnabled) {
ClickThroughEnabled = false;
}
Program.Platform.RestoreForm(this);
}
protected override void OnDeactivate(EventArgs e) {
@ -122,6 +126,7 @@ namespace OnTopReplica {
//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...
if (!IsFullscreen) { //fullscreen mode doesn't use TopMost
TopMost = false;
TopMost = true;
}
}
@ -247,7 +252,7 @@ namespace OnTopReplica {
if (IsFullscreen)
IsFullscreen = false;
if (Visible && WindowState != FormWindowState.Minimized) {
if (Program.Platform.IsHidden(this)) {
Program.Platform.HideForm(this);
}
else {
@ -255,6 +260,14 @@ namespace OnTopReplica {
}
}
void HotKeyCloneHandler() {
var handle = Win32Helper.GetCurrentForegroundWindow();
if (handle.Handle == this.Handle)
return;
SetThumbnail(handle, null);
}
#endregion
#region Fullscreen
@ -295,6 +308,8 @@ namespace OnTopReplica {
}
_isFullscreen = value;
Program.Platform.OnFormStateChange(this);
}
}
@ -417,6 +432,8 @@ namespace OnTopReplica {
//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;

View file

@ -85,11 +85,8 @@ namespace OnTopReplica {
ClickThroughEnabled = false;
Opacity = 1.0;
//Ensure main form is shown
WindowState = FormWindowState.Normal;
Show();
Activate();
TopMost = true;
//Restore main form in platform with dependent method
Program.Platform.RestoreForm(this);
}
/// <summary>

View file

@ -9,6 +9,9 @@ namespace OnTopReplica.Native {
/// </summary>
static class WindowManagerMethods {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern IntPtr RealChildWindowFromPoint(IntPtr parent, NPoint point);

View file

@ -9,7 +9,7 @@ namespace OnTopReplica {
public static PlatformSupport Create() {
var os = Environment.OSVersion;
if (os.Platform != PlatformID.Win32NT)
return new Other();
@ -19,6 +19,10 @@ namespace OnTopReplica {
else
return new WindowsVista();
}
else if (os.Version.Major > 6) {
//Ensures forward compatibility
return new WindowsSeven();
}
else {
//Generic NT
return new WindowsXp();
@ -43,24 +47,50 @@ namespace OnTopReplica {
protected MainForm Form { get; private set; }
/// <summary>
/// Initializes a form.
/// Initializes a form. Called once in the form lifetime.
/// </summary>
/// <param name="form">Form to initialize.</param>
public virtual void InitForm(MainForm form) {
Form = form;
}
/// <summary>
/// Prepares the app for shutdown. Called once before the program terminates.
/// </summary>
public virtual void ShutdownApp() {
}
/// <summary>
/// Hides a form in a way that it can be restored later by the user.
/// Hides the main form in a way that it can be restored later by the user.
/// </summary>
/// <param name="form">Form to hide.</param>
public virtual void HideForm(MainForm form) {
form.Hide();
}
/// <summary>
/// Gets whether the form is currently hidden or not.
/// </summary>
public virtual bool IsHidden(MainForm form) {
return form.Visible;
}
/// <summary>
/// Restores the main form to its default state after is has been hidden.
/// Can be called whether the form is hidden or not.
/// </summary>
/// <param name="form">Form to restore.</param>
public virtual void RestoreForm(MainForm form) {
form.Show();
}
/// <summary>
/// Called when the form changes its state, without calling into <see cref="RestoreForm"/> or <see cref="HideForm"/>.
/// Enables inheritors to update the form's state on each state change.
/// </summary>
public virtual void OnFormStateChange(MainForm form) {
}
#region IDisposable Members
bool _isDisposed = false;

View file

@ -11,15 +11,7 @@ namespace OnTopReplica.Platforms {
DwmManager.SetExludeFromPeek(form, true);
DwmManager.SetDisallowPeek(form, true);
//This hides the app from ALT+TAB, but when minimized the window is shrunk on the bottom, right above the task bar (ugly)
/*Native.WindowMethods.SetWindowLong(form.Handle, WindowMethods.WindowLong.ExStyle,
(IntPtr)WindowMethods.WindowExStyles.ToolWindow);*/
//This adds the task bar item, but hiding/showing again adds it back to alt+tab
/*var list = (ITaskbarList)new CoTaskbarList();
list.HrInit();
list.AddTab(form.Handle);
list.ActivateTab(form.Handle); */
SetWindowStyle(form);
}
public override void InitApp() {
@ -28,8 +20,31 @@ namespace OnTopReplica.Platforms {
}
public override void HideForm(MainForm form) {
form.WindowState = FormWindowState.Minimized;
form.Opacity = 0;
}
public override bool IsHidden(MainForm form) {
return (form.Opacity == 0.0);
}
public override void RestoreForm(MainForm form) {
if (form.Opacity == 0.0)
form.Opacity = 1.0;
form.Show();
SetWindowStyle(form);
}
public override void OnFormStateChange(MainForm form) {
SetWindowStyle(form);
}
private void SetWindowStyle(MainForm form) {
//This hides the app from ALT+TAB
//Note that when minimized, it will be shown as an (ugly) minimized tool window
Native.WindowMethods.SetWindowLong(form.Handle, WindowMethods.WindowLong.ExStyle,
(IntPtr)WindowMethods.WindowExStyles.ToolWindow);
}
}
}

View file

@ -25,7 +25,6 @@ namespace OnTopReplica.Platforms {
//Do not show in task bar, but display notify icon
//NOTE: this effectively makes Windows ignore the Flip 3D policy set above (on Windows 7)
// weird...
form.ShowInTaskbar = false;
//Install tray icon

View file

@ -106,5 +106,17 @@ namespace OnTopReplica {
return curr;
}
/// <summary>
/// Gets a handle to the window that currently is in the foreground.
/// </summary>
/// <returns>May return null if call fails or no valid window selected.</returns>
public static WindowHandle GetCurrentForegroundWindow() {
IntPtr handle = WindowManagerMethods.GetForegroundWindow();
if (handle == IntPtr.Zero)
return null;
return new WindowHandle(handle, string.Empty);
}
}
}