Загрузка данных


#define NOMINMAX // Обязательно ДО windows.h, чтобы убрать конфликт с max()
#include <iostream>
#include <cmath>
#include <windows.h>

using namespace std;

// Базовый класс
class Figure {
public:
    virtual void Show() const = 0;          // Вывод в консоль
    virtual void Draw(HDC hdc) const = 0;   // Отрисовка через GDI
    virtual ~Figure() {}
};

// Производный класс: Касающиеся окружности
class TouchingCircles : public Figure {
private:
    int x1, y1, r1;
    int x2, y2, r2;
    
    // Смещение для рисования в окне (чтобы фигура была по центру)
    const int offsetX = 300;
    const int offsetY = 300;

public:
    TouchingCircles(int x1, int y1, int r1, int x2, int y2, int r2)
        : x1(x1), y1(y1), r1(r1), x2(x2), y2(y2), r2(r2) {}

    // Реализация вывода в консоль
    void Show() const override {
        cout << "Окружность 1: центр (" << x1 << ", " << y1 << "), радиус " << r1 << endl;
        cout << "Окружность 2: центр (" << x2 << ", " << y2 << "), радиус " << r2 << endl;

        double dist = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
        if (abs(dist - (r1 + r2)) < 1e-6 || abs(dist - abs(r1 - r2)) < 1e-6) {
            cout << "Окружности касаются." << endl;
        } else {
            cout << "Окружности не касаются." << endl;
        }
    }

    // Реализация отрисовки через GDI
    void Draw(HDC hdc) const override {
        // Создаем кисти и перья
        HPEN hPen1 = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); // Красный для 1-й
        HPEN hPen2 = CreatePen(PS_SOLID, 3, RGB(0, 0, 255)); // Синий для 2-й
        HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);  // Прозрачная заливка

        // Сохраняем старые объекты
        HGDIOBJ oldPen = SelectObject(hdc, hPen1);
        HGDIOBJ oldBrush = SelectObject(hdc, hBrush);

        // Рисуем первую окружность
        Ellipse(hdc, x1 + offsetX - r1, y1 + offsetY - r1, x1 + offsetX + r1, y1 + offsetY + r1);

        // Меняем перо и рисуем вторую
        SelectObject(hdc, hPen2);
        Ellipse(hdc, x2 + offsetX - r2, y2 + offsetY - r2, x2 + offsetX + r2, y2 + offsetY + r2);

        // Восстанавливаем объекты и удаляем созданные
        SelectObject(hdc, oldPen);
        SelectObject(hdc, oldBrush);
        DeleteObject(hPen1);
        DeleteObject(hPen2);
    }
};

// Оконная процедура для обработки сообщений
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    static Figure* figure = nullptr;

    switch (uMsg) {
        case WM_CREATE:
            // Создаем фигуру при создании окна
            figure = new TouchingCircles(0, 0, 100, 200, 0, 100); // Внешнее касание
            break;

        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            if (figure) {
                figure->Draw(hdc); // Вызов GDI отрисовки
            }
            
            EndPaint(hwnd, &ps);
            break;
        }

        case WM_DESTROY:
            delete figure;
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int main() {
    setlocale(LC_ALL, "Russian");

    // 1. Вывод в консоль (полиморфный вызов)
    Figure* figure = new TouchingCircles(0, 0, 100, 200, 0, 100);
    figure->Show();
    
    cout << "\nНажмите Enter, чтобы открыть графическое окно..." << endl;
    cin.get();

    // 2. Создание окна для GDI
    HINSTANCE hInstance = GetModuleHandle(NULL);
    const wchar_t CLASS_NAME[] = L"GDI_Figure_Window";

    WNDCLASS wc = { };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // Белый фон
    RegisterClass(&wc);

    // Размеры окна (клиентская область 600x600)
    RECT rect = { 0, 0, 600, 600 };
    AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);

    HWND hwnd = CreateWindowEx(
        0, CLASS_NAME, L"GDI: Касающиеся окружности",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        rect.right - rect.left, rect.bottom - rect.top,
        NULL, NULL, hInstance, NULL
    );

    if (hwnd == NULL) {
        cout << "Ошибка создания окна!" << endl;
        delete figure;
        return 1;
    }

    ShowWindow(hwnd, SW_SHOW);

    // 3. Цикл сообщений
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    delete figure;
    return 0;
}