Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
SS_BLACKRECT | SS_BLACKFRAME |
SS_GRAYRECT | SS_GRAYFRAME |
SS_WHITERECT | SS_WHITEFRAME |
"BLACK", "GRAY" и "WHITE" не означает, что цветами являются соответственно черный, серый и белый. Эти цвета основаны на системных цветах так, как это показано ниже:
Кнопка статического класса | Системный цвет |
BLACK | COLOR_3DDKSHADOW |
GRAY | COLOR_BTNSHADOW |
WHITE | COLOR_BTNHIGHLIGHT |
Поле текста окна функции CreateWindow для этих стилей игнорируется. Верхний левый угол прямоугольника расположен в точке с координатами х и у по отношению к родительскому окну. (можно пользоваться стилями SS_ETCHEDHORZ, SS_ETCHEDVERT или SS_ETCHEDFRAME для создания рамки с тенью, состоящей из серого и белого цветов.)
Статический класс также включает в себя три стиля текста: SS_LEFT, SS_RIGHT и SS_CENTER. Они предназначены для выравнивания текста соответственно по левому краю, по правому краю и по центру. Текст задается в параметре текста окна функции CreateWindow, и позднее он может быть изменен с помощью функции SetWindowText. Когда оконная процедура кнопки управления статического класса выводит на экран этот текст, она использует функцию DrawText с параметрами DT_WORDBREAK, DT_NOCLIP и DT_EXPANDTABS. Текст помещается внутрь прямоугольника дочернего окна.
Фоном дочерних окон этих трех стилей обычно является COLOR_BTNFACE, а самого текста — COLOR_WINDOWTEXT. Можно обрабатывать сообщения WM_CTLCOLORSTATIC для изменения цвета текста с помощью вызова функции SetTextColor, а для изменения цвета фона текста — с помощью вызова функции SetBkColor, возвращая при этом описатель кисти фона. Это будет вскоре продемонстрировано в программе COLORS1.
И наконец, статический класс также содержит стили окна SS_ICON и SS_USERITEM. Однако, эти стили не имеют смысла при использовании в качестве дочерних окон управления.
В отличие от кнопок — элементов управления (и окон редактирования и списков), полосы прокрутки — элементы управления не посылают родительскому окну сообщений WM_COMMAND. Вместо этого они, также как и полосы прокрутки окна, посылают ему сообщения WM_VSCROLL и WM_HSCROLL. При обработке сообщений полос прокрутки с помощью параметра lParam можно различать сообщения полос прокрутки окна и полос прокрутки — элементов управления. Для полос прокрутки окна lParam равен 0, а для полос прокрутки — элементов управления он является описателем этих полос прокрутки или описателем дочернего окна управления — полосы прокрутки. Что же касается параметра wParam, то значения его старшего и младшего слова для полос прокрутки окна и для полос прокрутки — элементов управления имеют одинаковый смысл.
Несмотря на то, что полосы прокрутки окна имеют фиксированную ширину, для задания размеров полос прокрутки — элементов управления в Windows используются размеры всего прямоугольника, задаваемые при вызове функции CreateWindow (или позже при вызове функции MoveWindow). Можно сделать полосы прокрутки управления длинными и узкими, или короткими и широкими.
Если необходимо создать полосы прокрутки — элементы управления с теми же размерами, что и полосы прокрутки окна, можно использовать для получения высоты горизонтальной полосы прокрутки функцию GetSystemMetrics:
GetSystemMetrics (SM_CYHSCROLL);
или для получения ширины вертикальной полосы прокрутки:
GetSystemMetrics (SM_CXVSCROLL);
(Для задания стандартных размеров полосам прокрутки предназначены идентификаторы стиля окон полос прокрутки SBS_LEFTALIGN, SBS_RIGHTALIGN, SBS_TOPALIGN и SBS_BOTTOMALIGN. Однако, эти стили применимы только для полос прокрутки в окнах диалога.
Можно установить диапазон и положение полосы прокрутки — элемента управления с помощью тех же вызовов функций, что и для полос прокрутки окна:
SetScrollRange (hwndScroll, SB_CTL, iMin, iMax, bRedraw);
SetScrollPos (hwndScroll, SB_CTL, iPos, bRedraw);
SetScrollInfo (hwndScroll, SB_CTL, &si, bRedraw);
Отличие состоит в том, что для полос прокрутки окна в качестве первого параметра используется описатель главного окна, а в качестве второго SB_VERT или SB_HORZ.
Достаточно удивительно то, что системный цвет COLOR_SCROLLBAR более для полос прокрутки не используется. Цвета концевых кнопок и бегунка основаны на COLOR_BTNFACE, COLOR_BTNHIGHLIGHT, COLOR_BTNSHADOW, COLOR_BTNTEXT (для маленьких стрелок), COLOR_BTNSHADOW и COLOR_BTNLIGHT. Цвет большого участка между верхней и нижней концевыми кнопками основан на сочетании цветов COLOR_BTNFACE и COLOR_BTNHIGHLIGHT.
Если обрабатываются сообщения WM_CTLCOLORSCROLLBAR, то можно возвратить кисть из сообщения для изменения цвета определенной области.
При создании программы ресурсы определяются в файле описания ресурсов (resource script), который представляет собой ASCII-файл с расширением. RC. Файл описания ресурсов может содержать представление ресурсов в ASCII-кодах, а также может ссылаться и на другие файлы (ASCII или бинарные файлы), в которых содержатся остальные ресурсы. С помощью компилятора ресурсов файл описания ресурсов компилируется и становится бинарным файлом с расширением. RES.
Компилятор ресурсов RC. EXE использует препроцессор, который может учитывать добавленные и удаленные константы, определять символы ограничителей комментариев /* и */, и директивы препроцессора С #define, #undef, #ifdef, #ifndef, #include, #if, #elif, #else и #endif. Директива #include здесь работает несколько иначе, чем в обычных программах на С.
Другим изменением make-файла при использовании ресурсов является то, что файл с расширением. RES (наряду со всеми файлами с расширением. OBJ) для целевого файла с расширением. EXE становится определяющим файлом.
Ресурсы, определяемые пользователем (user-defined resourse) удобны для включения самых разнообразных данных в файл с расширением. EXE и получения доступа в программе к этим данным. Данные могут содержаться в любом выбранном и формате — текстовом или бинарном. При загрузке данных в оперативную память возвращаемым значением функций Windows, которые используются для доступа к определяемым пользователем ресурсам, является указатель на данные. С этими данными можно делать все, что угодно.
В процессе инициализации программы (например, при обработке сообщения WM_CREATE), можно получить описатель этого ресурса:
hResource = LoadResource (hInstance,
FindResource (hInstance, "TEXT", "helptext")) ;
Переменная hResource определяется как имеющая тип HGLOBAL. Несмотря на свое имя, функция LoadResource фактически не загружает сразу ресурс в оперативную память. Используемые вместе, так как это было показано, функции LoadResource и FindResource по существу эквивалентны функциям LoadIcon и LoadCursor. Фактически, функции LoadIcon и LoadCursor используют функции LoadResource и FindResource.
Вместо имен и типов ресурсов можно использовать числа. Числа могут быть преобразованы в дальние указатели при вызове функции FindResource с использованием MAKEINTRESOURCE. Числа, используемые в качестве типа ресурса, должны быть больше 255. (Числа от 1 до 9 при вызове функции FindResource используются в Windows для существующих типов ресурсов.)
Когда необходимо получить доступ к тексту, вызывайте функцию LockResource:
pHelpText = LockResource (hResource);
Функция LockResource загружает ресурс в память (если он еще не был загружен), и возвращает указатель на него. После окончания работы с этим ресурсом, можно освободить оперативную память, вызвав функцию FreeResource :
FreeResource (hResource);
Даже если не вызsdfnm функцию FreeResource, после завершения работы программы оперативная память все равно будет освобождена.
Строка меню выводится на экране непосредственно под строкой заголовка. Эта строка иногда называется главным меню (main menu) или меню верхнего уровня (top-level menu) программы. Выбор элемента главного меню обычно приводит к вызову другого меню, появляющегося под главным, и которое обычно называют всплывающим меню (popup menu) или подменю (submenu). Можно определить несколько уровней вложенности всплывающих меню: т. е. определенный пункт всплывающего меню может вызвать появление другого всплывающего меню. Иногда, с целью увеличения информативности, вызов каких-то пунктов меню приводит к появлению окон диалога. В большинстве родительских окон, в левой части строки заголовка, имеется маленький значок программы. Щелчок на этом значке приводит к появлению системного меню, которое фактически является всплывающим меню другого типа.
Пункты всплывающих меню могут быть помечены (checked), при этом слева от текста элемента меню Windows ставится специальная метка или "галочка". Галочки позволяют пользователю узнать о том, какие опции программы выбраны из этого меню. Эти опции могут быть взаимоисключающими. Пункты главного меню помечены быть не могут.
Пункты меню в главном и всплывающих меню могут быть "разрешены" (enabled), "запрещены" (disabled) или "недоступны" (grayed). Слова "активно" (active) и "неактивно" (inactive) иногда используются, как синонимы слов "разрешено" и "запрещено". Пункты меню, помеченные как разрешенные или запрещенные, для пользователя выглядят одинаково, а недоступный пункт меню выводится на экран в сером цвете.
С точки зрения пользователя все пункты меню, разрешенные, запрещенные и недоступные, могут быть выбраны. (Отличие только в том, что при выборе запрещенных или недоступных пунктов меню с приложением ничего не происходит.) Пользователь может щелкнуть клавишей мыши на запрещенном пункте меню, или переместить к запрещенному пункту меню подсветку, или переключиться на пункт меню с помощью буквенной клавиши, соответствующей этому пункту. Однако, с позиции программы разрешенные, запрещенные и недоступные пункты меню функционируют по-разному. Сообщения WM_COMMAND Windows посылает в программу только для разрешенных пунктов меню. Используйте запрещенные и недоступные пункты меню только для тех опций, которые в данный момент не могут быть выбраны. Для того чтобы пользователь знал, какие опции не могут быть выполнены, делайте их недоступными.
Структура меню
Если создается или изменяется меню программы, полезно разделять главное меню и все всплывающие меню. У главного меню имеется описатель меню, у каждого всплывающего меню внутри главного меню имеется собственный описатель меню, и у системного меню (тоже являющегося всплывающим меню) тоже имеется описатель меню.
Каждый пункт меню определяется тремя характеристиками. Первая характеристика определяет то, что будет отображено в меню. Это либо строка текста, либо битовый образ. Вторая характеристика определяет либо идентификатор, который Windows посылает программе в сообщении WM_COMMAND, либо всплывающее меню, которое Windows выводит на экран, когда пользователь выбирает данный пункт меню. Третья характеристика описывает атрибут пункта меню, включая то, является ли данный пункт запрещенным, недоступным или помеченным.
Шаблон меню
Меню можно создать тремя разными способами. Наиболее обычным (и самым простым) является определение меню в файле описания ресурсов в форме шаблона меню, например:
MyMenu MENU
{
[список элементов меню]
}
MyMenu — это имя меню. Имеется ссылка на это имя в структуре класса окна. Обычно имя меню такое же, как имя приложения.
Внутри квадратных скобок можно использовать либо инструкцию MENUITEM, либо POPUP. Инструкция MENUITEM имеет следующий формат:
MENUITEM "&Text", id [, признаки]
Формат инструкции POPUP:
POPUP "&Text" [, признаки]
{
[список элементов меню]
}
Вместо фигурных скобок можно использовать ключевые слова BEGIN и END. Текст, выводимый для каждого пункта меню должен быть заключен в парные кавычки. Амперсант (&) вызывает подчеркивание следующего за ним символа при выводе на экран. Windows ищет этот же символ, когда пользователь выбирает элемент меню с использованием клавиши <Alt>. Если не включить амперсант в текст, то в тексте меню не будет подчеркнутых символов, и Windows будет использовать первую букву текста при поиске.
Признаками в операторах MENUITEM и POPUP, которые появляются в списке главного меню, являются следующие:
q GRAYED — Данный пункт меню недоступен и не генерирует сообщений WM_COMMAND. Текст изображается недоступным (серым цветом).
q INACTIVE — Данный пункт меню неактивен и не генерирует сообщений WM_COMMAND. Текст изображается обычным образом.
q MENUBREAK — Данный пункт меню, а также все последующие появляются на экране в новой строке меню.
q HELP — Данный пункт меню, а также все последующие появляются на экране, выравненными по правому краю.
Признаки могут комбинироваться с помощью символа поразрядной операции OR языка С (|), но опции GRAYED и INACTIVE нельзя использовать вместе. Опция MENUBREAK не используется в главном меню, поскольку Windows автоматически создает новую строку главного меню, если окно слишком узкое для размещения всех пунктов меню в одну строку.
Следующие за инструкцией POPUP в главном меню квадратные скобки (или ключевые слова BEGIN и END) ограничивают список пунктов всплывающего меню. При определении всплывающего меню допускаются следующие инструкции:
MENUITEM "text", id [, признаки]
а также:
MENUITEM SEPARATOR
а также:
POPUP "text" [, признаки]
MENUITEM SEPARATOR рисует во всплывающем меню горизонтальную черту. Эта черта часто используется для разделения групп, связанных по смыслу и назначению опций.
Для пунктов всплывающего меню в строке символов можно использовать символ табуляции \t для разделения текста по столбцам. Текст, следующий за символом \t располагается в новом столбце, с достаточным отступом вправо для размещения в первом столбце всплывающего меню самой длинной строки текста. То, как это работает, мы рассмотрим при обсуждении быстрых клавиш ближе к окончанию этой главы. Символ \а выравнивает следующий за ним текст по правому краю. Признаками в инструкциях MENUITEM, относящихся к всплывающим меню, являются следующие:
q CHECKED — Слева от текста появляется метка ("галочка").
q GRAYED — Данный пункт меню недоступен и не генерирует сообщений WM_COMMAND. Текст изображается недоступным (серым цветом).
q INACTIVE — Данный пункт меню неактивен и не генерирует сообщений WM_COMMAND. Текст изображается обычным образом.
q MENUBREAK — Данный пункт меню, а также все последующие появляются на экране в новом столбце.
q MENUBARBREAK — Данный пункт меню, а также все последующие появляются на экране в новом столбце. Столбцы разделяются между собой вертикальной чертой.
Опции GRAYED и INACTIVE нельзя использовать вместе. Опции MENUBREAK и MENUBARBREAK нельзя использовать вместе. Если число пунктов всплывающего меню больше, чем можно разместить в одном столбце, необходимо использовать либо MENUBREAK, либо MENUBARBREAK.
Значения идентификаторов в инструкциях MENUITEM — это числа, которые Windows посылает оконной процедуре в сообщениях меню. Значение идентификатора должно быть уникальным в рамках меню. Вместо чисел может оказаться удобнее использовать идентификаторы, определенные в заголовочном файле. По договоренности эти идентификаторы начинаются с символов IDM (ID for a menu, идентификатор меню).
Ссылки на меню в программе
Во многих приложениях Windows в описании ресурсов имеется только одно меню. Ссылка в программе на это меню имеет место в определении класса окна:
wndclass. lpszMenuName = "MyMenu" ;
Часто программисты используют строку имени программы в качестве имени меню, имени класса окна, имени значка программы. Однако, вместо имени для меню можно использовать число (или идентификатор). Тогда описание ресурса выглядело бы так:
45 MENU
{
[определение меню]
}
В этом случае, оператор присваивания для поля lpszMenuName структуры класса окна может быть либо такой:
wndclass. lpszMenuName = MAKEINTRESOURCE (45) ;
либо такой:
wndclass. lpszMenuName = "#45" ;
Хотя задание имени меню в классе окна является наиболее обычным способом ссылки на ресурс меню, существуют альтернативные варианты. В приложении для Windows ресурс меню можно загрузить в память с помощью функции LoadMenu, которая аналогична функциям LoadIcon и LoadCursor. Если в описании ресурса меню используете имя, то возвращаемым значением функции LoadMenu является описатель меню:
hMenu = LoadMenu (hInstance, "MyMenu") ;
При использовании числа функция LoadMenu принимает либо такой вид:
hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (45)) ;
либо такой:
hMenu = LoadMenu (hInstance, "#45") ;
Затем этот описатель меню можно указать в качестве девятого параметра функции CreateWindow:
hwnd = CreateWindow ("MyClass", "Window Caption",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
hMenu,
hInstance,
NULL) ;
В этом случае меню, указанное при вызове функции CreateWindow, перекрывает любое меню, заданное в классе окна. Меню, задаваемое в классе окна, можно считать заданным по умолчанию меню для окон, созданных на основе данного класса окна, если девятый параметр функции CreateWindow установлен в NULL. Поэтому можно использовать разные меню для различных окон, созданных на основе одного и того же класса окна.
Можно также указать NULL для меню при регистрации класса окна и NULL для меню при вызове функции CreateWindow, а затем присоединить меню к окну следующим образом:
SetMenu (hwnd, hMenu) ;
Такая форма позволяет динамически изменять меню окна.
Любое меню, связанное с окном, удаляется при удалении окна. Любое несвязанное с окном меню перед завершением работы программы должно быть явно удалено при помощи вызова функции DestroyMenu.
Меню и сообщения
Когда пользователь выбирает пункт меню, Windows посылает оконной процедуре несколько различных сообщений. Большинство из этих сообщений могут игнорироваться программой, и просто передаваться DefWindowProc. Одним из таких сообщений является сообщение WM_INITMENU, которое имеет следующие параметры:
wParam | lParam |
Описатель главного меню | 0 |
Значением параметра wParam является описатель главного меню, даже если пользователь выбирает пункт системного меню. В программах для Windows сообщение WM_INITMENU обычно игнорируется. Хотя это сообщение существует для того, чтобы дать возможность изменить меню перед тем, как будет выбран пункт меню, возможно, что любые изменения главного меню в этот момент могут привести пользователя в замешательство.
Кроме того, программа получает сообщения WM_MENUSELECT. Если пользователь перемещает курсор мыши по пунктам меню, программа может получить множество сообщений WM_MENUSELECT. Это полезно при использовании строки состояния, содержащей полное описание опции меню. Данное сообщение имеет следующие параметры:
Младшее слово (LOWORD) wParam | Старшее слово (HIWORD) wParam | lParam |
Выбранный пункт: | Флаги выбора | Описатель меню, содержащего выбранный пункт |
Сообщение WM_MENUSELECT — это сообщение для отслеживания перемещения по меню. Младшее слово параметра wParam говорит о том, какой пункт меню выбран (подсвечен) в данный момент. В старшем слове параметра wParam могут быть комбинации из следующих флагов выбора: MF_GRAYED, MF_DISABLED, MF_CHECKED, MF_BITMAP, MF_POPUP, MF_HELP, MF_SYSMENU и MF_MOUSESELECT. Сообщение WM_MENUSELECT может понадобиться для того, чтобы изменить что-нибудь в рабочей области окна на основе информации о перемещении подсветки по пунктам меню. В большинстве программ это сообщение передается в DefWindowProc.
Когда Windows готова вывести на экран всплывающее меню, она посылает оконной процедуре сообщение WM_INITMENUPOPUP со следующими параметрами:
wParam | Младшее слово (LOWORD) lParam | Старшее слово (HIWORD) lParam |
Описатель всплывающего меню | Индекс всплывающего меню | Для системного меню 1, в противном случае 0 |
Это сообщение важно, если необходимо разрешать или запрещать пункты меню перед их выводом на экран. Например, предположим, что программа с помощью команды Paste всплывающего меню может копировать текст из буфера обмена. При получении для этого всплывающего меню сообщения WM_INITMENUPOPUP необходимо определить, имеется ли текст в буфере обмена. Если нет, то необходимо сделать этот пункт меню Paste недоступным.
Самым важным сообщением меню является WM_COMMAND. Это сообщение показывает, что пользователь выбрал разрешенный пункт меню окна. Сообщения WM_COMMAND также посылаются дочерними окнами управления. Если оказывается, что для меню и дочерних окон управления используются одни и те же идентификаторы, то различить их можно с помощью значения параметра lParam, который для пункта меню будет равен 0:
Младшее слово (LOWORD) wParam | Старшее слово (HIWORD) wParam | lParam | |
Меню: | Идентификатор меню | 0 | 0 |
Элемент управления: | Идентификатор | Код уведомления | Описатель дочернего окна |
Сообщение WM_SYSCOMMAND похоже на сообщение WM_COMMAND за исключением того, что сообщение WM_SYSCOMMAND сигнализирует, что пользователь выбрал разрешенный пункт системного меню:
Младшее слово (LOWORD) wParam | Старшее слово (HIWORD) wParam | lParam | |
Системное меню: | Идентификатор меню | 0 | 0 (Если сообщение WM_SYSCOMMAND является результатом щелчка мыши, тогда старшее и младшее слово lParam являются, соответственно, экранными координатами X и Y курсора мыши.) |
Идентификатор меню показывает, какой пункт системного меню выбран. Для предопределенных пунктов системного меню, четыре младших разряда должны быть замаскированы. Результирующая величина будет одной из следующих: SC_SIZE, SC_MOVE, SC_MINIMIZE, SC_MAXIMIZE, SC_NEXTWINDOW, SC_PREVWINDOW, SC_CLOSE, SC_VSCROLL, SC_HSCROLL, SC_ARRANGE, SC_RESTORE и SC_TASKLIST. Кроме того, младшее слово параметра wParam может быть SC_MOUSEMENU или SC_KEYMENU.
Если добавить к системному меню новые пункты, то младшее слово параметра wParam станет идентификатором, который определяется. Для избежания конфликта с предопределенными идентификаторами меню, используйте значения меньше чем 0xF000. Важно, чтобы обычные сообщения WM_SYSCOMMAND передавались в DefWindowProc. Если этого не сделать, то обычные команды системного меню будут отключены.
Последним сообщением является сообщение WM_MENUCHAR, которое, в действительности, не является собственно сообщением меню. Windows посылает это сообщение оконной процедуре в одном из двух случаев: если пользователь нажимает комбинацию клавиши <Alt> и символьной клавиши, несоответствующей пунктам меню, или при выводе на экран всплывающего меню, если пользователь нажимает символьную клавишу, не соответствующую пункту всплывающего меню. Параметры сообщения WM_MENUCHAR являются следующими:
Младшее слово (LOWORD) wParam | Старшее слово (HIWORD) wParam | lParam |
Код ASCII | Код выбора | Описатель меню |
Код выбора равен:
· 0 — всплывающее меню не отображается.
· MF_POPUP — отображается всплывающее меню.
· MF_SYSMENU — отображается системное меню.
Как правило, в программах для Windows это сообщение передается DefWindowProc, которая обычно возвращает 0 в Windows, после чего Windows издает звуковой сигнал (гудок).
Изменение меню
Функция AppendMenu может использоваться для определения меню в целом внутри программы и добавления пунктов к системному меню.
· AppendMenu — добавляет новый элемент в конец меню.
· DeleteMenu — удаляет существующий пункт меню и уничтожает его.
· InsertMenu — вставляет в меню новый пункт.
· ModifyMenu — изменяет существующий пункт меню.
· RemoveMenu — удаляет существующий пункт меню.
Отличие между функциями DeleteMenu и RemoveMenu весьма важно, если указанный пункт меню является всплывающим меню. Функция DeleteMenu уничтожает всплывающее меню, а функция RemoveMenu — нет.
Другие команды меню
Для работы с меню имеется еще несколько полезных функций.
Если изменяется пункт главного меню, изменения не произойдет, пока Windows не перерисует строку меню. Вызвав функцию DrawMenuBar, можно форсировать эту операцию:
DrawMenuBar (hwnd) ;
Обратите внимание, что параметром функции DrawMenuBar является описатель окна, а не описатель меню.
Описатель всплывающего меню можно получить с помощью функции GetSubMenu:
hMenuPopup = GetSubMenu (hMenu, iPosition) ;
где iPosition — это индекс (отсчитываемый с 0) всплывающего меню внутри главного меню, которое задается параметром hMenu. Затем, полученный описатель всплывающего меню hMenuPopup можно использовать в других функциях, например, AppendMenu.
Текущее число пунктов главного или всплывающего меню можно получить с помощью функции GetMenuItemCount :
iCount = GetMenuItemCount (hMenu) ;
Идентификатор меню для пункта всплывающего меню можно получить следующим образом:
id = GetMenuItemID (hMenuPopup, iPosition) ;
Работа функции EnableMenuItem похожа на работу функции CheckMenuItem за исключением того, что третьим параметром может быть MF_ENABLED, MF_DISABLED или MF_GRAYED. Если используется функция EnableMenuItem для пункта главного меню, содержащего всплывающее меню, то в качестве третьего параметра следует использовать идентификатор MF_BYPOSITION, поскольку этот пункт меню не имеет идентификатора меню. Функция HiliteMenuItem напоминает функции CheckMenuItem и EnableMenuItem, но использует идентификаторы MF_HILITE и MF_UNHILITE. Эта функция обеспечивает инверсное изображение, которое Windows использует, когда перемещается указатель от одного из пунктов меню к другому. Обычным приложениям нет необходимости использовать функцию HiliteMenuItem.
Символьные строки использованные в меню:
iByteCount = GetMenuString (hMenu, id, pString, iMaxCount, iFlag) ;
Параметр iFlag равен либо MF_BYCOMMAND (при этом id — это идентификатор меню), либо MF_BYPOSITION (при этом id — это индекс положения). Функция копирует iMaxCount байтов строки символов в pString и возвращает число скопированных байтов.
Может быть необходимо узнать, каковы текущие флаги пункта меню:
iFlags = GetMenuState (hMenu, id, iFlag) ;
И снова, параметр iFlag равен либо MF_BYCOMMAND, либо MF_BYPOSITION. Возвращаемое значение функции iFlags — это комбинация всех текущих флагов. Можно определить текущие флаги, проверив iFlags с помощью идентификаторов MF_DISABLED, MF_GRAYED, MF_CHECKED, MF_MENUBREAK, MF_MENUBARBREAK и MF_SEPARATOR.
В таком случае, если менюбольше не нужно, его можно удалить:
DestroyMenu (hMenu) ;
Эта функция делает недействительным описатель меню.
Окна диалога
Наиболее часто окна диалога или диалоговые окна используются для получения от пользователя дополнительной информации сверх той, которую может обеспечить меню. Программист показывает, что выбор какого-то пункта меню вызывает появления окна диалога, с помощью многоточия (...) после текста этого пункта меню.
Окно диалога обычно имеет вид всплывающего окна с разнообразными дочерними окнами элементов управления внутри. Размер и расположение этих дочерних окон задается в шаблоне окна диалога (dialog box template) в файле описания ресурсов программы. Microsoft Windows обеспечивает возможность создания всплывающих окон диалога и дочерних окон элементов управления в нем, и возможность обработки оконной процедурой сообщений окна диалога (включая все сообщения клавиатуры и мыши). Тот код внутри Windows, который дает возможность все это сделать, иногда называют менеджером окна диалога (dialog box manager).
Многие сообщения, которые обрабатываются оконной процедурой окна диалога внутри Windows, также передаются и в собственную программу в функцию, называемую процедурой окна диалога (dialog box procedure) или просто процедурой диалога (dialog procedure). Эта функция похожа на обычную оконную процедуру, но она имеет некоторые важные особенности. Как правило, внутри процедуры диалога не реализуется слишком много функций. Исключение составляют лишь инициализация дочерних окон элементов управления при создании окна диалога, обработка сообщений от дочерних окон элементов управления и завершение работы с окном диалога.
Тем не менее добавление в программу окна диалога – это непростая задача. Она требует внесения изменений в несколько файлов: шаблон окна диалога помещается в файл описания ресурсов, процедура окна диалога – в файл с исходными кодами программы, а идентификаторы, которые используются в окне диалога, часто вносятся в заголовочный файл программы.
Окна диалога бывают модальными (modal) или немодальными (modeless). Чаще всего встречаются модальные окна диалога. Если программа выводит на экран модальное окно диалога, то пользователь программы не может переключаться между окном диалога и другими окнами программы. Пользователь должен сначала закончить работу с окном диалога, это обычно делается путем щелчка на кнопке, помеченной либо OK, либо Cancel. Но, несмотря на наличие на экране окна диалога, пользователь может переключаться на другие программы. Некоторые окна диалога (называемые системными модальными окнами) этого делать не позволяют. Системное модальное окно диалога вынуждает пользователя, перед тем как он получит возможность сделать что-либо другое в Windows, завершить работу с ним.
Немодальное окно диалога позволяет пользователю переключаться между окном диалога и окном, в котором оно было создано, а также между окном диалога и остальными программами. Таким образом, немодальное окно диалога больше напоминает обычные всплывающие окна, которые могут создаваться программой.
Немодальные окна диалога предпочтительнее в том случае, когда пользователь хотел бы на некоторое время оставить окно диалога на экране. Например, в программах обработки текстов немодальные окна диалога часто используются при поиске (Find) и замене (Replace). Если бы окно диалога Find было бы модальным, то пользователю пришлось бы выбрать в меню опцию Find, ввести искомую строку, закрыть окно, чтобы вернуться в документ, а затем при необходимости повторения поиска, снова воспроизвести весь этот процесс. Гораздо удобнее дать пользователю возможность переключаться между документом и окном диалога.
Как уже известно, модальные окна диалога создаются с помощью функции DialogBox. Эта функция возвращает значение только после закрытия окна диалога. Ее возвращаемым значением является второй параметр функции EndDialog, которая использовалась в процедуре окна диалога для его закрытия. Немодальные окна диалога создаются с помощью функции CreateDialog. Параметры этой функции те же, что и параметры функции DialogBox:
hDlgModeless = CreateDialog (hInstance, szTemplate, hwndParent, DialogProc) ;
Отличие состоит в том, что функция CreateDialog сразу возвращает описатель окна диалога. Как правило, этот описатель хранится в глобальной переменной.
Хотя использование имен функций DialogBox для модальных окон диалога и CreateDialog для немодальных, может показаться несколько сомнительным, можно запомнить, что немодальные окна диалога похожи на обычные окна. А функция CreateDialog напоминает функцию CreateWindow, с помощью которой создаются обычные окна.
Различия между модальными и немодальными окнами диалога
Работа с немодальными окнами диалога похожа на работу с модальными, но есть несколько важных отличий:
q Немодальные окна диалога обычно содержат строку заголовка и значок системного меню. Инструкция STYLE в шаблоне окна диалога для немодального окна диалога будет выглядеть примерно так:
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
Строка заголовка и системное меню дают пользователю возможность перемещать немодальное окно диалога по экрану с помощью как мыши, так и клавиатуры. Модальные окна диалога обычно не имеют строки заголовка и системного меню, поскольку пользователь все равно ничего не сможет сделать с окном, в котором появляется модальное диалоговое окно.
q В инструкцию STYLE включен стиль WS_VISIBLE. Если этого не сделать, то после вызова функции CreateDialog необходимо вызвать функцию ShowWindow:
hDlgModeless = CreateDialog (...) ;
ShowWindow (hDlgModeless, SW_SHOW) ;
Если не включить в инструкцию STYLE стиль WS_VISIBLE и не вызвать функцию ShowWindow, немодальное окно диалога не появится на экране.
q В отличие от сообщений для модальных окон диалога и окон сообщений, сообщения для немодальных окон диалога проходят через очередь сообщений программы. Поэтому цикл их обработки должен быть изменен таким образом, чтобы эти сообщения передавались в оконную процедуру окна диалога. Вот как это делается: когда для создания немодального окна диалога используется функция CreateDialog, необходимо запомнить в глобальной переменной (например, hDlgModeless) описатель окна диалога, который является возвращаемым значением этой функции. Необходимо изменить цикл обработки сообщений, чтобы он выглядел так:
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
Если сообщение предназначено для немодального окна диалога, то функция IsDialogMessage отправляет его оконной процедуре окна диалога и возвращает TRUE (ненулевое значение); в противном случае она возвращает FALSE (0). Функции TranslateMessage и DispatchMessage будут вызываться только в том случае, если hDlgModeless равен 0 или если сообщение не для окна диалога. Если для окна приложения используются быстрые клавиши, то цикл обработки сообщений должен стать таким:
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
}
Поскольку глобальные переменные инициализируются нулем, hDlgModeless останется равной 0 до тех пор, пока окно диалога не будет создано; таким образом гарантируется, что функция IsDialogMessage не будет вызвана с недействительным описателем окна. При закрытии немодального окна диалога необходимо принять те же меры предосторожности.
Переменная hDlgModeless может использоваться и в других частях программы для проверки наличия на экране немодального окна диалога. Например, другие окна программы могут посылать окну диалога сообщения, пока hDlgModeless не равна 0.
q Для закрытия немодального окна диалога, вместо функции EndDialog, используйте функцию DestroyWindow. После вызова функции DestroyWindow глобальная переменная hDlgModeless должна быть установлена в 0.
По привычке, пользователь закрывает немодальное окно диалога используя опцию системного меню Close. Хотя опция Close разрешена, оконная процедура окна диалога внутри Windows не обрабатывает сообщения WM_CLOSE. Необходимо сделать это в процедуре диалога:
case WM_CLOSE :
DestroyWindow (hDlg) ;
hDlgModeless = 0 ;
break ;
Обратите внимание на отличие между параметром hDlg функции DestroyWindow, передаваемым в процедуру диалога и параметром hDlgModeless — глобальной переменной, являющейся возвращаемым значением функции CreateDialog, которая проверяется внутри цикла обработки сообщений.
Можно также обеспечить пользователю возможность закрывать немодальное окно диалога с помощью кнопки. При этом используйте ту же логику, что и для сообщения WM_CLOSE. Любая информация, которую окно диалога должно вернуть создавшему его окну, может храниться в глобальных переменных.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 |


