Win32 API. Меню
Страница 20. Пример значков пунктов меню



Пример значков пунктов меню

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

Первое меню содержит пункты меню, которые показывают каждую из трех типов диаграмм: круговую, линейную и гистограмму. Значки для этих пунктов меню определены как ресурсы и загружаются при помощи использования функции LoadBitmap. С этим меню, в горизонтальном меню, связано имя меню "Chart" (Диаграммы).

Второе меню содержит пункты меню, которые показывают каждый из пяти типов линии, использованных с функцией CreatePen: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT и PS_DASHDOTDOT. Прикладная программа создает значки для этих пунктов меню во время выполнения программы, используя, рисующие функции GDI. С этим меню, в горизонтальном меню, связано имя меню "Lines" (Линии).

В оконной процедуре прикладной программы заданы два статических массива дескрипторов значков. Один массив содержит дескрипторы трех значков, использованных для меню Chart, другой содержит дескрипторы из пяти значков, использованных для меню Lines. При обработке сообщения WM_CREATE, оконная процедура загружает значки диаграмм, создает значки линий, а затем добавляет соответствующие пункты меню. При обработке WM_DESTROY сообщения, оконная процедура удаляет все значки.

Ниже следуют необходимые части заголовочного файла приложения.

// Идентификаторы пунктов меню

#define IDM_PIE1
#define IDM_LINE2
#define IDM_BAR3
#define IDM_SOLID4
#define IDM_DASH5
#define IDM_DASHDOT6
#define IDM_DASHDOTDOT7

// Число пунктов в меню Chart и Lines

#define C_LINES5
#define C_CHARTS3

// Идентификаторы ресурса значков

#define IDB_PIE1
#define IDB_LINE2
#define IDB_BAR3

// Размеры значков линий

#define CX_LINEBMP40
#define CY_LINEBMP10

Ниже следуют необходимые части оконной процедуры. Оконная процедура выполняет большинство инициализаций путем вызова определяемой программой функции LoadChartBitmaps, CreateLineBitmaps и AddBitmapMenu, описанные ниже в этом разделе.

LRESULT CALLBACK MainWindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
static HBITMAP aHbmLines[C_LINES];
static HBITMAP aHbmChart[C_CHARTS];
int i;

switch (uMsg) {

case WM_CREATE:

// Вызовите определяемые программой функции, чтобы загрузить
// значки для меню Chart и создать их для меню Lines.


LoadChartBitmaps(aHbmChart);
CreateLineBitmaps(aHbmLines);

// Вызовите определяемую программой функцию, чтобы
// создать меню, содержащее значки пунктов меню.
// Функция к тому же добавляет название меню в строке
// меню окна.


AddBitmapMenu(
hwnd,// строка меню окна владельца
"&Chart",//текст имени меню в строке меню
IDM_PIE,// ID первого пункта меню
aHbmChart,// массив дескрипторов значков
C_CHARTS// число пунктов меню
);
AddBitmapMenu(hwnd, "&Lines", IDM_SOLID,
aHbmLines, C_LINES);
break;

case WM_DESTROY:
for (i = 0; i < C_LINES; i++)
DeleteObject(aHbmLines[i]);
for (i = 0; i < C_CHARTS; i++)
DeleteObject(aHbmChart[i]);
PostQuitMessage(0);
break;

.
. // здесь обрабатываются дополнительные сообщения.
.


default:
return (DefWindowProc(hwnd, uMsg, wParam, lParam));
}
return 0;
}

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

VOID WINAPI LoadChartBitmaps(HBITMAP *paHbm)
{
paHbm[0] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_PIE));
paHbm[1] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_LINE));
paHbm[2] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_BAR));
}

Определяемая программой функция CreateLineBitmaps создает значки для меню Lines при помощи использования, рисующих функций GDI. Функция создает контекст устройства в памяти (DC) с теми же самыми свойствами, что и DC главного окна программы. Для каждого типа линии, функция создает значок, выбирает его в DC в памяти и рисует в нем.

VOID WINAPI CreateLineBitmaps(HBITMAP *paHbm)
{
HWND hwndDesktop = GetDesktopWindow();
HDC hdcDesktop = GetDC(hwndDesktop);
HDC hdcMem = CreateCompatibleDC(hdcDesktop);
COLORREF clrMenu = GetSysColor(COLOR_MENU);
HBRUSH hbrOld;
HPEN hpenOld;
HBITMAP hbmOld;
int fnDrawMode;
int i;

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

hbrOld = SelectObject(hdcMem, CreateSolidBrush(clrMenu));

// Создайте значки. Выберите каждый из них в DC
// в памяти, которые были созданы и используйте их.


for (i = 0; i < C_LINES; i++) {
// Создадим точечный рисунок (значок) и выберем его в DC.

paHbm[i] = CreateCompatibleBitmap(hdcDesktop,
CX_LINEBMP, CY_LINEBMP);
hbmOld = SelectObject(hdcMem, paHbm[i]);

// Заполним фон, используя кисть.

PatBlt(hdcMem, 0, 0, CX_LINEBMP, CY_LINEBMP, PATCOPY);

// Создадим перо и выберем его в DC.

hpenOld = SelectObject(hdcMem,
CreatePen(PS_SOLID + i, 1, RGB(0, 0, 0)));

// Пропишем строку. Сохраним цвет фона, где
// перо является белым, используем режим рисунка R2_MASKPEN.


fnDrawMode = SetROP2(hdcMem, R2_MASKPEN);
MoveToEx(hdcMem, 0, CY_LINEBMP / 2, NULL);
LineTo(hdcMem, CX_LINEBMP, CY_LINEBMP / 2);
SetROP2(hdcMem, fnDrawMode);

// Уничтожим перо и выберем старое перо и значок.

DeleteObject(SelectObject(hdcMem, hpenOld));
SelectObject(hdcMem, hbmOld);
}
// Уничтожим кисть и выберем первоначальную кисть.
DeleteObject(SelectObject(hdcMem, hbrOld));
// Очистим память, отведенную для DC и освободим DC рабочего стола.
DeleteDC(hdcMem);
ReleaseDC(hwndDesktop, hdcDesktop);
}

Определяемая программой функция AddBitmapMenu создает меню и добавляет заданное число значков меню к его пунктам. Затем она добавляет соответствующее название меню к строке меню определяемого окна.

VOID WINAPI AddBitmapMenu(
HWND hwnd,// окно, которое владеет строкой меню
LPSTR lpszText,// текст имени меню на строке меню
UINT uID,// ID первого значка пункта меню
HBITMAP *paHbm,// значки для пунктов меню
int cItems)// число значков пунктов меню
{
HMENU hmenuBar = GetMenu(hwnd);
HMENU hmenuPopup = CreatePopupMenu();
MENUITEMINFO mii;
int i;

// Добавляем значки пунктов меню к меню.

for (i = 0; i < cItems; i++) {
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_DATA;
mii.fType = MFT_BITMAP;
mii.wID = uID + i;
mii.dwTypeData = (LPSTR) (paHbm[i]);
InsertMenuItem(hmenuPopup, i, TRUE, &mii);
}

// Добавляем имя меню в строку меню.

mii.fMask = MIIM_TYPE | MIIM_DATA | MIIM_SUBMENU;
mii.fType = MFT_STRING;
mii.hSubMenu = hmenuPopup;
mii.dwTypeData = lpszText;
InsertMenuItem(hmenuBar,
GetMenuItemCount(hmenuBar), TRUE, &mii);
}
 
« Предыдущая статья   Следующая статья »