Вы находитесь на странице: 1из 6

МИНОБРНАУКИ РОССИИ

Федеральное государственное бюджетное образовательное учреждение


высшего образования
"МИРЭА - Российский технологический университет"
РТУ МИРЭА

Институт информационных технологий (ИТ)


Кафедра инструментального и прикладного программного обеспечения
(ИиППО)

ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ № 5

по дисциплине
«Системное программное обеспечение»

Выполнил студент группы ИКБО-01-17 Ананьев Ф.А.

Принял ассистент Алпатов А.Н.

Работа выполнена «___» ________ 2020 г.

«Зачтено» «___» ________ 2020 г.

Москва 2020
Цель работы: получение практических навыков по использованию
Win32 API для исследования памяти Windows.
Задание:
Разработать программу, которая выдает информацию, получаемую
при использовании API GlobalMemoryStatus (при выводе информации
использовать диаграммы).
Ход работы
Для исследования памяти системы, разработаем программу с
графическим интерфейсом на основе функций Windows GDI.
Функция GlobalMemoryStatusEx возвращает структуру типа
MEMORYSTATUSEX. В ней содержатся (согласно документации):
 Длина структуры;
 Загруженность памяти в процентах;
 Общий и доступный объемы физической памяти в байтах;
 Размер максимального файла подкачки в байтах, и максимальный
его объем для текущего процесса.
 Общий и доступный объемы виртуальной памяти в байтах для
вызываемого процесса.
Для отображения результатов вызова этой функции создадим в теле
программы окна таймер, который в результате обработки сообщения
WM_TIMER будет инициализировать перерисовку содержимого окна с
помощью функции InvalidateRect(), вызывающей сообщение WM_PAINT.
В теле обработки сообщения WM_PAINT начинаем отрисовку
BeginPaint, получаем необходимый контекст и передаем его функции
DrawStatus(), в теле которой вызывается GlobalMemoryStatusEx,
обрабатываются полученные данные и выводятся в виде текстовых
заголовков и диаграмм.
Для обрисовку диаграммы также создадим функцию DrawPie(), где
отрисовываем линии, AngleArc в зависимости от заданного угла, и заливаем
полученную фигуру.
2
Исходный код программы:
#include <windows.h>
#include <string.h>
#include <stdio.h>
#define TO_MB 1048576

LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);


char szWinName[] = "MyWin";
char str[255] = "";

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs,


int nWinMode){
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;
wcl.hInstance = hThisInst;
wcl.lpszClassName = szWinName;
wcl.lpfnWndProc = WindowFunc;
wcl.style = 0;
wcl.cbSize = sizeof(WNDCLASSEX);

wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);


wcl.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

wcl.hCursor = LoadCursor(NULL, IDC_ARROW);


wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH)GetStockObject(HOLLOW_BRUSH);

if (!RegisterClassEx(&wcl))
return 0;

hwnd = CreateWindow(
szWinName,
"Memory usage",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hThisInst,
NULL
);

ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);
SetTimer(hwnd, 1, 3000, NULL);

while (GetMessage(&msg, NULL, 0,0)){


TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
} // WinMain

3
void DrawPie(HDC hdc, int nX, int nY, DWORD dwRadius, float xSweepAngle) {
float xStartAngle = 0;
BeginPath(hdc);
SelectObject(hdc, GetStockObject(GRAY_BRUSH));
MoveToEx(hdc, nX, nY, (LPPOINT) NULL);
AngleArc(hdc, nX, nY, dwRadius, xStartAngle, xSweepAngle);
LineTo(hdc, nX, nY);
EndPath(hdc);
StrokeAndFillPath(hdc);
}

void DrawStatus(HDC hdc) {


MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx(&statex);
float angle;

char mem[19];
sprintf(mem, "Memory usage: %ld%%", statex.dwMemoryLoad);
TextOut(hdc, 20, 0,mem, sizeof(mem));
DrawPie(hdc, 100, 150, 70, statex.dwMemoryLoad*3.6);

int availph = statex.ullAvailPhys/TO_MB;


int totalph = statex.ullTotalPhys/TO_MB;
angle = 360*(totalph - availph)/totalph;
char phys[10];
sprintf(phys, "%ld/%ld", totalph, availph);
TextOut(hdc, 220, 0, "Total/avaliable phys mem (MB):",31);
TextOut(hdc, 220, 20, phys, sizeof(phys));
DrawPie(hdc, 320, 150, 70, angle);

int availpag = statex.ullAvailPageFile/TO_MB;


int totalpag = statex.ullTotalPageFile/TO_MB;
char paging[10];
sprintf(paging, "%ld/%ld", totalpag, availpag);
angle = 360*(totalpag - availpag)/totalpag;
TextOut(hdc, 470, 0, "Total/avaliable phys paging file (MB):",39);
TextOut(hdc, 470, 20, paging, sizeof(paging));
DrawPie(hdc, 570, 150, 70, angle);

int availv = statex.ullAvailVirtual/TO_MB;


int totalv = statex.ullTotalVirtual/TO_MB;
char virtual[10];
sprintf(virtual, "%ld/%ld", totalv, availv);
angle = 360*(totalv - availv)/totalv;
TextOut(hdc, 750, 0, "Total/avaliable virtual mem (MB):",34);
TextOut(hdc, 750, 20, virtual, sizeof(virtual));
DrawPie(hdc, 850, 150, 70, angle);
}

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM


lParam){
PAINTSTRUCT ps;
RECT Rect;
HDC hdc, hCmpDC;
HBITMAP hBmp;

switch (message){
case WM_LBUTTONDOWN:
KillTimer(hwnd,1);
break;
case WM_DESTROY:

4
PostQuitMessage(0);
KillTimer(hwnd,1);
break;
case WM_PAINT:
GetClientRect(hwnd, &Rect);
hdc = BeginPaint(hwnd, &ps);

hCmpDC = CreateCompatibleDC(hdc);
hBmp = CreateCompatibleBitmap(hdc, Rect.right - Rect.left,
Rect.bottom - Rect.top);
SelectObject(hCmpDC, hBmp);

LOGBRUSH br;
br.lbStyle = BS_SOLID;
br.lbColor = 0xEECCEE;
HBRUSH brush;
brush = CreateBrushIndirect(&br);
FillRect(hCmpDC, &Rect, brush);
DeleteObject(brush);

DrawStatus(hCmpDC);

SetStretchBltMode(hdc, COLORONCOLOR);
BitBlt(hdc, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top,
hCmpDC, 0, 0, SRCCOPY);

DeleteDC(hCmpDC);
DeleteObject(hBmp);
hCmpDC = NULL;

EndPaint(hwnd, &ps);
break;

case WM_TIMER:
InvalidateRect(hwnd, NULL, FALSE);
break;
default:
return DefWindowProc(hwnd, message, wParam,lParam);
}
return 0;
}

Комплируем программу средствами MinGW, подключив библиотеку


lgdi32. В результате выполнения программы открывается окно с 4
диаграммами: общей используемой памяти, используемой физической
памяти, используемой памяти файла подкачки и используемой виртуальной
памяти, а также текстовые подписи к ним. Информация об используемой
памяти обновляется раз в 3 секунды и может быть остановлена нажатием
левой кнопки мыши. На рисунке 1 изображен интерфейс программы.

5
Рисунок 1 – готовая программа отслеживания использования памяти
Вывод: в результате выполнения лабораторной работы получены
практические навыки исследования памяти Windows средствами Win32 API,
разработана программа с графическим интерфейсом, позволяющая в
реальном времени раз в 3 секунды получать информацию об использовании
памяти.