Нижеследующий пример кода показывает, как создать меню, которое содержит значки пунктов меню. Он создает два меню. Первое - меню Chart (Диаграммы), которое содержит три значка пунктов меню: круговая диаграмма, линейная диаграмма и гистограмма. Пример показывает, как загрузить эти значки из файла ресурса прикладной программы, а затем использовать функции CreatePopupMenu и AppendMenu, чтобы создать меню и пункты меню.
Второе меню - меню Lines (Линии). Оно содержит значки, показывая типы линий, предоставляемые предопределенным пером в Windows. Значки типа линий созданы во время выполнения программы при помощи использования функций GDI.
Здесь определения растровых ресурсов в файле определения ресурса прикладной программы.
PIE BITMAP pie.bmp LINE BITMAP line.bmp BAR BITMAP bar.bmp
Здесь находятся необходимые части заголовочного файла прикладной программы.
// Идентификаторы пункта меню #define IDM_SOLID PS_SOLID #define IDM_DASH PS_DASH #define IDM_DASHDOT PS_DASHDOT #define IDM_DASHDOTDOT PS_DASHDOTDOT #define IDM_PIE 1 #define IDM_LINE 2 #define IDM_BAR 3 // Флажки типов линий #define SOLID 0 #define DOT 1 #define DASH 2 #define DASHDOT 3 #define DASHDOTDOT 4 // Счет перьев #define CPENS 5 // Флажки типа диаграммы #define PIE 1 #define LINE 2 #define BAR 3 // Прототипы функций LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM); VOID MakeChartMenu(HWND); VOID MakeLineMenu(HWND, HPEN, HBITMAP);Следующий пример показывает, как меню и значки пункта меню создаются в приложении.
LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam) HWND hwnd; UINT uMsg; WPARAM wParam; LPARAM lParam; { static HPEN hpen[CPENS]; static HBITMAP hbmp[CPENS]; int i; switch (uMsg) { case WM_CREATE: // Создадим меню Chart и Line MakeChartMenu(hwnd); MakeLineMenu(hwnd, hpen, hbmp); return 0; . . // Обработаем другие сообщения окна. . case WM_DESTROY: for (i = 0; i < CPENS; i++) { DeleteObject(hbmp[i]); DeleteObject(hpen[i]); } PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return NULL; } VOID MakeChartMenu(hwnd) HWND hwnd; // дескриптор окна владельца { HBITMAP hbmpPie; // дескриптор значка круговой диаграммы HBITMAP hbmpLine; // дескриптор значка линейной диаграммы HBITMAP hbmpBar; // дескриптор значка гистограммы HMENU hmenuMain; // дескриптор главного меню HMENU hmenuChart; // дескриптор меню Chart (диаграммы) // Загрузим значки круговой, линейной диаграммы и // гистограммы из файла определения ресурса. hbmpPie = LoadBitmap(hinst, MAKEINTRESOURCE(PIE)); hbmpLine = LoadBitmap(hinst, MAKEINTRESOURCE(LINE)); hbmpBar = LoadBitmap(hinst, MAKEINTRESOURCE(BAR)); // Создадим меню Chart и добавим его к строке меню. // Добавим в конец к меню Диаграммы пункты меню Круговая, // Линейная и Гистограмма. hmenuMain = GetMenu(hwnd); hmenuChart = CreatePopupMenu(); AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (UINT) hmenuChart,"Chart"); AppendMenu(hmenuChart, MF_BITMAP, IDM_PIE, (LPCTSTR) hbmpPie); AppendMenu(hmenuChart, MF_BITMAP, IDM_LINE, (LPCTSTR) hbmpLine); AppendMenu(hmenuChart, MF_BITMAP, IDM_BAR, (LPCTSTR) hbmpBar); return; } VOID MakeLineMenu(hwnd, phpen, phbmp) HWND hwnd; HPEN *phpen; HBITMAP *phbmp; { HMENU hmenuLines; // дескриптор меню Линии HMENU hmenu; // дескриптор главного меню COLORREF crMenuClr; // цвет фона пункта меню HBRUSH hbrBackground; // дескриптор кисти фона HBRUSH hbrOld; // дескриптор предыдущей кисти LONG lCheckXY; // размеры значка-метки типа «галочки» WORD wLineX; // ширина значка линии WORD wLineY; // высота значка линии HDC hdcMain; // дескриптор контекста устройства (DC) окна HDC hdcLines; // дескриптор совместимого DC HBITMAP hbmpOld; // дескриптор предыдущего значка int i; // цикл счетчика // Создадим меню Lines. Добавьте его к строке меню hmenu = GetMenu(hwnd); hmenuLines = CreatePopupMenu(); AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT) hmenuLines, "&Lines"); // Создадим кисть для цвета фона пункта меню. crMenuClr = GetSysColor(COLOR_MENU); hbrBackground = CreateSolidBrush(crMenuClr); // Создадим совместимый контекст устройства значков линий, // а затем выберем фоновую кисть в нем. hdcMain = GetDC(hwnd); hdcLines = CreateCompatibleDC(hdcMain); hbrOld = SelectObject(hdcLines, hbrBackground); // Получим габариты значка "галочки ". Ширина // значка линии будет в пять раз шире значка "галочки". lCheckXY = GetMenuCheckMarkDimensions(); wLineX = LOWORD(lCheckXY) * (WORD) 5; wLineY = HIWORD(lCheckXY); // Создадим значки и выберите их, по одному, в совместимом контексте устройства. // Инициализируем каждый значок, заполняя его цветом фона пункта меню. for (i = 0; i < CPENS; i++) { phbmp[i] = CreateCompatibleBitmap(hdcMain, wLineX, wLineY); if (i == 0) hbmpOld = SelectObject(hdcLines, phbmp[i]); else SelectObject(hdcLines, phbmp[i]); ExtFloodFill(hdcLines, 0, 0, crMenuClr, FLOODFILLBORDER); } // Создаем перья. phpen[0] = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); phpen[1] = CreatePen(PS_DOT, 1, RGB(0, 0, 0)); phpen[2] = CreatePen(PS_DASH, 1, RGB(0, 0, 0)); phpen[3] = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0)); phpen[4] = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 0)); // Выберем перо и значок в совместимом контексте устройства, // проведем линию в значке, а затем добавим в конец значок // как пункт в меню Lines. for (i = 0; i < CPENS; i++) { SelectObject(hdcLines, phbmp[i]); SelectObject(hdcLines, phpen[i]); MoveToEx(hdcLines, 0, wLineY / 2, NULL); LineTo(hdcLines, wLineX, wLineY / 2); AppendMenu(hmenuLines, MF_BITMAP, i + 1, (LPCTSTR) phbmp[i]); } // Освободим контекст устройства основного окна, и уничтожим // совместимый контекст устройства. А также, уничтожим кисть фона. ReleaseDC(hwnd, hdcMain); SelectObject(hdcLines, hbrOld); DeleteObject(hbrBackground); SelectObject(hdcLines, hbmpOld); DeleteDC(hdcLines); return; }