http://habrahabr.ru/post/137233/
1) Запустите Qt Creator: Создайте проект (Проект Qt С++, GUI приложение Qt) При создании каркаса приложения выберите/оставьте базовый класс – QMainWindow
2) В режиме дизайнера адаптируйте вид главного окна для экспериментирования c заданиями: а) заголовок, меню и tool bar – по желанию б) для каждого задания добавляйте на форму в режиме дизайнера простейшие элементы управления, например, для запуска процесса – кнопку (для удобства изменяйте имя объекта, например PushButton на PushButtonCalc – чтобы имена слотов, генерируемых дизайнером были читабельными) в режиме дизайнера свяжите нажатие кнопки с действием (в режиме дизайнера кнопку сделать активной, щелкнуть правую кнопку мыши и в контекстном меню выбрать «Перейти к слоту»/ clicked()/ OK) – в результате будет создан слот, имя которого дизайнер генерирует исходя из имени объекта-кнопки
А) автономный дочерний процесс (от порождающего процесса требуется только запуск). Для начала поэкспериментируйте с запуском какого-нибудь “безобидного” приложения (калькулятор – Calc, солитер – sol, ,блокнот – Notepad…)..
#include <windows.h>
Прототип основной (рекомендуемой) системной Win32-функции запуска процесса:
BOOL CreateProcess(
LPCTSTR lpApplicationName, //имя исполняемого файла или 0, если имя указано в командной строке
LPTSTR lpCommandLine, //командная строка
LPSECURITY_ATTRIBUTES lpProcessAttributes, //атрибуты безопасности создаваемого процесса или 0
LPSECURITY_ATTRIBUTES lpThreadAttributes, //атрибуты безопасности потока или 0
BOOL bInheritHandles, //наследует ли порождаемый процесс дескрипторы порождающего
DWORD dwCreationFlags, // параметры создания процесса: задание приоритета и состояния выполнения. Если 0, приоритет создаваемого процесса по умолчанию NORMAL_PRIORITY_CLASS и первичный поток начинает выполняться
LPVOID lpEnvironment, // значения переменных окружения или 0, если наследуется окружение порождающего процесса
LPCTSTR lpCurrentDirectory // текущий каталог или 0, если используется текущий каталог порождающего
LPSTARTUPINFO lpStartupInfo , //задаваемая информация о запускаемом процессе
LPPROCESS_INFORMATION lpProcessInformation// сюда возвращается функцией информация о порожденном процессе
);
Б) ожидание процессом-родителем завершения дочернего процесса
WaitForSingleObject(HANDLE, … ); //приостанавливает выполнение текущего потока до тех пор, пока объект, дескриптор которого указан в качестве первого параметра, не перейдет в сигнальное состояние или
WaitForMultipleObjects(DWORD ncount,// - количество дескрипторов в указанном вторым параметром массиве CONST HANDLE* pArray…);//приостанавливает выполнение текущего потока до тех пор, пока все или часть объектов не перейдут в сигнальное состояние
В) получение информации о дочернем процессе (код завершения, время работы…)
GetExitCodeProcess( HANDLE hProcess,…); //получает код завершения дочернего процесса. Возвращает или STILL_ACTIVE или код завершения
GetProcessTimes(HANDLE hProcess,LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime); степень использования CPU процессом
Для того чтобы перевести FILETIME в секунды, минуты… - FileTimeToSystemTime()
GetThreadTimes(HANDLE hThread,…);- аналогично
Подсказки:
Для вычитания двух структур – приведение типа к qlonglong*- reinterpret_cast<qlonglong*>
Для формирования результирующей строки – QString::
Для вывода - QMessageBox:: information()
Г) создание процесса в «приостановленном» состоянии. Подсказка: - не забудьте когда-нибудь возобновить первичный поток приостановленного процесса – ResumeThread()
Д) Запустите три дочерних процесса: калькулятор, cmd, notepad (илилюбые другие). При завершении любого из дочерних процессов, требуется вывести диагностику: какой процесс завершился сам, а остальные завершить «насильно» (TerminateProcess). Реализуйте возможность обработки родительским процессом сообщений при ожидании посредством MsgWaitForMultipleObjects
DWORD MsgWaitForMultipleObjects(
DWORD nCount, // количество «ожидаемых» дескрипторов
CONST HANDLE pHandles, // адрес массива дескрипторов
BOOL bWaitAll, // условие ожидания: TRUE – ждем всех + какое-нибудь событие для нашего приложения, FALSE – хотя бы одного из перечисленных
DWORD dwMilliseconds, // time-out или INFINITE
DWORD dwWakeMask // критерий «пробуждения»: QS_ALLEVENTS – все события, QS_MOUSE – мышиные QS_KEY – клавиатура …
);
Пример: Ждем, пока дочерний поток завершится, но обрабатываем свои сообщения
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.