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


#include <windows.h>
#include <iostream>

// Базовый абстрактный класс
class Figure {
protected:
    int x, y;
public:
    Figure(int _x = 0, int _y = 0) : x(_x), y(_y) {
        std::cout << "Figure() constructor called\n";
    }
    virtual ~Figure() {
        std::cout << "~Figure() destructor called\n";
    }
    virtual void Draw(HDC hdc) = 0; // Чисто виртуальная функция отрисовки
};

// Простая фигура 1: Прямоугольник (Виртуальное наследование)
class Rectangle : virtual public Figure {
protected:
    int width, height;
public:
    Rectangle(int _x = 0, int _y = 0, int w = 100, int h = 100) 
        : Figure(_x, _y), width(w), height(h) {
        std::cout << "Rectangle() constructor called\n";
    }
    ~Rectangle() {
        std::cout << "~Rectangle() destructor called\n";
    }
    void Draw(HDC hdc) override {
        // Используем WinAPI функцию ::Rectangle
        ::Rectangle(hdc, x, y, x + width, y + height); 
    }
};

// Простая фигура 2: Соприкасающиеся окружности (Виртуальное наследование)
class TouchingCircles : virtual public Figure {
protected:
    int radius;
public:
    TouchingCircles(int _x = 0, int _y = 0, int r = 30) 
        : Figure(_x, _y), radius(r) {
        std::cout << "TouchingCircles() constructor called\n";
    }
    ~TouchingCircles() {
        std::cout << "~TouchingCircles() destructor called\n";
    }
    void Draw(HDC hdc) override {
        // Рисуем две окружности, соприкасающиеся в точке (x + radius, y)
        Ellipse(hdc, x, y - radius, x + 2 * radius, y + radius);
        Ellipse(hdc, x + 2 * radius, y - radius, x + 4 * radius, y + radius);
    }
};

// Составная фигура (Множественное наследование)
class CompositeFigure : public Rectangle, public TouchingCircles {
public:
    // Так как Figure - виртуальный базовый класс, его конструктор 
    // должен вызываться из самого производного класса (CompositeFigure)
    CompositeFigure(int _x, int _y, int w, int h, int r)
        : Figure(_x, _y), 
          Rectangle(_x, _y, w, h), 
          TouchingCircles(_x + w / 2 - r, _y + h / 2, r) {
        std::cout << "CompositeFigure() constructor called\n";
    }
    
    ~CompositeFigure() {
        std::cout << "~CompositeFigure() destructor called\n";
    }

    void Draw(HDC hdc) override {
        // Сначала рисуем прямоугольник
        Rectangle::Draw(hdc);
        // Затем рисуем окружности поверх него
        TouchingCircles::Draw(hdc);
    }
};

// Глобальный указатель на фигуру для использования в оконной процедуре
CompositeFigure* g_figure = nullptr;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE:
            // Создание объекта при создании окна
            g_figure = new CompositeFigure(100, 100, 300, 200, 40);
            break;
            
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            
            // Отрисовка фигуры
            if (g_figure) {
                g_figure->Draw(hdc);
            }
            
            EndPaint(hWnd, &ps);
            break;
        }
        
        case WM_DESTROY:
            // Удаление объекта при закрытии окна
            delete g_figure;
            PostQuitMessage(0);
            break;
            
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // Выделяем консоль для вывода порядка вызова конструкторов/деструкторов
    AllocConsole();
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "r", stdin);

    WNDCLASS wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "Lab4WindowClass";
    RegisterClass(&wc);

    HWND hwnd = CreateWindow("Lab4WindowClass", "Lab 4 - Variant 1.6 (OO)", 
                             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 
                             500, 400, NULL, NULL, hInstance, NULL);
    
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    FreeConsole();
    return msg.wParam;
}