Гобелен - кликните для возврата на главную
Не прошло и месяца а Фурмановская ЦРБ в очередной раз попала в историю. На этот раз сотрудница клеветала на пациентов, а именно огласку получил случай когда сотрудница назвала пациента алкашём.
Ровно 3 года назад произошло событие, которое подарило жителям планеты Змеля новый чистый праздник 6 апреля - в этот замечательный день земля забрала гнить негодяя и СПАМера Жладимира Вольфовича Жириновского.
Как бы не обстояли дела в области культуры и IT-технологий, Самосвал писал статьи на связанные темы и планирует ещё написать.
Начал разбираться с информацией которая находится в HTTPS клиентском запросе рукопожатия.
Обратите внимание! Объект изображённый на гобилене может отличаться от общепринятого вида описанного объекта. Тут дело в том что художник видит именно так!
Ссылка на видео на видеохостинге YouTube: https://www.youtube.com/watch?v=rxI-Aqi6KRI
Файл Unit1.h
#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
#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)
{
}
Отлично. Работает. Теперь задача следующая. Требуется послать файл изображения на сайт blog.ivru.net/10-11/form11.php методом POST по HTTP(не HTTPS) для отправки файла требуется использовать WinSock. Нельзя использовать какие либо библиотеки, заголовки требуется задать самостоятельно(включая длину контента если она нужна). Файл должен отправляться в POST именно как файл а не просто данные формы, так как если бы он отправлялся с HTML формы из input с именем screen. Других данных на форму передавать не требуется(то-есть предположим что input с файлом скринсшота единственный на форме) Не требуется производить отправку в потоках(поскольку это учебный проект а не prodaction, то-есть оптимальность не нужна). В остальном форма проекта такая же. То есть кнопка для создания скринсшота и отправки, пусть всё так же скринсшот попадает в TImage.
Файл Unit1.h
#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
#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());
}
Вы так же можете прочитать следующие статьи: