Итак, мы собираемся управлять ориентацией изображения с помощью левой кнопки мыши. Перемещение курсора мыши при нажатой кнопке должно вращать изображение наиболее естественным образом, то есть горизонтальное перемещение должно происходить вокруг вертикальной оси Y, а вертикальное — вокруг горизонтальной оси X. Если одновременно с мышью нажата клавиша Ctrl, то мы будем перемещать (транслировать) изображение вдоль осей X и Y. С помощью правой кнопки будем перемещать изображение вдоль оси Z. Кроме того, с помощью левой кнопки мыши мы дадим возможность придать вращению постоянный характер. Для этого в обработчик WM_LBUTTONUP введем анализ на превышение квантом перемещения (m_dx, m_dy) некоторого порога чувствительности. Если он превышен, то мы запустим таймер, и дальнейшее вращение будем производить с его помощью. Если очередной квант перемещения ниже порога чувствительности, то мы остановим таймер, прекращая вращение. В обработке WM_MOUSEMOVE следует оценивать желаемую скорость вращения, которая является векторной величиной из двух компонентов и должна быть пропорциональна разности двух последовательных координат курсора. Такой алгоритм обеспечивает гибкое и довольно естественное управление ориентацией объекта. Начнем с обработки нажатия левой кнопки. Оно, очевидно, должно всегда останавливать таймер, запоминать факт нажатия кнопки и текущие координаты курсора мыши:
void COGView: :OnLButtonDown (UINT nFlags, CPoint point)
{
//====== Останавливаем таймер
KillTimer(1);
//====== Обнуляем кванты перемещения
m_dx = 0.f; m_dy = 0.f;
//====== Захватываем сообщения мыши,
//====== направляя их в свое окно
SetCapture ();
//====== Запоминаем факт захвата
m_bCaptured = true;
//====== Запоминаем координаты курсора
m_pt = point;
}
При нажатии на правую кнопку необходимо выполнить те же действия, что и при нажатии на левую, но дополнительно надо запомнить сам факт нажатия правой кнопки, с тем чтобы правильно интерпретировать последующие сообщения о перемещении указателя мыши и вместо вращения производить сдвиг вдоль оси Z: