9.6.7 - Создание клавиш - ускорителей для атрибутов шрифта

Пример в этом разделе показывает, как исполнить следующие задачи:

  1. Создать ресурс таблицы клавиш-ускорителей.
  2. Загрузить таблицу акселераторов во время прогона программы.
  3. Преобразовать клавиши - ускорители в цикле сообщений.
  4. Обработать сообщения WM_COMMAND, сгенерированные акселераторами.

Эти задачи демонстрируются применительно к прикладной программе, которая включает в себя меню Символ (Character) и соответствующие клавиши - ускорители, которые позволяют пользователю выбирать атрибуты текущего шрифта.

Нижеследующая часть файла определения ресурса определяет меню Character и связанную с ним таблицу клавиш-ускорителей.

Обратите внимание!, что пункты меню показывают нажатие клавиши - ускорителя и то, что каждый акселератор имеет тот же самый идентификатор, что и связанный с ним пункт меню.

#include <windows.h>
#include "acc.h"

MainMenu MENU
BEGIN
	POPUP "&Character"
	BEGIN
		MENUITEM "&Regular\tF5", IDM_REGULAR
		MENUITEM "&Bold\tCtrl+B", IDM_BOLD
		MENUITEM "&Italic\tCtrl+I", IDM_ITALIC
		MENUITEM "&Underline\tCtrl+U", IDM_ULINE
	END
END

FontAccel ACCELERATORS
BEGIN
	VK_F5, IDM_REGULAR, VIRTKEY
	"B", IDM_BOLD, CONTROL, VIRTKEY
	"I", IDM_ITALIC, CONTROL, VIRTKEY
	"U", IDM_ULINE, CONTROL, VIRTKEY
END

Следующий раздел исходного файла приложения показывает как реализовать акселератор:

HWND hwndMain; /* дескриптор главного окна */
HANDLE hinstAcc; /*дескриптор экземпляра приложения */

int WINAPI WinMain(hinst, hinstPrev, lpCmdLine, nCmdShow)
HINSTANCE hinst;
HINSTANCE hinstPrev;
LPSTR lpCmdLine;
int nCmdShow;
{
	MSG msg; /* сообщения прикладной программы */
	HACCEL haccel; /* дескриптор таблицы клавиш-ускорителей */

	.
	. /* Исполнение процедуры инициализации */
	.

	/* создание главного окна для этого экземпляра приложения.  */
	hwndMain = CreateWindowEx(0L, "MainWindowClass",
		"Sample Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
		hinst, NULL );

	/* Если окно невозможно создать возвращается значение "failure." -неудача. */

	if (!hwndMain) return FALSE;

	/* Сделаем окно видимым и обновим его рабочую область. */

	ShowWindow(hwndMain, nCmdShow);
	UpdateWindow(hwndMain);

	/* Загрузим таблицу клавиш-ускорителей. */

	haccel = LoadAccelerators(hinstAcc, "FontAccel");
	if (haccel == NULL)
		HandleAccelErr(ERR_LOADING); /* заданное приложение */

	/*
	* Получим и отправим по назначению сообщения, пока не принято сообщение WM_QUIT.
	* .
	*/

	while (GetMessage(&msg, NULL, NULL, NULL)) {
		/* Проверка нажата ли клавиша-ускоритель. */
		if (!TranslateAccelerator(
			hwndMain,	/* дескриптор окна-приемника */
			haccel,	/* дескриптор таблицы активного акселератора */
			&msg)) {	/* адрес данных для сообщений */
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return msg.wParam;
}

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)
HWND hwndMain;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
	BYTE fbFontAttrib; /* массив флажков атрибутов шрифта */
	static HMENU hmenu; /* дескриптор главного меню */

	switch (uMsg) {

		case WM_CREATE:
			/*
			* Прибавим галочку к пункту меню Regular, чтобы указать, что это - значение по
			*. умолчанию.
			*/

			hmenu = GetMenu(hwndMain);
			CheckMenuItem(hmenu, IDM_REGULAR, MF_BYCOMMAND |  MF_CHECKED);
			return 0;

		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				/* Обработаем клавишу - ускоритель и команды меню

				case IDM_REGULAR:
				case IDM_BOLD:
				case IDM_ITALIC:
				case IDM_ULINE:

				/*
				* GetFontAttributes - это функция, определяемая программой
				* функция, которая выставляет метки пунктам меню
				* и возвращает атрибуты шрифта, выбранные пользователем.
				*/
					fbFontAttrib = GetFontAttributes(
					(BYTE) LOWORD(wParam), hmenu);


				/*
				* SetFontAttributes - это функция, определяемая приложением,
				* которая создает шрифт с атрибутами, определенными пользователем
				* при помощи контекста устройства главного окна.
				*/

					SetFontAttributes(fbFontAttrib);
					break;

				default:
					break;
			}
			break;

			.
			. /* Обработка других сообщений. */
			.

		default:
			return DefWindowProc(hwndMain, uMsg, wParam, lParam);
	}
	return NULL;
}

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