Provide support of HotKeys to manage thumbnails and corresponding EVE clients - implemented w/o GUI required to set hotkeys
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace EveOPreview.Configuration
|
namespace EveOPreview.Configuration
|
||||||
@@ -35,6 +36,7 @@ namespace EveOPreview.Configuration
|
|||||||
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
|
this.PerClientLayout = new Dictionary<string, Dictionary<string, Point>>();
|
||||||
this.FlatLayout = new Dictionary<string, Point>();
|
this.FlatLayout = new Dictionary<string, Point>();
|
||||||
this.ClientLayout = new Dictionary<string, ClientLayout>();
|
this.ClientLayout = new Dictionary<string, ClientLayout>();
|
||||||
|
this.ClientHotkey = new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MinimizeToTray { get; set; }
|
public bool MinimizeToTray { get; set; }
|
||||||
@@ -66,6 +68,8 @@ namespace EveOPreview.Configuration
|
|||||||
private Dictionary<string, Point> FlatLayout { get; set; }
|
private Dictionary<string, Point> FlatLayout { get; set; }
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private Dictionary<string, ClientLayout> ClientLayout { get; set; }
|
private Dictionary<string, ClientLayout> ClientLayout { get; set; }
|
||||||
|
[JsonProperty]
|
||||||
|
private Dictionary<string, string> ClientHotkey { get; set; }
|
||||||
|
|
||||||
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation)
|
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation)
|
||||||
{
|
{
|
||||||
@@ -129,5 +133,23 @@ namespace EveOPreview.Configuration
|
|||||||
{
|
{
|
||||||
this.ClientLayout[currentClient] = layout;
|
this.ClientLayout[currentClient] = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Keys GetClientHotkey(string currentClient)
|
||||||
|
{
|
||||||
|
string hotkey;
|
||||||
|
if (this.ClientHotkey.TryGetValue(currentClient, out hotkey))
|
||||||
|
{
|
||||||
|
// Protect from incorrect values
|
||||||
|
object rawValue = (new KeysConverter()).ConvertFromInvariantString(hotkey);
|
||||||
|
return rawValue != null ? (Keys)rawValue : Keys.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Keys.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetClientHotkey(string currentClient, Keys hotkey)
|
||||||
|
{
|
||||||
|
this.ClientHotkey[currentClient] = (new KeysConverter()).ConvertToInvariantString(hotkey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace EveOPreview.Configuration
|
namespace EveOPreview.Configuration
|
||||||
{
|
{
|
||||||
@@ -32,5 +33,8 @@ namespace EveOPreview.Configuration
|
|||||||
|
|
||||||
ClientLayout GetClientLayout(string currentClient);
|
ClientLayout GetClientLayout(string currentClient);
|
||||||
void SetClientLayout(string currentClient, ClientLayout layout);
|
void SetClientLayout(string currentClient, ClientLayout layout);
|
||||||
|
|
||||||
|
Keys GetClientHotkey(string currentClient);
|
||||||
|
void SetClientHotkey(string currentClient, Keys hotkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -119,8 +119,8 @@
|
|||||||
<Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" />
|
<Compile Include="UI\Interface\IThumbnailDescriptionViewFactory.cs" />
|
||||||
<Compile Include="UI\Interface\ViewZoomAnchor.cs" />
|
<Compile Include="UI\Interface\ViewZoomAnchor.cs" />
|
||||||
<Compile Include="Configuration\ApplicationConfiguration.cs" />
|
<Compile Include="Configuration\ApplicationConfiguration.cs" />
|
||||||
<None Include="Hotkeys\Hotkey.cs" />
|
<Compile Include="Hotkeys\HotkeyHandler.cs" />
|
||||||
<None Include="Hotkeys\HotkeyNativeMethods.cs" />
|
<Compile Include="Hotkeys\HotkeyHandlerNativeMethods.cs" />
|
||||||
<Compile Include="UI\Implementation\MainForm.cs">
|
<Compile Include="UI\Implementation\MainForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@@ -1,332 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace EveOPreview
|
|
||||||
{
|
|
||||||
public class Hotkey : IMessageFilter
|
|
||||||
{
|
|
||||||
private static int _currentId;
|
|
||||||
private const int MaxId = 0xBFFF;
|
|
||||||
|
|
||||||
[XmlElement("keyCode")]
|
|
||||||
private Keys _keyCode;
|
|
||||||
[XmlElement("shift")]
|
|
||||||
private bool _shift;
|
|
||||||
[XmlElement("control")]
|
|
||||||
private bool _control;
|
|
||||||
[XmlElement("alt")]
|
|
||||||
private bool _alt;
|
|
||||||
[XmlElement("windows")]
|
|
||||||
private bool _windows;
|
|
||||||
|
|
||||||
[XmlIgnore]
|
|
||||||
private int _id;
|
|
||||||
[XmlIgnore]
|
|
||||||
private bool _isRegistered;
|
|
||||||
[XmlIgnore]
|
|
||||||
private Control _windowControl;
|
|
||||||
|
|
||||||
public event HandledEventHandler Pressed;
|
|
||||||
|
|
||||||
public Hotkey()
|
|
||||||
: this(Keys.None, false, false, false, false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hotkey(Keys keyCode, bool shift, bool control, bool alt, bool windows)
|
|
||||||
{
|
|
||||||
// Assign properties
|
|
||||||
this.KeyCode = keyCode;
|
|
||||||
this.Shift = shift;
|
|
||||||
this.Control = control;
|
|
||||||
this.Alt = alt;
|
|
||||||
this.Windows = windows;
|
|
||||||
|
|
||||||
// Register us as a message filter
|
|
||||||
Application.AddMessageFilter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Hotkey()
|
|
||||||
{
|
|
||||||
// Unregister the hotkey if necessary
|
|
||||||
if (this.IsRegistered)
|
|
||||||
{
|
|
||||||
this.Unregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hotkey Clone()
|
|
||||||
{
|
|
||||||
// Clone the whole object
|
|
||||||
return new Hotkey(this._keyCode, this._shift, this._control, this._alt, this._windows);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool GetCanRegister(Control windowControl)
|
|
||||||
{
|
|
||||||
// Handle any exceptions: they mean "no, you can't register" :)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Attempt to register
|
|
||||||
if (this.Register(windowControl))
|
|
||||||
{
|
|
||||||
// Unregister and say we managed it
|
|
||||||
this.Unregister();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Win32Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
catch (NotSupportedException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Register(Control windowControl)
|
|
||||||
{
|
|
||||||
// Check that we have not registered
|
|
||||||
if (this._isRegistered)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("You cannot register a hotkey that is already registered");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't register an empty hotkey
|
|
||||||
if (this.IsEmpty)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("You cannot register an empty hotkey");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get an ID for the hotkey and increase current ID
|
|
||||||
this._id = Hotkey._currentId;
|
|
||||||
Hotkey._currentId = Hotkey._currentId + 1 % Hotkey.MaxId;
|
|
||||||
|
|
||||||
// Translate modifier keys into unmanaged version
|
|
||||||
uint modifiers = (this.Alt ? HotkeyNativeMethods.MOD_ALT : 0) | (this.Control ? HotkeyNativeMethods.MOD_CONTROL : 0) |
|
|
||||||
(this.Shift ? HotkeyNativeMethods.MOD_SHIFT : 0) | (this.Windows ? HotkeyNativeMethods.MOD_WIN : 0);
|
|
||||||
|
|
||||||
// Register the hotkey
|
|
||||||
if (HotkeyNativeMethods.RegisterHotKey(windowControl.Handle, this._id, modifiers, _keyCode) == 0)
|
|
||||||
{
|
|
||||||
// Is the error that the hotkey is registered?
|
|
||||||
if (Marshal.GetLastWin32Error() != HotkeyNativeMethods.ERROR_HOTKEY_ALREADY_REGISTERED)
|
|
||||||
{
|
|
||||||
throw new Win32Exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the control reference and register state
|
|
||||||
this._isRegistered = true;
|
|
||||||
this._windowControl = windowControl;
|
|
||||||
|
|
||||||
// We successfully registered
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Unregister()
|
|
||||||
{
|
|
||||||
// Check that we have registered
|
|
||||||
if (!this._isRegistered)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("You cannot unregister a hotkey that is not registered");
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's possible that the control itself has died: in that case, no need to unregister!
|
|
||||||
if (!this._windowControl.IsDisposed)
|
|
||||||
{
|
|
||||||
// Clean up after ourselves
|
|
||||||
if (HotkeyNativeMethods.UnregisterHotKey(this._windowControl.Handle, this._id) == 0)
|
|
||||||
{
|
|
||||||
throw new Win32Exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the control reference and register state
|
|
||||||
this._isRegistered = false;
|
|
||||||
this._windowControl = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reregister()
|
|
||||||
{
|
|
||||||
// Only do something if the key is already registered
|
|
||||||
if (!this._isRegistered)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save control reference
|
|
||||||
Control windowControl = this._windowControl;
|
|
||||||
|
|
||||||
// Unregister and then reregister again
|
|
||||||
this.Unregister();
|
|
||||||
this.Register(windowControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool PreFilterMessage(ref Message message)
|
|
||||||
{
|
|
||||||
// Only process WM_HOTKEY messages
|
|
||||||
if (message.Msg != HotkeyNativeMethods.WM_HOTKEY)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the ID is our key and we are registerd
|
|
||||||
return this._isRegistered && (message.WParam.ToInt32() == this._id) && this.OnPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool OnPressed()
|
|
||||||
{
|
|
||||||
// Fire the event if we can
|
|
||||||
HandledEventArgs handledEventArgs = new HandledEventArgs(false);
|
|
||||||
this.Pressed?.Invoke(this, handledEventArgs);
|
|
||||||
|
|
||||||
// Return whether we handled the event or not
|
|
||||||
return handledEventArgs.Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
// We can be empty
|
|
||||||
if (this.IsEmpty)
|
|
||||||
{
|
|
||||||
return "(none)";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build key name
|
|
||||||
string keyName = Enum.GetName(typeof(Keys), this._keyCode) ?? " ";
|
|
||||||
switch (this._keyCode)
|
|
||||||
{
|
|
||||||
case Keys.D0:
|
|
||||||
case Keys.D1:
|
|
||||||
case Keys.D2:
|
|
||||||
case Keys.D3:
|
|
||||||
case Keys.D4:
|
|
||||||
case Keys.D5:
|
|
||||||
case Keys.D6:
|
|
||||||
case Keys.D7:
|
|
||||||
case Keys.D8:
|
|
||||||
case Keys.D9:
|
|
||||||
// Strip the first character
|
|
||||||
keyName = keyName.Substring(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build modifiers
|
|
||||||
string modifiers = "";
|
|
||||||
if (this._shift)
|
|
||||||
{
|
|
||||||
modifiers += "Shift+";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._control)
|
|
||||||
{
|
|
||||||
modifiers += "Control+";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._alt)
|
|
||||||
{
|
|
||||||
modifiers += "Alt+";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._windows)
|
|
||||||
{
|
|
||||||
modifiers += "Windows+";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return result
|
|
||||||
return modifiers + keyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsEmpty
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._keyCode == Keys.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsRegistered
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._isRegistered;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Keys KeyCode
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._keyCode;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
// Save and reregister
|
|
||||||
this._keyCode = value;
|
|
||||||
this.Reregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Shift
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._shift;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
// Save and reregister
|
|
||||||
this._shift = value;
|
|
||||||
this.Reregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Control
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._control;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
// Save and reregister
|
|
||||||
this._control = value;
|
|
||||||
this.Reregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Alt
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._alt;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
// Save and reregister
|
|
||||||
this._alt = value;
|
|
||||||
this.Reregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Windows
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._windows;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
// Save and reregister
|
|
||||||
this._windows = value;
|
|
||||||
this.Reregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
159
Eve-O-Preview/Hotkeys/HotkeyHandler.cs
Normal file
159
Eve-O-Preview/Hotkeys/HotkeyHandler.cs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
class HotkeyHandler : IMessageFilter, IDisposable
|
||||||
|
{
|
||||||
|
private static int _currentId;
|
||||||
|
private const int MaxId = 0xBFFF;
|
||||||
|
|
||||||
|
#region Private fields
|
||||||
|
private readonly int _hotkeyId;
|
||||||
|
private readonly IntPtr _hotkeyTarget;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public HotkeyHandler(IntPtr target, Keys hotkey)
|
||||||
|
{
|
||||||
|
this._hotkeyId = HotkeyHandler._currentId;
|
||||||
|
HotkeyHandler._currentId = (HotkeyHandler._currentId + 1) & HotkeyHandler.MaxId;
|
||||||
|
|
||||||
|
this._hotkeyTarget = target;
|
||||||
|
|
||||||
|
// Assign properties
|
||||||
|
this.IsRegistered = false;
|
||||||
|
|
||||||
|
this.KeyCode = hotkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (this.IsRegistered)
|
||||||
|
{
|
||||||
|
this.Unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~HotkeyHandler()
|
||||||
|
{
|
||||||
|
// Unregister the hotkey if necessary
|
||||||
|
if (this.IsRegistered)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.Unregister();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Please no exceptions in the finalizer thread
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsRegistered { get; private set; }
|
||||||
|
|
||||||
|
public Keys KeyCode { get; private set; }
|
||||||
|
|
||||||
|
public event HandledEventHandler Pressed;
|
||||||
|
|
||||||
|
public bool CanRegister()
|
||||||
|
{
|
||||||
|
// Any exception means "no, you can't register"
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Attempt to register
|
||||||
|
if (this.Register())
|
||||||
|
{
|
||||||
|
// Unregister and say we managed it
|
||||||
|
this.Unregister();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Win32Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (NotSupportedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Register()
|
||||||
|
{
|
||||||
|
// Check that we have not registered
|
||||||
|
if (this.IsRegistered)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("This hotkey is already registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.KeyCode == Keys.None)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Cannot register an empty hotkey");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all modifiers from the 'main' hotkey
|
||||||
|
uint key = (uint)this.KeyCode & (~(uint)Keys.Alt) & (~(uint)Keys.Control) & (~(uint)Keys.Shift);
|
||||||
|
|
||||||
|
// Get unmanaged version of the modifiers code
|
||||||
|
uint modifiers = (this.KeyCode.HasFlag(Keys.Alt) ? HotkeyHandlerNativeMethods.MOD_ALT : 0)
|
||||||
|
| (this.KeyCode.HasFlag(Keys.Control) ? HotkeyHandlerNativeMethods.MOD_CONTROL : 0)
|
||||||
|
| (this.KeyCode.HasFlag(Keys.Shift) ? HotkeyHandlerNativeMethods.MOD_SHIFT : 0);
|
||||||
|
|
||||||
|
// Register the hotkey
|
||||||
|
if (!HotkeyHandlerNativeMethods.RegisterHotKey(this._hotkeyTarget, this._hotkeyId, modifiers, key))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Application.AddMessageFilter(this);
|
||||||
|
|
||||||
|
this.IsRegistered = true;
|
||||||
|
|
||||||
|
// We successfully registered
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unregister()
|
||||||
|
{
|
||||||
|
// Check that we have registered
|
||||||
|
if (!this.IsRegistered)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("This hotkey was not registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
Application.RemoveMessageFilter(this);
|
||||||
|
|
||||||
|
// Clean up after ourselves
|
||||||
|
if (!HotkeyHandlerNativeMethods.UnregisterHotKey(this._hotkeyTarget, this._hotkeyId))
|
||||||
|
{
|
||||||
|
throw new Win32Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.IsRegistered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IMessageFilter
|
||||||
|
public bool PreFilterMessage(ref Message message)
|
||||||
|
{
|
||||||
|
return this.IsRegistered
|
||||||
|
&& (message.Msg == HotkeyHandlerNativeMethods.WM_HOTKEY)
|
||||||
|
&& (message.WParam.ToInt32() == this._hotkeyId)
|
||||||
|
&& this.OnPressed();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private bool OnPressed()
|
||||||
|
{
|
||||||
|
// Fire the event if we can
|
||||||
|
HandledEventArgs handledEventArgs = new HandledEventArgs(false);
|
||||||
|
this.Pressed?.Invoke(this, handledEventArgs);
|
||||||
|
|
||||||
|
// Return whether we handled the event or not
|
||||||
|
return handledEventArgs.Handled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
Eve-O-Preview/Hotkeys/HotkeyHandlerNativeMethods.cs
Normal file
23
Eve-O-Preview/Hotkeys/HotkeyHandlerNativeMethods.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace EveOPreview.UI
|
||||||
|
{
|
||||||
|
static class HotkeyHandlerNativeMethods
|
||||||
|
{
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||||
|
|
||||||
|
public const uint WM_HOTKEY = 0x0312;
|
||||||
|
|
||||||
|
public const uint MOD_ALT = 0x1;
|
||||||
|
public const uint MOD_CONTROL = 0x2;
|
||||||
|
public const uint MOD_SHIFT = 0x4;
|
||||||
|
public const uint MOD_WIN = 0x8;
|
||||||
|
|
||||||
|
public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace EveOPreview
|
|
||||||
{
|
|
||||||
static class HotkeyNativeMethods
|
|
||||||
{
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
public static extern int RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
|
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
public static extern int UnregisterHotKey(IntPtr hWnd, int id);
|
|
||||||
|
|
||||||
public const uint WM_HOTKEY = 0x312;
|
|
||||||
|
|
||||||
public const uint MOD_ALT = 0x1;
|
|
||||||
public const uint MOD_CONTROL = 0x2;
|
|
||||||
public const uint MOD_SHIFT = 0x4;
|
|
||||||
public const uint MOD_WIN = 0x8;
|
|
||||||
|
|
||||||
public const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -215,6 +215,8 @@ namespace EveOPreview.UI
|
|||||||
view.ThumbnailLostFocus = this.ThumbnailViewLostFocus;
|
view.ThumbnailLostFocus = this.ThumbnailViewLostFocus;
|
||||||
view.ThumbnailActivated = this.ThumbnailActivated;
|
view.ThumbnailActivated = this.ThumbnailActivated;
|
||||||
|
|
||||||
|
view.RegisterHotkey(this._configuration.GetClientHotkey(processTitle));
|
||||||
|
|
||||||
this._thumbnailViews.Add(processHandle, view);
|
this._thumbnailViews.Add(processHandle, view);
|
||||||
|
|
||||||
this.ApplyClientLayout(processHandle, processTitle);
|
this.ApplyClientLayout(processHandle, processTitle);
|
||||||
@@ -224,13 +226,7 @@ namespace EveOPreview.UI
|
|||||||
else if ((view != null) && (processTitle != view.Title)) // update thumbnail title
|
else if ((view != null) && (processTitle != view.Title)) // update thumbnail title
|
||||||
{
|
{
|
||||||
view.Title = processTitle;
|
view.Title = processTitle;
|
||||||
|
view.RegisterHotkey(this._configuration.GetClientHotkey(processTitle));
|
||||||
// TODO Shortcuts should be handled at manager level
|
|
||||||
//string value;
|
|
||||||
//if (_flatLayoutShortcuts.TryGetValue(processTitle, out value))
|
|
||||||
//{
|
|
||||||
// view.RegisterShortcut(value);
|
|
||||||
//}
|
|
||||||
|
|
||||||
this.ApplyClientLayout(processHandle, processTitle);
|
this.ApplyClientLayout(processHandle, processTitle);
|
||||||
|
|
||||||
@@ -261,7 +257,8 @@ namespace EveOPreview.UI
|
|||||||
|
|
||||||
this._thumbnailViews.Remove(processHandle);
|
this._thumbnailViews.Remove(processHandle);
|
||||||
|
|
||||||
// TODO Remove hotkey here
|
view.UnregisterHotkey();
|
||||||
|
|
||||||
view.ThumbnailResized = null;
|
view.ThumbnailResized = null;
|
||||||
view.ThumbnailMoved = null;
|
view.ThumbnailMoved = null;
|
||||||
view.ThumbnailFocused = null;
|
view.ThumbnailFocused = null;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@ namespace EveOPreview.UI
|
|||||||
private IntPtr _thumbnailHandle;
|
private IntPtr _thumbnailHandle;
|
||||||
private Size _baseSize;
|
private Size _baseSize;
|
||||||
private Point _baseLocation;
|
private Point _baseLocation;
|
||||||
|
private HotkeyHandler _hotkeyHandler;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public ThumbnailView()
|
public ThumbnailView()
|
||||||
@@ -207,6 +209,47 @@ namespace EveOPreview.UI
|
|||||||
this.Location = this._baseLocation;
|
this.Location = this._baseLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterHotkey(Keys hotkey)
|
||||||
|
{
|
||||||
|
if (this._hotkeyHandler != null)
|
||||||
|
{
|
||||||
|
this.UnregisterHotkey();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hotkey == Keys.None)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._hotkeyHandler = new HotkeyHandler(this.Handle, hotkey);
|
||||||
|
this._hotkeyHandler.Pressed += HotkeyPressed_Handler;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this._hotkeyHandler.Register();
|
||||||
|
System.Diagnostics.Debug.WriteLine("Registered shortcut for " + this.Title);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("Failed to register shortcut for " + this.Title);
|
||||||
|
// There can be a lot of possible exception reasons here
|
||||||
|
// In case of any of them the hotkey setting is silently ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnregisterHotkey()
|
||||||
|
{
|
||||||
|
if (this._hotkeyHandler == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._hotkeyHandler.Unregister();
|
||||||
|
this._hotkeyHandler.Pressed -= HotkeyPressed_Handler;
|
||||||
|
this._hotkeyHandler.Dispose();
|
||||||
|
this._hotkeyHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void Refresh(bool forceRefresh)
|
public void Refresh(bool forceRefresh)
|
||||||
{
|
{
|
||||||
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created
|
// To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created
|
||||||
@@ -327,6 +370,13 @@ namespace EveOPreview.UI
|
|||||||
//this.Refresh();
|
//this.Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HotkeyPressed_Handler(object sender, HandledEventArgs e)
|
||||||
|
{
|
||||||
|
this.ThumbnailActivated?.Invoke(this.Id);
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void RegisterThumbnail()
|
private void RegisterThumbnail()
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace EveOPreview.UI
|
namespace EveOPreview.UI
|
||||||
{
|
{
|
||||||
@@ -24,6 +25,9 @@ namespace EveOPreview.UI
|
|||||||
void ZoomIn(ViewZoomAnchor anchor, int zoomFactor);
|
void ZoomIn(ViewZoomAnchor anchor, int zoomFactor);
|
||||||
void ZoomOut();
|
void ZoomOut();
|
||||||
|
|
||||||
|
void RegisterHotkey(Keys hotkey);
|
||||||
|
void UnregisterHotkey();
|
||||||
|
|
||||||
void Refresh(bool forceRefresh);
|
void Refresh(bool forceRefresh);
|
||||||
|
|
||||||
Action<IntPtr> ThumbnailResized { get; set; }
|
Action<IntPtr> ThumbnailResized { get; set; }
|
||||||
|
Reference in New Issue
Block a user