Обработка сообщения WM_COMMAND
Сообщение WM_COMMAND поступает в функцию дочернего MDI-окна, когда пользователь выбирает строки плавающего меню.
Если пользователь выбирает из этого меню, например, строку Suspend, выполняется приостановка работы задачи, запущенной для данного дочернего MDI-окна. Приостановка выполняется при помощи функции SuspendThread. Идентификатор задачи, необходимый для нее, извлекается из поля hThread структуры типа CHILD_WINDOW_TAG:
lpMyWndTag = LPCHILD_WINDOW_TAG)GetWindowLong(hwnd,
GWL_USERDATA);
EnterCriticalSection(&(lpMyWndTag->csChildWindowPaint));
SuspendThread(lpMyWndTag->hThread);
LeaveCriticalSection(&(lpMyWndTag->csChildWindowPaint));
Для возобновления выполнения приостановленной задачи мы использовали функцию ResumeThread:
ResumeThread(lpMyWndTag->hThread);
Заметим, что перед выполнением приостановки задачи мы входим в критическую секцию. Это необходимо для того, чтобы избежать полной блокировки главной задачи процесса в момент, когда блокировка рисующей задачи выполняется после входа одной из задач в критическую секцию. В самом деле, если этой произойдет, главная задача не сможет войти в критическую секцию, так как она уже занята другой задачей. Если при этом задача, вошедшая в критическую секцию, оказалась заблокирована до своего выхода из критической секции, главная задача так и останется в состоянии ожидания. При этом пользователь не сможет, например, работать с меню приложения.
Относительный приоритет задачи изменяется фукнцией SetThreadPriority, как это показано ниже:
SetThreadPriority(lpMyWndTag->hThread,
THREAD_PRIORITY_LOWEST);
Если выбрать из плавающего меню строку Get priority, с помощью функции GetThreadPriority определяется текущий относительный приоритет задачи, запущенной для данного дочернего MDI-окна. Значение этого приоритета отображается затем на экране при помощи простейшей диалоговой панели, создаваемой функцией MessageBox.
При выборе из плавающего меню строки Kill Thread задача будет принудительно уничтожена функцией TerminateThread:
TerminateThread(lpMyWndTag->hThread, 5);
В качестве кода завершения здесь передается произвольно выбранное нами значение 5.
С помощью плавающего меню вы можете удалить дочернее MDI-окно, завершив работу соответствующей задачи. Для этого окну Client Window посылается сообщение WM_MDIDESTROY:
SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM)hwnd, 0);
Все остальное делает обработчик сообщения WM_CLOSE, который получит управление при удалении дочернего MDI-окна. А именно, этот обработчик сбрасывает признак активности задачи, в результате чего задача завершает свою работу.