лекция. Зиборов. Справочник для опытных и как пособие для начинающих программистов. Компактдиск содержит исходные коды примеров из книги
Скачать 7.39 Mb.
|
ГЛАВА 6 Управление буфером обмена с данными в текстовом и графическом форматах ставлены в формате растровой графики, то записывает эти данные в ВМР-файл Текст этой программы приведен в листинге 6.4.Листинг 6.4. Запись содержимого буфера обмена в ВМР-файл // Программа читает буфер обмена, и если данные в нем представлены // в формате растровой графики, то записывает их в ВМР-файл using System; using System.Drawing; using System.Windows.Forms; // Другие директивы using удалены, поскольку они не используются в данной программе namespace БуферОбменаSaveBMP { public partial class Form1:Form { public Form1() { InitializeComponent(); this.Text = "Сохраняю копию БО в ВМР-файл"; button1.Text = "Сохранить"; } private void button1_Click(object sender, EventArgs e) { // Объявление объекта-получателя из буфера обмена IDataObject Получатель = Clipboard.GetDataObjectО; Bitmap Растр; // Если данные в буфере обмена представлены в формате Bitmap... if (Получатель.GetDataPresent(DataFormats.Bitmap) == true) { //то записать их из БО в переменную Растр в формате Bitmap Растр = (Bitmap)Получатель .GetData (DataFormats .Bitmap) // Сохранить изображение в файле Clip.bmp Растр.Save(@"С:\Clip.BMP"); //this.Text = @"Сохранено в файле C:\Clip.BMP"; //button1.Text = "Еще записать?"; MessageBox.Show (@"Изображение из БО записано в файл C:\Clip.BMP", "Успех"); } else // В БО нет данных в формате изображений MessageBox.Show("В буфере обмена нет данных в формате Bitmap", "Запишите какое-либо изображение в БО"); } } } Рис. 6.3. Запись изображения из буфера обмена в файл Впрограммном коде при обработке события "щелчок на кнопке" Сохранить объявляем объектную переменную Получатель. Это объект-получатель из буфера обмена. Далее следует проверка: записаны ли данные, представленные в буфере обмена, в формате растровой графики Bitmap. Если да, то записать данные из буфера обмена в переменную Растр в формате Bitmap с помощью объектной переменной Получатель, используя неявное преобразование в переменную типа Bitmap. Сохранить изображение Растр на винчестер очень просто, воспользовавшись методом Save(). Чтобы не запутать читателя и упростить программу, автор не стал организовывать запись файла в диалоге. При необходимости читатель сделает э самостоятельно, воспользовавшись элементом управления SaveFileDialog. Фрагмент работы данной программы представлен на рис. 6.3. Убедиться в работоспособности программы можно, открыв решение БуферОбменаSaveBMP.sln в папке БуферОбменаSaveBMP. Пример 42. Использование таймера Timer Автор несколько раз встречал задачу записи моментальных снимков экрана (screen shot) в растровые файлы с некоторым промежутком времени, например пять секунд. Кстати, такая задача была выставлена на тендер на сайте оффшорного программирования (www.rentacoder.com). За ее решение указывалось вознаграждение 100 долларов США. Конечно, сразу появляется очень много желающих эту задачу решить, но попробуйте выиграть тендер. Следующая задача является частью упомянутой задачи, ее сформулируем таким образом: после запуска программы должна отображаться форма с элементом управления ListBox, а через две секунды в список добавляется запись "Прошло две секунды", далее через каждые две секунды в список добавляется аналогична запись. На этой задаче мы освоим технологию работы с таймером. Для реализации программы в форму из панели элементов Toolbox перетащим элемент управления Timer и список ListBox. Программный код приведен в листинге 6.5. Листинг 6.5. Использование таймера // Демонстрация использования таймера Timer. После запуска программы // показываются форма и элемент управления список элементов ListBox. // Через 2 секунды в списке элементов появляется запись "Прошло две секунды", // и через каждые последующие 2 секунды в список добавляется аналогичная запись using System; using System.Windows. Forms ; // Другие директивы using удалены, поскольку они не используются в данной программе namespace ПростоТаймер { public partial class Form1:Form { public Form1() { InitializeComponent(); this.Text = "Timer"; timer1.Interval = 2000; // - 2 секунды // Старт отчета времени Timer1.Enabled = true; // - время пошло } private void timer1_Tick(object sender, EventArgs e) { listBox1.Items.Add("Прошло две секунды"); } } } Экземпляр класса Timer — это невидимый во время работы программы элемент управления, предназначенный для периодического генерирования события Tick. В программном коде сразу после инициализации конструктором компонентов программы задаем интервал времени (interval), равный 2000 миллисекунд (две секунды). Каждые две секунды будет возникать событие Tick, при этом в список элементов listBox1 будет добавляться запись "Прошло две секунды ". Этот текст будет выводиться каждые две секунды до тех пор, пока пользователь программы не щелкнет на кнопке формы Закрыть. На рис. 6.4 показан фрагмент работы программы. Рис. 6.4. Вывод сообщения Убедиться в работоспособности программы можно, открыв решение ПростоТаймер.sln в папке ПростоТаймер. Пример 43. Запись в файлы текущих состояний экрана каждые пять секунд Как уже говорилось в предыдущем разделе, работа с таймером — довольно распространенная задача. Напишем очередную программу в следующей постановке. После запуска программы через каждые пять секунд снимается текущее состояние экрана и записывается в файлы Pic1.BMP,… Pic5.BMP. Для решения данной задачи мы имеем уже весь инструментарий, он был рассмотрен в предыдущих задачах. А именно, задание интервала времени в пять секунд с помощью элемента управления Timer, эмуляция нажатия клавиш <Alt>+<PrintScreen> для записи текущего состояния экрана в буфер обмена и, наконец, чтение буфера обмена в формате изображения и запись этого изображени файл BMP. Для решения задачи перетаскиваем в форму элементы управления Timer и Вutton. Текст программы приведен в листинге 6.6. Листинг 6.6. Запись в файлы текущих состояний экрана с интервалом 5 секунд // Программа после запуска каждые пять секунд делает снимок текущего // состояния экрана и записывает эти снимки в файлы Pic1.BMP, Pic2.BMP // и т. д. Количество таких записей в файл — пять using System; using System. Drawing; using System.Windows.Forms; // Другие директивы using удалены, поскольку они не используются в данной программе namespace SaveCкpиншoтKaждыe5ceк { public partial class Form1 : Form { int i = 0; // счет секунд public Form1 () { InitializeComponent(); this.Text = "Запись каждые 5 секунд в файл"; button1.Text = "Пуск"; } private void timer1_Tick(object sender, EventArgs e) { i = i + 1; this.Text = string.Format("Прошло {0} секунд", i); if (i >= 28) { timer1.Enabled = false; this.Close(); } if (i % 5 != 0) return; // Имитируем нажатие клавиш SendKeys.Send("%{PRTSC}"); // Объявление объекта-получателя из буфера обмена IDataObject Получатель = Clipboard.GetDataObject (); Bitmap Растр; // Если данные в буфере обмена представлены в формате Bitmap, то записать if (Получатель.GetDataPresent(DataFormats.Bitmap) == true) { // эти данные из буфера обмена в переменную Растр в формате Bitmap Растр = (Bitmap)Получатель.GetData(DataFormats.Bitmap); // Сохранить изображение из переменной Растр // в файл C:\Picl, C:\Pic2, C:\Pic3, ... string ИмяФайла = string.Format(@"С:\Pic{0}.BMP", i / 5); Растр. Save (ИмяФайла) ; } } private void button1_Click(object sender, EventArgs e) { this.Text = string.Format("Прошло 0 секунд"); timer1.Interval = 1000; // равно 1 секунде timer1.Enabled = true; // время пошло } } } Как видно, структура программы включает в себя обработку события "щелчок на кнопке" button1_Сlick и обработку события Timer1_Tick. В начале программы задаем переменную i, которая считает, сколько раз программа сделает запись в буфер обмена, а из буфера обмена — в файл. При щелчке на кнопке Пуск задаем интервал времени interval, равный 1000 миллисекунд, т. е. одной секунде. Далее даем команду таймеру начать отсчет времени timer1.Enabled = true и через каждую секунду наступает событие timer1_Tick(), т.е. управление переходит этой процедуре. При обработке события timer1_Tick наращиваем значение переменной i, которая ведет счет секунд после старта таймера. Выражение i % 5 вычисляет целочисленный остаток после деления первого числового выражения на второе. Понятно, что если число i будет кратно пяти, то этот остаток будет равен нулю, и только в этом случае будет происходить имитация нажатия клавиш <Alt>+<PrintScreen> и запись содержимого буфера обмена в файл. Убедиться в работоспособности программы можно, открыв соответствующее pешение в папке SavеСкриншотКаждые5сек. |
// функции Microsoft Windows API, а также методом Send класса SendKeys
using System;
using System. Windows. Forms ;
using System.Runtime. InteropServices; // - следует добавить эту директиву
// Другие директивы using удалены, поскольку они не используются в данной программе
namespace AltPrintScreen
{
public partial class Form1: Form
{ // Следует добавить пространство имен
// using System.Runtime.InteropServices.
//Объявление функции Microsoft API
[DllImport("user32.dll")]
extern static void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtralnfo);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{ // Вызов функции Microsoft API
keybd_event(44, 1, 0, 0);
}
private void button2_Click(object sender, EventArgs e)
{ //Метод SendKeys.Send посылает сообщение активному приложению
//онажатии клавиш
SendKeys.Send("%{PRTSC} ") ;
// string QQ = Keys.PrintScreen.ToString();
}
}
}
В этой программе при обработке события "щелчок на первой кнопке" мы воспользовались функцией Microsoft Windows API (Application Programming Interface, интерфейс программирования приложений). Функция keybd_event () позволяет имитировать (эмулировать) нажатие пользователем клавиш. Функция находится в динамической библиотеке user32.dll (см. программный код). В динамической библиотеке user32.dll также присутствуют управляющие функции Windows для обработки сообщений, таймеров, меню и взаимодействия. Эту библиотеку вы можете увидеть в системном каталоге C:\Windows\System32. В dll-файлах (dynamic link library) находятся скомпилированные классы.
Как видно, сначала функцию API следует объявить с указанием типов аргументе, подаваемых на вход функции keybd_event(). Параметр "user32" или “User32 .dll" определяет имя используемой библиотеки. В скобках записан список apгументов функции keybd_event (). Мы можем задавать любые имена аргументов, но их типы должны соответствовать формату функции API.
При обработке события "щелчок на кнопке" Button1_Click() мы программируем вызов API-функции keybd_event () по формату, заданному в объявлении функции. Из четырех аргументов функции keybd_event () важным является первый, он задает код клавиши <PrintScreen>. Можно задать шестнадцатеричный код, равный 0xH2CS, однако мы задали десятичный код клавиши <PrintScreen>, равный 44.
Также представляет интерес второй аргумент функции keybd_event (). Второй аргумент, равный единице, эмулирует одновременное нажатие клавиши <Alt> c клавишей <PrintScreen>. Таким образом, вызывая функцию keybd_event (44, 0, 0), мы эмулируем нажатие комбинации клавиш <Alt>+<PrintScreen>, а keybd_event(44, 0, 0, 0) — нажатие только <PrintScreen>. С помощью функции keybd_event () можно эмулировать нажатие любых клавиш, подавая вход функции коды соответствующих клавиш.
Обрабатывая событие "щелчок на второй кнопке", мы решаем абсолютно ту задачу, но более современными средствами. Метод Send класса SendKeys посылает сообщение активному приложению о нажатии комбинации клавиш <Alt> +<PrintScreen>. Кодом клавиши <PrintScreen> является код "{prtsc}". Чтобы указать сочетание клавиши <Alt> +<PrintScreen>, следует в этот код добавить символ процента: "%{prtsc}". Коды других клавиш можно посмотреть по адресу:
http://msdn.microsoft.com/ru-ru/library/system.windows.forms.sendkeys.aspх
Таким образом, результаты нажатия обеих клавиш одинаковы. Убедиться в работоспособности программы можно, открыв решение AltPrintScreen.sln в папке AltPrintScreen.
Пример 41. Запись содержимого буфера обмена в ВМР-файл
Напишем программу, которая читает буфер обмена, и если данные в нем п