Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ch-10.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
681.98 Кб
Скачать

Разрешение пунктов меню

Основная работа оконной процедуры состоит теперь в разрешении и запрещении пунктов меню Edit, что осуществляется при обработке сообщения WM_INITMENUPOPUP. Сначала программа проверяет, отображается ли всплывающее меню Edit. Поскольку индекс положения пункта Edit в меню (начинающегося с пункта File, чей индекс положения равен 0) равен 1, то lParam равен 1 в том случае, если отображается всплывающее меню Edit.

Для того чтобы определить, может ли быть разрешена опция Undo, программа POPPAD2 посылает сообщение EM_CANUNDO дочернему окну редактирования. Возвращаемое значение функции SendMessage не равно нулю, если дочернее окно редактирования может выполнить операцию Undo, в этом случае опция Undo делается разрешенной; в противном случае опция делается недоступной:

EnableMenuItem ((HMENU) wParam, IDM_UNDO,

SendMessage (hwndEdit, EM_CANUNDO, 0, 0) ?

MF_ENABLED : MF_GRAYED) ;

Опцию Paste следует делать разрешенной только в том случае, если в данный момент в папке обмена имеется текст. Определить это можно с помощью функции IsClipboardFormatAvailable с идентификатором CF_TEXT:

EnableMenuItem ((HMENU) wParam, IDM_PASTE,

IsClipboardFormatAvailable (CF_TEXT) ?

MF_ENABLED : MF_GRAYED) ;

Опции Cut, Copy и Delete следует делать разрешенными только в том случае, если в окне редактирования был выделен текст. При посылке окну управления сообщения EM_GETSEL возвращаемым значением функции SendMessage является целое, в котором содержится эта информация:

iSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0) ;

Младшим словом iSelect является положение первого выбранного символа; старшим словом iSelect является положение первого символа после выделения. Если два этих слова равны, то в окне редактирования нет выбранного текста:

if (HIWORD(iSelect) == LOWORD(iSelect))

iEnable = MF_GRAYED ;

else

iEnable = MF_ENABLED ;

Затем значение iEnable используется для опций Cut, Copy и Delete:

EnableMenuItem ((HMENU) wParam, IDM_CUT, iEnable) ;

EnableMenuItem ((HMENU) wParam, IDM_COPY, iEnable) ;

EnableMenuItem ((HMENU) wParam, IDM_DEL, iEnable) ;

Обработка опций меню

Конечно, если бы мы в программе POPPAD2 не использовали элемент управления — дочернее окно редактирования, то теперь нам пришлось бы заняться проблемами, связанными с фактической реализацией опций Undo, Cut, Copy, Paste, Delete и Select All из меню Edit. Но окно редактирования делает этот процесс элементарным: мы просто посылаем окну редактирования сообщение для каждой из этих опций:

case IDM_UNDO :

SendMessage (hwndEdit, WM_UNDO, 0, 0) ;

return 0 ;

case IDM_CUT :

SendMessage (hwndEdit, WM_CUT, 0, 0) ;

return 0 ;

case IDM_COPY :

SendMessage (hwndEdit, WM_COPY, 0, 0) ;

return 0 ;

case IDM_PASTE :

SendMessage (hwndEdit, WM_PASTE, 0, 0) ;

return 0 ;

case IDM_DEL :

SendMessage (hwndEdit, WM_CLEAR, 0, 0) ;

return 0 ;

case IDM_SELALL :

SendMessage (hwndEdit, WM_SETSEL, 0, -1) ;

return 0 ;

Обратите внимание, что мы могли бы еще больше все упростить, приравняв значения IDM_UNDO, IDM_CUT и другие — значениям соответствующих сообщений окна WM_UNDO, WM_CUT и т. д.

Опция About всплывающего меню File вызывает простое окно сообщения:

case IDM_ABOUT :

MessageBox (hwnd,

"POPPAD2 (c) Charles Petzold, 1996",

szAppName, MB_OK | MB_ICONINFORMATION) ;

return 0 ;

В главе 11 мы создадим здесь окно диалога. Окно сообщения появляется также при выборе опции Help этого меню или при нажатии быстрой клавиши <F1>.

Опция Exit посылает оконной процедуре сообщение WM_CLOSE:

case IDM_EXIT :

SendMessage (hwndEdit, WM_CLOSE, 0, 0) ;

return 0 ;

Это именно то, что делает функция DefWindowProc при получении сообщения WM_SYSCOMMAND с параметром wParam, равным SC_CLOSE.

В предыдущих программах мы не обрабатывали сообщение WM_CLOSE в оконной процедуре, а просто передавали его в DefWindowProc. DefWindowProc поступает с сообщениями WM_CLOSE очень просто: она вызывает функцию DestroyWindow. Однако в программе POPPAD2 сообщение WM_CLOSE обрабатывается, а не пересылается в DefWindowProc. В данном случае это не имеет большого значения, но обработка сообщения WM_CLOSE станет важна, когда, как будет показано в главе 11, программа POPPAD будет фактически редактировать файлы:

case WM_CLOSE :

if (IDYES == AskConfirmation (hwnd))

DestroyWindow (hwnd) ;

return 0 ;

В программе POPPAD2 функция AskConfirmation выводит на экран окно сообщения, запрашивая подтверждение на завершение программы:

AskConfirmation (HWND hwnd)

{

return MessageBox (hwnd, "Do you really want to close Poppad2?",

szAppName, MB_YESNO | MB_ICONQUESTION) ;

}

Окно сообщения (как и функция AskConfirmation) возвращает IDYES, если нажата кнопка Yes. Только после этого программа POPPAD2 вызывает функцию DestroyWindow. В противном случае программа не завершается.

Если перед завершением программы требуется подтверждение, то необходимо также обрабатывать сообщение WM_QUERYENDSESSION. Windows посылает каждой оконной процедуре сообщение WM_QUERYENDSESSION, когда пользователь заканчивает сеанс работы с Windows. Если какая-либо оконная процедура возвращает 0 в ответ на это сообщение, то сеанс работы с Windows не завершается. Мы обрабатываем сообщение WM_QUERYENDSESSION следующим образом:

case WM_QUERYENDSESSION :

if ( IDYES == AskConfirmation (hwnd))

return 1 ;

else

return 0 ;

Сообщения WM_CLOSE и WM_QUERYENDSESSION — это два сообщения, которые требуют обработки, если необходимо запрашивать пользователя о подтверждении завершения программы. По этой причине в программе POPPAD2 опция Exit отправляет оконной процедуре сообщение WM_CLOSE. Это сделано во избежание еще и третьего запроса на подтверждение завершения.

Если вы обрабатываете сообщение WM_QUERYENDSESSION, вас заинтересует и сообщение WM_ENDSESSION. Windows посылает это сообщение каждой оконной процедуре, которая ранее получила сообщение WM_QUERYENDSESSION. Параметр wParam этого сообщения равен 0, если сеанс работы не может завершиться из-за того, что другая программа возвратила 0 в ответ на сообщение WM_QUERYENDSESSION. Практически сообщение WM_ENDSESSION отвечает на вопрос: "Я сообщил Windows, что могу закончить свою работу, но завершена ли она на самом деле?"

Хотя в меню File программы POPPAD2 включены обычные опции New, Open, Save и Save As, в этой программе они не работают. Для обработки этих опций необходимо использовать окна диалога. Сейчас мы готовы перейти к их изучению.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]