#include
#include
#include
#include
#include
// Простая структура для хранения данных QR-кода
typedef struct {
int version;
int size;
unsigned char* data;
} QRCode;
// Функция для создания QR-кода (упрощенная реализация)
QRCode* create_qr_code(const char* text) {
if (!text || strlen(text) == 0) {
return NULL;
}
// В реальной реализации здесь должна быть библиотека генерации QR-кода
// Для примера создаем простой "заглушечный" QR-код
QRCode* qr = (QRCode*)malloc(sizeof(QRCode));
if (!qr) return NULL;
qr->version = 1;
qr->size = 21; // Размер QR-кода версии 1
// Выделяем память для данных (1 бит на модуль)
int data_size = (qr->size * qr->size + 7) / 8;
qr->data = (unsigned char*)malloc(data_size);
if (!qr->data) {
free(qr);
return NULL;
}
memset(qr->data, 0, data_size);
// Простой паттерн для демонстрации
for (int i = 0; i < qr->size; i++) {
for (int j = 0; j < qr->size; j++) {
if (i == 0 || i == qr->size - 1 || j == 0 || j == qr->size - 1 ||
(i + j) % 3 == 0) {
int bit_pos = i * qr->size + j;
qr->data[bit_pos / 8] |= (1 << (bit_pos % 8));
}
}
}
return qr;
}
// Функция для отрисовки QR-кода в окне
void draw_qr_code(HDC hdc, QRCode* qr, int x, int y, int scale) {
if (!qr || !qr->data) return;
HBRUSH black_brush = CreateSolidBrush(RGB(0, 0, 0));
HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
// Рисуем QR-код
for (int i = 0; i < qr->size; i++) {
for (int j = 0; j < qr->size; j++) {
int bit_pos = i * qr->size + j;
int is_black = qr->data[bit_pos / 8] & (1 << (bit_pos % 8));
HBRUSH brush = is_black ? black_brush : white_brush;
RECT rect = {
x + j * scale,
y + i * scale,
x + (j + 1) * scale,
y + (i + 1) * scale
};
FillRect(hdc, &rect, brush);
}
}
DeleteObject(black_brush);
DeleteObject(white_brush);
}
// Функция для сохранения QR-кода в BMP файл
BOOL save_qr_to_bmp(QRCode* qr, const char* filename, int scale) {
if (!qr || !filename) return FALSE;
int width = qr->size * scale;
int height = qr->size * scale;
// Создаем временный HDC для рисования
HDC hdc = GetDC(NULL);
HDC mem_dc = CreateCompatibleDC(hdc);
BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height; // Отрицательная высота для top-down DIB
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
void* bits;
HBITMAP hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
if (!hbitmap) {
DeleteDC(mem_dc);
ReleaseDC(NULL, hdc);
return FALSE;
}
SelectObject(mem_dc, hbitmap);
// Рисуем белый фон
RECT rect = {0, 0, width, height};
HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
FillRect(mem_dc, &rect, white_brush);
// Рисуем QR-код
draw_qr_code(mem_dc, qr, 0, 0, scale);
// Сохраняем в файл
BITMAPFILEHEADER bmfh = {0};
bmfh.bfType = 0x4D42; // "BM"
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + width * height * 3;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
FILE* file = fopen(filename, "wb");
if (!file) {
DeleteObject(hbitmap);
DeleteDC(mem_dc);
ReleaseDC(NULL, hdc);
DeleteObject(white_brush);
return FALSE;
}
fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, file);
fwrite(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
fwrite(bits, 1, width * height * 3, file);
fclose(file);
// Очистка ресурсов
DeleteObject(hbitmap);
DeleteDC(mem_dc);
ReleaseDC(NULL, hdc);
DeleteObject(white_brush);
return TRUE;
}
// Оконная процедура
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static QRCode* qr_code = NULL;
static char input_text[256] = "Hello, World!";
switch (msg) {
case WM_CREATE: {
// Создаем элементы управления
CreateWindow("EDIT", input_text, WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
10, 10, 200, 25, hwnd, (HMENU)1, NULL, NULL);
CreateWindow("BUTTON", "Generate QR", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
220, 10, 100, 25, hwnd, (HMENU)2, NULL, NULL);
CreateWindow("BUTTON", "Save as BMP", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
330, 10, 100, 25, hwnd, (HMENU)3, NULL, NULL);
// Создаем начальный QR-код
if (qr_code) {
free(qr_code->data);
free(qr_code);
}
qr_code = create_qr_code(input_text);
break;
}
case WM_COMMAND: {
if (LOWORD(wParam) == 2) { // Кнопка Generate
GetDlgItemText(hwnd, 1, input_text, sizeof(input_text));
if (qr_code) {
free(qr_code->data);
free(qr_code);
}
qr_code = create_qr_code(input_text);
InvalidateRect(hwnd, NULL, TRUE);
}
else if (LOWORD(wParam) == 3) { // Кнопка Save
if (qr_code) {
save_qr_to_bmp(qr_code, "qrcode.bmp", 10);
MessageBox(hwnd, "QR-код сохранен как 'qrcode.bmp'", "Сохранение", MB_OK);
}
}
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// Рисуем QR-код
if (qr_code) {
draw_qr_code(hdc, qr_code, 50, 50, 10);
}
EndPaint(hwnd, &ps);
break;
}
case WM_DESTROY: {
if (qr_code) {
free(qr_code->data);
free(qr_code);
}
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// Точка входа
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
const char CLASS_NAME[] = "QRCodeGenerator";
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hwnd = CreateWindow(
CLASS_NAME,
"QR Code Generator - C++/WinAPI",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 400,
NULL, NULL, hInstance, NULL
);
if (!hwnd) {
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}