Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h> // заголовочный файл, содержащий WINAPI
- inline int GetFilePointer(HANDLE FileHandle){
- return SetFilePointer(FileHandle, 0, 0, FILE_CURRENT);
- }
- bool SaveBMPFile(char *filename, HBITMAP bitmap, HDC bitmapDC, int width, int height){
- bool Success=0;
- HDC SurfDC=NULL;
- HBITMAP OffscrBmp=NULL;
- HDC OffscrDC=NULL;
- LPBITMAPINFO lpbi=NULL;
- LPVOID lpvBits=NULL;
- HANDLE BmpFile=INVALID_HANDLE_VALUE;
- BITMAPFILEHEADER bmfh;
- if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, width, height)) == NULL)
- return 0;
- if ((OffscrDC = CreateCompatibleDC(bitmapDC)) == NULL)
- return 0;
- HBITMAP OldBmp = (HBITMAP)SelectObject(OffscrDC, OffscrBmp);
- BitBlt(OffscrDC, 0, 0, width, height, bitmapDC, 0, 0, SRCCOPY);
- if ((lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)])) == NULL)
- return 0;
- ZeroMemory(&lpbi->bmiHeader, sizeof(BITMAPINFOHEADER));
- lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- SelectObject(OffscrDC, OldBmp);
- if (!GetDIBits(OffscrDC, OffscrBmp, 0, height, NULL, lpbi, DIB_RGB_COLORS))
- return 0;
- if ((lpvBits = new char[lpbi->bmiHeader.biSizeImage]) == NULL)
- return 0;
- if (!GetDIBits(OffscrDC, OffscrBmp, 0, height, lpvBits, lpbi, DIB_RGB_COLORS))
- return 0;
- if ((BmpFile = CreateFile((LPCWSTR)filename,
- GENERIC_WRITE,
- 0, NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL)) == INVALID_HANDLE_VALUE)
- return 0;
- DWORD Written;
- bmfh.bfType = 19778;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL))
- return 0;
- if (Written < sizeof(bmfh))
- return 0;
- if (!WriteFile(BmpFile, &lpbi->bmiHeader, sizeof(BITMAPINFOHEADER), &Written, NULL))
- return 0;
- if (Written < sizeof(BITMAPINFOHEADER))
- return 0;
- int PalEntries;
- if (lpbi->bmiHeader.biCompression == BI_BITFIELDS)
- PalEntries = 3;
- else PalEntries = (lpbi->bmiHeader.biBitCount <= 8) ?
- (int)(1 << lpbi->bmiHeader.biBitCount) : 0;
- if(lpbi->bmiHeader.biClrUsed)
- PalEntries = lpbi->bmiHeader.biClrUsed;
- if(PalEntries){
- if (!WriteFile(BmpFile, &lpbi->bmiColors, PalEntries * sizeof(RGBQUAD), &Written, NULL))
- return 0;
- if (Written < PalEntries * sizeof(RGBQUAD))
- return 0;
- }
- bmfh.bfOffBits = GetFilePointer(BmpFile);
- if (!WriteFile(BmpFile, lpvBits, lpbi->bmiHeader.biSizeImage, &Written, NULL))
- return 0;
- if (Written < lpbi->bmiHeader.biSizeImage)
- return 0;
- bmfh.bfSize = GetFilePointer(BmpFile);
- SetFilePointer(BmpFile, 0, 0, FILE_BEGIN);
- if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL)) {
- MessageBox(NULL, (LPCWSTR)"Запись картинки закончена", L"", MB_OK);
- return 0;
- }
- if (Written < sizeof(bmfh))
- return 0;
- return 1;
- }
- bool ScreenCapture(int x, int y, int width, int height, char *filename){
- HDC hDC = CreateCompatibleDC(0);
- HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), width, height);
- SelectObject(hDC, hBmp);
- BitBlt(hDC, 0, 0, width, height, GetDC(0), x, y, SRCCOPY); //GetDC(0)
- bool ret = SaveBMPFile(filename, hBmp, hDC, width, height);
- DeleteObject(hBmp);
- return ret;
- }
- // Прототип функции обработки сообщений с пользовательским названием:
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- TCHAR mainMessage[] = L"Какой то-текст!"; // строка с сообщением
- // Управляющая функция:
- int WINAPI WinMain(HINSTANCE hInst, // дескриптор экземпляра приложения
- HINSTANCE hPrevInst, // не используем
- LPSTR lpCmdLine, // не используем
- int nCmdShow) // режим отображения окошка
- {
- TCHAR szClassName[] = L"Мой класс"; // строка с именем класса
- HWND hMainWnd; // создаём дескриптор будущего окошка
- MSG msg; // создём экземпляр структуры MSG для обработки сообщений
- WNDCLASSEX wc; // создаём экземпляр, для обращения к членам класса WNDCLASSEX
- wc.cbSize = sizeof(wc); // размер структуры (в байтах)
- wc.style = CS_HREDRAW | CS_VREDRAW; // стиль класса окошка
- wc.lpfnWndProc = WndProc; // указатель на пользовательскую функцию
- wc.lpszMenuName = NULL; // указатель на имя меню (у нас его нет)
- wc.lpszClassName = szClassName; // указатель на имя класса
- wc.cbWndExtra = NULL; // число освобождаемых байтов в конце структуры
- wc.cbClsExtra = NULL; // число освобождаемых байтов при создании экземпляра приложения
- wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // декриптор пиктограммы
- wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // дескриптор маленькой пиктограммы (в трэе)
- wc.hCursor = LoadCursor(NULL, IDC_ARROW); // дескриптор курсора
- wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // дескриптор кисти для закраски фона окна
- wc.hInstance = hInst; // указатель на строку, содержащую имя меню, применяемого для класса
- if(!RegisterClassEx(&wc)){
- // в случае отсутствия регистрации класса:
- MessageBox(NULL, L"Не получилось зарегистрировать класс!", L"Ошибка", MB_OK);
- return NULL; // возвращаем, следовательно, выходим из WinMain
- }
- // Функция, создающая окошко:
- hMainWnd = CreateWindow(
- szClassName, // имя класса
- L"Для сохранения снимка щёлкните по снимку (в окне)", // имя окошка (то что сверху)
- WS_OVERLAPPEDWINDOW | WS_VSCROLL, // режимы отображения окошка
- CW_USEDEFAULT, // позиция окошка по оси х
- NULL, // позиция окошка по оси у (раз дефолт в х, то писать не нужно)
- CW_USEDEFAULT, // ширина окошка
- NULL, // высота окошка (раз дефолт в ширине, то писать не нужно)
- (HWND)NULL, // дескриптор родительского окна
- NULL, // дескриптор меню
- HINSTANCE(hInst), // дескриптор экземпляра приложения
- NULL); // ничего не передаём из WndProc
- if(!hMainWnd){
- // в случае некорректного создания окошка (неверные параметры и тп):
- MessageBox(NULL, L"Не получилось создать окно!", L"Ошибка", MB_OK);
- return NULL;
- }
- ShowWindow(hMainWnd, nCmdShow); // отображаем окошко
- UpdateWindow(hMainWnd); // обновляем окошко
- while(GetMessage(&msg, NULL, NULL, NULL)){ // извлекаем сообщения из очереди, посылаемые фу-циями, ОС
- TranslateMessage(&msg); // интерпретируем сообщения
- DispatchMessage(&msg); // передаём сообщения обратно ОС
- }
- return msg.wParam; // возвращаем код выхода из приложения
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
- HDC hDC, hDCMem, hDCold, hdcForSave; // создаём дескриптор ориентации текста на экране
- PAINTSTRUCT ps; // структура, сод-щая информацию о клиентской области (размеры, цвет и тп)
- RECT rect; // стр-ра, определяющая размер клиентской области
- COLORREF colorText = RGB(255, 0, 0); // задаём цвет текста
- HBITMAP hBmp, hMaska, hOldBitmap, bmpMem, bmpForSave;
- BITMAP bmInfo;
- HINSTANCE hInstance;
- BOOL sucess;
- OPENFILENAME ofn;
- static BOOL SetWindowPosRes = FALSE;
- switch(uMsg){
- case WM_CREATE:
- hDC = BeginPaint(hWnd, &ps);
- //HBITMAP hBmp;
- break;
- case WM_PAINT: {// если нужно нарисовать, то:
- GetClientRect(hWnd, &rect);
- hDC = BeginPaint(hWnd, &ps); // инициализируем контекст устройства
- if ( OpenClipboard(hWnd) )
- hBmp = (HBITMAP)GetClipboardData(CF_BITMAP);
- if (hBmp == NULL)
- {
- MessageBox(NULL, L"Error", L" ", MB_OK);
- CloseClipboard();
- PostQuitMessage(NULL);
- }
- hDCMem = CreateCompatibleDC(hDC);
- hOldBitmap = (HBITMAP) SelectObject(hDCMem, hBmp);
- GetObject(hBmp, sizeof(bmInfo), &bmInfo);
- bmpMem = CreateCompatibleBitmap (hDC, bmInfo.bmWidth-16, bmInfo.bmHeight-38);
- BitBlt(hDC, 0, 0, bmInfo.bmWidth-16, bmInfo.bmHeight-38, hDCMem, 8, 30, SRCCOPY); //Оставлю этот идеальный код потомкам
- if (SetWindowPosRes == FALSE)
- {
- SetWindowPos(hWnd, (HWND)NULL, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, SWP_NOMOVE);
- SetWindowPosRes = TRUE;
- }
- CloseClipboard();
- DeleteDC(hDCMem);
- EndPaint(hWnd, &ps); // заканчиваем рисовать
- break;
- }
- case WM_LBUTTONDOWN: {
- char szFileName[MAX_PATH] = "";
- ZeroMemory(&ofn, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = NULL;
- ofn.lpstrFilter = (LPCWSTR)L"Text Files (*.bmp)\0*.bmp\0All Files (*.*)\0*.*\0";
- ofn.lpstrFile = (LPWSTR)szFileName;
- ofn.nMaxFile = MAX_PATH;
- ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
- ofn.lpstrDefExt = (LPCWSTR)L"bmp";
- GetSaveFileName(&ofn);
- //SAVE FUNCTION
- GetClientRect(hWnd, &rect);
- Sleep(1000);
- if(ScreenCapture(rect.right-rect.left, rect.bottom-rect.top, rect.right, rect.bottom, szFileName))
- PostQuitMessage(NULL);
- break;
- }
- case WM_DESTROY: // если окошко закрылось, то:
- PostQuitMessage(NULL); // отправляем WinMain() сообщение WM_QUIT
- break;
- default:
- return DefWindowProc(hWnd, uMsg, wParam, lParam); // если закрыли окошко
- }
- return NULL; // возвращаем значение
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement