Операционная система Microsoft Windows 3.1 для программиста© Александр Фролов, Григорий ФроловТом 13, М.: Диалог-МИФИ, 1993, 284 стр. 1.7. Системное менюПри необходимости вы можете изменить системное меню (рис. 1.6), добавив в него новые строки или горизонтальные разделительные линии. Прежде всего вам надо получить идентификатор системного меню. Это можно сделать при помощи функции GetSystemMenu : HMENU WINAPI GetSystemMenu(HWND hwnd, BOOL fRevert); Параметр hwnd является идентификатором окна, к системному меню которого требуется получить доступ. Параметр fRevert определяет действия, выполняемые функцией GetSystemMenu. Если этот параметр указан как FALSE, функция GetSystemMenu возвращает идентификатор используемой на момент вызова копии системного меню. Если же значение этого параметра равно TRUE, функция восстанавливает исходный вид системного меню, используемый в Windows по умолчанию и уничтожает все созданные ранее копии системного меню. В последнем случае возвращаемое значение не определено. После того как вы получили идентификатор системного меню, вы можете использовать функции AppendMenu, InsertMenu или ModifyMenu для изменения внешнего вида системного меню. Есть одна особенность, которую нужно учитывать при добавлении собственной строки в системное меню. Как мы уже говорили, младшие четыре бита в сообщении WM_SYSCOMMAND могут иметь любые значения. С учетом этого обстоятельства следует выбирать идентификатор для добавляемой в системное меню строки. Очевидно, что значение этого идентификатора должно быть больше 15 и не должно конфликтовать с идентификаторами других строк меню приложения. Приложение SMARTPAD, которое мы рассмотрим немного позже, добавляет в системное меню разделительную линию и новую строку, а также блокирует строку "Close", предназначенную для удаления окна. Вначале в этом приложении мы определяем идентификатор системного меню, вызывая функцию GetSystemMenu: hmenuSystemMenu = GetSystemMenu(hwnd, FALSE); Далее к системному меню добавляется разделительная линия и строка "About...", для чего используется уже знакомая вам функция AppendMenu: AppendMenu(hmenuSystemMenu, MF_SEPARATOR, 0, 0); AppendMenu(hmenuSystemMenu, MF_BYCOMMAND | MF_ENABLED, CM_SYSABOUT, "&About..."); В качестве идентификатора мы использовали значение 0x8880 (младшие четыре бита равны нулю): #define CM_SYSABOUT 0x8880 Для блокирования строки "Close" мы вызываем функцию EnableMenuItem, указывая ей в качестве первого параметра идентификатор системного меню: EnableMenuItem(hmenuSystemMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); Обработчик сообщения WM_SYSCOMMAND, определенный в функции главного окна приложения SMARTPAD, проверяет значение параметра wParam на совпадение с идентификатором добавленной нами строки без учета младших четырех бит: case WM_SYSCOMMAND: { if((wParam & 0xfff0) == CM_SYSABOUT) { lpfnDlgProc = (DLGPROC)MakeProcInstance((FARPROC)DlgProc, hInst); DialogBox(hInst, "ABOUT", hwnd, lpfnDlgProc); return 0; } else if((wParam & 0xfff0) == SC_CLOSE) return 0; break; } Для того чтобы заблокировать строку "Close", мы выполняем обработку сообщения WM_SYSCOMMAND с параметром wParam, равным SC_CLOSE (идентификатор стандартной строки "Close" в системном меню). Обработка заключается в возврате нулевого значения. Так как ранее мы уже заблокировали эту строку при помощи функции EnableMenuItem, нет необходимости выполнять еще одну блокировку в обработчике сообщения WM_SYSCOMMAND. Мы сделали это исключительно для иллюстрации возможности блокировки строки системного меню при обработке сообщения WM_SYSCOMMAND. |