11.18.3.3 - Добавление меню Линии и Диаграммы

Нижеследующий пример кода показывает, как создать меню, которое содержит значки пунктов меню. Он создает два меню. Первое - меню 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;
}

Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Владимир Соковиков - 07.10.2002