Здавалка
Главная | Обратная связь

Компиляция ресурсов



Ресурсы исполняемого модуля определяются на этапе разработки. Инструментальные среды разработки обычно оперируют таким понятием, как файл описания ресурсов. Этот файл, как правило, имеет текстовый формат, в котором хранится указание компилятору какие данные, где находятся и что из себя представляют. Например, так может выглядеть описание ресурса ID_MainIcon типа «значок» (icon), данные которого хранятся в файле «MainIcon.ico»:

ID_MainIcon ICON "MainIcon.ico"

После компиляции проекта все данные, которые были определены в файле описания ресурсов включаются в исполняемый модуль.

Использование ресурсов

Каждый ресурс имеет уникальное символьное имя, которое задается при разработке исполняемого файла. Это имя используется при обращении к ресурсу. Для работы с ресурсами существует множество специализированных функций, но они очень похожи друг на друга.

Следующий код демонстрирует, как при определении собственного класса окна указать, что иконку и курсор следует загружать из ресурсов:

WNDCLASS windowClass;

windowClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ID_MainIcon));

windowClass.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(ID_MainCursor));

...

Первым параметром функций LoadIcon и LoadCursor передается дескриптор модуля, в котором следует искать ресурс. Вторым параметром указывается имя ресурса. Таким образом, функция LoadIcon пытается получить доступ к ресурсу ID_MainIcon указанного модуля и интерпретировать полученные данные, как «значок».

Диалоги

Диалоги, или диалоговые окна, используются для получения от пользователя дополнительной информации.

По типу диалоговые окна подразделяют на модальные (modal) и немодальные (modeless). Характерной чертой первых является то, что они блокируют прочие окна приложения до тех пор, пока не будут закрыты. Модальные диалоги используются в том случае, когда работа программы не может быть продолжена, пока пользователь не введет нужную информацию.

Windows предоставляет много предопределенных, или «стандартных», диалоговых окон: диалог открытия файла, диалог сохранения файла, диалог выбора цвета, диалог выбора шрифта и т.д.

При разработке собственных диалогов их, как правило, помещают в ресурсы приложения. Таким образом, при загрузке диалога достаточно указать имя ресурса и обработчик сообщений окна диалога:

// Обработчик сообщений окна диалога

BOOL CALLBACK SomeDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

switch(msg)

{

case WM_CLOSE:

// Закрытие окна диалога

INT_PTR result = 0;

EndDialog(hWnd, result);

return TRUE;

 

...

}

 

return FALSE;

}

 

...

 

// Отобразить модальный диалог

INT_PTR result = DialogBox(hInstance, MAKEINTRESOURCE(ID_SomeDlg),

hParentWindow, SomeDlgProc);

Если обработчик сообщений окна диалога не обрабатывает какое-либо сообщение, он должен вернуть FALSE, в противном случае – TRUE. Иначе говоря, для необработанных сообщений диалоговых окон нет необходимости в вызове функции DefWindowProc.

Диалог закрывается вызовом функции EndDialog, в которую передается дескриптор окна диалога и результат (причина) его закрытия:

BOOL EndDialog(HWND hDlg, INT_PTR result);

Меню

Меню – элемент управления пользовательского интерфейса. Обычно меню выводится под строкой заголовка окна – в таком случае оно называется главным меню (main menu) или меню верхнего уровня (top-level menu). Однако бывают и другие виды меню, например, системное и всплывающее меню.

Системное меню имеется у окон, созданных со стилем WS_SYSMENU, и появляется при нажатии на значок окна. Элементы системного меню определяют операции с данным окном: восстановить, свернуть, развернуть, закрыть и т.д.

Вызов элемента меню может привести к вызову другого меню, которое обычно называют всплывающим меню (popup menu) или подменю (submenu). Также возможно определить несколько уровней всплывающих меню: определенный пункт всплывающего меню может вызывать появление другого всплывающего меню (рис. 15).

Рисунок 15 – Главное меню и подменю

Важно отметить, что меню не является окном, это просто элемент управления. Меню можно определить в ресурсах приложения. В этом случае меню можно задать при определении класса окна:

WNDCLASS windowClass;

windowClass.lpszMenuName = MAKEINTRESOURCE(ID_MyMainMenu);

...

При этом все окна данного класса будут иметь одно и то же меню ID_MyMainMenu, определенное в ресурсах приложения. Тем не менее, есть возможность указать меню при создании окна CreateWindow(Ex), а если окно уже существует можно воспользоваться функцией SetMenu:

BOOL SetMenu(HWND hWindow, HMENU hMenu);

При загрузке меню из ресурсов следует указать модуль hModule, в ресурсах которого определено меню, и имя ресурса-меню menuName:

HMENU LoadMenuA(HINSTANCE hModule, LPCSTR menuName);

HMENU LoadMenuW(HINSTANCE hModule, LPCWSTR menuName);

При создании меню каждому его элементу присваивается уникальный числовой идентификатор. Когда пользователь выбирает определенный элемент меню, операционная система посылает сообщение WM_COMMAND с информацией о том, какой элемент был выбран, то есть его идентификатор. Анализируя эту информацию в обработчике сообщений, приложение определяет, какое действие необходимо выполнить.

Очень часто при обработке сообщений от меню возникает необходимость анализировать состояние этого или других элементов. Например, элементы меню могут быть отмечены (checked), при этом слева от текста элемента меню ставится специальная метка или «галочка» (рис. 16). Это позволяет определить, какие опции программы были выбраны.

Рисунок 16 – Состояния элементов меню

Для определения информации об элементе меню, в том числе о его текущем состоянии, следует использовать функцию GetMenuItemInfo:

BOOL GetMenuItemInfo(

HMENU hMenu,

UINT itemID,

BOOL position,

MENUITEMINFO* itemInfo);

Для изменения элемента меню используют функцию SetMenuItemInfo:

BOOL SetMenuItemInfo(

HMENU hMenu,

UINT itemID,

BOOL position,

MENUITEMINFO* itemInfo);

При вызове обеих функций необходимо передать указатель на структуру MENUITEMINFO, которая описывает элемент меню.

Ниже приведен фрагмент обработчика сообщений окна, в котором показано, как обработать сообщение о выборе конкретного элемента меню:

switch(msg)

{

case WM_COMMAND:

// Если выбран элемент меню с идентификатором menuItemID

if (wParam == menuItemID)

{

// Обработка

}

break;

...

}







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.