Изобразить на экране детскую пирамидку - C (СИ)
Формулировка задачи:
Изобразить на экране детскую пирамидку из n разноцветных прямоугольников, размеры которых шаг за шагом уменьшаются на 10%.
Решение задачи: «Изобразить на экране детскую пирамидку»
textual
Листинг программы
#include <windows.h> #include <stdlib.h> #include <time.h> #define TIMER_FOR_SEC 10000 #define CLR 256; LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); int GetPerimetre(int, int); int SetEdge (int, int); int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd) { srand(time(0)); WNDCLASSEX wClass; ZeroMemory(&wClass,sizeof(WNDCLASSEX)); wClass.cbClsExtra=NULL; wClass.cbSize=sizeof(WNDCLASSEX); wClass.cbWndExtra=NULL; wClass.hbrBackground=(HBRUSH)COLOR_WINDOW; wClass.hCursor=LoadCursor(NULL,IDC_ARROW); wClass.hIcon=NULL; wClass.hIconSm=NULL; wClass.hInstance=hInst; wClass.lpfnWndProc=(WNDPROC)WinProc; wClass.lpszClassName="Window Class"; wClass.lpszMenuName=NULL; wClass.style=CS_HREDRAW|CS_VREDRAW; if(!RegisterClassEx(&wClass)) { int nResult=GetLastError(); MessageBox(NULL, "Window class creation failed\r\n", "Window Class Failed", MB_ICONERROR); } HWND hWnd=CreateWindowEx(NULL, "Window Class", "Windows application", WS_OVERLAPPEDWINDOW, 200, 200, 1000, 800, NULL, NULL, hInst, NULL); if(!hWnd) { int nResult=GetLastError(); MessageBox(NULL, "Window creation failed\r\n", "Window Creation Failed", MB_ICONERROR); } ShowWindow(hWnd,nShowCmd); MSG msg; ZeroMemory(&msg,sizeof(MSG)); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { static int n = 9; static int sx, sy; HDC hdc; RECT rct; HBRUSH rectangles [n]; GetClientRect(hWnd, &rct); switch(msg) { case WM_CREATE: { SetTimer(hWnd, TIMER_FOR_SEC, 400, NULL); break; } case WM_PAINT: { int i = 0, bottom = rct.bottom; for (i = 0; i < n; ++i) { int R = rand() % CLR; int G = rand() % CLR; int B = rand() % CLR; rectangles [i] = (HBRUSH)CreateSolidBrush(RGB( R, G, B )); } hdc = GetDC(hWnd); sy = (rct.bottom - rct.top) / n; sx = (rct.right - rct.left) - 100; for (i = 0; i < n; ++i) { int top = bottom - sy; int right = rct.right - ((rct.right - rct.left - sx) / 2); int left = rct.left + ((rct.right - rct.left - sx) / 2); int p; SelectObject(hdc, rectangles [i]); Rectangle(hdc, left, top, right, bottom); bottom -= sy; p = GetPerimetre(sx, sy); sx = SetEdge(p - (p / 10) , sy); } for (i = 0; i < n; ++i) { DeleteObject(rectangles [i]); } ReleaseDC(hWnd, hdc); break; } case WM_TIMER: { switch(wParam) { case TIMER_FOR_SEC: { SendMessage(hWnd, WM_PAINT, 0, 0); break; } break; } break; } case WM_DESTROY: { KillTimer(hWnd, TIMER_FOR_SEC); PostQuitMessage(0); } break; } return DefWindowProc(hWnd,msg,wParam,lParam); } int GetPerimetre(int width, int height) { return 2 * (width + height); } int SetEdge (int perimetre, int height) { return (perimetre - (height * 2)) / 2; }
Объяснение кода листинга программы
- Переменная
n
инициализируется значением 9. - Переменные
sx
иsy
инициализируются нулевыми значениями. - Создается массив
rectangles
изn
элементов, который будет хранитьHBRUSH
объекты. - Получается размер окна
rct
. - В случае
WM_CREATE
сообщения, устанавливается таймер, который будет вызыватьWM_PAINT
сообщение каждую секунду. - В случае
WM_PAINT
сообщения, происходит отрисовка пирамидки, состоящей изn
прямоугольников, каждый из которых имеет свой уникальный цвет. - Для каждого прямоугольника создается
HBRUSH
объект, который хранит его цвет. - Для отрисовки каждого прямоугольника используются функции
SelectObject
иRectangle
, которые принимают в качестве аргументовhdc
(дескриптор устройства),left
,top
,right
иbottom
(координаты прямоугольника), а такжеrectangles[i]
(дескриптор кисти). - После отрисовки всех прямоугольников, все
HBRUSH
объекты удаляются с помощью функцииDeleteObject
. - В случае
WM_TIMER
сообщения, проверяется его параметрwParam
. Если он равенTIMER_FOR_SEC
, то это вызываетWM_PAINT
сообщение. - В случае
WM_DESTROY
сообщения, останавливается таймер и отправляется сообщениеPostQuitMessage
, которое завершает работу программы. - Функция
GetPerimetre
принимает в качестве аргументов ширину и высоту прямоугольника и возвращает периметр этого прямоугольника, который вычисляется как двойная сумма ширины и высоты. - Функция
SetEdge
принимает в качестве аргументов периметр прямоугольника и его высоту. Вычитает из периметра значение, равное удвоенной высоте, и возвращает полученное значение, которое будет использоваться как ширина прямоугольника.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д