Иллюстрированный самоучитель по Visual Studio .NET

Интерактивное управление положением и ориентацией

Теперь хочется рассмотреть трехмерный объект с разных сторон. Удобнее это делать с помощью мыши. Документация MSDN содержит весьма скудные сведения относительно aux-функций, но в примерах все же можно найти какую-то информацию. Оказывается для введения реакции на мышиные события надо ввести в main следующие строки и, конечно, написать функции обработки:

auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSELOC,OnLMouseMove);
auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSELOC,OnRMouseMove);
auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,OnButtonDown);
auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSEDOWN,OnButtonDown);

Обратите внимание, что их разделяет WM_MOUSEMOVE на две (в общем случае на три) кнопки. Это нам как раз подходит, так как мы хотим левой кнопкой вращать, а правой удалять-приближать (делать zooming) изображение. События отпускания кнопок нам не понадобились по причине того, что обработчики AUX_MOUSELOC (читай WM_MOUSEMOVE) вызываются только в случае, если соответствующие кнопки нажаты. Поэтому не нужно поднимать и отпускать флаг захвата объекта мышью. Именно это нам и нужно.

Как легко, когда кто-то все продумал! Мы не делаем различия между нажатиями левой и правой кнопки, так как задача у них общая – запомнить текущие координаты указателя мыши. Вставьте декларации четырех функций, а затем приступим к их созданию. Так как сейчас мы не имеем классов для инкапсуляции переменных состояния мыши, то придется добавить глобальные переменные:

int giX, giY; // Текущая позиция указателя мыши

Тела глобальных функций обработки вы должны вставить до того места, в котором они вызываются. Алгоритм изменения параметров gdAngleX, gdAngleX и gdTransZ очевиден, но обратите внимание на детали. Например, как добывать координаты курсора мыши. Их присылает система, a AUX хранит их в структуре data, информацию о которой вы можете получить разве что в файле заголовков Glaux.h:

static void _stdcall OnButtonDown(AUX_EVENTREC *pEvent)
{
//====== Запоминаем координаты мыши
giX = pEvent › data[AUX_MOUSEX];
giY = pEvent › data[AUX_MOUSEY];
}
static void _stdcall OnLMouseMove(AUX_EVENTREC *pEvent)
{
//====== Узнаем текущие координаты
int x = pEvent › data[AUX_MOUSEX];
int у = pEvent › data[AUX_MOUSEY];
//====== Изменяем углы поворота пропорционально
//====== смещению мыши
gdAngleX += (у – giY)/10.f;
gdAngleY += (x – giX)/10.f;
//====== Запоминаем координаты мыши
giX = x; giY = у; >
Static void _stdcall OnRMouseMove(AUX_EVENTREC *pEvent)
int x = pEvent › data[AUX_MOUSEX];
int у = pEvent › data[AUX_MOUSEY];
//=====<= На сколько удалить или приблизить
double dx = (x – giX)/200.f;
double dy = (y – giY)/200.f;
//====== Удаляем или приближаем
gdTransZ += (dx + dy)/2.f;
//====== Запоминаем координаты мыши
giX = x; giY = y;
}

Запустите и опробуйте. Кубик должен управляться, но в обработке мышиных событий присутствует явная ошибка. Для того чтобы ее увидеть, нажмите правую кнопку и выведите курсор мыши за пределы окна влево. Изображение исчезло. один из слушателей наших курсов (Халип В. М. E-mail: viktor@mail.ru) самостоятельно нашел объяснение этому казусу и устранил дефект. Для того чтобы обнаружить его, вставьте в список директив препроцессора еще одну – #include <stdio.h>, а в функцию OnRMouseMove – вызов printf ("\n%d",x);.

Теперь координата курсора мыши будет выводиться в текстовое окно консольного приложения. Повторите опыт с правой кнопкой и убедитесь в том, что при выходе за пределы окна (влево), координата х получает недопустимое значение (>65000). Для устранения дефекта достаточно заменить строки:

int x = pEvent › data[AUX_MOUSEX];
int у = pEvent › data[AUX_MOUSEY];

На:

short x= pEvent › data[AUX_MOUSEX];
short у = pEvent › data[AUX_MOUSEY];

В функциях OnLMouseMove и OnRMouseMove. Теперь повторите опыт и убедитесь в том, что, переходя через границу окна, координата х изменяется монотонно и приобретает отрицательные значения. Чтобы быть последовательным, замените тип глобальных данных для хранения текущей позиции курсора мыши. Вместо int giX, giY; вставьте short giX, giY;. Объяснение эффекта мы оставляем читателю в качестве упражнения по информатике.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.