Сейчас на сайте

Сейчас 4 гостей онлайн

Поиск

Tag Cloud

Twitter oAuth и Cod... Баллада о г... сихи лирик... стихи лири... Динамическ... Домашняя с... Использова... Использова... Отправка с... Создание ф... Шепот посл... TinyMCE в Rails стихи лири... Быстрая ра... Пишем собс... Создание с... Установка ... Ностальгия... Москва-Бел... стихи лири... Стихи про п... Крылья сти... Создание п... Простой по... Создание п... Одинокий в... Гражданин ... Несчастный... Сонет стих... Отрезок ст... Врагу не сд... Предчувств... Поиск в ст... Использова... Смерть дву... Использова... Как сделат... Как сделат... Облако тег... Южная сере... Программна... Codeigniter в де... CodeIgniter: фор... проверка в... стихи лири... WEB fetcher(scrappe... Простой Twitt... стихи твор... стихи лири... Проверка п... Создание и ... Побег с Сол... Отправка SMS... MS VSTO 2007/Infusio... Установка R... Fckeditor в при... Степные тр... моя любовь. К твоим оз... Сомкнуть л... чтоб отдат... вот – вот ... еще не расс... Снег тишина и лу... и мира пово... что мой пос... Лишь ты. И т... ты любима ты чиста. Экспорт да... Я пью до дн... что нам теп... -Наш первый... Социальные... Социальные... Спит в можж... Воздух про... Стены рожденные ... эхо умрет. Неотправле... стихи лири... Он порезал... Боясь шагн... не осталос... Услышать з... Программир...

Пишем собственный screencapturer для Windows PDF Печать E-mail
31.05.2011 02:23

 

В повседневной работе с Windows иногда , однако, все же возникает потребность в получений копий снимков с текущего рабочего стола Windows. Для этого есть масса свободных или платных программ, а мы напишем свою. Тем боле, займет это очень мало времени. Для этого нам нужно только работающий компьютер с установленной операционной системой Windows, Microsoft Visual Studio 2003 и конечно, MSDN . Сама процедура разработка будет описана пошагово, там же будут те части программного кода, которые будут нами созданы.

 

  1. Как обычно, создаем шаблон программы. Для этого запускаем Microsoft Visual Studio 2003 , выбираем “New Project…”, затем “Visual C++”. В этом меню выбираем “MFC Application”. Выбираем путь где будет расположен наш проект и вводим название “screencapture”. (Хотя каждый может ввести любое название J ) Жмем «ОК». Дальше мы выбираем «Application Type» - “Dialog based”. Если кто желает подарить другу или подруге свою программу, то нужно выбрать Use MFC in static library”. Все остальные настройки можно оставить без изменений.
  2. Открываем проект. Компилируем его, чтобы увидеть, то что мы имеем сейчас. Для начала удаляем «TODO: Place dialog controls here.» и обе кнопки “OK и Cancel”. Увеличим размеры окна, например сделаем их 850x650. Отредактируем заголовок программы и введем туда “Screen Capturer”

Затем, идем в редактор ресурсом и редактируем иконку «IDR_MAINFRAME»

Эта икона в последствии будет нам использована, но поскольку

стандартный вид не совсем удобный, нам надо то-то специфическое.

Рисуем иконку новую на основе существующей или создаем новую.

  1. Теперь создаем в редакторе ресурсов новое меню. Добавляем «Add Resource», там выбираем “New-> Menu”. Переименовываем его из “IDR_MENU1” в “IDR_MENU_TRAY”. Затем займемся редактированием самого меню. Назовем его к примеру “Action”, затем добавляем

в подпункты “Get Screen”, “Hide In Tray”, “Restore” и “Exit”. Перед последним пунктом нажмем клавишу «-» для того, чтобы отделить Exit” от

остальных команд.

4. На этом с ресурсами все, и мы начнем программировать. По логике работы программы, нам нужно, чтобы программа была не видна

в момент получения снимка экрана. Значит, она должна находится в системном трее, той области, где приложение свернуто до

размеров иконки. Сначала создадим новую переменную типа NOTIFYICONDATA с именем tray_icon для класса CscreencaptureDlg.cpp

Обозначим ее как public”. Это структура, которая будет использована для хранения данных для обработки сообщений системного трея.

  1. Теперь займемся нашим меню. Создадим переменную типа CMenu и назовем ее “menu” опять же для класса CscreencaptureDlg.cpp. Затем в переходим в этом классе к методу OniInitDialog() и после комментариев // TODO: Add extra initialization here

пишем такой код

menu.LoadMenu(IDR_MENU_TRAY);

SetMenu(&menu);

Первая строка загружает в переменную меню из ресурсов, в вторая делает его видимы на окне нашего приложения.

Компилируем программу и видим результат ее работы, - появляется наше меню.

Теперь переходим снова в редактор ресурсов и назначаем обработчики событий для пунктов меню. Сначала

добавляем обработчик к пункту “Exit”. Делаем правый клик мышью на выбранном нами пункте меню и из выпавшего списка опций

выбираем “Add Event Handler…”. Затем выбираем обработчик типа COMMAND и связываем с классом CscreencaptureDlg.cpp.

В открывшемся окне нам нужно ввести код обработчика.

 

void CscreencaptureDlg::OnActionExit() {

EndDialog(0);

}

Сперва мы создаем переменную типа int и присваиваем ей значение 1. Это сделано скорее с данью традиции,

можно присвоить любое значение этого же типа. Потому что метод EndDialog (int someresult);

принимает значения этого типа. Сам же метод, согласно его описанию и названию, просто уничтожает модальное

диалоговое окно.

  1. Чтобы создать обработчик сообщений для системного трея, мы должны сделать следующее; ввести в файл Ressource.h

добавляем идентификатор иконки:

 

             #define ID_TrayIcon                135

Число «135» взято произвольно, главное чтобы не совпадало с уже существующими ID ресурсов. Этот ID будет впоследствии использовано для

обращения к иконке. Затем мы создаем обработчик события для системного трея - в классу диалогового окна вводим новое сообщение:

#define WM_TRAYICONNOTIFY WM_USER+1

все сообщения типа WM_USER+1 представляют собой частные сообщения, определяемые самим пользователем.

Затем в карту сообщений добавляем собственно обработчик сообщений для трея

ON_MESSAGE(WM_ICON, OnTrayIcon)

 

После чего она будет выглядеть таким образом:

 

BEGIN_MESSAGE_MAP(CscreencaptureDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_COMMAND(ID_ACTION_EXIT, OnActionExit)

ON_COMMAND(ID_ACTION_HIDE, OnActionHide)

ON_MESSAGE(WM_ICON, OnTrayIcon)

ON_COMMAND(ID_ACTION_RESTORE, OnActionRestore)

END_MESSAGE_MAP()

И самое главное, надо добавить новый метод, который и собственно будет обрабатывать это сообщение. Для этого мы добавим к классу CscreencaptureDlg.cpp.

такой метод, кликнув мышью на “Class View” ( « Вид Классов») и выбрав класс диалогового окна. В выпавшем меню выберем “Add..-> Add Function

Новый метод OnTrayIcon будет возвращать значения типа LRESULT и принимать WPARAM wp, LPARAM lp. Затем вводим внутрь его такой код:

 

LRESULT CscreencaptureDlg::OnTrayIcon(WPARAM wp, LPARAM lp) {

if(wp != tray_icon.uID || lp != WM_LBUTTONDBLCLK &&

lp != WM_RBUTTONUP)

return 0;

// Получение подменю

CMenu *SubMenu = menu.GetSubMenu(0);

// Если была нажата правая кнопка мыши

if(lp == WM_RBUTTONUP)

{

// Первый пункт меню выделяется "жирным" шрифтом

SubMenu->SetDefaultItem(0, true);

// Получение позиции курсора

CPoint mouse;

GetCursorPos(&mouse);

// Установка окна, которое будет получать фокус

// (в данном случае это иконка и связанное с ней меню)

::SetForegroundWindow(tray_icon.hWnd);

// Отображение контекстного меню

SubMenu->TrackPopupMenu(0, mouse.x, mouse.y, this);

}

// Если была дважды нажата левая кнопка мыши

else if(lp == WM_LBUTTONDBLCLK)

// Имитация выбора пункта меню по умолчанию

::SendMessage(tray_icon.hWnd, WM_COMMAND,

SubMenu->GetMenuItemID(0), 0);

return 1;

}

7. Далее мы в методе OniInitDialog() класса CscreencaptureDlg.cpp. инициализируем переменную структуры NOTIFYICONDATA

tray_icon

 

memset(&tray_icon, 0, sizeof(NOTIFYICONDATA));

// Размер структуры

tray_icon.cbSize = sizeof(NOTIFYICONDATA);

// Иконка

tray_icon.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

// Дескриптор окна, получающего сообщения из трея

tray_icon.hWnd = m_hWnd;

// Подсказка

strcpy(tray_icon.szTip, "Get Screen");

// Идентификатор обработчика

tray_icon.uCallbackMessage = WM_ICON;

// Установка флагов

tray_icon.uFlags = NIF_TIP | NIF_MESSAGE | NIF_ICON;

// Идентификатор иконки

trya_icon.uID = ID_TrayIcon;

8. Снова возвращаемся в редактор ресурсов к нашему меню и аналогичным способом добавляем обработчик к пункту Hide In Tray”.

Затем редактируем его код:

void CscreencaptureDlg::OnActionHide()

{

ShowWindow(SW_HIDE);

//окно минимизируется

Shell_NotifyIcon(NIM_ADD, &trray_icon);

// В трее появляется иконка

}

Затем компилируем программу. Мы видим, что после нажатия на пункт меню “Hide In Tray” появляется иконка в системном трее и окно исчезает.

9. Аналогичным способом добавляем обработчик к пункту меню “Restore”:

void CscreencaptureDlg::OnActionRestore()

{

// Удаление иконки из трея

Shell_NotifyIcon(NIM_DELETE, &tray_icon);

// Отображение главного окна

ShowWindow(SW_NORMAL);

// Теперь фокус будет получать главное окно

::SetForegroundWindow(m_hWnd);

}

10. Компилируем приложение, пробуем. Если не было синтаксических ошибок, то все работает. J. Теперь перейдем к самому главному, тому, для чего мы создали

эту программу. Нам потребуется использования класса контекста устройства, для чего мы создаем новую переменную для класса диалогового окна –

CDC DC. Далее создаем новый метод GetScreen().

 

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” в редакторе ресурсов.

void CscreencaptureDlg::OnActionGetscreen()

{

ShowWindow(SW_HIDE);

//скрываем основное окно программы

::Sleep(1000);

//задержка исполнения в миллисекундах

GetScreen();

//получаем картинку экрана

Shell_NotifyIcon(NIM_ADD, &tray_icon);

//убираем программу в трей

}

Пауза нам нужна, чтобы в наш снимок экрана не попало окно нашей программы.

 

11. Все работает замечательно, только никакой выгодны лично для нас. Потому что мы не можем увидеть то, что сохраняет программа. Для этого нам нужно создать новый служебный метод класса, который будет сохранять полученный результат в файл. Добавляем новый метод SaveBitmap, который возвращает тип BOOL.

BOOL CscreencaptureDlg::SaveBitmap(LPCSTR FileName, HBITMAP hBitmap, HPALETTE hPal)

{

BOOL bResult = FALSE;

//служебная булевая переменная

PICTDESC stPictDesc;

// переменная структуры PICTDESC для описания картинки

stPictDesc.cbSizeofstruct = sizeof(PICTDESC);

//задаем размеры переменной этой структуры

stPictDesc.picType = PICTYPE_BITMAP;

stPictDesc.bmp.hbitmap = hBitmap;

//устанавливаем тип как bitmap

stPictDesc.bmp.hpal = hPal;

//выбираем текущую палитру

LPPICTURE pPicture;

//создаем переменную структуры, содержащую информацию о клиентской области

HRESULT hr = OleCreatePictureIndirect( &stPictDesc, IID_IPicture, FALSE, reinterpret_cast<void**>(&pPicture) );

//создаем объект картинку

if ( SUCCEEDED(hr) )

{

//если картинка создана

LPSTREAM pStream;

hr = CreateStreamOnHGlobal( NULL, TRUE, &pStream );

//создаем объект Stream в памяти используя полученный объект hr

if ( SUCCEEDED(hr) )

{

long lBytesStreamed = 0;

hr = pPicture->SaveAsFile( pStream, TRUE, &lBytesStreamed );

//сохраняем картинку в файле

if ( SUCCEEDED(hr) )

{

HANDLE hFile = CreateFile( FileName,

GENERIC_WRITE,

FILE_SHARE_READ,

NULL,

CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL,

NULL );

//создаем дескриптор файла

if ( hFile )

{

HGLOBAL hMem = NULL;

GetHGlobalFromStream( pStream, &hMem );

LPVOID lpData = GlobalLock( hMem );

DWORD dwBytesWritten;

bResult = WriteFile( hFile, lpData, lBytesStreamed, &dwBytesWritten, NULL );

bResult &= ( dwBytesWritten == (DWORD)lBytesStreamed );

//записываем данные из памяти в файл

GlobalUnlock(hMem);

CloseHandle(hFile);

}

}

pStream->Release();

}

pPicture->Release();

}

//освобождаем используемые ресурсы

return bResult;

}

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

//сообщение об успешном выполнении задачи

}

 

Директорий файла, где будет храниться картинка, нужно создать вручную, хотя в дальнейшем можно сделать и программно J. Нам остается добавить еще одну опцию в программу. Об этом ниже.

13. Несколько неудобно каждый раз, чтобы увидеть снимок экрана ходить в каталог, где храниться текущая версия файла. Мы переопределим стандартный метод окна

для этой цели. Код будет таким:

 

void CscreencaptureDlg::OnPaint()

{

CPaintDC dc(this);

// создаем контекст устройства для рисования

CDC MemDC;

// создаем локальная переменная контекста устройства

CString path="C:\\bmp\\screen.bmp";

//указываем путь к файлу для чтения

RECT Rect;

GetClientRect(&Rect);

//создаем переменную структуры CRECT и заполняем ее.

HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

MemDC.CreateCompatibleDC(&dc);

MemDC.SelectObject(hBitmap);

//создаем bitmap и загружаем его в контекст устройства

dc.StretchBlt(0,0, Rect.right, Rect.bottom,&MemDC,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_ CYSCREEN),SRCCOPY);

//отображаем картинку в нашем окне.

}

 

14. Компилируем программу и пробуем. Теперь можно получать снимки рабочего стола и тут же просматривать их. Программа очень простая, но в тоже время обладает необходимой функциональностью. В дальнейшем ее можно модифицировать и улучшить, если конечно, это будет нужно J

Здесь и далее полный исходный код программы:

 

// 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

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

CscreencaptureDlg dlg;

m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

// dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

// dismissed with Cancel

}

// Since the dialog has been closed, return FALSE so that we exit the

// application, rather than start the application's message pump.

return FALSE;

}

 

// screencaptureDlg.cpp : implementation file

//

#include "stdafx.h"

#include "screencapture.h"

#include "screencaptureDlg.h"

#include ".\screencapturedlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

#define WM_ICON WM_APP + 1

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

// CscreencaptureDlg dialog

CscreencaptureDlg::CscreencaptureDlg(CWnd* pParent /*=NULL*/)

: CDialog(CscreencaptureDlg::IDD, pParent)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CscreencaptureDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CscreencaptureDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_COMMAND(ID_ACTION_EXIT, OnActionExit)

ON_COMMAND(ID_ACTION_HIDE, OnActionHide)

ON_MESSAGE(WM_ICON, OnTrayIcon)

ON_COMMAND(ID_ACTION_RESTORE, OnActionRestore)

ON_COMMAND(ID_ACTION_GETSCREEN, OnActionGetscreen)

END_MESSAGE_MAP()

// CscreencaptureDlg message handlers

BOOL CscreencaptureDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

menu.LoadMenu(IDR_MENU_TRAY);

SetMenu(&menu);

// Установка всех полей структуры в 0

memset(&tray_icon, 0, sizeof(NOTIFYICONDATA));

// Размер структуры

tray_icon.cbSize = sizeof(NOTIFYICONDATA);

// Иконка

tray_icon.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

// Дескриптор окна, получающего сообщения из трэя

tray_icon.hWnd = m_hWnd;

// Подсказка

strcpy(tray_icon.szTip, "Get Screen");

// Идентификатор обработчика

tray_icon.uCallbackMessage = WM_ICON;

// Установка флагов

tray_icon.uFlags = NIF_TIP | NIF_MESSAGE | NIF_ICON;

// Идентификатор иконки

tray_icon.uID = ID_TrayIcon;

return TRUE; // return TRUE unless you set the focus to a control

}

void CscreencaptureDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework.

// The system calls this function to obtain the cursor to display while the user drags

// the minimized window.

HCURSOR CscreencaptureDlg::OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

void CscreencaptureDlg::OnActionExit()

{

EndDialog(0);

}

void CscreencaptureDlg::OnActionHide()

{

ShowWindow(SW_HIDE);

//окно минимизируется

Shell_NotifyIcon(NIM_ADD, &tray_icon);

// В трее появляется иконка

}

LRESULT CscreencaptureDlg::OnTrayIcon(WPARAM wp, LPARAM lp)

{

if(wp != tray_icon.uID || lp != WM_LBUTTONDBLCLK &&

lp != WM_RBUTTONUP)

return 0;

// Получение подменю

CMenu *SubMenu = menu.GetSubMenu(0);

// Если была нажата правая кнопка мыши

if(lp == WM_RBUTTONUP)

{

// Первый пункт меню выделяется "жирным" шрифтом

SubMenu->SetDefaultItem(0, true);

// Получение позиции курсора

CPoint mouse;

GetCursorPos(&mouse);

// Установка окна, которое будет получать фокус

// (в данном случае это иконка и связанное с ней меню)

::SetForegroundWindow(tray_icon.hWnd);

// Отображение контекстного меню

SubMenu->TrackPopupMenu(0, mouse.x, mouse.y, this);

}

// Если была дважды нажата левая кнопка мыши

else if(lp == WM_LBUTTONDBLCLK)

// Имитация выбора пункта меню по умолчанию

::SendMessage(tray_icon.hWnd, WM_COMMAND,

SubMenu->GetMenuItemID(0), 0);

return 1;

}

void CscreencaptureDlg::OnActionRestore()

{

// Удаление иконки из трэя

Shell_NotifyIcon(NIM_DELETE, &tray_icon);

// Отображение главного окна

ShowWindow(SW_NORMAL);

// Теперь фокус будет получать главное окно

::SetForegroundWindow(m_hWnd);

}

void CscreencaptureDlg::GetScreen(void)

{

CString path="c:\\bmp\\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");

//сообщение об успешном выполнени задачи

 

}

 

void CscreencaptureDlg::OnActionGetscreen()

{

ShowWindow(SW_HIDE);

//скрываем основное окно программы

::Sleep(1000);

//задержка исполнения в миллисекундах

GetScreen();

//получаем картинку экрана

Shell_NotifyIcon(NIM_ADD, &tray_icon);

//убираем программу в трей

}

 

BOOL CscreencaptureDlg::SaveBitmap(LPCSTR FileName, HBITMAP hBitmap, HPALETTE hPal)

{

BOOL bResult = FALSE;

//служебная булевая переменная

PICTDESC stPictDesc;

// переменная структуры PICTDESC для описания картинки

stPictDesc.cbSizeofstruct = sizeof(PICTDESC);

//задаем размеры переменной этой структуры

stPictDesc.picType = PICTYPE_BITMAP;

stPictDesc.bmp.hbitmap = hBitmap;

//устанавливаем тип как bitmap

stPictDesc.bmp.hpal = hPal;

//выбираем текущую палитру

LPPICTURE pPicture;

//создаем переменную структуры, содержащую информацию о клиентcкой области

HRESULT hr = OleCreatePictureIndirect( &stPictDesc, IID_IPicture, FALSE, reinterpret_cast<void**>(&pPicture) );

//создаем объект картинку

if ( SUCCEEDED(hr) )

{

//если картинка создана

LPSTREAM pStream;

hr = CreateStreamOnHGlobal( NULL, TRUE, &pStream );

//создаем объект Strem в памяти используя полученный объект hr

if ( SUCCEEDED(hr) )

{

long lBytesStreamed = 0;

hr = pPicture->SaveAsFile( pStream, TRUE, &lBytesStreamed );

//сохраняем картинку в файле

if ( SUCCEEDED(hr) )

{

HANDLE hFile = CreateFile( FileName,

GENERIC_WRITE,

FILE_SHARE_READ,

NULL,

CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL,

NULL );

//создаем дескриптор файла

if ( hFile )

{

HGLOBAL hMem = NULL;

GetHGlobalFromStream( pStream, &hMem );

LPVOID lpData = GlobalLock( hMem );

DWORD dwBytesWritten;

bResult = WriteFile( hFile, lpData, lBytesStreamed, &dwBytesWritten, NULL );

bResult &= ( dwBytesWritten == (DWORD)lBytesStreamed );

//записываем данные из памяти в файл

GlobalUnlock(hMem);

CloseHandle(hFile);

}

}

pStream->Release();

}

pPicture->Release();

}

//освобождаем используемые ресурсы

return bResult;

}

 

 

// stdafx.cpp : source file that includes just the standard includes

// screencapture.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

 

 

 

 

 

//{{NO_DEPENDENCIES}}

// Microsoft Visual C++ generated include file.

// Used by screencapture.rc

//

#define IDM_ABOUTBOX 0x0010

#define IDD_ABOUTBOX 100

#define IDS_ABOUTBOX 101

#define IDD_SCREENCAPTURE_DIALOG 102

#define IDR_MAINFRAME 128

#define IDR_MENU1 129

#define IDR_MENU_TRAY 129

#define ID_ACTION_GETSCREEN 32771

#define ID_ACTION_HIDE 32772

#define ID_ACTION_RESTORE 32773

#define ID_ACTION_EXIT 32774

#define ID_TrayIcon 135

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE 130

#define _APS_NEXT_COMMAND_VALUE 32775

#define _APS_NEXT_CONTROL_VALUE 1000

#define _APS_NEXT_SYMED_VALUE 101

#endif

#endif

 

 

 

 

 

 

// screencapture.h : main header file for the PROJECT_NAME application

//

#pragma once

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

#include "resource.h" // main symbols

// CscreencaptureApp:

// See screencapture.cpp for the implementation of this class

//

class CscreencaptureApp : public CWinApp

{

public:

CscreencaptureApp();

// Overrides

public:

virtual BOOL InitInstance();

// Implementation

DECLARE_MESSAGE_MAP()

};

 

extern CscreencaptureApp theApp;

 

 

 

 

 

// screencaptureDlg.h : header file

//

#pragma once

#include "afxwin.h"

// CscreencaptureDlg dialog

class CscreencaptureDlg : public CDialog

{

// Construction

public:

CscreencaptureDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data

enum { IDD = IDD_SCREENCAPTURE_DIALOG };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

HICON m_hIcon;

// Generated message map functions

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

DECLARE_MESSAGE_MAP()

public:

NOTIFYICONDATA tray_icon;

CMenu menu;

afx_msg void OnActionExit();

afx_msg void OnActionHide();

LRESULT OnTrayIcon(WPARAM wp, LPARAM lp);

afx_msg void OnActionRestore();

CDC DC;

void GetScreen(void);

afx_msg void OnActionGetscreen();

BOOL SaveBitmap(LPCSTR FileName, HBITMAP hBitmap, HPALETTE hPal);

};

 

 

 

 

 

 

 

// stdafx.h : include file for standard system include files,

// or project specific include files that are used frequently,

// but are changed infrequently

#pragma once

#ifndef VC_EXTRALEAN

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#endif

// Modify the following defines if you have to target a platform prior to the ones specified below.

// Refer to MSDN for the latest info on corresponding values for different platforms.

#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.

#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.

#endif

#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.

#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.

#endif

#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.

#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.

#endif

#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.

#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.

#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit

// turns off MFC's hiding of some common and often safely ignored warning messages

#define _AFX_ALL_WARNINGS

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

 

 

 

 

 

0
 

Добавить комментарий


Защитный код
Обновить