捕获Alt + PrintScreen热键和剪贴板内容

时间:2009-09-26 12:35:18

标签: c# hotkeys printscreen alt-key

我在alt + printscreen上设置捕捉热键。它完美捕获但缓冲区中没有任何东西 - 没有图像。如何在捕获热键后从Clipboard.GetImage()获取图像?

这是代码。

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);
    }
}

错误在哪里?

2 个答案:

答案 0 :(得分:1)

在处理密钥之前捕获密钥,您必须调度热键并让它完成其工作,然后在通过SetClipboardViewer Windows API调用之类的更新剪贴板后捕获结果。

答案 1 :(得分: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