
- •1 Курс, 1 семестр
- •230105 Программное обеспечение вычислительной техники и автоматизированных систем
- •График выполнения лабораторных работ 2 семестр
- •Рубежный контроль курсового проекта ( 50 баллов)
- •Блок-схемы алгоритмов и откорректированные после выполнения тексты только тех функций, которые реализуют приложения индивидуальных заданий.
- •Общие требования к разрабатываемым текстам приложений, выполняемых в лабораторных работах и в курсовой работе
- •Лабораторная работа №1
- •Теоретический материал Ресурсы Windows – приложения
- •Вызов редактора меню
- •Задание на лабораторную работу
- •Лабораторная работа №2
- •Теоретический материал
- •Создание и обработка диалогового окна
- •Задание на лабораторную работу
- •Индивидуальные задания к лабораторной работе № 2
- •Задание на лабораторную работу
- •Варианты индивидуальных заданий
- •Лабораторная работа №3
- •Задание на лабораторную работу
- •Варианты индивидуальных заданий
Задание на лабораторную работу
В лабораторной работе необходимо создать приложение, которое должно рисовать одну из трех фигур по выбору пользователя:
прямоугольник,
ромб,
эллипс.
Фигуры должны быть закрашены однородной кистью одним из трех цветов (красный, зеленый, синий). Цвет заливки фигуры выбирает пользователем в соответствующем пункте подменю. Пользователь может задать через меню интенсивность цвета, выбираемый из трех вариантов ( Dark- темный цвет, Medium - средний по интенсивности цвет, Light - светлый цвет), размер фигуры также задает пользователь в соответствующих пунктах меню, выбирая размер из двух возможных (фиксированный приложением размер или максимальный размер, определенный размером клиентской области окна). Приложение должно скрывать или показывать изображение фигур по требованию пользователя, выраженное опять же через соответствующие пункты меню.
В приложении должно функционировать подменю File, пункты которого вызывают окна сообщений с информацией о выбранном пункте.
1. Прочитайте текст функции drawShape и разберитесь в том, как и что она делает. Функция реализует возможность управления своей работой, получая от вызывающей ее функции соответствующие управляющие данные через свои параметры.
Вам предстоит сделать меню, которое будет изменять по требованию пользователя ее входные параметры этой функции и таким образом управлять режимом ее работы.
#define W 200 // фиксированная ширина фигуры
#define H 140 // фиксированная высота фигуры
enum ShapeSize {MIN, MAX }; // именованная константа MIN = 0, MAX = 1
struct SHAPE_DATA {
int id_shape; // целое, определяет идентификатор
// рисуемой фигуры
BOOL fRed; // флаг установки цвета
BOOL fGreen; // флаг установки цвета
BOOL fBlue; // флаг установки цвета
int id_bright; // установка интенсивности
};
// функция drawShape получает параметры по значению:
// hWnd - дескриптор окна
// hdc - дескриптор контекста устройства
// shapeData - иформация о рисуемой фигуре
// shapeSize - информация о размере фигуры
// bShow - информация о режиме (показать – не показать)
void drawShape (HWND hWnd, HDC hdc, SHAPE_DATA shapeData,
ShapeSize shapeSize, BOOL bShow )
{
if (bShow)
{
int intensity[3] = {100, 170, 255 };
int brightness = intensity [shapeData.id_bright - ID_DARK ];
// создаем кисть заданного цвета, запоминаем дескриптор кисти в hBrush
HBRUSH hBrush = CreateSolidBrush (RGB(
shapeData.fRed ? brightness : 0,
shapeData.fGreen ? brightness : 0,
shapeData.fBlue ? brightness : 0 )
);
// дескриптор новой кисти hBrush записываем в контекст устройства, дескриптор
// старой кисти сохраняем в holdBrush
HBRUSH holdBrush = (HBRUSH) SelectObject(hdc,hBrush);
RECT rect; // определение объекта rect типа RECT, где RECT стандартная
// структура, задающая координаты левого верхнего и правого
// нижнего угла прямоугольника , где
GetClientRect(hWnd, &rect); // получили размер клиентского окна
// в объекте rect с помощью стандартной функции
// определение центра фигуры (x0, y0) - всегда в центре клиентской области (окна)
int x0=rect.right /2, x1, x2;
int y0=rect.bottom /2, y1, y2;
// определение координат прямоугольника и эллипса
if ( shapeSize == MIN )
{ x1 = x0 - W/2; y1 = y0 - H/2;
x2 = x0 + W/2; y2 = y0 + H/2;
}
else
{
x1 = y1 = 0;
x2 = rect.right; y2 = rect.bottom;
}
// определение координат ромба в массиве структур pt[4] типа POINT
POINT pt[4];
pt[0].x = (x1+x2) / 2; pt[0].y = y1;
pt[1].x = x2; pt[1].y = (y1+y2) / 2;
pt[2].x = (x1+x2) / 2; pt[2].y = y2;
pt[3].x = x1; pt[3].y = (y1+y2) / 2;
switch ( shapeData.id_shape)
{
case ID_RECTANGLE:
Rectangle(hdc, x1,y1,x2,y2);
break;
case ID_RHOMB:
Polygon(hdc, pt,4);
break;
case ID_ELLIPSE:
Ellipse(hdc, x1,y1,x2,y2);
break;
}
// старую кисть возвращаем в контекст, кисть, которой рисовали - удаляем
DeleteObject(SelectObject(hdc,holdBrush));
} // конец тела if (bShow)
}
2. Создайте проект Win32 Project не пустой с именем – ваша_ фамилия1.
Система создала Вам минимальное приложение. Запустите проект.
Откройте двойным щелчком в окне Обозреватель решений в папке Заголовочные файлы файл Resource.h и ознакомьтесь с макросами, определенными с помощью директив препроцессора #define. Макросы были построены автоматически и задают идентификаторы ресурсов, таких как меню, подменю, иконки, заголовок приложения и другие объекты .
Откройте в окне Обозреватель решений в папке Файлы ресурсов с помощью любого текстового редактора, например редактора исходного текста, файл ваша_ фамилия1.rc и рассмотрите его. Найдите связь идентификаторов объектов ресурсов из файла Resource.h с описанием этих объектов в файле, который вы рассматриваете.
Вздохните облегченно, потому что вам не придется самим писать эти тексты. Тексты этих файлов будут строиться автоматически Редакторами ресурсов. (Но понимать эти тексты вы должны!)
Закройте окна файла Resource.h и файла ваша_ фамилия1.rc
3. В окне Обозреватель решений откройте файл ваша_ фамилия1.rc двойным щелчком. В появившемся окне Окно ресурсов откройте папку Menu, щелкнув по его пункту IDC_MY (это идентификатор главного меню), и откройте Редактор меню.
Измените заголовки пунктов О программе…. ( на О моей программе…), Справка ( на Помощь). Это можно сделать двумя способами:
изменив название непосредственно в прямоугольнике пункта меню;
вызвав диалоговое окно Свойства - окно свойств пункта (дважды щелкнуть по пункту меню) и изменив атрибут этого окна Надпись (Caption).
Сделайте изменения, применив оба способа. Запустите проект. Посмотрите изменения.
Модифицируйте главное меню. Добавьте новые пункты нулевого уровня, руководствуясь следующими таблицами.
Пункты главного меню ( 0-й уровень )
Имя пункта |
Тип пункта |
Идентификатор |
Позиция |
&Файл |
подменю |
- |
0 (уже есть) |
&Видимость |
подменю |
- |
1 |
&Рисовать |
подменю |
- |
2 |
&Увеличить! |
команда |
IDM_RESIZE |
3 |
С&правка |
подменю |
- |
4 (уже есть) |
Для того, чтобы сделать пункт меню пунктом-командой, в окне Свойств этого пункта необходимо изменить установку свойства Всплывающее меню с True на False
Для пункта – команда в его окне Свойств сначала заполняйте поле ИД, и только после этого – поле Надпись. Это оградит вас от засорения файла Resource.h неправильными макросами с неиспользуемыми идентификаторами, которые строятся автоматически, как только вы заполнили поле Надпись!!!! |
Имя пункта «Увеличить!» завершается восклицательным знаком, чтобы информировать пользователя, что данный пункт главного меню является командой, а не заголовком подменю.
Добавьте пункты подменю первого уровня в пункты Файл, Видимость, Рисовать
Пункты подменю «Файл» ( 1-й уровень )
Имя пункта |
Тип пункта |
Идентификатор |
О&ткрыть |
команда |
IDM_OPEN |
&Закрыть |
команда |
IDM_CLOSE |
Со&хранить |
команда |
IDM_SAVE |
- |
SEPARATOR |
- |
В&ыход |
команда |
IDM_EXIT (уже есть) |
|
|
|
Пункты подменю «Видимость» ( 1-й уровень )
Имя пункта |
Тип пункта |
Идентификатор |
&Показать |
команда |
IDM_SHOW_SHAPE |
С&крыть |
команда |
IDM_HIDE_SHAPE |
Пункты подменю «Рисовать» ( 1-й уровень )
Имя пункта |
Тип пункта |
Идентификатор |
Фигура |
подменю |
- |
Цвет |
подменю |
- |
Будьте внимательны. Пункты подменю 1 уровня по умолчанию создаются как команды. Для того, чтобы сделать пункт меню пунктом-подменю, в окне Свойств этого пункта необходимо сначала изменить установку свойства Всплывающее меню с False на True
Поле ИД будет сделано недоступным, что оградит вас от засорения файла Resource.h неправильными макросами с неиспользуемыми идентификаторами, которые строятся автоматически, как только вы заполнили поле Надпись!!!! |
Пункты подменю «Справка» ( 1-й уровень ) – уже есть
Имя пункта |
Тип пункта |
Идентификатор |
О программе … |
команда |
IDM_ABOUT |
Добавьте пункты подменю второго уровня в пункты Фигура и Цвет
Пункты подменю «Фигура» ( 2-й уровень )
Имя пункта |
Тип пункта |
Идентификатор |
Прямоугольник |
команда |
ID_RECTANGLE |
Ромб |
команда |
ID_RHOMB |
Эллипс |
команда |
ID_ELLIPSE |
Пункты подменю «Цвет» ( 2-й уровень )
Имя пункта |
Тип пункта |
Идентификатор |
Красный |
команда |
ID_RED |
Зеленый |
команда |
ID_GREEN |
Синий |
команда |
ID_BLUE |
- |
SEPARATOR |
- |
Темный |
команда |
ID_DARK |
Средний |
команда |
ID_MEDIUM |
Светлый |
команда |
ID_LIGHT |
Откройте снова файлы Resource.h и ваша_ фамилия1.rc и рассмотрите изменения в них.
Запустите проект. Пункты меню есть в приложении, теперь надо организовать реакции приложения на соответствующие команды.
4. Откройте файл ваша_ фамилия1.h и добавьте в него макросы W и H, перечисление
enum ShapeSize, а также структуру SHAPE_DATA.
#define W 200 // фиксированная ширина фигуры
#define H 140 // фиксированная высота фигуры
enum ShapeSize { MIN, MAX }; // именованная константа MIN = 0, MAX = 1
struct SHAPE_DATA {
int id_shape; // целое, определяет идентификатор
// рисуемой фигуры
BOOL fRed; // флаг установки цвета
BOOL fGreen; // флаг установки цвета
BOOL fBlue; // флаг установки цвета
int id_bright; // установка интенсивности
};
Создайте в проекте новый файл drawShape.cpp , запишите в него текст функции
drawShape.
Перед функцией пропишите две директивы препроцессора
#include "stdafx.h"
#include "ФамилияСтудента.h"
Откомпилируйте созданный файл
Откройте файл ваша_ фамилия1.cpp. Прототип функции drawShape запишите в файле ваша_ фамилия1.cpp
Внесите изменения в функцию WndProc, в ту ее часть, где происходит обработка сообщений – команд WM_CREATE , WM_COMMAND и WM_PAINT, организующие обработку сообщений от созданных пунктов меню. Создайте ветви case для обработки сообщений WM_COMMAND , пришедших от пунктов – команд добавленных вами в меню.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
// добавьте описания объектов, которые инициализируются сначала своими
// начальными значениями, определяющими исходное поведение функции drawShape.
// В процессе работы приложения эти значения должны меняться по указанию
// пользователя и изменять поведение функции drawShape
static ShapeSize shapeSize = MIN;
static BOOL bShow = TRUE;
static SHAPE_DATA shapeData = { ID_RECTANGLE, TRUE, FALSE, FALSE, ID_DARK};
static HMENU hMenu = GetMenu(hWnd); // стандартная функция
// GetMenu возвращает дескриптор главного меню
// Обратите внимание на определение объектов с ключевым словом static.
// Объекты, определенные как static, имеют область видимости как локальные объекты,
// т. е. они видны только в блоке, их ограничивающем, но живут, как и глобальные
// объекты – все время работы приложения. Их инициализация, в отличие от локальных
// объектов осуществляется только один раз, при первом входе в блок, их
// ограничивающий. Эти объекты «помнят» свои значения и при выходе из функции,
// в которой они определены.
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_OPEN:
// функция MessageBox вызывает диалоговое окно
// с соответствующим сообщением
MessageBox (hWnd, TEXT("выбран пункт 'Открыть ' "),
TEXT("меню 'Файл' "), MB_OK);
break;
case IDM_CLOSE:
MessageBox(hWnd, TEXT("выбран пункт 'Закрыть ' "),
TEXT("меню 'Файл '"), MB_OK);
break;
case IDM_SAVE:
MessageBox(hWnd, TEXT("выбран пункт 'Сохранить ' "),
TEXT("меню ’Файл’ "), MB_OK);
break;
case IDM_SHOW_SHAPE:
bShow = TRUE;
break;
case IDM_HIDE_SHAPE:
bShow = FALSE;
break;
case ID_RECTANGLE:
shapeData.id_shape = ID_RECTANGLE;
break;
case ID_RHOMB:
shapeData.id_shape = ID_RHOMB;
break;
case ID_ELLIPSE:
shapeData.id_shape = ID_ELLIPSE; break;
case ID_RED:
shapeData.fRed= TRUE;
shapeData.fGreen =FALSE ;
shapeData.fBlue=FALSE;
break;
case ID_GREEN:
shapeData.fRed=FALSE;
shapeData.fGreen =TRUE ;
shapeData.fBlue=FALSE;
break;
case ID_BLUE:
shapeData.fRed=FALSE;
shapeData.fGreen = FALSE;
shapeData.fBlue=TRUE;
break;
case ID_DARK:
shapeData.id_bright = ID_DARK;
break;
case ID_MEDIUM :
shapeData.id_bright = ID_MEDIUM;
break;
case ID_LIGHT:
shapeData.id_bright = ID_LIGHT;
break;
case IDM_RESIZE:
// пока не обрабатываем команду !!!!!!!!
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Вызов очень важной InvalidateRect функции, после того, как произведены изменения
// значений параметров функции drawShape
// функция InvalidateRect , посылая сообщение WM_PAINT, перерисовывает клиентскую // область окна с дескриптором hWnd
InvalidateRect(hWnd,NULL,TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
drawShape( hWnd, hdc, shapeData, shapeSize, bShow );
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Откомпилируйте файл и выполните проект.
Просмотрите и проанализируйте, как работают пункты меню всех уровней, какие параметры функции drawShape изменяются в при поступлении сообщения от конкретного пункта меню и как это изменение влияет на поведение функции.
Подменю может содержать один пункт, выполняемый по умолчанию. Имя этого пункта выделяется жирным шрифтом. Когда пользователь открывает подменю двойным щелчком, Windows автоматически выполнит команду по умолчанию, закрыв при этом подменю. Если пункт по умолчанию отсутствует, то двойной щелчок приводит просто к открытию подменю.
Атрибут «применяемый по умолчанию» может быть назначен любому пункту подменю при помощи функции:
BOOL SetMenuDefaultItem( HMENU hMenu, // дескриптор подменю
UINT uItem, // идентификатор пункта подменю, назначаемого пунктом по умолчанию
UINT fByPos // если этот третий параметр назначается FALSE
);
Создайте в блоке обработки сообщений функции WndProc обработку сообщения WM_CREATE и выполните в нем функцию, сделав таким образом пунктом по умолчанию пункт «Открыть»:
SetMenuDefaultItem(GetSubMenu(hMenu,0), IDM_OPEN, FALSE);
Обратите внимание, что дескриптор подменю определяется функцией
HMENU GetSubMenu( HMENU hMenu, // дескриптор родительского меню
int nPos // позиция-уровень пункта подменю в родительском меню
);
Относительная позиция nPos для родительского меню отсчитывается от нуля.
Откомпилируйте файл и выполните проект. Просмотрите и проанализируйте, как работают пункты «Открыть» и любого другого пункта меню нулевого уровня.
Пункты меню могут использоваться в роли переключателей (radio button). Переключатели обычно используются в группе. В группе можно выбрать только один переключатель, поэтому в группу связываются только пункты подменю с взаимно исключающими опциями. Выбранный переключатель отмечается жирной точкой.
BOOL CheckMenuRadioItem( HMENU hmenu, // дескриптор меню
UINT idFirst, // идентификатор или позиция первого пункта меню в группе
UINT idLast, // идентификатор или позиция последнего пункта меню в группе
UINT idCheck, // идентификатор или позиция выбранного пункта меню из группы
UINT uFlags // интерпретация параметра idFirst, idLast или idCheck
);
Если параметр uFlags имеет значение MF_BYCOMMAND, то параметры со второго по четвертый указывают идентификаторы пунктов меню. Если параметр uFlags равен MF_BYPOSITTION, то эти параметры указывают позиции пунктов меню.
Задавая в редакторе пункты меню для группы переключателей, следует убедиться, что их идентификаторы в файле Resurce.h имеют сквозную нумерацию и упорядочены в соответствии с позициями этих пунктов на полосе меню. При нарушении этого условия функция CheckMenuRadioItem может работать некорректно.
Создайте группу из двух пунктов подменю «Видимость» - «Скрыть» и «Показать». Для этого инициализируйте группу и начальное положение в группе пункта «Скрыть», вызвав функцию с параметрами
CheckMenuRadioItem(GetSubMenu(hMenu,1),IDM_SHOW_SHAPE,
IDM_HIDE_SHAPE, IDM_SHOW_SHAPE, MF_BYCOMMAND);
в блоке блоке сообщения WM_CREATE.
В блоке сообщений WM_COMMAND при обработке его младшего слова wParam со значениями, равными всем идентификаторам пунктов меню создаваемой группы вызвать функцию
case IDM_SHOW_SHAPE :
CheckMenuRadioItem(GetSubMenu(hMenu,1),IDM_ SHOW_SHAPE,
IDM_ HIDE_SHAPE, LOWORD(wParam), MF_BYCOMMAND);
case IDM_HIDE_SHAPE:
CheckMenuRadioItem(GetSubMenu(hMenu,1),IDM_ SHOW_SHAPE,
IDM_ HIDE_SHAPE, LOWORD(wParam), MF_BYCOMMAND);
Откомпилируйте файл и выполните проект. Просмотрите и проанализируйте, как работают пункты созданной группы пунктов меню.
Аналогично создайте группы пунктов:
Группа |
Позиция nPos в функции GetSubMenu |
Первый пункт в группе |
Последний пункт в группе |
подменю «Фигура» |
2 |
ID_RECTANGLE |
ID_ELLIPSE |
подменю «Цвет» |
2 |
ID_RED |
ID_BLUE |
2 |
ID_DARK |
ID_LIGHT |
Откомпилируйте файл и выполните проект. Проверьте, как работают пункты созданных групп пунктов меню.
8. Пункт главного меню «Увеличить!» с идентификатором IDM_RESIZE является командой и должен использоваться как флажок, сигнализирующий об изменении размеров фигуры. Вставьте в блок «case IDM_RESIZE:» инструкцию, изменяющую значение shapeSize:
shapeSize = (shapeSize == MIN )? MAX : MIN;
// значение, которое будет принимать объект shapeSize 0 или 1
Пункты меню нулевого уровня не могут получать отметку взведенного флажка. Показать пользователю реакцию на его действие следует, изменив заголовок пункта-команды функцией ModifyMenu.
BOOL ModifyMenu( HMENU hMnu, // дескриптор меню
UINT uPosition, // идентификатор или позиция пункта
UINT uFlags, // флаги (значение MF_BYCOMMAND или
// MF_BYPOSITTION)
PTR uIDNewItem, // новый идентификатор пункта
LPCTSTR lpNewItem // новое название пункта
);
Перед оператором switch в функции WndProc создайте массив из двух строк типа TCHAR и инициализируйте его названиями пунктов меню:
TCHAR* itemResizeName[2] = {TEXT("Увеличить!"),TEXT("Уменьшить!")};
И добавьте следующие инструкции в блок «case IDM_RESIZE:»
ModifyMenu(hMenu, IDM_RESIZE, MF_BYCOMMAND, IDM_RESIZE,
itemResizeName[shapeSize]); // индекс 0 или 1!!
DrawMenuBar(hWnd); // перерисовать меню с новым названием
// пункта
Откомпилируйте файл и выполните проект.
Проверьте, как работает пункт «Увеличить!» главного меню.
9. Когда изображение скрыто после выполнения команды «Скрыть» подменю «Видимость», действия по рисованию фигуры, изменению ее размеров, цветов и их оттенков теряют смысл. Интерфейс программы выиграет, если в этой ситуации соответствующие пункты меню сделать недоступными. Этого можно достичь, используя функцию EnableMenuItem.
BOOL EnableMenuItem( HMENU hMenu, // дескриптор меню
UINT uIDEnableItem, // идентификатор или позиция пункта
UINT uEnable // интерпретация второго параметра и выполняемое действие
);
Три действия может определять параметр uEnable:
MFS_ENABLED (пункт разрешен),
MFS_DISABLED (пункт запрещен),
MFS_GRAYED (пункт недоступен).
Сделайте недоступным пункт меню IDM_RESIZE. При обработке сообщения WM_COMMAND, с параметром wParam, равным IDM_HIDE_SHAPE, вызовите функцию EnableMenuItem, которой передается флаг MF_BYCOMMAND|MFS_GRAYED.
EnableMenuItem (hMenu, IDM_RESIZE, MF_BYCOMMAND|MFS_GRAYED);
DrawMenuBar(hWnd); // не забудьте перерисовать меню!!!!!!!!
А при обработке сообщения WM_COMMAND, с параметром wParam, равным IDM_SHOW_SHAPE, вызовите туже функцию EnableMenuItem, но с флагом MF_BYCOMMAND|MFS_ENABLED.
EnableMenuItem (hMenu, IDM_RESIZE, MF_BYCOMMAND|MFS_ ENABLED);
DrawMenuBar(hWnd); // не забудьте перерисовать меню!!!!!!!!
Откомпилируйте файл и выполните проект. Проверьте, как работает пункт «Увеличить!» главного меню при отжатом пункте меню «Скрыть».
Для того чтобы сделать недоступным много пунктов меню, нужно применить эти функции многократно для всех пунктов. Как уже говорилось, при отжатом пункте меню «Скрыть» бессмысленно выполнение пунктов меню с идентификаторами ID_RECTANGLE , ID_RHOMB , ID_ ELLIPSE , ID_ RED, ID_ GREEN, ID_BLUE , ID_DARK, ID_LIGHT , ID_MEDIUM. Помня, что идентификатор пункта меню – это объект типа определите открытый массив
UINT IdPunktMenu[ ] = { IDM_RESIZE,
ID_RECTANGLE , ID_RHOMB, ID_ELLIPSE ,
ID_RED, ID_GREEN , ID_BLUE ,
ID_DARK, ID_LIGHT, ID_MEDIUM };
Размер этого массива можно вычислить как sizeof (IdPunktMenu) / sizeof(UINT).
Разработайте свою функцию с тем же именем EnableMenuItem, которая, получает адрес массива идентификаторов IdPunktMenu, количество его элементов n, а также параметр UINT uEnable и вызывает стандартную функцию EnableMenuItem столько раз, сколько идентификаторов пунктов меню в массиве, т.е.создайте функцию с заголовком:
void EnableMenuItem ( HMENU hMenu, UINT* IdPunktMenu, int n, UINT uEnable).
Замените в функции в соответствующих ветвях case стандартную функцию EnableMenuItem на разработанную вами функцию.
Откомпилируйте файл и выполните проект. Проверьте, как работают пункты меню при «отжатом» пункте меню «Скрыть».
10. Быстрая клавиша (keyboard accelerator) – это клавиша или комбинация клавиш, которые при нажатии генерируют сообщение WM_COMMAND. Обычно быстрые клавиши дублируют пункты меню, предоставляя пользователю альтернативный способ вызова команд.
Чтобы добавить в приложение обработку быстрых клавиш, нужно выполнить простую последовательность действий:
Модифицировать определение ресурса меню, добавив к имени каждого дублируемого пункта информацию о быстрой клавише.
Определить быструю клавишу в таблице быстрых клавиш файла описания ресурсов
В главной функции _tWinMain обеспечивается загрузка таблицы быстрых клавиш функцией LoadAccelerators, а функция TranslateAccelerator перехватывает сообщения с клавиатуры, анализирует их коды и в случае совпадения с кодом, определенным в таблице быстрых клавиш, направляет соответствующее сообщение в оконную процедуру главного окна. Еще раз посмотрите на цикл обработки сообщений в функции _tWinMain!
Добавьте горячую клавишу для пункта меню «Открыть» - alt + Т (Т символ кириллицы).
В окне Обозреватель решений откройте файл ваша_ фамилия.rc двойным щелчком. В появившемся окне Окно ресурсов откройте папку Menu, щелкнув по его пункту IDC_MY (это идентификатор главного меню), и откройте Редактор меню.
Сделайте подсказку пользователю о наличии горячей клавише. Вызовите диалоговое окно Свойства для пункта меню «Открыть» и в конце имени пункта, которое указано в поле Надпись, добавьте текстовую строку, подсказывающую пользователю, какая горячая клавиша или сочетание клавиш являются горячими для этого пункта меню. В данном случае добавьте к имени “…\alt + Т”
В окне Окно ресурсов откройте папку Accelerator и, щелкнув по ее пункту, откройте редактор таблицы быстрых клавиш. В поле ID таблицы выберите идентификатор пункта «Открыть», в поле Модификатор(Modifier) виртуальное имя клавиши alt, в поле Ключ( Key) пропишите символ Т, поле Тип(Type) оставьте ASCII.
Откомпилируйте файл и выполните проект. Проверьте, как работают горячие клавиши.
Добавьте несколько горячих клавиш по своему усмотрению.
Теоретически, можно определить быструю клавишу почти для каждой виртуальной или символьной клавиши в сочетании с клавишами Shift, Ctrl или Alt. Однако надо избегать тех быстрых клавиш, которые имеют традиционное применение во многих приложениях Windows.
При защите общей части этой лабораторной работы вы должны продемонстрировать преподавателю практические навыки работы в графическом редакторе, умение читать и понимать созданное вами приложение и уметь отвечать на теоретические вопросы, список которых приводится ниже.
1. Что такое сообщение?
2. Как реализовано сообщение?
3. Windows многозадачная система. Кому адресуются сообщения?
4. Что такое системная очередь сообщений? Кто ее создает? Когда?
5. Как Windows определяет адресата, которому предназначено сообщение?
6. Что такое дескриптор?
7. Что такое очередь сообщений приложения? Кто ее создает? Когда? Зачем? Как долго живет эта очередь?
8. Что такое оконная процедура?
9. Какая функция называется функцией обратного вызова?
10. Как компилятор узнает функцию обратного вызова?
11. Какой заголовок у функции обратного вызова главного окна?
12. Какие параметры имеет оконная процедура?
13. Какова структура тела функции обратного вызова?
14. Что такое оконный класс?
15. Что определяет оконный класс?
16. Какую возможность дает использование одного и того же класса при создании множества окон?
17. Какова структура главной функции WinMain?
18. Что такое hInstance?
19. Что происходит в цикле обработки сообщений?
20. Зачем приложению извлекать сообщения из очереди сообщений, а затем снова возвращать их Windows?
21. Когда посылается сообщение WM_COMMAND?
22. Что делает макрос LOWORD?
23. Что делает макрос HIWORD?
24. Какую информацию содержит младшее слово параметра wParam , когда обрабатывается сообщение WM_COMMAND?
25. Какую информацию содержит младшее слово параметра wParam , когда обрабатывается сообщение WM_COMMAND?
26. Что такое контекст устройства?
26. Перечислите основные графические объекты.
27. Какие действия необходимо выполнить при использовании графических объектов?
28. О чем уведомляет приложение сообщение WM_PAINT?
29. Когда посылается сообщение WM_PAINT?
30. В каких ситуациях клиентская область окна становится недействительной?
31. Назовите функцию, которая посылает сообщение WM_PAINT и перерисовывает клиентскую/ область окна с дескриптором hWnd?
32. Какие различают типы пунктов меню?
33. Что такое пункт-команда?
34. Какие действия следуют за выбором пункта-команды меню?
35. Что такое пункт-подменю?
36. Какие действия следуют за выбором пункта-подменю?
37. Какими могут быть пункты меню по уровню доступности?
38. Какой уровень доступности пунктов меню назначается по умолчанию?
39. Что нужно сделать, чтобы пользователь знал, что пункт «отменен»?
40. Какая функция изменяет уровень доступности пунктов меню?
41. С помощью какой функции можно получить дескриптор подменю?
42. Какой функцией можно задать группы переключателей?