Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Поcобие_БЕЛОВ_Графический_интерфейс_API

.pdf
Скачиваний:
158
Добавлен:
18.03.2016
Размер:
3 Мб
Скачать
☆

191

//Создаем временное меню для раздела "Файлы" hFileMenu=CreatePopupMenu();

int i=0; //Инициализация позиции в меню

CreateMenuItem(hFileMenu,"&Новый\tCtrl+N", i++, CM_FILE_NEW, NULL, FALSE,

MFT_STRING); CreateMenuItem(hFileMenu,"&Открыть\t Ctrl+O", i++,CM_FILE_OPEN, NULL, FALSE,

MFT_STRING); CreateMenuItem(hFileMenu,"&Сохранить\tCtrl+S", i++,CM_FILE_SAVE, NULL, FALSE,

MFT_STRING); CreateMenuItem(hFileMenu,NULL,i++,0, NULL, FALSE, MFT_SEPARATOR); CreateMenuItem(hFileMenu,"Выход\t Alt+F4", i++,CM_FILE_QUIT, NULL, FALSE,

MFT_STRING); hEditMenu=CreatePopupMenu();

i=0; //Инициализация позиции в меню

CreateMenuItem(hEditMenu,"&Вырезать\tCtrt+X", i++,CM_EDIT_CUT, NULL, FALSE,

MFT_STRING); CreateMenuItem(hEditMenu,"&Bcтaвить\tCtri+V", i++,CM_EDIT_PASTE, NULL, FALSE,

MFT_STRING); CreateMenuitem(hEditMenu,"&Копировать\tCtrl+C",

i++, CM_EDIT_COPY, NULL, FALSE, MFT_STRING);

CreateMenuitem(hEditMenu,"&Удалить\t{ Delete", i++, CM_EDIT_DEL, NULL; FALSE,

MFT_STRING); hHelpMenu=CreatePopupMenu();

i=0; //Инициализация позиции в меню

CreateMenuItem(hHeipMenu,"&Помощь", i++,CM_HELP_HELP, NULL, FALSE,

MFT_STRING); CreateMenuItem(hHelpMenu,NULL,i++,0, NULL, FALSE, MFT.SEPARATOR); CreateMenuItem(hHelpMenu,"&0 программе",

192

i++,CM_HELP_ABOUT, NULL, FALSE, MFT_STRING);

//Подключаем временные меню к главному меню i=0; //Инициализация позиции в меню

CreateMenuItem(hMainMenu,"&Файл'', i++, 0, hFileMenu, FALSE, MFT_STRING); CreateMenuItem(hMainMenu,"&Правка", i++, 0, hEditMenu, FALSE, MFT_STRING); CreateMenuItem(hMainMenu,"&Помощь", i++, 0, hHelpMenu, FALSE, MFT_STRING); DrawMenuBar(hwnd);

return 0;

}

caseWM_COMMAND:

{char str[30]; if(HIWORD(wParam)==1)

strcpy(str,"Сообщение от акселератора"); else strcpy(str,"Сообщение от меню"); switch (LOWORD(wParam))

{ case CM_FILE_NEW:

{MessageBox(hwnd,"Создать",

str, MB_OK); return 0;

}

case CM_FILE_OPEN:

{MessageBox(hwnd,"Открыть",

str, MB_OK); return 0;

}

case CM_FILE_SAVE:

{MessageBox(hwnd,"Сохранить ",

str, MB_OK); return 0;

}

case CM_FILE_QUIT:

{DestroyWindow(hwnd); return 0;

}

193

case CM_EDIT_CUT:

{MessageBox(hwnd,"Вырезать",

str, MB_OK); return 0;

}

case CM_EDIT_PASTE:

{MessageBox(hwnd,"Вклеить",

str, MB_OK); return 0;

}

caseCM_EDIT_COPY:

{MessageBox(hwnd,"Копировать",

str, MB_OK); return 0;

}

case CM_EDIT_DEL:

{MessageBox(hwnd, "Удалить",

str, MB_OK); return 0;

}

caseCM_HELP_HELP:

{MessageBox(hwnd,"Помощь", "Помощь", MB_OK);

return 0;

}

caseCM_HELP_ABOUT:

{MessageBox(hwnd,

"Демонстрация подключения акселераторов", "О программе", МВ_ОК);

return 0;

}

}

}

case WM_DESTROY:

{PostQuitMessage(0); return 0;

}

}

194

return DefWindowProc(hwnd, msg, wParam, lParam);

}

Проанализируем те изменения в этом приложении, которые обусловлены включением работы с акселераторами.

1.Главная функция содержит описание дескриптора таблицы акселераторов, трансляцию сообщений акселераторов в цикле обработки сообщений и разрушение таблицы перед завершением работы приложения:

HACCEL hAccel=CreateAccelTable(); while(GetMessage(&msg, 0,0,0))

{ if (!hAccel || !TranslateAccelerator(hwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg);

}

}

DestroyAcceleratorTable(hAccel);

Дескриптор таблицы акселераторов должен быть описан до цикла обработки сообщений. Здесь таблица создается единственный раз при запуске приложения. Если таблица создается в другом месте или модифицируется при обработке тех или иных сообщений, то этот дескриптор необходимо описывать глобально. Так, до описания главной функции необходимо записать оператор вида НACCEL hAccel;. Тогда в любом месте приложения можно построить новую таблицу акселераторов и запомнить их дескриптор обычным способом. Так, если есть функция с именем CreateAccelTablel, то можно записать так:

hAccel=CreateAccelTable1 ();

2.Функция CreateAccelTable была подробно рассмотрена. Таких функций может быть несколько, если требуется модифицировать таблицу акселераторов в процессе работы приложения.

Для различения сообщения от акселераторов используют

значение старшего слова параметра wParam. При поступлении сообщения WM_COMMAND от акселератора это значение равно 1.

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

char str[30];

if (HIW0RD(wParam)==1) strcpy(str,"Сообщение от акселератора");

195

else strcpy(str,"Сообщение от меню");

Упражнения

1.Главное меню содержит строки «Невидимый курсор», «Обычный курсор» и «Выход». Создать плавающее меню с такими же строками. Чтобы курсор стал невидимым, вызвать функцию

ShowCursor(O); видимым – ShowCursor(1).

2.Раздел «Пользователи» главного меню содержит список пользователей. При выборе пользователя в главном меню появляются дополнительные разделы. При смене пользователя меняются и эти разделы.

3.При открытии или создании документа появляется раздел «Правка» с единственной командой «Выделить». После выбора этой команды в этом разделе добавляются строки «Удалить» и «Копировать», а команда «Выделить» отмечается галочкой (которая убирается при повторном выборе). Если выбрать команду «Копировать», то элемент «Удалить» заменяется элементом «Вставить».

4.Главное меню содержит раздел «Файл», в котором перечислены строки с именами команд «Создать», «Открыть» и «Выход». После выбора строк «Создать» или «Открыть» добавить строки «Сохранить» и «Печать», а также раздел «Правка» со строками «Вырезать», «Вклеить» и «Копировать». Команды связать с акселераторами.

5.Главное меню содержит раздел «Файл» с именами команд «Создать», «Открыть», «Сохранить», «Закрыть», «Печать» и «Выход», а также раздел «Правка» со строками «Вырезать», «Вклеить» и «Копировать». После выбора команды «Закрыть» удалить раздел «Правка». Команды связать с акселераторами.

6.Главное меню содержит раздел «Рисунок» с именами четырех геометрических фигур. После выбора фигуры отобразить фигуру в определенной части окна. При нажатии правой клавиши мыши над любой отображенной фигурой на месте нажатия отобразить плавающее меню с соответствующими выбранной фигуре командами.

7.Главное меню содержит раздел «Файл» со строками «Создать», «Открыть» и «Выход». При выборе строки «Создать» или «Открыть» создать окно, которое содержит меню с разделами «Правка» и «Эффекты». Команды связать с акселераторами.

8. Главное меню содержит раздел «Файл» со строками

196

«Создать», «Открыть» и «Выход». При выборе строк «Создать» или «Открыть» создать окно, которое содержит раздел меню «Фигуры» со списком имен геометрических фигур; при выборе имени отобразить фигуру с таким именем и отметить имя галочкой. При повторном выборе имени убрать фигуру и удалить галочку.

9. Главное меню содержит раздел «Фигуры» с именами геометрических фигур. При выборе названия фигуры в главное меню добавить раздел с названием фигуры и перечислением основных ее параметров в этом разделе. При повторном нажатии должны исчезнуть этот раздел игалочка.

10.Строки главного меню расположить в нескольких линиях, а строки плавающего меню – в одну линию.

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

HCURSOR hCursor=LoadCursor(NULL, IDC_CR0SS); SetCursor(hCursor);

12.Главное меню содержит раздел «Файл» со строками «Новый», «Открыть» и «Выход» и раздел «Помощь» со строками «Содержание» и «О программе». При выборе строки «Содержание» появляются строки «Введение», «Часть 1», «Часть 2» ..., а при выборе строки «Часть ...» появляются строки «Раздел 1», «Раздел 2»...

13.Рабочую область окна полностью занимают два временных окна. Главное меню первого окна содержит раздел «Файл» со строками «Открыть» и «Выход». Если выбрать строку «Открыть», то во втором окне появляется главное меню с разделом «Правка».

14.Плавающее меню содержит строки «Спрятать», «Показать»,»Масштаб», «Свойства». Строка «Масштаб» указывает на временное меню из четырех зависимых строк: «50 %», «100 %», «150 %» и «200 %», при выборе одна из которых отмечается кружочком.

15.Рабочую область окна приложения занимают два временных окна. Главное меню первого временного окна содержит раздел «Файл» с командами «Создать», «Открыть», «Демо-версия» и «Выход». Причем состоянием строки «Демо-версия» управляет второе окно.

16.Главное меню содержит раздел «Файл» со строками «Создать», «Открыть» и «Выход». При выборе команды «Создать»

197

или «Открыть» добавить раздел «Правка» со строками «Вырезать», «Вклеить» и «Копировать». Команды только отображаемых строк связать с акселераторами.

17.Главное меню содержит раздел «Файл», в котором перечислены строки с именами команд «Создать», «Открыть» и «Выход», которые могут быть отмечены как зависимые переключатели. После выбора строк «Создать» или «Открыть» добавить раздел «Правка» с командами «Вырезать», «Вклеить» и «Копировать», которые могут быть отмечены как независимые флажки. Команды отмеченных строк связать с акселераторами.

18.Главное меню содержит раздел «Фигуры» с зависимым списком имен геометрических фигур. При выборе имени должна быть отображена только эта фигура и отмечено кружочком только это имя.

19.Раздел «Файл» содержит строки «Создать», «Открыть», «Демо-версия» и «Выход». При выборе строки «Создать» или «Открыть» создать перекрывающееся окно с разделом меню «Эффекты». Список строк раздела «Эффекты» зависит от состояния строки «Демо-версия». Команды отображенных строк меню связать с акселераторами.

20.Главное меню содержит раздел «Файл» со строкой «Открыть». При выборе этой строки в главное меню добавить раздел «Правка» со строками «Вырезать», «Копировать» и «Удалить», удалить строку «Открыть» и добавить строку «Закрыть». При выборе строки «Закрыть» вернуться к исходному состоянию. Команды отображенных строк меню связать с акселераторами.

21.Рабочую область окна приложения полностью занимает временное окно с пустым главным меню. Главное меню окна приложения содержит раздел «Файл» со строками «Открыть» и «Закрыть» (заблокирована). При выборе команды «Открыть» создать главное меню временного окна с разделом «Правка» со строками «Вырезать», «Копировать» и «Удалить». После этого заблокировать строку «Открыть» и разблокировать команду «Закрыть». При выборе строки «Закрыть» вернуться к исходному состоянию.

22.На месте нажатия правой клавиши мыши всплывает меню. Если курсор мыши ближе к верхнему или нижнему краю рабочей области, то строки меню выстроить в линию, иначе – в столбик.

23.Главное меню содержит раздел «Пользователи», в котором перечислены строки с именами типов пользователей. После выбора

198

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

24.Главное меню содержит раздел «Цвета» с пятью именами стандартных цветов Windows и раздел «Фигуры» с именами трех плоских фигур. После выбора цвета и фигуры отобразить фигуру выбранным цветом, а соответствующие строки меню отметить галочкой. При повторном нажатии должны исчезнуть эта фигура и галочки,.

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

Контрольные вопросы

1.Перечислите основные виды меню и укажите различия между

ними.

2.Запишите алгоритм создания главного меню, состоящего из двух разделов, если в каждом разделе строки связаны с командами.

3.Для чего в цикле обработки сообщений в листинге 4.1

вызывают функцию TranslateMessage?

4.Какие меню посылают сообщения функции окна и какие меню необходимо разрушать при обработке сообщения WM_DESTROY?

5.Каким образом можно послать сообщение WM_COMMAND с идентификатором команды, если связанная с этой командой строка заблокирована?

6.Чем отличаются плавающие меню от остальных видов меню?

7.Чем отличается генерация команды с помощью акселератора от генерации команды путем выбора строки меню?

8.В каком порядке необходимо описать основные объекты приложения, если таблица акселераторов изменяется при обработке сообщений?

9.В чем заключается преимущество использования виртуального кода в акселераторах?

199

ГЛАВА 5. ПАНЕЛЬ ИНСТРУМЕНТОВ И СТРОКА

СОСТОЯНИЯ

Панель инструментов и строка состояния являются окнами дополнительных классов Win32 API.

Функции для работы с окнами таких классов объявлены в заголовочном файле commctrl.h, поэтому в текст приложения необходимо включить файл commctrl.h. Эти функции описаны в файле comctl32.dll. До сих пор мы использовали объекты статических библиотек системы: kernel32.1ib, user32.1ib, gdi32.1ib, winspool.lib, comdlg32.1ib, advapi32.1ib, shell32.1ib, ole32.1ib, oleaut32.1ib, uuid.lib, odbc32.1ib и odbccp32.1ib. Эти библиотеки автоматически подключаются к приложению Win32 API. В этом можно убедиться, заглянув в установки проекта интегрированной среды

(Project\Settings\Link – "Object/library modules:"). Для использования дополнительных классов окон сюда же необходимо приписать текст

"comctl32.1ib".

Теперь можно пользоваться дополнительными классами.

5.1. Панель инструментов

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

5.1.1. Создание панели инструментов

Для создания панели инструментов вызывают функцию

HWND CreateToolbarEx(HWND hwnd, DWORD ws, UINT wID, int nBitmaps, HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons, int iNumButtons,

int dxButton, int dyButton, int dxBitmap, int dyBitmap, UINT uStructSize);

Она создает окно панели инструментов и добавляет в него заданные кнопки.

Приведем параметры функции:

1)hwnd – дескриптор родительского окна панели;

2)ws – стиль панели. Должен содержать константу WS_CHILD, часто дополняют константой TBSTYLETOOLTIPS;

200

3)wID – идентификатор панели инструментов;

4)nBitmaps – число изображений кнопок в контейнере, хранящемся в файле hBMInst под номером wBMID. Изображения кнопок (обычно формата ICO, размером 32x32, 16 цветов) хранятся в файлах ЕХЕ и DLL, упакованные по несколько штук в контейнерах. В одном файле может быть несколько контейнеров. Функция находит контейнеры по порядковому номеру, извлекает из них необходимые изображения и выводит на кнопках;

5)hBMInst – дескриптор экземпляра приложения, содержащего контейнер с кнопками;

6)wBMID – идентификатор запрашиваемого формата кнопки;

7)lpButtons – указатель на массив структур типа TBBUTTON, который содержит информацию о кнопках создаваемой панели инструментов;

8)iNumButtons – число кнопок панели инструментов;

9)dxButton – ширина кнопок в пикселях;

10)dyButton – высота кнопок в пикселях;

11)dxBitmap – ширина изображения кнопки в пикселях;

12)dyBitmap – высота изображения кнопки в пикселях;

13)uStructSize – размер структуры TBBUTTON.

Если параметры dxButton, dyButton, dxBitmap и dyBitmap задать равными нуль, то размеры кнопок берутся по умолчанию.

При успешном создании панели функция возвращает дескриптор окна созданной панели инструментов, иначе – NULL.

Структура TBBUTTON содержит информацию о кнопке панели

инструментов:

 

typedef struct

 

{ int

iBitmap;

int

idCommand;

BYTE

fsState;

BYTE

fsStyle;

DWORD

dwData;

int

iString;

}TBBUTTON;

Рассмотрим назначение полей этой структуры:

1)iBitmap – номер изображения кнопки в контейнере;

2)idCommand – идентификатор связанный с кнопкой команды.

Если fsStyle=TBSTYLE_SEP, то idCommand должен быть равен 0;

3)fsState – флажки состояния кнопки. В общем случае кнопки