Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

352

MENUITEM "&Paste\tCtrl+V",

IDM_PASTE

MENUITEM "De&lete\tDel",

IDM_DEL

MENUITEM SEPARATOR

 

MENUITEM "&Select All",

IDM_SELALL

}

 

 

 

 

POPUP "&Help"

 

 

 

{

 

 

 

 

MENUITEM "&Help...",

IDM_HELP

MENUITEM "&About PopPad2...", IDM_ABOUT

}

 

 

 

 

}

 

 

 

 

PopPad2 ACCELERATORS

 

 

{

 

 

 

 

"^Z",

IDM_UNDO

 

 

VK_BACK,

IDM_UNDO,

VIRTKEY, ALT

 

"^X",

IDM_CUT

 

 

VK_DELETE, IDM_CUT,

VIRTKEY, SHIFT

"^C",

IDM_COPY

 

 

VK_INSERT, IDM_COPY,

VIRTKEY, CONTROL

"^V",

IDM_PASTE

 

 

VK_INSERT, IDM_PASTE, VIRTKEY, SHIFT

VK_DELETE, IDM_DEL,

VIRTKEY

 

VK_F1,

IDM_HELP,

VIRTKEY

 

}

 

 

 

 

POPPAD2.H

 

 

 

 

/*-----------------------

 

 

POPPAD2.H header file

 

 

-----------------------*/

 

#define IDM_NEW

 

1

 

 

#define IDM_OPEN

2

 

 

#define IDM_SAVE

3

 

 

#define IDM_SAVEAS

4

 

 

#define IDM_PRINT

5

 

 

#define IDM_EXIT

6

 

 

#define IDM_UNDO

10

 

 

#define IDM_CUT

 

11

 

 

#define IDM_COPY

12

 

 

#define IDM_PASTE

13

 

 

#define IDM_DEL

 

14

 

 

#define IDM_SELALL

15

 

 

#define IDM_HELP

20

 

 

#define IDM_ABOUT

22

 

 

POPPAD2.ICO

Рис. 10.10 Программа POPPAD2

В файле описания ресурсов POPPAD2.RC содержится меню и таблица быстрых клавиш. Обратите внимание, что все быстрые клавиши показаны после символа табуляции (\t) внутри символьных строк всплывающего меню Edit.

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

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

353

ли всплывающее меню 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 вызывает простое окно сообщения:

354

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, в этой программе они не работают. Для обработки этих опций необходимо использовать окна диалога. Сейчас мы готовы перейти к их изучению.

Соседние файлы в предмете Операционные системы