Колір фону вікна визначається дескриптором кисті, записаним в структуру WNDCLASS. В принципі кисті можна надати будь-який колір, але найпростіше користуватися однією з вбудованих кистей, що зберігаються на "складі" windows. Для отримання вбудованої кисті слід скористатися макросом getStockBrash(), в якості єдиного аргументу якого вказується константа, що характеризує колір кисті. Можливі значення констант (їх дуже небагато).
Для створення кисті служить функція CreateSolidBrush(), в якості єдиного параметра якій вказується необхідний колір у вигляді трьох чисел, який характеризує інтенсивність червоною, зеленою і синій складових кольору. Для упаковки цих трьох чисел в одне 4-байтовий слово і перетворення отриманого значення в тип COLORREF, необхідний функцією CreateSolidBrush, служить макрос RGB().
Стиль є ціле число (32 біта), окремі біти якого закріплені за тими чи іншими загальними характеристиками всіх вікон, які належать класу, який зареєстрований; кожному біту відповідає своя символічна константа. Так, установка біта 3 дозволяє програмі реагувати на подвійні клацання мишею в області вікна; установка бітів 0 і змушує Windows перемальовувати вікно заново при кожній зміні його розмірів по горизонталі і вертикалі; установка біта 9 забороняє закриття вікна користувачем і т.д.
Функція RegisterClass() вимагає в якості аргументу адресу структурної змінної типу WNDCLASS.
Зареєструвавши клас вікна, можна приступити до його створення і виведення на Робочий стіл.
Створення і показ вікна
Для створення вікна, зокрема головного вікна програми, використовується функція Windows CreateWindow(), прототип якої можна знайти в інтерактивному довіднику.
Істотними елементами прототипу є порядок і типи параметрів; вказівка в довіднику та необов'язкову рекомендацію. У програмі строка з ім’ям класу вікна названа szClassName, рядок із заголовком вікна - szTitle, а в якості параметрів використані символічні або числові константи.
Перший параметр IpClassName - адреса рядка з ім'ям реєстрованого класу вікна. Передача функції CreateWindow() імені класу дозволяє використовувати при створенні вікна ті загальні характеристики вікна, які були визначені в структурі WNDCLASS, наприклад форму курсора і колір фону. Викликаючи функцію CreateWindow() багаторазово, можна створити багато вікон даного класу, що розрізняються, наприклад, розмірами і розташуванням на екрані.
Параметр IpWindowName визначає адресу рядки з заголовком, який з'явиться у верхній частині вікна.
Параметр dwStyle визначає стиль вікна. За допомогою стилю задаються такі характеристики вікна, як вид навколишнього його рамки, наявність або відсутність рядка заголовка і цілий ряд інших. Стиль є ціле число (32 біта), окремі біти якого закріплені за тими чи іншими елементами оформлення або властивостями вікна; кожному біту відповідає своя символічна константа. Так, установка біта 18 надає вікну товсту рамку; установка біта 19 постачає вікно системним меню; біт 21 відповідає за появу лінійки вертикальної прокрутки і т.д. операція побітового АБО (знак |) дозволяє "набрати" необхідний комплект властивостей.
Зазвичай головне вікно описується константою WS_OVERLAPPEDWINDOW. Якщо потрібно створити головне вікно з меншою кількістю елементів, весь необхідний набір можна вказати явним чином.
З іншого боку, скориставшись операторами побітових операцій І (&) і НЕ (~), можна не набирати заново всю комбінацію констант, а просто виключити НЕ-потрібний елемент WS_MAXHMlZEBOX з повного набору:OVERLAPPEDWINDOW & -WS MAXIMIZEBOX
Наступні 4 параметри визначають х- і у-координати лівого верхнього кута вікна відносно початку Робочого столу і розміри вікна по горизонталі і вертикалі (в пік-селах).
Як параметр hWndParent вказується дескриптор батьківського вікна. Для головного вікна, у якого немає батька, використовується константа HWND_ DESKTOP.
Параметр hMenu дозволяє задати меню вікна. Якщо меню немає (як у нашому випадку) або використовується меню класу, задане в структурі WNDCLASS, цей параметр повинен бути рівний нулю (MULL).
Параметр hlnstance ідентифікує екземпляр додатку. Значення дескриптора додатки було отримано нами через параметр hlnst функції WinMainQ. програма winmain файл алгоритм
Останній параметр IpParam є адресою додаткових даних, які зазвичай не потрібні.
Символічне позначення NULL (нуль-покажчик) використовується в тих випадках, коли для деякої функції треба вказати нульове значення параметра.
Функція CreateWindow () при успішному виконанні повертає дескриптор утвореного вікна. Цей дескриптор передається в функцію ShowWindow(), котра організує виведення створеного вікна на екран. Тепер для правильного функціонування додатку необхідно організувати цикл повідомлень.
Цикл виявлення повідомлень
Цикл виявлення повідомлень в найпростішому вигляді складається з одного
У цьому нескінченному (якщо його не розірвати зсередини) циклі викликається функція Windows GetMessage (), і, якщо вона повертає нульове значення, викликається функція DispatchМеssаgе(). Призначення циклу обробки повідомлень - отримання повідомлень, що надходять в додаток, і виклик у відповідь на кожне повідомлення віконної процедури для обробки цього повідомлення.
Якщо протягом якогось часу повідомлення в
додаток не надходять, цикл обробки повідомлень "крутиться" вхолосту.
Як тільки у черзі виявляється повідомлення, функція GetMessage забирає його з
черги і переносить в структурну змінну, призначену для прийому повідомлень.
Викликається далі функція DispatchMessage() викликає віконну процедуру того
вікна, якому призначено дане повідомлення, і передає їй (через її параметри)
вміст повідомлення зі структури Msg. Завдання віконної процедури - виконати
необхідну обробку повідомлення. Коли віконна процедура завершить обробку
отриманого повідомлення, управління повернеться в цикл обробки повідомлень,
який продовжить своє циклічне виконання в очікуванні нового повідомлення.
. Практична частина
Завдання: Написати програму, яка дозволяє
запускати процеси, використовуючи для цього вибрані на диску файли. Користувач
може задавати ім'я запускається файлу і командний рядок. Програма стежить за
всіма запущеними нею процесами і виводить на вимогу користувача наступну
інформацію: ім'я процесу, значення покажчика та ідентифікатора процесу, час
виконання процесу.
.1 Постановка завдання
Дану програму можна написати, розділивши її на 3 частини:
. Необхідно запускати процеси, використовуючи для цього вибрані на диску файли.
. Відслідковувати кожен з процесів(його статус, назву, час життя).
. Відслідковувати діяльність користувача, і якщо він захотів вивести розгорнуту інформацію про всі процесі замість згорнутої обробити його запит.
Всі частини завдання будуть виконанні на мові
WinApi32 з використанням відповідних функцій та методів.
.2 Запуск процесу, використання для цього
вибраних на диску файлів
Найпростіший спосіб дозволити користувачу завантажити файл з будь яким ім’ям це використати стандартний огляд MS Windows з невеликими правками.надає набір готових стандартних діалогів через бібліотеки Common Dialog Boxes Library (COMDLG32.DLL): діалог відкриття і збереження файлу, діалог друку документа, діалог вибору кольору, шрифту. Щоб створити один з перерахованих діалогів, треба заповнити певну структуру і викликати відповідну функцію з цієї бібліотеки в моєму випадку це:WINAPI GetOpenFileName (OPENFILENAME * lpofn) створюють діалог, що відображає вміст того чи іншого каталогу, і дозволяє поставити користувачеві вибрати унікальне ім'я файлу для відкриття.
Синтаксис:
char filename[MAX_PATH]="";of;.lStructSize=OPENFILENAME_SIZE_VERSION_400A;.hwndOwner=hw;.hInstance=h;.lpstrFilter="All files (*.*)\0*.*\0";.lpstrCustomFilter=NULL;.nMaxCustFilter=0;.nFilterIndex=1;.lpstrFile=filename;.nMaxFile=MAX_PATH;.lpstrFileTitle=NULL;.nMaxFileTitle=0;.lpstrInitialDir=NULL; of.Flags=OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;(GetOpenFileName(&of)) {}
filename[MAX_PATH]
буфер який буде містить ім’я завантаженого файлу..hwndOwner
Це дескриптор родительського вікна..hInstance=h
Дескриптор екземпляра програми..lpstrFilter
Фільтр файлів які будуть доступні для завантаження..lpstrCustomFilter та of.nMaxCustFilter;
Також фільтри але вже для файлів які необхідно декілька разів запустити.
of.nFilterIndex
Загальна кількість використаних файлів..lpstrFile
Адреса буфера виділеного під ім’я файлу..nMaxFile
Розмір буфера виділений під ім’я файлу..lpstrFileTitle
Буфер під рекомендовані заголовки..nMaxFileTitle
Розмір буфера для рекомендованих заголовків..lpstrInitialDir
Стартовий каталог (за замовчанням це поточний
каталог)
Рис. 1 Результат використання
функції GetOpenFileName
2.3 Відслідковування кожного з
процесів (його статус, назву, час життя)
Після того я файл був обраний він запускається у процесі, а процес створюється за допомогою: CreateProcess.имеет следующий прототип:
CreateProcess(lpApplicationName, // ім’я виконуючого модуляlpCommandLine, // командна строчка_ATTRIBUTES lpProcessAttributes,// захист процесу_ATTRIBUTES lpThreadAttributes, // захист потокаbInheritHandles, // ознак наслідування дескрипторуdwCreationFlags, // прапорці створення процесуlpEnvironment, // блок нового середовищаlpCurrentDirectory, // поточний каталогlpStartUpInfo, // головне вікно_INFORMATION lpProcessInformation // інформація о процесі
);
За роботою кожного з процесів слідкує функція: IsProcessStillRunning ця функція перевіряє активний або неактивній процес.
Час життя вимірює звичайним
таймером: WM_TIMER який підраховує скільки працює кожен з процесів.
СинтаксисWM_TIMER: WM_TIMER
( WPARAM wParam LPARAM lParam;
)
wParam
[in] Визначає ідентифікатор таймера.
[in] Покажчик на певну програмою функцію зворотного виклику, яка передавалася в функцію SetTimer, коли таймер був встановлений.
Синтаксис WM_PAINT:
CALLBACK WindowProc(hwnd, // дескриптор вікнаuMsg, // WM_PAINTwParam,lParam
);
Рис. 2 виведення розгорнутої
інформації про запущений процес
2.4 Відслідковування діяльності
користувача
У завдані чітко вказано що не обхідно виводити інформацію тільки в тому випадку якщо користувач так захоче.
Це було реалізовано за допомогою WM_RBUTTONDOWN яка виконує певні дій на натиснуту праву кнопку миші. Є глобальна змінна button_check дані якої перезаписуються з 0 на 1 та навпаки при натиснутій правій клавіші миші. Після чого у WM_PAINT виконується один с двох варіантів виконання при button_check = 0 дивитись рисунок 3 та при button_check =1 дивитись рисунок 4.
Синтаксис WM_RBUTTONDOWN
_RBUTTONDOWNwParamlParam;
Рис 3. Стисла інформація про процес
Рис 4. розгорнута інформація про
процес
2.5 Інші функції, використані в програмі
_DESTROY
Це повідомлення надсилається коли необхідно знищити вікно. Після видалення його з екрана. Надсилається повідомлення спочатку головного вікна, а потім дочірнім вікнам. Після прийняття цього повідомлення необхідно викликати функцію PostQuitMessage (). Повідомлення про руйнування вікна надійде саме віконної процедури, а не в стандартній черзі повідомлення.
Також у цій функцій використовується
KillTimer який виключає таймер щоб він не висів у системі навіть після
виключення програми.
.6 Опис алгоритму роботи програми
При старті програми користувачеві необхідно у полі меню вибрати пункт StartExe після чого для нього відкриється вікно оглядача в якому він повинен буде обрати файл для запуску у програмі. Файли можуть бути лише з розширенням .ехе. Обраній файл запускається у процесі, програма може підтримувати у робочому стані двадцять процесів одночасно. Після того як процес було створено за його статусом слідкує IsProcessStillRunning ця функція перевіряє активний або неактивній процес і передає параметри у таймер WM_TIMER який підраховує скільки працює кожен з процесів до поки від функції IsProcessStillRunning не прийде підтвердження що користувач завершив процес у цьому випадку статус процесу зминеться з ACTIVE на STOPED, а таймер припинить підраховувати час життя процесу.
Якщо користувач під час роботи процесів натисне правою кнопкою миші на робочої області програми він отримає розгорнуту інформацію по кожному з процесів навіть по тим що вже завершили роботу за цим слідкує WM_RBUTTONDOWN завдяки глобальній змінній яка змінює своє значення з 0 на 1 та навпаки при натисканні на праву клавішу миші. Вся інформація передається у WM_PAINT де існує два способи виводу інформації стислий та розгорнутий і варіюється вони в залежності від того що записано у глобальній зміні.
Для того щоб завершити виконання
програми необхідно вибрати пункт вихід у меню програми або натиснути на хрестик
у правому верхньому куті вікна, в цьому випадку знищується батьківське вікно, а
разом з ним всі дочірні, також припиняє свою роботу таймер.
Висновки
В курсовій роботі було вирішена поставлена задача, для цього були використані функції, масиви, цикли та інше.
Були здобуті навички роботи з файлами, процесами та обробка даних цих процесів.
В процесі розробки були здобуті
навички роботи з програмним забезпеченням Microsoft Visual Studio, з
використанням стандартних бібліотек та функцій Win API.
Список використаних джерел
1. Финогенов К.Г. Win32. Основы программирования. - 2-е изд., испр. и дополн. - М.: ДИАЛОГ - МИФИ, 2006. - 416 с.
. Побегайло А.П. Системное программирование в Windows, - СПб.: БХВ - Петербург, 2006. - 1056 с.: ил.
. Литвиненко Н.А. - Технология программирования на С++. Win32 API-приложения - 2010.
. Рихтер Дж. Windows для профессионалов: создание эффективных Win32- приложений с учетом специфики 64-разрядной версии Windows: Пер. с англ.
. Шупак Ю.А. Win32 АР1. Разработка приложений для \Vindows. - СПб.: Питер, 2008.
.
Верма Р.Д. Справочник по функциям Win32 АР1. - 2-е изд., перераб. и доп М.:
Горячая линия - Телеком, 2005.
Додаток А
// Kurs.cpp: определяет точку входа для приложения.
//
#include "stdafx.h"
#include "Kurs.h"
#include <Windows.h>
#include <CommDlg.h>
#define MAX_LOADSTRING 100
#define MAX_PROCESSES 20
#define IDT_TIMER 1000button_check=0;
// Глобальные переменные:hInst;// текущий экземплярszTitle[MAX_LOADSTRING];// Текст строки заголовкаszWindowClass[MAX_LOADSTRING];// имя класса главного окнаfilename[MAX_PATH]; /*буфер под имя файла*/filters[] = "Program files (.)\0*.exe\0";of;hPen;struct {si;_INFORMATION pi;process_name[MAX_PATH];UINT nCount;
} PROCESS;processes[MAX_PROCESSES];current_process;
// Отправить объявления функций, включенных в этот модуль кода:(HINSTANCE hInstance);(HINSTANCE, int);CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);_PTR CALLBACKAbout(HWND, UINT, WPARAM, LPARAM);StartExe(HWND);IsProcessStillRunning(PROCESS p);APIENTRY _tWinMain(HINSTANCE hInstance,hPrevInstance,lpCmdLine,nCmdShow)
{_PARAMETER(hPrevInstance);_PARAMETER(lpCmdLine);
// TODO: разместите код здесь.msg;hAccelTable;
// Инициализация глобальных строк(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);(hInstance, IDC_KURS, szWindowClass, MAX_LOADSTRING);(hInstance);
// Выполнить инициализацию приложения:(!InitInstance (hInstance, nCmdShow))
{FALSE;
}= LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_KURS));
// Цикл основного сообщения:(GetMessage(&msg, NULL, 0, 0))
{(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{(&msg);(&msg);
}
}(int) msg.wParam;
}
//
// ФУНКЦИЯ: MyRegisterClass()
//
// НАЗНАЧЕНИЕ: регистрирует класс окна.
//
// КОММЕНТАРИИ:
//
// Эта функция и ее использование необходимы только в случае, если нужно, чтобы данный код
// был совместим с системами Win32, не имеющими функции RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции важен для того,
// чтобы приложение получило "качественные" мелкие значки и установило связь
// с ними.
{wcex;.cbSize = sizeof(WNDCLASSEX);.style= CS_HREDRAW | CS_VREDRAW;.lpfnWndProc= WndProc;.cbClsExtra= 0;.cbWndExtra= 0;.hInstance= hInstance;.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_KURS));.hCursor= LoadCursor(NULL, IDC_ARROW);.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);.lpszMenuName= MAKEINTRESOURCE(IDC_KURS);.lpszClassName= szWindowClass;.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));RegisterClassEx(&wcex);