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

Класс QwertyWin

В программе Qwerty, как и во всех остальных программах этой книги, специализированный класс окна порождается от базового класса DirectDrawWin. В данном случае производный класс называется QwertyWin (см. листинг 6.1).

Листинг 6.1. Класс QwertyWin

class QwertyWin : public DirectDrawWin {

public:

 QwertyWin();

protected:

 //{{AFX_MSG(QwertyWin)

 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

 afx_msg void OnDestroy();

 afx_msg void OnActivate(UINT nState, CWnd* pWndOther,    BOOL bMinimized);

 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

private:

 int SelectDriver();

 int SelectInitialDisplayMode();

 BOOL CreateCustomSurfaces();

 void DrawScene();

 void RestoreSurfaces();

private:

 LPDIRECTINPUT dinput;

 LPDIRECTINPUTDEVICE keyboard;

 BOOL esc_pressed;

 LPDIRECTDRAWSURFACE esc_up, esc_dn;

 LPDIRECTDRAWSURFACE space_up, space_dn;

 LPDIRECTDRAWSURFACE q_up, q_dn;

 LPDIRECTDRAWSURFACE w_up, w_dn;

 LPDIRECTDRAWSURFACE e_up, e_dn;

 LPDIRECTDRAWSURFACE r_up, r_dn;

 LPDIRECTDRAWSURFACE t_up, t_dn;

 LPDIRECTDRAWSURFACE y_up, y_dn;

 LPDIRECTDRAWSURFACE rctrl_up, rctrl_dn;

 LPDIRECTDRAWSURFACE lctrl_up, lctrl_dn;

 LPDIRECTDRAWSURFACE lalt_up, lalt_dn;

 LPDIRECTDRAWSURFACE ralt_up, ralt_dn;

};

Прежде чем двигаться дальше, обратите внимание на отсутствие обработчика OnKeyDown(). Во всех программах, рассмотренных нами ранее, функция OnKeyDown() обрабатывала сообщения от клавиатуры. В программе Qwerty мы пользуемся услугами DirectInput и потому не нуждаемся в OnKeyDown().

В самом начале объявляются три обработчика сообщений:

• OnCreate()

• OnDestroy()

• OnActivate()

Функция OnCreate() инициализирует и настраивает DirectInput, а функция OnDestroy() освобождает объекты DirectInput. Функция OnActivate(), вызываемая MFC при получении или потере фокуса, будет использована для повторного захвата клавиатуры.

Две следующие функции, SelectDriver() и SelectInitialDisplayMode(), присутствуют почти во всех наших программах. Они остались в том виде, в котором их создал AppWizard, и потому не требуют обсуждения.

Функции CreateCustomSurfaces() и RestoreSurfaces() делают то же, что и раньше, так что они тоже не рассматриваются. Достаточно сказать, что эти функции инициализируют и восстанавливают поверхности, указатели на которые объявляются в нижней части листинга 6.1.

Функция DrawScene() с помощью DirectInput определяет, какие клавиши были нажаты, и обеспечивает соответствующий вывод. Вскоре мы рассмотрим эту функцию.

После функций следуют переменные класса. Сначала объявляется указатель на интерфейс DirectInput(dinput), через него выполняется инициализация и осуществляются обращения к DirectInput. Переменная key — указатель на интерфейс DirectInputDevice, используемый для обращений к клавиатуре. Логическая переменная esc_pressed сигнализирует о завершении приложения.

Оставшаяся часть определения класса состоит из указателей на интерфейсы DirectDrawSurface. Для каждой клавиши, поддерживаемой приложением, создаются две поверхности (для нажатого и отпущенного состояния).

Инициализация DirectInput

Инициализация DirectInput и DirectDraw выполняется в функции OnCreate(). DirectInput инициализируется версией OnCreate () класса QwertyWin, а DirectDraw — версией из DirectDrawWin. Функция QwertyWin::OnCreate() приведена в листинге 6.2.

Листинг 6.2. Функция QwertyWin::OnCreate()

int QwertyWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {

 HRESULT r=DirectInputCreate(AfxGetInstanceHandle(),    DIRECTINPUT_VERSION, &dinput, 0);

 if (r!=DI_OK) {

  AfxMessageBox('DirectInputCreate() failed');

  return -1;

 }

 r = dinput->CreateDevice(GUID_SysKeyboard, &keyboard, 0);

 if (r!=DI_OK) {

  AfxMessageBox('CreateDevice(keyboard) failed');

  return -1;

 }

 r = keyboard->SetDataFormat(&c_dfDIKeyboard);

 if (r!=DI_OK) {

  AfxMessageBox('keyboard->SetDataFormat() failed');

  return -1;

 }

 r=keyboard->SetCooperativeLevel(GetSafeHwnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

 if (r!=DI_OK) {

  AfxMessageBox('keyboard->SetCooperativeLevel() failed');

  return -1;

 }

 if (DirectDrawWin::OnCreate(lpCreateStruct)==-1) return -1;

 return 0;

}

Прежде всего обратите внимание — версия OnCreate() базового класса вызывается лишь в конце функции. Это сделано для того,

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату