Пишем собственный screencapturer для Windows. Часть 2
Во второй части нашей этой статьи мы начнем прямо с кода:
void CscreencaptureDlg::GetScreen(void) { int Width=GetSystemMetrics(SM_CXSCREEN); //получем ширину экрана int Height=GetSystemMetrics(SM_CYSCREEN); //получем высоту экрана CDC dc; //локальная переменная контекста устройства HDC h=::GetDC(NULL); //получаем дескриптор окна dc.Attach(h); //присоединемя его к переменной контекста устройства DC.CreateCompatibleDC(&dc); //размещаем данный контекст устройства в памяти CBitmap Win; //cоздаем локальную переменную класса CBitmap Win.CreateCompatibleBitmap(&dc,Width,Height); //cоздаем совместимый с bimap контекст устройства DC.SelectObject(&Win); //выбираем контекст устройства DC.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY); //копируем указанную область экрана dc.Detach(); //освобождаем локальный контекст устройства ::ReleaseDC(NULL, h); //SaveBitmap("c:\\bmp\\screen.bmp",(HBITMAP)Win,0); DC.DeleteDC(); //освобождаем глобальный контекст устройства MessageBox("This screen was caputered well"); //сообщение об успешном выполнени задачи
}
Теперь добавим новый обработчик сообщений к пункту меню “GetScreen” в редакторе ресурсов.
Пауза нам нужна, чтобы в наш снимок экрана не попало окно нашей программы.
11. Все работает замечательно, только никакой выгодны лично для нас. Потому что мы не можем увидеть то, что сохраняет программа. Для этого нам нужно создать новый служебный метод класса, который будет сохранять полученный результат в файл. Добавляем новый метод SaveBitmap, который возвращает тип BOOL.
12. После этого редактируем метод GetScreen(), добавив в него код сохранение файла bmp. После правки этот код будет выглядеть таким образом:
void CscreencaptureDlg::GetScreen(void)
{
CString path="d:\\myscreens\\current_screen.bmp";
//задаем путь к файлу, в которм будет храниться картинка
int Width=GetSystemMetrics(SM_CXSCREEN);
//получем ширину экрана
int Height=GetSystemMetrics(SM_CYSCREEN);
//получем высоту экрана
CDC dc;
//локальная переменная контекста устройства
HDC h=::GetDC(NULL);
//получаем дескриптор окна
dc.Attach(h);
//присоединемя его к переменной контекста устройства
DC.CreateCompatibleDC(&dc);
//размещаем данный контекст устройства в памяти
CBitmap Win;
//cоздаем локальную переменную класса CBitmap
Win.CreateCompatibleBitmap(&dc,Width,Height);
//cоздаем совместимый с bimap контекст устройства
DC.SelectObject(&Win);
//выбираем контекст устройства
DC.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
//копируем указанную область экрана
dc.Detach();
//освобождаем локальный контекст устройства
::ReleaseDC(NULL, h);
SaveBitmap(path,(HBITMAP)Win,0);
DC.DeleteDC();
//освобождаем глобальный контекст устройства
MessageBox("This screen was caputered well");
//сообщение об успешном выполнении задачи
}
Директорий файла, где будет храниться картинка, нужно создать вручную, хотя в дальнейшем можно сделать и программно . Нам остается добавить еще одну опцию в программу. Об этом ниже.
13. Несколько неудобно каждый раз, чтобы увидеть снимок экрана ходить в каталог, где храниться текущая версия файла. Мы переопределим стандартный метод окна
для этой цели. Код будет таким:
void CscreencaptureDlg::OnPaint()
{
CPaintDC dc(this);
// создаем контекст устройства для рисования
CDC MemDC;
// создаем локальная переменная контекста устройства
CString path="C:\\bmp\\screen.bmp";
//указываем путь к файлу для чтения
RECT Rect;
GetClientRect(&Rect);
//создаем переменную структуры CRECT и заполняем ее.
14. Компилируем программу и пробуем. Теперь можно получать снимки рабочего стола и тут же просматривать их. Программа очень простая, но в тоже время обладает необходимой функциональностью. В дальнейшем ее можно модифицировать и улучшить, если конечно, это будет нужно 
Здесь и далее полный исходный код программы:
// screencapture.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "screencapture.h"
#include "screencaptureDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CscreencaptureApp
BEGIN_MESSAGE_MAP(CscreencaptureApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// CscreencaptureApp construction
CscreencaptureApp::CscreencaptureApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CscreencaptureApp object
CscreencaptureApp theApp;
// CscreencaptureApp initialization
BOOL CscreencaptureApp::InitInstance()
{
// InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
InitCommonControls();
CWinApp::InitInstance();
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization