Я пытаюсь обнаружить кнопку Print Screen
, пока форма не является текущим активным приложением.
Как это сделать, если возможно?
Я пытаюсь обнаружить кнопку Print Screen
, пока форма не является текущим активным приложением.
Как это сделать, если возможно?
Да, вы можете, он называется "Системные перехватчики", посмотрите Глобальные системные клики в .NET.
Хорошо, если у вас были проблемы с системными перехватами, вот готовое решение (на основе http://www.dreamincode.net/forums/topic/180436-global-hotkeys/):
Определите статический класс в вашем проекте:
public static class Constants
{
//windows message id for hotkey
public const int WM_HOTKEY_MSG_ID = 0x0312;
}
Определите класс в своем проекте:
public class KeyHandler
{
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private int key;
private IntPtr hWnd;
private int id;
public KeyHandler(Keys key, Form form)
{
this.key = (int)key;
this.hWnd = form.Handle;
id = this.GetHashCode();
}
public override int GetHashCode()
{
return key ^ hWnd.ToInt32();
}
public bool Register()
{
return RegisterHotKey(hWnd, id, 0, key);
}
public bool Unregiser()
{
return UnregisterHotKey(hWnd, id);
}
}
добавить сообщения:
using System.Windows.Forms;
using System.Runtime.InteropServices;
теперь в вашей форме добавьте поле:
private KeyHandler ghk;
и в конструкторе форм:
ghk = new KeyHandler(Keys.PrintScreen, this);
ghk.Register();
Добавьте эти 2 метода в вашу форму:
private void HandleHotkey()
{
// Do stuff...
}
protected override void WndProc(ref Message m)
{
if (m.Msg == Constants.WM_HOTKEY_MSG_ID)
HandleHotkey();
base.WndProc(ref m);
}
HandleHotkey - ваш обработчик нажатия кнопки. Вы можете изменить кнопку, передав здесь другой параметр: ghk = new KeyHandler(Keys.PrintScreen, this);
Теперь ваша программа реагирует на вход бутона, даже если не сфокусирована.
API GetAsyncKeyState()
может быть вполне приемлемой альтернативой настройке Windows Hook.
Это зависит от того, как вы хотите получить вход. Если вы предпочитаете уведомления, связанные с событиями, то крючок - это путь; однако, если вы предпочитаете опросить клавиатуру для изменений состояния, вы можете использовать API выше.
Вот простая демонстрация использования GetAsyncKeyState
:
Получено из Pinvoke.NET
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(int vKey);
private static readonly int VK_SNAPSHOT = 0x2C; //This is the print-screen key.
//Assume the timer is setup with Interval = 16 (corresponds to ~60FPS).
private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
private void timer1_Tick(object sender, EventArgs e)
{
short keyState = GetAsyncKeyState(VK_SNAPSHOT);
//Check if the MSB is set. If so, then the key is pressed.
bool prntScrnIsPressed = ((keyState >> 15) & 0x0001) == 0x0001;
//Check if the LSB is set. If so, then the key was pressed since
//the last call to GetAsyncKeyState
bool unprocessedPress = ((keyState >> 0) & 0x0001) == 0x0001;
if (prntScrnIspressed)
{
//TODO Execute client code...
}
if (unprocessedPress)
{
//TODO Execute client code...
}
}