Главная :: Программы для программирования :: wxWidgets :: Перевод книги "Programming with wxWidgets" :: Глава 6 – Обработка данных с устройств ввода. Часть 5
Если твой компьютер завис - выдерни шнур, выдави стекло.

Глава 6 – Обработка данных с устройств ввода. Часть 5

6.3 Обработка событий от джойстика

Класс wxJoystick дает вашему приложению возможность получать информацию от одного или двух джойстиков в ОС Windows или Linux. Как правило, вы создаете объект wxJoystick, передавая wxJOYSTICK1 или wxJOYSTICK2 и храните объект в ОЗУ, пока он нужен. Когда вам нужно получить с него данные, пошлите функцию SetCapture, передав указатель на окно, которое будет получать события джойстика, а затем вызовите ReleaseCapture, если вам больше не нужны события. Вы можете поставить захват на все время работы приложения вызвав SetCapture при инициализации и ReleaseCapture при выходе.

Для более детального описания событий и методов рассмотрим пример samples/joystick из дистрибутива wxWidgets. Управляя джойстиком пользователь может рисовать последовательности линий на холсте, нажимая любую из кнопок джойстика. При нажатии также воспроизводится звук.

Ниже представлен фрагмент кода инициализации. Сначала приложение, создавая временный объект джойстика, проверяет, установлен ли джойстик и завершается, если нет. Звуковой файл buttonpress.wav загружается в объект wxSound, хранящийся в объекте приложения. Минимальная и максимальная позиции джойстика также сохраняются, чтобы линии помещались в окно.

#include "wx/wx.h" #include "wx/sound.h" #include "wx/joystick.h" bool MyApp::OnInit() { wxJoystick stick(wxJOYSTICK1); if (!stick.IsOk()) { wxMessageBox(wxT("No joystick detected!")); return false; } m_fire.Create(wxT("buttonpress.wav")); m_minX = stick.GetXMin(); m_minY = stick.GetYMin(); m_maxX = stick.GetXMax(); m_maxY = stick.GetYMax(); // Создаем главный фрейм окна ... return true; }

MyCanvas — это окно, которое хранит объект джойстика, а также получает от

него события. Вот реализация MyCanvas:

BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) EVT_JOYSTICK_EVENTS(MyCanvas::OnJoystickEvent) END_EVENT_TABLE() MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size): wxScrolledWindow(parent, wxID_ANY, pos, size, wxSUNKEN_BORDER) { m_stick = new wxJoystick(wxJOYSTICK1); m_stick->SetCapture(this, 10); } MyCanvas::~MyCanvas() { m_stick->ReleaseCapture(); delete m_stick; } void MyCanvas::OnJoystickEvent(wxJoystickEvent& event) { static long xpos = -1; static long ypos = -1; wxClientDC dc(this); wxPoint pt(event.GetPosition()); // Если возможны отрицательные координаты, то делаем, чтобы минимум был 0 int xmin = wxGetApp().m_minX; int xmax = wxGetApp().m_maxX; int ymin = wxGetApp().m_minY; int ymax = wxGetApp().m_maxY; if (xmin < 0) { xmax += abs(xmin); pt.x += abs(xmin); } if (ymin < 0) { ymax += abs(ymin); pt.y += abs(ymin); } // Масштабируем по размеру холста int cw, ch; GetSize(&cw, &ch); pt.x = (long) (((double)pt.x/(double)xmax) * cw); pt.y = (long) (((double)pt.y/(double)ymax) * ch); if (xpos > -1 && ypos > -1 && event.IsMove() && event.ButtonIsDown()) { dc.SetPen(*wxBLACK_PEN); dc.DrawLine(xpos, ypos, pt.x, pt.y); } xpos = pt.x; ypos = pt.y; wxString buf; if (event.ButtonDown()) buf.Printf(wxT("Joystick (%d, %d) Fire!"), pt.x, pt.y); else buf.Printf(wxT("Joystick (%d, %d)"), pt.x, pt.y); frame->SetStatusText(buf); if (event.ButtonDown() && wxGetApp().m_fire.IsOk()) { wxGetApp().m_fire.Play(); } }

6.3.1 События wxJoystick

Класс wxJoystick создает события типа wxJoystickEvent. Соответствующие им макросы представлены в таблице 6.5. Каждый макрос принимает один аргумент — функцию обработки события.

6.3.2 Методы класса wxJoystickEvent

Ниже представлено описание функции класса wxJoystickEvent, которые вы можете вызывать для получения дополнительной информации о событии. Как обычно, вы можете вызвать функцию GetEventType, чтобы получить тип события, что полезно при использовании макроса EVT_JOYSTICK_EVENTS, который отлавливает все события от джойстика.

Вызов ButtonDown позволяет проверить, было ли событие вызвано нажатием кнопки. Вы можете дополнительно передать идентификатор кнопки wxJOY_BUTTONn

(где n = 1, 2, 3 или 4) чтобы определить, какая конкретно кнопка была нажата, или wxJOY_BUTTON_ANY, если вам это не важно. Метод ButtonUp работает также, но проверяет событие отпускание соответствующей кнопки. Метод IsButton равносилен применению конструкции ButtonDown() || ButtonUp().

Чтобы проверить, была ли кнопка нажата во время генерации события (если, например, событие представляет не само нажатие кнопки), вызывите метод ButtonIsDown с теми же аргументами, что и ButtonDown. В противном случае используйте GetButtonState (с теми же аргументами), чтобы получить битовый список идентификаторов wxJOY_BUTTONn.

Вызовете метод IsMove чтобы проверить, было ли событие движением в плоскости XY и IsZMove — по оси Z.

Функция GetPosition возвращает объект wxPoint с текущей позицией в плоскости XY, а GetZPosition возвращает целое, представляющее собой Z-координату, если таковая поддреживается.

Наконец, вы можете определить, какой джойстик послужил причиной события (wxJOYSTICK1 или wxJOYSTICK2) вызвав GetJoystick.

6.3.3 Методы класса wxJoystick

Мы не хотим приводить здесь все методы джойстика полностью, для этого вы можете обратиться к справочной информации по классу wxJoystick, но укажем наиболее интересные.

Как было показано в примере, функцию SetCapture необходимо вызывать для прямого получения данных с джойстика в определенное окно, и, соответственно, ReleaseCapture для освобождения и использования его другими приложениями. В случае, если джойстик занят другим приложением или неисправен, вызывайте IsOK перед попыткой захвата. Вы также можете определить характеристики джойстика при помощи функций GetNumberButtons, GetNumberJoysticks, GetNumberAxes, HasRudder и прочих.

Вы можете получить состояние джойстика извне обработчика события с такими фунциями как GetPosition и GetButtonState.

Вашему приложению почти всегда потребуется вызвать GetXMin, GetXMax и подобные функции для определения диапазона, поддерживаемого джойстиком.

6.4 Заключение

В этой главе вы узнали о получении данных с мыши, клавиатуры и джойстика. Теперь вы сможете добавить взаимодействие с устройствами ввода в ваше приложение. Для углубления степени понимания рекомендуем изучить примеры samples/keyboard, samples/joytest и samples/dragimag, а также класс wxThumbnailCtrl в examples/chap12 на прилагаемом CD-ROM.

Следующая глава расскажет, как можно добиться гибкой, переносимой, легко переводимой, и, прежде всего, привлекательной компоновки элементов окна с помощью нашего гибкого друга — сайзера (sizer).