Программирование для Windows NT

       

Обработка сообщения 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-окна.  А именно, этот обработчик сбрасывает признак активности задачи, в результате чего задача завершает свою работу.



Содержание раздела