2012-06-05 2 views
0

Я нашел способ захватить кнопку Print Screen на C#. При нажатии Alt + Print Screen появляется всплывающее сообщение с сообщением, что клавиши были нажаты. Но он не отвечает в течение нескольких секунд. Я понятия не имею, почему это происходит.Программа не отвечает на вас пару секунд

Вот код я использую:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     _hookID = SetHook(_proc); 
     Application.Run(new Form1()); 
     UnhookWindowsHookEx(_hookID); 
    } 

    /****************************************/ 
    private const int WH_KEYBOARD_LL = 13; 
    //private const int WH_KEYBOARD_LL = 13; 
    private const int WM_KEYDOWN = 0x0100; 
    private const int VK_F1 = 0x70; 
    private static LowLevelKeyboardProc _proc = HookCallback; 
    private static IntPtr _hookID = IntPtr.Zero; 

    private static IntPtr SetHook(LowLevelKeyboardProc proc) 
    { 
     using (Process curProcess = Process.GetCurrentProcess()) 
     using (ProcessModule curModule = curProcess.MainModule) 
     { 
      return SetWindowsHookEx(WH_KEYBOARD_LL, proc, 
       GetModuleHandle(curModule.ModuleName), 0); 
     } 
    } 

    private delegate IntPtr LowLevelKeyboardProc(
     int nCode, IntPtr wParam, IntPtr lParam); 

    private static IntPtr HookCallback(
     int nCode, IntPtr wParam, IntPtr lParam) 
    { 

     if (nCode >= 0) 
     { 
      Keys number = (Keys)Marshal.ReadInt32(lParam); 
      if (number == Keys.PrintScreen) 
      { 
       if ((wParam == (IntPtr)260 && Keys.Alt == Control.ModifierKeys && number == Keys.PrintScreen)) 
       { 
        MessageBox.Show("You pressed alt+ print screen"); 
       } 
      } 

     } 
     return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam); 

    } 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr SetWindowsHookEx(int idHook, 
     LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, 
     IntPtr wParam, IntPtr lParam); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr GetModuleHandle(string lpModuleName); 
} 

Кто-нибудь есть ключ, почему она висит после MessageBox?

+0

сохранить точку останова здесь 'return CallNextHookEx (IntPtr.Zero, nCode, wParam, lParam);' и посмотреть, что происходит ... это ждет или нет? – PresleyDias

+0

Он ждет, да. Он ждет пару секунд, а затем переходит к Visual Studio .. – Devator

+0

Похож на http://stackoverflow.com/questions/2999013/global-low-level-keyboard-hook-freezing-in-c-sharp-net -3-5 – sgmoore

ответ

1

Windows не может отправить следующее сообщение клавиатуры до завершения выполнения обратного вызова крючка. Очевидно, вы делаете не хотите использовать MessageBox.Show(), который блокирует обратный вызов. Windows запускает это в течение нескольких секунд, прежде чем объявит ваш код сломанным и отключит hook.

Вместо этого используйте Debug.Print().

+0

Мне нужно показать другая форма, которая также, похоже, блокирует ее. Что было бы лучше всего? Начать новую тему, которая покажет форму? – Devator

+0

Вызов метода Show() формы не должен быть проблемой. ShowDialog() * - проблема, это блокирующий вызов. Используйте метод BeginInvoke() для запуска кода позже, не используйте потоки. –