Added global HotKey to hide/show OnTopReplica (Ctrl+Shift+O).

This commit is contained in:
Lorenz Cuno Klopfenstein 2010-05-31 15:53:30 +02:00
parent d389573363
commit 04a1b6cfd0
5 changed files with 165 additions and 46 deletions

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace OnTopReplica {
/// <summary>
/// HotKey registration helper.
/// </summary>
public class HotKeyManager : IDisposable {
public HotKeyManager(Form form) {
Owner = form;
}
public Form Owner { get; private set; }
[Flags]
public enum HotKeyModifiers : int {
Alt = 0x1,
Control = 0x2,
Shift = 0x4,
Windows = 0x8
}
const int WM_HOTKEY = 0x312;
[DllImport("user32.dll")]
static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
[DllImport("user32.dll")]
static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private delegate void FormDelegate(HotKeyModifiers mod, Keys key, HotKeyHandler handler);
public void RegisterHotKey(HotKeyModifiers mod, Keys key, HotKeyHandler handler) {
Owner.Invoke(new FormDelegate(RegisterHotKeyCore), mod, key, handler);
}
private void RegisterHotKeyCore(HotKeyModifiers mod, Keys keys, HotKeyHandler handler) {
var newKey = ++_lastUsedKey;
if (!RegisterHotKey(Owner.Handle, newKey, (int)mod, (int)keys)) {
Console.Error.WriteLine("Failed to register {0} hot key.", newKey);
return;
}
_handlers[newKey] = handler;
}
public void ProcessHotKeys(Message msg) {
if (msg.Msg == WM_HOTKEY) {
int keyId = msg.WParam.ToInt32();
if (!_handlers.ContainsKey(keyId))
return;
_handlers[keyId].Invoke();
}
}
private delegate void VoidFormDelegate();
private void UnregisterHotKeysCore() {
foreach (var key in _handlers.Keys) {
if (!UnregisterHotKey(Owner.Handle, key))
Console.Error.WriteLine("Failed to unregister {0} hot key.", key);
}
}
#region IDisposable Members
public void Dispose() {
if (Owner != null && Owner.IsHandleCreated) {
Owner.Invoke(new VoidFormDelegate(UnregisterHotKeysCore));
}
}
#endregion
public delegate void HotKeyHandler();
private int _lastUsedKey = 0;
Dictionary<int, HotKeyHandler> _handlers = new Dictionary<int, HotKeyHandler>();
}
}

View file

@ -448,7 +448,7 @@
this.openToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
this.openToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuOpen;
this.openToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuOpenTT;
this.openToolStripMenuItem.Click += new System.EventHandler(this.IconContextOpen_click);
this.openToolStripMenuItem.Click += new System.EventHandler(this.TaskIconOpen_click);
//
// resetWindowToolStripMenuItem
//
@ -456,7 +456,7 @@
this.resetWindowToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
this.resetWindowToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuReset;
this.resetWindowToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuResetTT;
this.resetWindowToolStripMenuItem.Click += new System.EventHandler(this.IconContextReset_click);
this.resetWindowToolStripMenuItem.Click += new System.EventHandler(this.TaskIconReset_click);
//
// exitToolStripMenuItem
//
@ -465,7 +465,7 @@
this.exitToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
this.exitToolStripMenuItem.Text = global::OnTopReplica.Strings.MenuClose;
this.exitToolStripMenuItem.ToolTipText = global::OnTopReplica.Strings.MenuCloseTT;
this.exitToolStripMenuItem.Click += new System.EventHandler(this.IconContextExit_click);
this.exitToolStripMenuItem.Click += new System.EventHandler(this.TaskIconExit_click);
//
// MainForm
//

View file

@ -17,6 +17,7 @@ namespace OnTopReplica
ThumbnailPanel _thumbnailPanel = null;
RegionBox _regionBox = null;
FullscreenForm _fullscreenForm;
HotKeyManager _hotKeyManager;
//Icon
NotifyIcon taskIcon = null;
@ -40,6 +41,7 @@ namespace OnTopReplica
public MainForm() {
InitializeComponent();
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
KeepAspectRatio = false;
//Thumbnail panel
@ -75,6 +77,11 @@ namespace OnTopReplica
//Hook keyboard handler
this.KeyUp += new KeyEventHandler(Common_Key);
this.KeyPreview = true;
//Add hotkeys
_hotKeyManager = new HotKeyManager(this);
_hotKeyManager.RegisterHotKey(HotKeyManager.HotKeyModifiers.Control | HotKeyManager.HotKeyModifiers.Shift,
Keys.O, new HotKeyManager.HotKeyHandler(HotKeyOpenHandler));
}
#region Child forms & controls events
@ -181,33 +188,36 @@ namespace OnTopReplica
#region Event override
protected override void OnClosing(CancelEventArgs e) {
//Destroy NotifyIcon
if (taskIcon != null) {
taskIcon.Visible = false;
taskIcon.Dispose();
taskIcon = null;
}
//Store settings
if (Settings.Default.StoreWindowPosition) {
Settings.Default.WindowPositionStored = true;
Settings.Default.LastLocation = Location;
Settings.Default.LastSize = ClientSize;
}
else
Settings.Default.WindowPositionStored = false;
base.OnClosing(e);
protected override void OnNotifyMessage(Message m) {
if (_hotKeyManager != null)
_hotKeyManager.ProcessHotKeys(m);
}
protected override void OnResizeBegin(EventArgs e) {
base.OnResizeBegin(e);
protected override void OnClosing(CancelEventArgs e) {
//Destroy NotifyIcon
if (taskIcon != null) {
taskIcon.Visible = false;
taskIcon.Dispose();
taskIcon = null;
}
//Update aspect ratio if needed
/*if (_thumbnailPanel.IsShowingThumbnail) {
SetAspectRatio(_thumbnailPanel.ThumbnailOriginalSize);
}*/
//Destroy hotkeys
{
var manager = _hotKeyManager;
_hotKeyManager = null;
manager.Dispose();
}
//Store settings
if (Settings.Default.StoreWindowPosition) {
Settings.Default.WindowPositionStored = true;
Settings.Default.LastLocation = Location;
Settings.Default.LastSize = ClientSize;
}
else
Settings.Default.WindowPositionStored = false;
base.OnClosing(e);
}
protected override void OnResize(EventArgs e) {
@ -250,7 +260,7 @@ namespace OnTopReplica
taskIcon.Icon = Properties.Resources.main_icon;
taskIcon.Visible = true;
taskIcon.ContextMenuStrip = menuIconContext;
taskIcon.DoubleClick += new EventHandler(Icon_doubleclick);
taskIcon.DoubleClick += new EventHandler(TaskIcon_doubleclick);
//Reload position settings
if (_startOverride) {
@ -271,22 +281,15 @@ namespace OnTopReplica
#region Task Icon events
void Icon_doubleclick(object sender, EventArgs e) {
if (_isFullscreen)
ToggleFullscreen();
//Ensure main form is shown
this.Show();
this.Activate();
this.TopMost = true;
void TaskIcon_doubleclick(object sender, EventArgs e) {
EnsureMainFormVisible();
}
private void IconContextOpen_click(object sender, EventArgs e) {
Icon_doubleclick(sender, e);
private void TaskIconOpen_click(object sender, EventArgs e) {
EnsureMainFormVisible();
}
private void IconContextReset_click(object sender, EventArgs e) {
private void TaskIconReset_click(object sender, EventArgs e) {
var dlg = new TaskDialog(Strings.AskReset, Strings.AskResetTitle, Strings.AskResetContent);
dlg.UseCommandLinks = true;
dlg.CustomButtons = new CustomButton[] {
@ -297,7 +300,7 @@ namespace OnTopReplica
if (dlg.Show().CommonButton == Result.OK) {
//Reset display status
Icon_doubleclick(sender, e);
TaskIcon_doubleclick(sender, e);
//Reset form settings
ThumbnailUnset();
@ -314,7 +317,7 @@ namespace OnTopReplica
}
}
private void IconContextExit_click(object sender, EventArgs e) {
private void TaskIconExit_click(object sender, EventArgs e) {
this.Close();
}
@ -630,6 +633,18 @@ namespace OnTopReplica
}
}
void HotKeyOpenHandler() {
if (_isFullscreen)
ToggleFullscreen();
if (this.Visible) {
this.Hide();
}
else {
EnsureMainFormVisible();
}
}
#endregion
#region Fullscreen
@ -783,6 +798,19 @@ namespace OnTopReplica
dlg.Show(this.Handle);
}
/// <summary>
/// Ensures that the main form is visible (either closing the fullscreen mode or reactivating from task icon).
/// </summary>
private void EnsureMainFormVisible() {
if (_isFullscreen)
ToggleFullscreen();
//Ensure main form is shown
this.Show();
this.Activate();
this.TopMost = true;
}
#endregion
}

View file

@ -49,8 +49,8 @@
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.htm</WebPage>
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
<ApplicationRevision>2</ApplicationRevision>
<ApplicationVersion>2.9.3.%2a</ApplicationVersion>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>2.9.4.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
@ -107,6 +107,7 @@
<Compile Include="CloseRequestEventArgs.cs" />
<Compile Include="EnumerationExtensions.cs" />
<Compile Include="FullscreenMode.cs" />
<Compile Include="HotKeyManager.cs" />
<Compile Include="Strings.it.Designer.cs">
<DependentUpon>Strings.it.resx</DependentUpon>
<AutoGen>True</AutoGen>

View file

@ -32,5 +32,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("2.9.3.0")]
[assembly: AssemblyFileVersion("2.9.3.0")]
[assembly: AssemblyVersion("2.9.4.0")]
[assembly: AssemblyFileVersion("2.9.4.0")]