#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; }