В хуке, который я нашел на просторах сети, вроде-бы все понятно и просто, но до меня не доходит как его вызывать, и не понимаю как объявить вместо клавиши с "d" с параметром Keys (В основной форме - NewForm), только одну, ту которую нажимаешь в 2 форме и которая хранится в Storage.cs.
P.S. [HookKeyBoard] - Все связанное с хуком.
UPD: Загрузил все на яндекс.диск, с гитом пока-что не в ладах, поэтому и выбрал яд. Очень надеюсь что поможете..
https://yadi.sk/d/RNTbfC9kfCXiZw
Сам хукusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SplashSpamKey
{
class GlobalKeyHook
{
/// <summary>
/// Specifies key modifiers.
/// </summary>
[Flags]
public enum KeyModifiers : uint
{
/// <summary>
/// Empty modifiers
/// </summary>
None = 0x0000,
/// <summary>
/// Either ALT key must be held down.
/// </summary>
Alt = 0x0001,
/// <summary>
/// Either CTRL key must be held down.
/// </summary>
Control = 0x0002,
/// <summary>
/// Either SHIFT key must be held down.
/// </summary>
Shift = 0x0004,
/// <summary>
/// Either WINDOWS key was held down.
/// These keys are labeled with the Windows logo.
/// Keyboard shortcuts that involve the WINDOWS key are reserved for use by the operating system.
/// </summary>
Windows = 0x0008,
//IgnoreAllModifier = 0x0400,
//OnKeyUp = 0x0800,
//MouseRight = 0x4000,
//MouseLeft = 0x8000,
}
//Сам хук [HookKeyBoard]
public class HotKey : IMessageFilter, IDisposable
{
#region Extern
const int WM_HOTKEY = 0x312;
const int ERROR_HOTKEY_ALREADY_REGISTERED = 0x581;
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool RegisterHotKey(IntPtr hWnd, IntPtr id, KeyModifiers fsModifiers, Keys vk);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool UnregisterHotKey(IntPtr hWnd, IntPtr id);
#endregion
private IntPtr windowHandle;
public event HandledEventHandler Pressed;
public HotKey()
: this(Keys.None, KeyModifiers.None)
{
}
public HotKey(Keys keyCode, KeyModifiers modifiers)
{
this.KeyCode = keyCode;
this.Modifiers = modifiers;
Application.AddMessageFilter(this);
}
~HotKey()
{
this.Dispose();
}
public void Dispose()
{
if (this.IsRegistered)
this.Unregister();
this.windowHandle = IntPtr.Zero;
this.Modifiers = KeyModifiers.None;
this.KeyCode = Keys.None;
this.Tag = 0;
}
private bool OnPressed()
{
HandledEventArgs e = new HandledEventArgs(false);
if (this.Pressed != null)
this.Pressed(this, e);
return e.Handled;
}
/// <summary>
/// Filters out a message before it is dispatched.
/// </summary>
/// <param name="message">
/// The message to be dispatched. You cannot modify this message.
/// </param>
/// <returns>
/// true to filter the message and stop it from being dispatched;
/// false to allow the message to continue to the next filter or control.
/// </returns>
public bool PreFilterMessage(ref Message message)
{
if (message.Msg != WM_HOTKEY || !this.IsRegistered)
return false;
if (message.WParam == this.Guid)
return this.OnPressed();
return false;
}
/// <summary>
/// Defines a system-wide hot key.
/// </summary>
/// <param name="windowControl">
/// A handle to the window that will receive messages generated by the hot key.
/// </param>
public void Register(Control window)
{
if (this.IsRegistered)
throw new NotSupportedException("Ты не можешь зарегистровать уже занятый хоткей");
if (this.IsEmpty)
throw new NotSupportedException("Ты не можешь зарегистрировать пустой хоткей");
if (window.IsDisposed)
throw new ArgumentNullException("window");
this.windowHandle = window.Handle;
if (!RegisterHotKey(this.windowHandle, this.Guid, this.Modifiers, this.KeyCode))
{
if (Marshal.GetLastWin32Error() != ERROR_HOTKEY_ALREADY_REGISTERED)
throw new Win32Exception();
}
this.IsRegistered = true;
}
/// <summary>
/// Frees a hot key previously registered by the calling thread.
/// </summary>
public void Unregister()
{
if (!this.IsRegistered)
return;
if (!UnregisterHotKey(this.windowHandle, this.Guid))
throw new Win32Exception();
this.IsRegistered = false;
}
public bool HasModifier(KeyModifiers modifiers)
{
return (this.Modifiers & modifiers) != 0;
}
public static HotKey Parse(object content)
{
if (content == null)
return new HotKey();
return Parse(content.ToString());
}
#region Fields
private IntPtr Guid
{
get { return new IntPtr((int)Modifiers << 16 | (int)KeyCode & 0xFFFF); }
}
public bool IsEmpty
{
get { return (this.KeyCode == Keys.None); }
}
public bool IsRegistered { get; private set; }
public KeyModifiers Modifiers { get; private set; }
public Keys KeyCode { get; private set; }
public int Tag { get; set; }
#endregion
}
}
}
Основная форма в которой и должен происходить хук и эмуляция нажатия клавишиprivate void NewForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == Storage.KeyData)
{
if (Storage.IsEnabled == false)
{
Storage.IsEnabled = true;
Storage.RandValue = true;
StatusOnOff.BackColor = Color.Green;
timer1.Start();
//Пример использования хука [HookKeyBoard] Если не понятно что это вообще за проект и что он должен делать, закоментите пример ниже и запустите проект
var hkey = new HotKey(Keys.D, KeyModifiers.None); //Вместо "D" Нужна кнопка которую задает пользователь (Хранится в storage.cs)
hkey.Pressed += (o, e) => { timer1.Start(); e.Handled = true; };
hkey.Register(this);
}
}
}
private void NewForm_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == Storage.KeyData)
{
if (Storage.IsEnabled == true)
{
Storage.IsEnabled = false;
Storage.RandValue = false;
StatusOnOff.BackColor = Color.Red;
timer1.Stop();
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Random rand = new Random();
while (Storage.RandValue == true)
{
int kk = rand.Next(100, 250);
timer1.Interval = kk;
SendKeys.SendWait("{" + Storage.KeyStr + "}");
}
}
Форма в которой пользователь вводит клавишу, (которая при зажатии будет эмулировать своё-же нажатие по таймеру) - в 1 формеprivate void ChooseKeyForm_KeyDown(object sender, KeyEventArgs e)
{
Storage.KeyStr = e.KeyCode.ToString();
Storage.KeyData = e.KeyValue;
this.Dispose();
}
Класс в котором хранятся переменные, для того чтобы передавать их между формамиinternal class Storage {
public static string KeyStr { get; set; }
public static int KeyData { get; set; }
public static bool IsEnabled { get; set; }
public static bool RandValue { get; set; }
}
Уточняю что мне нужно сделать. В хуке идет отлов нажатий всех клавиш с модификаторами и в последствии их регистрация. Мне-же нужно сделать отлов только одной клавиши (пользователь сам её выбирает) с модификаторами (ALT,WIN,SHIFT,CTRL) - эти модификаторы уже написаны, поэтому их трогать не нужно. Но я столкнулся с проблемой регистрации этой клавиши, так как в хуке регистрация на прямую через Keys, а мне нужно сделать эту регистрацию через ту клавишу, которая хранится в классе Storage (которую задает пользователь)