ShareX/ShareX.HelpersLib/Input/HotkeyForm.cs
2024-01-03 02:57:14 +03:00

143 lines
4.6 KiB
C#

#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright (c) 2007-2024 ShareX Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using System.Diagnostics;
using System.Windows.Forms;
namespace ShareX.HelpersLib
{
public class HotkeyForm : Form
{
public delegate void HotkeyEventHandler(ushort id, Keys key, Modifiers modifier);
public event HotkeyEventHandler HotkeyPress;
public int HotkeyRepeatLimit { get; set; }
private Stopwatch repeatLimitTimer;
public HotkeyForm()
{
HotkeyRepeatLimit = 1000;
repeatLimitTimer = Stopwatch.StartNew();
}
public void RegisterHotkey(HotkeyInfo hotkeyInfo)
{
if (hotkeyInfo != null && hotkeyInfo.Status != HotkeyStatus.Registered)
{
if (!hotkeyInfo.IsValidHotkey)
{
hotkeyInfo.Status = HotkeyStatus.NotConfigured;
return;
}
if (hotkeyInfo.ID == 0)
{
string uniqueID = Helpers.GetUniqueID();
hotkeyInfo.ID = NativeMethods.GlobalAddAtom(uniqueID);
if (hotkeyInfo.ID == 0)
{
DebugHelper.WriteLine("Unable to generate unique hotkey ID: " + hotkeyInfo);
hotkeyInfo.Status = HotkeyStatus.Failed;
return;
}
}
if (!NativeMethods.RegisterHotKey(Handle, hotkeyInfo.ID, (uint)hotkeyInfo.ModifiersEnum, (uint)hotkeyInfo.KeyCode))
{
NativeMethods.GlobalDeleteAtom(hotkeyInfo.ID);
DebugHelper.WriteLine("Unable to register hotkey: " + hotkeyInfo);
hotkeyInfo.ID = 0;
hotkeyInfo.Status = HotkeyStatus.Failed;
return;
}
hotkeyInfo.Status = HotkeyStatus.Registered;
}
}
public bool UnregisterHotkey(HotkeyInfo hotkeyInfo)
{
if (hotkeyInfo != null)
{
if (hotkeyInfo.ID > 0)
{
bool result = NativeMethods.UnregisterHotKey(Handle, hotkeyInfo.ID);
if (result)
{
NativeMethods.GlobalDeleteAtom(hotkeyInfo.ID);
hotkeyInfo.ID = 0;
hotkeyInfo.Status = HotkeyStatus.NotConfigured;
return true;
}
}
hotkeyInfo.Status = HotkeyStatus.Failed;
}
return false;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WindowsMessages.HOTKEY && CheckRepeatLimitTime())
{
ushort id = (ushort)m.WParam;
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
Modifiers modifier = (Modifiers)((int)m.LParam & 0xFFFF);
OnKeyPressed(id, key, modifier);
return;
}
base.WndProc(ref m);
}
protected void OnKeyPressed(ushort id, Keys key, Modifiers modifier)
{
HotkeyPress?.Invoke(id, key, modifier);
}
private bool CheckRepeatLimitTime()
{
if (HotkeyRepeatLimit > 0)
{
if (repeatLimitTimer.ElapsedMilliseconds >= HotkeyRepeatLimit)
{
repeatLimitTimer.Reset();
repeatLimitTimer.Start();
}
else
{
return false;
}
}
return true;
}
}
}