我在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);
}
}
错误在哪里?
答案 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