Форум программистов, компьютерный форум, киберфорум
Бета-тестирование
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10

Простой класс для сохранения снимков окна (C++)

16.01.2015, 19:56. Показов 1603. Ответов 0

Студворк — интернет-сервис помощи студентам
Это простой класс для создания снимков окна и сохранения их в формат BMP при нажатии кнопки PrintScreen.
Для простоты подключения он описан в одном заголовочном файле.
Проверка маловероятных ошибок отсутствует.
Сам класс:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#ifndef __WINDOW_SHOT_H__
#define __WINDOW_SHOT_H__
 
class window_shot {
 
    // Идентификатор окна для Subclassing
    // Так же служит признаком успешной инициализации класса
    HWND m_wnd;
 
    // делать снимок всего окна или только клиентской области
    BOOL m_shot_full_window;
 
    void shot( HWND hWnd ) const {
        HDC hDC;
        RECT rc;
 
        // снимок всего окна, или только клиентской области?
        if ( m_shot_full_window ) {
            GetWindowRect( hWnd, &rc );
            hDC = GetWindowDC( hWnd );
        } else {
            GetClientRect( hWnd, &rc );
            hDC = GetDC( hWnd );
        }
 
        // получаем имя окна
        char caption[64];
        GetWindowText( hWnd, caption, 63 );
 
        // если окно без имени, задаём префикс файла по умолчанию
        if ( caption[0] == '\0' ) {
            strcpy( caption, "shot" );
        }
 
        // ищем первое свободное имя файла
        char filename[80];
        for ( int file_index = 0; file_index < 10000; ++file_index ) {
 
            //sprintf_s( filename, 80, "%s - %04d.bmp", caption, file_index );
            sprintf( filename, "%s - %04d.bmp", caption, file_index );
 
            // имя файла свободно?
            if ( GetFileAttributes( filename ) == INVALID_FILE_ATTRIBUTES ) break;
        }
 
        // раземры изображения
        LONG lWidth = rc.right - rc.left;
        LONG lHeight = rc.bottom - rc.top;
        DWORD dwSize = lHeight * (lWidth << 2); // размер в байтах
 
        BITMAPINFO bi = { { sizeof( BITMAPINFOHEADER ), lWidth, lHeight, 1, 32, BI_RGB, dwSize, 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
 
        HDC hDCmem = CreateCompatibleDC( hDC );
        HBITMAP hBMP = CreateCompatibleBitmap( hDC, lWidth, lHeight );
        SelectObject( hDCmem, hBMP );
        BitBlt( hDCmem, 0, 0, lWidth, lHeight, hDC, 0, 0, SRCCOPY );
 
        char * p_image = new char [lWidth * lHeight * 4];
 
        GetDIBits( hDC, hBMP, 0, lHeight, p_image, &bi, DIB_RGB_COLORS );
 
        DWORD dwHdrSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
        BITMAPFILEHEADER bfh = { ('M' << 8) | 'B', dwHdrSize + dwSize, 0, 0, dwHdrSize };
 
        // запись изображения
        HANDLE hFile = CreateFile( filename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
        if ( hFile != INVALID_HANDLE_VALUE ) {
            DWORD dwWritten;
            WriteFile( hFile, &bfh, sizeof( bfh ), &dwWritten, NULL );
            WriteFile( hFile, &bi.bmiHeader, sizeof( bi.bmiHeader ), &dwWritten, NULL );
            WriteFile( hFile, p_image, dwSize, &dwWritten, NULL );
            CloseHandle( hFile );
        }
        delete [] p_image;
 
        DeleteObject( hBMP );
        DeleteDC( hDCmem );
        ReleaseDC( hWnd, hDC );
    }
 
    static LRESULT CALLBACK subclassproc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR dwRefData ) {
        // VK_SNAPSHOT не посылается через WM_KEYDOWN
        if ( uMsg == WM_KEYUP && wParam == VK_SNAPSHOT ) {
            ((window_shot *)dwRefData)->shot( hWnd );
        }
        return DefSubclassProc( hWnd, uMsg, wParam, lParam );
    }
 
public:
    explicit window_shot( HWND hWnd, BOOL bShotFullWindow = TRUE ) : m_wnd( hWnd ), m_shot_full_window( bShotFullWindow ) {
        // Обрабатывать нажатие клавиши 'Print Screen' будем через Subclassing
        if ( !SetWindowSubclass( m_wnd, subclassproc, 0, (DWORD_PTR)this ) ) {
            m_wnd = NULL;
        }
    }
 
    virtual ~window_shot() {
        if ( m_wnd ) {
            RemoveWindowSubclass( m_wnd, subclassproc, 0 );
        }
    }
};
 
#endif // __WINDOW_SHOT_H__

Пример использования:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <windows.h>
#include <commctrl.h>
#include <cstdio>
 
#include "window_shot.h"
 
static LRESULT CALLBACK wnd_proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
    switch ( uMsg ) {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }
    return 0;
}
 
int main()
{
    WNDCLASS wc;
    ZeroMemory( &wc, sizeof( WNDCLASS ) );
    wc.lpfnWndProc      = wnd_proc;
    wc.hInstance        = GetModuleHandle( NULL );
    wc.lpszClassName    = "test32cls";
    wc.hCursor          = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground    = (HBRUSH)(COLOR_BTNFACE + 1);
    RegisterClass( &wc );
 
    HWND hWnd = CreateWindow( "test32cls", "Test Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 300, 200, NULL, NULL, wc.hInstance, NULL );
 
    window_shot shooter( hWnd );
 
    MSG msg;
    while ( GetMessage( &msg, NULL, 0, 0 ) ) {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    return 0;
}

В зависимостях - библиотека comctl32.dll
Вложения
Тип файла: 7z window_shot.7z (2.0 Кб, 21 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.01.2015, 19:56
Ответы с готовыми решениями:

Предлагаю людям класс для написания специфических снимков системы
Задачи, преследуемые этим классом минимальные, но тем не менее. Делать снимки системы привязываясь к одному какому-нибудь процессу...

ПО разработанное производителем камеры не предусматривает фонового сохранения полученных снимков
1. ПО разработанное производителем камеры не предусматривает фонового сохранения полученных снимков, т.е. требуется непосредственное...

Простой скрипт для сохранения писем Outlook
Здравствуйте. Прочитал все подобные темы на форуме и ничего не нашел. Нужен самый простой скрипт, который берет письма из определенной...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.01.2015, 19:56
Помогаю со студенческими работами здесь

Простой код для сохранения Вложения на локальный/сетевой диск
Здравствуйте. У меня есть таблица в Access. У каждой записи есть поля с вложениями (Поле1). Мне необходимо, чтобы при нажатии на кнопку,...

Диалоговые окна для создания,сохранения
Здравствуйте. У меня такая проблема. Есть кнопка. При нажатии на неё, нужно, чтобы появилось диалоговое окно для выбора файла .txt ,чтобы...

Отсутствие диалогового окна для сохранения файла типа XML в IE8
привет! сделал скромненький веб-сайт на asp.net. веб-сайт позволяет выбрать файл типа XML (т.е. пользователь выбирает в соответ-м...

объединение кнопки для сохранения в базу данных и вызов модального окна
Здравствуйте, суть проблемы отразил в заголовке &quot;объединение кнопки для сохранения в базу данных и вызов модального окна&quot; нужно...

CDocument::OnSaveDocument указать фильтр для диалогового окна сохранения файла
Добрый день Создал класс наследуемый от CDocument и в нем переопределяется виртуальная функция OnSaveDocument. Пробовал трассировать, она...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru