.NET 2.x Получить координаты внешней активной формы - C#
Формулировка задачи:
Здравствуйте, пишу программу сохранения скрина сразу в файл картинки. Идея состоит в том что прога работает в фоновом режиме, нажал printscreen и показал куда сохранять. Хочу еще реализовать сразу обрезку по координатам активной формы. Может есть какая технология перехвата типа хука клавиатуры?
Решение задачи: «.NET 2.x Получить координаты внешней активной формы»
textual
Листинг программы
using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
namespace ConsoleApplication4
{
class Program
{
#region Функции по клаве MSDN.
//эта библиотека
[DllImport("user32.dll")]
//Данная функция винды определяет какая клавиша нажата в данное время
private static extern short GetAsyncKeyState(int vKey);
#endregion
#region Функции по скриншоту MSDN.
[System.Runtime.InteropServices.DllImport("user32.dll")]
//Функция которая получает дескриптор окна рабочего стола.
//Окно рабочего стола охватывает весь экран.
//Окно рабочего стола - это область, поверх которой рисуются другие окна.
public extern static IntPtr GetDesktopWindow();
[System.Runtime.InteropServices.DllImport("user32.dll")]
//Функция GetWindowDC извлекает контекст устройства(DC) для всего окна,
//включая строку заголовка, меню и полосы прокрутки.
//Контекст оконного устройства позволяет рисовать в любом месте окна,
//потому что источником контекста устройства является верхний левый угол окна, а не область клиента.
public static extern IntPtr GetWindowDC(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
//Функция BitBlt выполняет передачу бит-блоков данных цвета, соответствующих прямоугольнику пикселей
//из указанного контекста исходного устройства, в контекст целевого устройства.
public static extern UInt64 BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight,
IntPtr hSrcDC, int xSrc, int ySrc, System.Int32 dwRop);
#endregion
//[STAThreadAttribute] // в случае использования выбора папки раскоментировать
static void Main(string[] args)
{
//бесконечный цикл для отлова нажатия клавиши
while (true)
{
//выставляем задержку на 100 милисекунды
Thread.Sleep(100);
//проверяем все возможные коды клавиатуры ([url]http://www.vsokovikov.narod.ru/New_MSDN_API/Other/virtual_key_code.htm[/url])
//сдесь можно попробовать сделать по другому, отлавливать только принтскрин, но мне лень
for (Int32 i = 0; i < 255; i++)
{
//Функция GetAsyncKeyState определяет, является ли клавиша отпущенной или нажатой
//во время вызова функции и была ли клавиша нажата после предыдущего вызова GetAsyncKeyState.
int state = GetAsyncKeyState(i);
//если возврат 1 - то клавиша опущена, а -32767 - нажата
if (state == 1 || state == -32767)
{
//PrintScreen имеет номер десетичное число 44
if (i == 44)
{
//Инициализируем новый экземпляр класса System.Drawing.Bitmap
//с заданным размером. В качестве параметров нового изображения, передаем
//ширину главного экрана в пикселях и высоту.
Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
//Создаем новый объект System.Drawing.Graphics из
//рисунка myImage, с новым объектом System.Drawing.Graphics
//для указанного объекта.
Graphics grl = Graphics.FromImage(myImage);
//Получаем дескриптор контекста устройства, связанный с
//данным объектом System.Drawing.Graphics.
IntPtr del = grl.GetHdc();
//Получаем значение дескриптора окна рабочего стола Windows.
//(Окно рабочего стола является областью, на верхней части
//которой изображены все значки и другие окна). После чего
//получаем идентификатоp контекста дисплея; 0 - если ошибка.
IntPtr dc2 = GetWindowDC(GetDesktopWindow());
//Функция BitBlt передает прямоугольный блок пикселов с поверхности
//устройства-источника dc2 на поверхность устройства-приемника del
BitBlt(del, 0, 0, Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height, dc2, 0, 0, 13369376);
//Освобождаем дескриптор контекста устройства, полученный
//в результате предыдущего вызова метода
//System.Drawing.Graphics.GetHdc() данного объекта
//System.Drawing.Graphics.
grl.ReleaseHdc(del);
//Сохраняем полученное изображение в директорию с запускаемым
//файлом проекта.
myImage.Save("screenshot.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
////ну или выбираем папку и добавляем имя файла (имя файла писать не стал, лень)
//string path = null;
//using (var dialog = new FolderBrowserDialog())
// if (dialog.ShowDialog() == DialogResult.OK)
// path = dialog.SelectedPath;
}
}
}
}
}
}
}