Создание скринсшота в Borland C++ Builder 6 по нажатию Button1 без использования PrtScr и обращения к буферу обмена

Гобелен - кликните для возврата на главную

Не прошло и месяца а Фурмановская ЦРБ в очередной раз попала в историю. На этот раз сотрудница клеветала на пациентов, а именно огласку получил случай когда сотрудница назвала пациента алкашём.

Ровно 3 года назад произошло событие, которое подарило жителям планеты Змеля новый чистый праздник 6 апреля - в этот замечательный день земля забрала гнить негодяя и СПАМера Жладимира Вольфовича Жириновского.

Как бы не обстояли дела в области культуры и IT-технологий, Самосвал писал статьи на связанные темы и планирует ещё написать.

Начал разбираться с информацией которая находится в HTTPS клиентском запросе рукопожатия.

Обратите внимание! Объект изображённый на гобилене может отличаться от общепринятого вида описанного объекта. Тут дело в том что художник видит именно так!

104 549 руб.

Описание товара


Ссылка на видео на видеохостинге YouTube: https://www.youtube.com/watch?v=rxI-Aqi6KRI

Файл Unit1.h

C++
    
#ifndef Unit1H
#define Unit1H
      
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>  // Для TImage
      
class TForm1 : public TForm
{
__published:
    TButton *Button1;
    TImage *Image1;  // Компонент для предпросмотра
    void __fastcall Button1Click(TObject *Sender);
      
private:
    void CaptureToImage(TImage *img);  // Захват экрана в TImage
    bool SaveImageToFile(TImage *img, const AnsiString &filename);  // Сохранение из TImage
public:
    __fastcall TForm1(TComponent* Owner);
};
      
extern PACKAGE TForm1 *Form1;
      
#endif

  

Файл Unit1.cpp

C++
    
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
      
#include "Unit1.h"
      
#pragma package(smart_init)
#pragma resource "*.dfm"
      
TForm1 *Form1;
      
// Захват экрана и вывод в TImage
void TForm1::CaptureToImage(TImage *img)
{
    HDC hScreenDC = GetDC(0);
    HDC hMemDC = CreateCompatibleDC(hScreenDC);
      
    int screenW = GetDeviceCaps(hScreenDC, HORZRES);
    int screenH = GetDeviceCaps(hScreenDC, VERTRES);
      
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, screenW, screenH);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
      
    // Копируем экран в битмап
    BitBlt(hMemDC, 0, 0, screenW, screenH, hScreenDC, 0, 0, SRCCOPY);
      
    // Выводим в TImage
    img->Picture->Bitmap->Handle = hBitmap;
    img->Width = screenW;
    img->Height = screenH;
      
    // Убираем выделение и освобождаем ресурсы
    SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hMemDC);
    ReleaseDC(0, hScreenDC);
}
      
// Сохранение TImage в BMP-файл
bool TForm1::SaveImageToFile(TImage *img, const AnsiString &filename)
{
    if (!img->Picture->Bitmap->Empty)
    {
        img->Picture->Bitmap->SaveToFile(filename);
        return true;
    }
    return false;
}
      
// Обработчик кнопки
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // Захватываем экран и выводим в Image1
    CaptureToImage(Image1);
      
    // Сохраняем в файл
    AnsiString path = "C:/yy/screenshot.bmp";
    if (SaveImageToFile(Image1, path))
    {
        ShowMessage("Скриншот сохранён в " + path);
    }
    else
    {
        ShowMessage("Ошибка сохранения!");
    }
}
      
// Конструктор формы
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}

  

Вариант с отправкой скринсшота на сервер по HTTP методом POST

Отлично. Работает. Теперь задача следующая. Требуется послать файл изображения на сайт blog.ivru.net/10-11/form11.php методом POST по HTTP(не HTTPS) для отправки файла требуется использовать WinSock. Нельзя использовать какие либо библиотеки, заголовки требуется задать самостоятельно(включая длину контента если она нужна). Файл должен отправляться в POST именно как файл а не просто данные формы, так как если бы он отправлялся с HTML формы из input с именем screen. Других данных на форму передавать не требуется(то-есть предположим что input с файлом скринсшота единственный на форме) Не требуется производить отправку в потоках(поскольку это учебный проект а не prodaction, то-есть оптимальность не нужна). В остальном форма проекта такая же. То есть кнопка для создания скринсшота и отправки, пусть всё так же скринсшот попадает в TImage.

Файл Unit1.h

C++
    
#ifndef Unit1H
#define Unit1H
      
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <winsock2.h>  // WinSock 2
      
class TForm1 : public TForm
{
__published:
    TButton *Button1;
    TImage *Image1;
    void __fastcall Button1Click(TObject *Sender);
      
private:
    void CaptureToImage(TImage *img);
    bool SaveImageToFile(TImage *img, const AnsiString &filename);
    bool SendFileToServer(const AnsiString &filename);
    AnsiString GenerateBoundary();
    AnsiString GetFileContents(const AnsiString &filename);
      
public:
    __fastcall TForm1(TComponent* Owner);
};
      
extern PACKAGE TForm1 *Form1;
      
#endif

  

Файл Unit1.cpp

C++
    
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
      
#include "Unit1.h"
#include <stdio.h>
      
#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma comment(lib, "ws2_32.lib")  // Автоподключение библиотеки
      
TForm1 *Form1;
      
// Генерация границы для multipart/form-data
AnsiString TForm1::GenerateBoundary()
{
    return "---------------------------" + IntToStr(rand()) + IntToStr(rand()) + IntToStr(rand());
}
      
// Чтение файла в строку
AnsiString TForm1::GetFileContents(const AnsiString &filename)
{
    TFileStream *fs = new TFileStream(filename, fmOpenRead);
    AnsiString result;
    try {
        result.SetLength(fs->Size);
        fs->Read(result.c_str(), fs->Size);
    }
    __finally {
        delete fs;
    }
    return result;
}
      
// Отправка файла на сервер
bool TForm1::SendFileToServer(const AnsiString &filename)
{
    WSADATA wsaData;
    SOCKET sock;
    struct sockaddr_in server;
    char buffer[1024];
    int bytesSent;
    bool result = false;
      
    // Инициализация WinSock
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        ShowMessage("WSAStartup failed");
        return false;
    }
      
    // Создание сокета
    if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
        ShowMessage("Socket creation failed");
        WSACleanup();
        return false;
    }
      
    // Настройка сервера
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("149.154.68.56");  // IP blog.ivru.net
    server.sin_port = htons(80);
      
    // Подключение
    if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
        ShowMessage("Connection failed: " + AnsiString(WSAGetLastError()));
        closesocket(sock);
        WSACleanup();
        return false;
    }
      
    // Подготовка данных
    AnsiString boundary = GenerateBoundary();
    AnsiString fileContent = GetFileContents(filename);
      
    // Формирование запроса
    AnsiString requestHeader = 
        "POST /10-11/formx.php HTTP/1.1\r\n"
        "Host: blog.ivru.net\r\n"
        "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n"
        "Connection: close\r\n";
      
    AnsiString requestBody =
        "--" + boundary + "\r\n"
        "Content-Disposition: form-data; name=\"screen\"; filename=\"screenshot.bmp\"\r\n"
        "Content-Type: application/octet-stream\r\n\r\n" +
        fileContent + "\r\n" +
        "--" + boundary + "--\r\n";
      
    requestHeader += "Content-Length: " + IntToStr(requestBody.Length()) + "\r\n\r\n";
    AnsiString fullRequest = requestHeader + requestBody;
      
    // Отправка
    bytesSent = send(sock, fullRequest.c_str(), fullRequest.Length(), 0);
    if (bytesSent == SOCKET_ERROR) {
        ShowMessage("Send failed");
    } else {
        // Получение ответа
        AnsiString response;
        while ((bytesSent = recv(sock, buffer, sizeof(buffer), 0)) > 0) {
            response += AnsiString(buffer).SubString(1, bytesSent);
        }
        ShowMessage("Server response:\n" + response.SubString(1, 500));
        result = true;
    }
      
    closesocket(sock);
    WSACleanup();
    return result;
}
      
// Захват экрана
void TForm1::CaptureToImage(TImage *img)
{
    HDC hScreenDC = GetDC(0);
    HDC hMemDC = CreateCompatibleDC(hScreenDC);
    int screenW = GetDeviceCaps(hScreenDC, HORZRES);
    int screenH = GetDeviceCaps(hScreenDC, VERTRES);
      
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, screenW, screenH);
    SelectObject(hMemDC, hBitmap);
    BitBlt(hMemDC, 0, 0, screenW, screenH, hScreenDC, 0, 0, SRCCOPY);
      
    img->Picture->Bitmap->Handle = hBitmap;
    DeleteDC(hMemDC);
    ReleaseDC(0, hScreenDC);
}
      
// Сохранение в файл
bool TForm1::SaveImageToFile(TImage *img, const AnsiString &filename)
{
    if (!img->Picture->Bitmap->Empty) {
        img->Picture->Bitmap->SaveToFile(filename);
        return true;
    }
    return false;
}
      
// Обработчик кнопки
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    CaptureToImage(Image1);
    AnsiString tempFile = "C:\\temp_scr.bmp";
    
    if (SaveImageToFile(Image1, tempFile)) {
        if (SendFileToServer(tempFile)) {
            ShowMessage("Success!");
        }
        DeleteFile(tempFile.c_str());
    } else {
        ShowMessage("Save failed");
    }
}
      
// Конструктор
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
    srand(GetTickCount());
}

  

Другие товары

Вы так же можете прочитать следующие статьи: