2009-09-26 24 views
1

我在alt + printscreen上設置捕捉熱鍵。它完美捕捉,但緩衝區中沒有任何東西 - 沒有圖像。捕獲熱鍵後,如何從Clipboard.GetImage()獲取圖像?捕獲Alt + PrintScreen熱鍵和剪貼板內容

以下是代碼。

using System; 
using System.Runtime.InteropServices; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace Magic_Screenshot 
{ 
    public enum ModifierKey : uint 
    { 
     MOD_NULL = 0x0000, 
     MOD_ALT = 0x0001, 
     MOD_CONTROL = 0x0002, 
     MOD_SHIFT = 0x0004, 
     MOD_WIN = 0x0008, 
    } 

    public enum HotKey 
    { 
     PrintScreen, 
     ALT_PrintScreen, 
     CONTROL_PrintScreen 
    } 

    public class HotKeyHelper : IMessageFilter 
    { 
     const string MSG_REGISTERED = "Горячие клавиши уже зарегистрированы, вызовите UnRegister для отмены регистрации."; 
     const string MSG_UNREGISTERED = "Горячие клавиши не зарегистрированы, вызовите Register для регистрации."; 
     //Делаем из нашего класса singleton 
     public HotKeyHelper() 
     { 
     } 
     //public static readonly HotKeyHelper Instance = new HotKeyHelper(); 
     public bool isRegistered; 
     ushort atom; 
     //ushort atom1; 
     ModifierKey modifiers; 
     Keys keyCode; 
     public void Register(ModifierKey modifiers, Keys keyCode) 
     { 
      //Эти значения нам будут нужны в PreFilterMessage 
      this.modifiers = modifiers; 
      this.keyCode = keyCode; 
      //Не выполнена ли уже регистрация? 
      //if (isRegistered) 
      // throw new InvalidOperationException(MSG_REGISTERED); 
      //Сохраняем atom, для последующей отмены регистрации 
      atom = GlobalAddAtom(Guid.NewGuid().ToString()); 
      //atom1 = GlobalAddAtom(Guid.NewGuid().ToString()); 
      if (atom == 0) 
       ThrowWin32Exception(); 
      if (!RegisterHotKey(IntPtr.Zero, atom, modifiers, keyCode)) 
       ThrowWin32Exception(); 

      //if (!RegisterHotKey(IntPtr.Zero, atom1, ModifierKey.MOD_CONTROL, Keys.PrintScreen)) 
      // ThrowWin32Exception(); 
      //Добавляем себя в цепочку фильтров сообщений 
      Application.AddMessageFilter(this); 
      isRegistered = true; 
     } 
     public void UnRegister() 
     { 
      //Не отменена ли уже регистрация? 
      if (!isRegistered) 
       throw new InvalidOperationException(MSG_UNREGISTERED); 
      if (!UnregisterHotKey(IntPtr.Zero, atom)) 
       ThrowWin32Exception(); 
      GlobalDeleteAtom(atom); 
      //Удаляем себя из цепочки фильтров сообщений 
      Application.RemoveMessageFilter(this); 
      isRegistered = false; 
     } 
     //Генерирует Win32Exception в ответ на неудачный вызов импортируемой Win32 функции 
     void ThrowWin32Exception() 
     { 
      throw new Win32Exception(Marshal.GetLastWin32Error()); 
     } 
     //Событие, инициируемое при обнаружении нажатия HotKeys 
     public event HotKeyHelperDelegate HotKeyPressed; 

     public bool PreFilterMessage(ref Message m) 
     { 
      //Проверка на сообщение WM_HOTKEY 
      if (m.Msg == WM_HOTKEY && 
       //Проверка на окно 
       m.HWnd == IntPtr.Zero && 
       //Проверка virtual key code 
       m.LParam.ToInt32() >> 16 == (int)keyCode && 
       //Проверка кнопок модификаторов 
       (m.LParam.ToInt32() & 0x0000FFFF) == (int)modifiers && 
       //Проверка на наличие подписчиков сообщения 
       HotKeyPressed != null) 
      { 
       if ((m.LParam.ToInt32() & 0x0000FFFF) == (int)ModifierKey.MOD_CONTROL && (m.LParam.ToInt32() >> 16 == (int)Keys.PrintScreen)) 
       { 
        HotKeyPressed(this, EventArgs.Empty, HotKey.CONTROL_PrintScreen); 
       } 
       else if ((m.LParam.ToInt32() & 0x0000FFFF) == (int)ModifierKey.MOD_ALT && (m.LParam.ToInt32() >> 16 == (int)Keys.PrintScreen)) 
       { 
        HotKeyPressed(this, EventArgs.Empty, HotKey.ALT_PrintScreen); 
       } 
       else if (m.LParam.ToInt32() >> 16 == (int)Keys.PrintScreen) 
       { 
        HotKeyPressed(this, EventArgs.Empty, HotKey.PrintScreen); 
       } 
      } 
      return false; 
     } 

     //Необходимые Win32 константы и функции 
     const string USER32_DLL = "User32.dll"; 
     const string KERNEL32_DLL = "Kernel32.dll"; 
     const int WM_HOTKEY = 0x0312; 
     [DllImport(USER32_DLL, SetLastError = true)] 
     static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKey fsModifiers, Keys vk); 
     [DllImport(USER32_DLL, SetLastError = true)] 
     static extern bool UnregisterHotKey(IntPtr hWnd, int id); 
     [DllImport(KERNEL32_DLL, SetLastError = true)] 
     static extern ushort GlobalAddAtom(string lpString); 
     [DllImport(KERNEL32_DLL)] 
     static extern ushort GlobalDeleteAtom(ushort nAtom); 
    } 
} 

錯誤在哪裏?

+0

請提供一些更多的信息。你在什麼環境中捕捉這些關鍵事件?該計劃的目的是什麼? – 2009-09-26 12:38:24

+5

在屏幕截圖之前,alt + printscreen是否被捕獲? – pavium 2009-09-26 13:11:12

回答

1

在你的事件處理程序添加以下代碼:

captureRect = Screen.PrimaryScreen.Bounds; 

// Set the bitmap object to the size of the screen 
bmpScreenshot = new Bitmap(captureRect.Width, captureRect.Height, PixelFormat.Format32bppArgb); 

// Create a graphics object from the bitmap 
gfxScreenshot = Graphics.FromImage(bmpScreenshot); 

// Take the screenshot from the upper left corner to the right bottom corner 
gfxScreenshot.CopyFromScreen(captureRect.X, captureRect.Y, 0, 0, captureRect.Size, CopyPixelOperation.SourceCopy); 

//NOTE: gfxScreenshot is your captured bitmap image, use some simple functions to save or display it 
1

密鑰在被處理之前被捕獲,您將不得不分配熱鍵並讓它完成它的工作,然後在通過類似SetClipboardViewer Windows API Call的更新剪貼板之後捕獲結果。