| « Поставить закладку » « Сделать стартовой » | |||
|
|||
|
Статьи:: Графика и игроделание DirectX, OpenGL etc.) :: Direct3D :: Использование мышки средствами DirectInput
Использование мышки средствами DirectInput
В прошлом уроке мы научились, я надеюсь :), с помощью DirectInput8 пользоваться клавиатурой. В данном уроке мы продолжим тему пользовательского ввода и научимся использовать в наших программах мышку. В предыдущем уроке мы уже создали класс для работы
с DirectInput8, теперь нам осталось всего лишь добавить части отвечающие за
работу мышки. И теперь данный класс выглядит следующим образом :
class csc_DInput
{
private:
LPDIRECTINPUT8 p_dinput;
public:
csc_DInput ();
~csc_DInput ();
int CreateDInput (HINSTANCE);
int CreateKeyboard (HWND);
int CreateMouse (HWND);
void Destroy (void);
void Update (void);
void Accure (void);
void UnAccure (void);
class _keyboard
{
friend class csc_DInput;
private:
LPDIRECTINPUTDEVICE8 p_dev;
void Update (void);
bool bActive;
bool bUse;
unsigned char keys[256];
public:
bool IsActive (void) { return bActive; };
bool IsButD (DWORD);
bool IsAnyButD (void);
} keyboard;
class _mouse
{
friend class csc_DInput;
private:
LPDIRECTINPUTDEVICE8 p_dev;
void Update (void);
bool bActive;
bool bUse;
bool bDone;
DIDEVICEOBJECTDATA data;
DWORD elem;
int Speed;
bool bMove;
bool bButD[8];
int But[8];
int oldpos[3];
int posrange[6];
int curpos[3];
int deltapos[3];
#define X_AXIS 0
#define Y_AXIS 1
#define Z_AXIS 2
#define WHEEL_AXIS Z_AXIS
public:
void SetData
(int, int, int, int, int, int, int, int, int, int);
bool IsActive (void) { return bActive; };
int GetCurPos (int axis) { return curpos[axis]; };
int GetDeltaPos (int axis) { return deltapos[axis]; };
bool IsMove (void) { return bMove; };
bool IsButD (int but) { return bButD[but]; };
bool IsBJustD (int but)
{ return But[but]==1 ? true : false; };
bool IsBJustU (int but)
{ return But[but]==2 ? true : false; };
bool IsAnyButD (void);
} mouse;
};
здесь нам следует обратить внимание на следующие вещи : int CreateMouse (HWND); - Данная функция
предназначена для создание устройства типа мышь. Рассмотрим теперь внутренности класса _mouse :
class _mouse
{
friend class csc_DInput;
private:
LPDIRECTINPUTDEVICE8 p_dev;
void Update (void);
bool bActive;
bool bUse;
bool bDone;
DIDEVICEOBJECTDATA data;
DWORD elem;
int Speed; // mouse speed in pexel
bool bMove; // is mouse moved after last updating
bool bButD[8]; // is mouse buttons down
int But[8]; // buttons state
int oldpos[3]; // old mouse pos
int posrange[6]; // range of mouse movement (x1, y1, z1, x2, y2, z2)
int curpos[3]; // current mouse pos
int deltapos[3]; // delta update
#define X_AXIS 0
#define Y_AXIS 1
#define Z_AXIS 2
#define WHEEL_AXIS Z_AXIS
public:
void SetData (int, int, int, int, int, int, int, int, int, int);
bool IsActive (void) { return bActive; };
int GetCurPos (int axis) { return curpos[axis]; };
int GetDeltaPos (int axis) { return deltapos[axis]; };
bool IsMove (void) { return bMove; };
bool IsButD (int but) { return bButD[but]; };
bool IsBJustD (int but) { return But[but]==1 ? true : false; };
bool IsBJustU (int but) { return But[but]==2 ? true : false; };
bool IsAnyButD (void);
} mouse;
Вот что у нас там содержится : для того, что бы он был доступен из нашего главного класса, мы делаем его дружественным ( friend class csc_DInput; ) LPDIRECTINPUTDEVICE8 p_dev; - устройство
DirectInput8 для работы, в нашем случае, с мышкой bool bDone; - полностью ли мы получили
данные о мышке или нет int Speed; - скорость передвижения курсора
в пикселях #define X_AXIS 0 - представляет ось Х
И методы для работы с мышкой : void SetData (int X0, int Y0, int Z0, int X1, int Y1, int Z1, int X2, int Y2, int Y3, int Speed); - установка начальных данных для мышки - текущее положение X0 , Y0 , Z0
bool IsActive (void); - возвращает нам -
активна ли мышь в данный момент Вот мы рассмотрели протокол данного класса, теперь возьмемся за его внутренне устройство. Для начала рассмотрим функцию создания мышки int CreateMouse (HWND); :
int csc_DInput::CreateMouse (HWND hWnd)
{
if(FAILED(hr = p_dinput->CreateDevice (GUID_SysMouse,
&mouse.p_dev, 0))) return hr;
if(FAILED(hr = mouse.p_dev->SetDataFormat (&c_dfDIMouse))) return hr;
if(FAILED(hr = mouse.p_dev->SetCooperativeLevel (hWnd,
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
сначала мы создаем устройство DirectInput8 для
работы с мышкой ( GUID_SysMouse ), далее мы настраиваем и устанавливаем параметры работы мыши, здесь нам интересна цифра 64 - она показывает размер буфера, в который будут заноситься данные о состоянии мышки. и затем показываем, что мы используем мышку и она у нас активна. Также в главном классе у нас имеются функции, которые предназначены для всех устройств, следовательно, их нам необходимо обновить для того, что бы они обрабатывали и мышку. Я привожу тут сразу все эти четыре метода :
void csc_DInput::Accure (void)
{
if(keyboard.p_dev) keyboard.p_dev->Acquire ();
if(mouse.p_dev) mouse.p_dev->Acquire ();
};
void csc_DInput::UnAccure (void)
{
if(keyboard.p_dev) keyboard.p_dev->Unacquire ();
if(mouse.p_dev) mouse.p_dev->Unacquire ();
};
void csc_DInput::Update (void)
{
if(keyboard.bUse)
if(keyboard.bActive)
keyboard.Update ();
if(mouse.bUse)
if(mouse.bActive)
mouse.Update ();
};
void csc_DInput::Destroy (void)
{
UnAccure ();
_RELEASE_ (mouse.p_dev);
_RELEASE_ (keyboard.p_dev);
_RELEASE_ (p_dinput);
mouse.bUse = false;
mouse.bActive = false;
keyboard.bUse = false;
keyboard.bActive = false;
};
причем, как вы заметили, без объяснений. Надеюсь тут все понятно... Если нет, то посмотрите предыдущий урок. Далее возьмемся за методы, которые отвечают за работу с мышкой. Сперва самое первое - установка первоначальных параметров :
void csc_DInput::_mouse::SetData
(int in_x0, int in_y0, int in_z0,
int in_x1, int in_y1, int in_z1,
int in_x2, int in_y2, int in_z2,
int in_speed)
{
But[0] = But[1] = But[2] = 0;
curpos[X_AXIS] = in_x0;
curpos[Y_AXIS] = in_y0;
curpos[Z_AXIS] = in_z0;
posrange[X_AXIS] = in_x1;
posrange[Y_AXIS] = in_y1;
posrange[Z_AXIS] = in_z1;
posrange[X_AXIS+3] = in_x2;
posrange[Y_AXIS+3] = in_y2;
posrange[Z_AXIS+3] = in_z2;
Speed = in_speed;
};
здесь мы просто устанавливаем параметры. Далее идет самая главная часть по работе с мышкой - это обновление данных о состоянии мышки :
void csc_DInput::_mouse::Update (void)
{
memcpy (oldpos, curpos, sizeof(curpos));
ZeroMemory (But, sizeof(But));
ZeroMemory (deltapos, sizeof(deltapos));
bDone = FALSE;
while(!bDone)
{
elem = 1;
if(FAILED(hr = p_dev->GetDeviceData (sizeof(data), &data, &elem, 0)))
if(hr == DIERR_INPUTLOST) p_dev->Acquire ();
if(elem == 1)
{
switch(data.dwOfs)
{
case DIMOFS_X:
case DIMOFS_Y:
case DIMOFS_Z:
{
int axis = data.dwOfs >> 2;
deltapos[axis] += data.dwData * Speed;
curpos[axis] += deltapos[axis];
if(curpos[axis] < posrange[axis])
curpos[axis] = posrange[axis];
else if(curpos[axis] > posrange[axis+3])
curpos[axis] = posrange[axis+3];
};
break;
case DIMOFS_BUTTON0:
case DIMOFS_BUTTON1:
case DIMOFS_BUTTON2:
case DIMOFS_BUTTON3:
case DIMOFS_BUTTON4:
case DIMOFS_BUTTON5:
case DIMOFS_BUTTON6:
case DIMOFS_BUTTON7:
{
int butn = data.dwOfs - DIMOFS_BUTTON0;
if(bButD[butn])
bButD[butn] = false, But[butn] = 2;
else
bButD[butn] = true, But[butn] = 1;
};
break;
};
}
else if(elem == 0) bDone = true;
};
bMove = ((deltapos[X_AXIS] != 0) || (deltapos[Y_AXIS] != 0)) ? true : false;
};
сперва мы копируем данные о текущем положении
мышки в массив данных со старым положением, далее мы входим в цикл, и не выйдем из него до тех пор, пока не исчерпаем данные из буфера. далее мы извлекаем из буфера необходимые нам
данные о состоянии мышки и обрабатываем их. И последнее это мы проверяем, менялось ли положение мышки. Теперь мы можем взяться за функции получения этих данных в нашей программе. Они почти все представлены как инлайн функции в виде одной строки, так что привожу их сразу все.
bool IsActive (void) { return bActive; };
int GetCurPos (int axis) { return curpos[axis]; };
int GetDeltaPos (int axis) { return deltapos[axis]; };
bool IsMove (void) { return bMove; };
bool IsButD (int but) { return bButD[but]; };
bool IsBJustD (int but) { return But[but]==1 ? true : false; };
bool IsBJustU (int but) { return But[but]==2 ? true : false; };
bool csc_DInput::_mouse::IsAnyButD (void)
{
for(int i=0; i<8; i++)
if(bButD[i]) return true;
return false;
};
они очень просты и что они делают - я уже описывал, так что на данном месте данный урок заканчивается. Покажу лишь скриншот для данного примера, и предложу его скачать :). !!! Обратите внимание !!! тут я хочу обратить ваше внимание на следующий факт - я убрал из функции создание устройства строчки, отвечающие за захват устройств - и вынес это в отдельную функцию (собственно это и была отдельная функция). И теперь после того как вы создали все необходимые вам устройства ввода (клавиатура, мышка, а потом еще и джойстик или геймпад) и установили для них данные - то вам необходимо вызвать метод захвата устройств - например у меня это выглядит так : directinput8.CreateDInput (hInst); directinput8.CreateKeyboard (hWnd); directinput8.CreateMouse (hWnd); directinput8.mouse.SetData (d3ddm[iModeNum].Width/2, d3ddm[iModeNum].Height/2, 0, 0, 0, d3ddm[iModeNum].Width, d3ddm[iModeNum].Height, -10000, 10000, 1); directinput8.Accure (); И еще один аспект. Вы должны были заметить в функции обновления данных о состоянии мышки то, что я проверяю а не потеряно ли наше устройство : if(FAILED(hr = p_dev->GetDeviceData (sizeof(data), &data, &elem, 0))) if(hr == DIERR_INPUTLOST) p_dev->Acquire (); Это нужно для того, что бы удостовериться, что наша мышка не потеряна. Данную работу нужно было проделать и с клавиатурой, но в прошлом уроке я это упустил. Исправляюсь и привожу здесь правильную функцию для обновления состояния клавиатуры :
void csc_DInput::_keyboard::Update (void)
{
if(FAILED(hr = p_dev->GetDeviceState (sizeof(keys), (LPVOID)&keys)))
if(hr == DIERR_INPUTLOST)
p_dev->Acquire ();
};
Вот теперь действительно, вроде бы :), все... Рубрика: Direct3D
HTML 5: пять вещей вызывающих особый интер....
HTML 5 — это грядущее обновление гипертекстового языка разметки, основного способа создания контента для размещения его во всемирной паутине. Разработка HTML остановилась в 1999 году, на версии HTML 4.01 и с тех пор web-содержимое изменилось так, что текущие спецификации HTML перестали соответствовать сегодняшним требованиям. HTML 5 нацелен на то, чтобы увеличить функциональную совместимость HTML и соответствовать растущим требованиям разнообразного и смешанного web-контента. HTML 5 так же нацелен на устранение недостатков четвертой версии. В этой статье мы взглянем на 5 новых интересных вещей в HTML 5.
Подробнее... |
Рубрика: Html
| Добавлено: 22.12.2008
asp.net: ListView с разных сторон.
Элемент управления ListView был представлен в .Net Framework 3.5 как замена устаревшему GridView. Новый элемент имеет более расширенный функционал, чем его предшественник, но в тоже время лишен некоторых внутренних механизмов, что впрочем целиком следствие из расширенной универсальности ListView. Среди отличий ListView и GridView можно назвать и гибкую настройку разметки, что позволяет выводить данные не только в табличном виде, но и вообще в любом каком пожелает программист. Благодаря шаблонам ItemTemplate, EditItemTemplate, InsertItemTeplate можно настроить внешний вид при любом из состояний ListView: редактировании или выборе элемента.
Подробнее... |
Рубрика: .NET компоненты
| Добавлено: 22.12.2008
Создание кросс-таб отчета в Stimulsoft Rep....
Компания Стимулсофт предоставляет для разработчиков мощный набор инструментов для создания отчетов для Microsoft Visual Studio .Net 2005 и 2008; эти инструменты доступны как для Windows Forms, так и для Web Forms. Это генератор отчетов Stimulsoft Reports.Net. Генератор отчетов Stimulsoft Reports.Net имеет ряд особенностей: простая работа с дизайнером отчетов, полная поддержка экспорта в PDF, Word, Excel и многие другие форматы. Crystal Report и Microsoft Reporting Service – очень хорошие программные продукты для повседневной работы, но, если Вам необходимо создать отчеты с поддержкой кросс-табов, drill down, Ajax, штрих-кодов и возможностью подключения одновременно более одного источника данных, то Stimulsoft Reports.Net поможет Вам сэкономить массу времени. Также, данный генератор отчетов позволяет пользователям создавать свои собственные отчеты любой сложности. И все эти особенности делают Stimulsoft Reports.Net хорошим выбором в сфере программных продуктов для Business Intelligence.
Подробнее... |
Рубрика: .NET компоненты
| Добавлено: 22.12.2008
Остальные статьи: |
Цитата дня (все,добавить):
|
Realcoding.NET
© 2003-2008 |
Контакты |
Реклама на сайте
|