Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 [Все]   Вниз
  Печать  
Автор Тема: DirectInput в DirectX 9  (Прочитано 78371 раз)
0 Пользователей и 1 Гость смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« : 31-07-2009 08:44 » 

У меня:

1. Microsoft Visual C++ 6.0 Standard Edition
2. DirectX 9c SDK ноябрь 2008

А так начинается мой код

Код:
#define DIRECTINPUT_VERSION 0x0800

#include <windows.h>
// подключаем заголовочный файл DirectX 9 SDK
#include <d3d9.h>
#include <d3dx9.h>
// Для работы с mesh
#include <d3dx9mesh.h>

// Для работы с DirectInput
#include <dinput.h>
#include <math.h>
#include "camera.h"

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
// Для работы с DirectInput
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

// Для того, что бы работала функция timeGetTime()
#pragma comment(lib, "winmm.lib")

LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;

// Указатель на Mesh
LPD3DXMESH pMesh = NULL;
// Указател на буфер mesh-а
LPD3DXBUFFER pMeshBuffer = NULL;
// Указатель на буфер материалов
D3DMATERIAL9 *pMeshMaterial = NULL;
// Указатель на буфер текстур
LPDIRECT3DTEXTURE9 *pMeshTexture = NULL;
// Указатель на интерфейс DirectInput
LPDIRECTINPUT8 pInput = NULL;
//  Указатель на устройство ввода
LPDIRECTINPUTDEVICE8 pInputDevice = NULL;
// Количество материала и текстур
DWORD dwNumber = 0;

DWORD OneTick = 0;

HINSTANCE hInstance;
...
...
...

Ошибки:

--------------------Configuration: di - Win32 Debug--------------------
Compiling...
di.cpp
c:\di\di.cpp(38) : error C2146: syntax error : missing ';' before identifier 'pInput'
c:\di\di.cpp(38) : error C2501: 'LPDIRECTINPUT8' : missing storage-class or type specifiers
c:\di\di.cpp(38) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

Подключить директории я не забыл, вот printscreen-ы





Я как-то не так задал библиотеки для работы DirectInput, а как правильно, не знаю, в Интернете по-разному пишут, но всё не работает.
Помогите, пожалуйста, избавиться от этих ошибок.
« Последнее редактирование: 13-09-2009 10:52 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 31-07-2009 09:39 » 

прицепи проект

а кстати, не относится к теме, но
LPDIRECT3DTEXTURE9 *pMeshTexture = NULL;
надо ли тут * ? Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #2 : 31-07-2009 09:49 » 

Я тоже на счёт этого удивился, но без * вроде не работает.

Я прицепил не проект, а исходный код, проект прицепить не смог, так как он очень большой и не приципляется.

* di.rar (43.95 Кб - загружено 1043 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 31-07-2009 15:25 » 

как я выяснил путём ковыряния, происходит конфликт:
C:\Program Files\Microsoft DirectX SDK (August 2008)\Include\dinput.h
и
C:\Program Files\Visual Studio 6\VC98\Include\dinput.h


вставляется первый файл в списке - а это у нас обоих выходит студийный файл

победить ещё не смог
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #4 : 31-07-2009 17:28 » 

Алексей1153++

Какой хитрый DirectInput))). А я думал я что то туплю))). Ну уже есть от чего отталкиваться. Большое спасибо.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 31-07-2009 18:05 » 

поищи в интернете, наверняка кто то решал ) А я щас немного шарпом (бэ) занят, да и трафика маловато осталось. Потом расскажи, как это перебороть )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #6 : 31-07-2009 20:10 » 

Вот код для правельной компиляции.

Код:
// Для работы с DirectInput
#define DIRECTINPUT_VERSION 0x0800
#define INITGUID

#include <dinput.h>

#pragma comment (lib, "dinput.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

А так же настроить Microsoft Visual C++ 6.0 Standard Edition



И ещё несколько вопросов по DirectInput

1. В DirectInput делать лучше с буферизированным вводом с клавиатуры или без него?

2. В какой части кода я должен запускать функцию InitDirectInput в которой происходит инициализация и проверка нажатых клавиш может её надо разбить на две функции инициализация и проверка нажатых клавишь, тогда в каком месте кода писать эти две функции?

Сейчас у меня нажатия клавишь не ловятся, а должны ловится клавиши 1, 2, 3, 4.

Прикрепляю код.

* di_Edit.rar (43.99 Кб - загружено 1040 раз.)
« Последнее редактирование: 31-07-2009 21:16 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 01-08-2009 04:49 » 

я ещё не разбирался с инпутом ) А по интуиции:

1) клавиши навигации по 3D миру лучше не буферизировать - они актуальны только в момент нажатия. А вот клавиши вызова меню и прочик окошек - думаю стОит запомнить в буфер

2) инициализацию и настройку вынести в отдельную йункцию. А опрос делать где нибудь в конце функции Render

---------
насчёт кода:
компиляция у меня прошла, только линкер ругается
dxguid.lib(dxguid.obj) : fatal error LNK1103: debugging information corrupt; recompile module

пока не разбирался, почемур

------------
а ещё компилятор правильно подсказывает, что ползуешься неинициализированной переменной Ага
    return (int)msg.wParam;


Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #8 : 01-08-2009 05:21 » 

Цитата: Алексей1153++
а ещё компилятор правильно подсказывает, что ползуешься неинициализированной переменной
return (int)msg.wParam;

На счёт этого знаю. Пока руки не доходят поправить.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 01-08-2009 05:22 » 

это поправить невероятно легко

return 0;
Ага
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #10 : 01-08-2009 05:32 » 

Исправил что бы не было предупреждения связанного с return (int)msg.wParam; перенёс использование функции InitDirectInput(); в функцию рендерига, теперь клавиши стали определятся.

Осталось из функции  InitDirectInput(); вынуть код отвечающий за определения нажатой клавиши, и сделать из него отдельную функцию, а также сделать буферизированный ввод и нажатия мыши отловить, с джостиком вазится не буду если понадобится по ходу дела сделаю.
« Последнее редактирование: 01-08-2009 05:46 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 01-08-2009 06:04 » 

Осталось из функции  InitDirectInput(); вынуть код отвечающий за определения нажатой клавиши, и сделать из него отдельную функцию,
воистину обязательно разднлить ) Ведь инитку надо вызвать один раз, а опрос - в конце каждого рендера

и вообще , напрашивается класс-обёртка
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #12 : 01-08-2009 06:08 » 

Класс я пуду делать когда буду первую игру создавать, а пока обойдусь этим.

К стати инициализацию DirectInput в какой части кода лучше проводить?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 01-08-2009 06:42 » 

где - ну, по смыслу. Когда игра началась, скажем )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #14 : 01-08-2009 07:02 » 

То есть в конце функции int WINAPI WinMain(HINSTANCE hInst,   HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)?

И ещё такая странность, когда так всё прекрасно работает

То есть:
1. Нажимаю клавишу '1' выводится сообщение "Нажата клавиша 1"
3. Нажимаю клавишу '2' выводится сообщение "Нажата клавиша 2"
3. Нажимаю клавишу '3' выводится сообщение "Нажата клавиша 3"
4. Нажимаю клавишу '4' выводится сообщение "Нажата клавиша 4"

Код:
#define  KEYDOWN(name,key)(name[key] &0x80)

// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
            ...
            ...
            ...
InitDirectInput();
            ...
            ...
            ...
}


// Функция инициализация DirectInput
bool InitDirectInput(void)
{
    // Создание интерфейс устройства
    if FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL))
        return false;

    // Создание устройства клавиатуры
    if FAILED(pInput->CreateDevice(GUID_SysKeyboard, &pInputDevice, NULL))
    {
        DeleteDirectInput();
        return false;
    }

    // Установка формата данных клавиатуры
if FAILED(pInputDevice->SetDataFormat(&c_dfDIKeyboard))
    {
        DeleteDirectInput();
        return false;
    }
    // Установка уровня взаимодействия клавиатуры (совместный доступ)
    if FAILED(pInputDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))
    {
        DeleteDirectInput();
        return false;
    }

    // Захват доступа к клавиатуре (активизировать управление)
    if FAILED(pInputDevice->Acquire())
    {
        DeleteDirectInput();
        return false;
    }

char keyboard[256]; // Буфер для хранения полученных данных от клавиатуры

    // Полученние данных с клавиатуры
    if FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard))
    {
        DeleteDirectInput();
        return false;
    }

    // Обработка клавиши < 1 >
    // Изменяем окружающие освещенние на зеленный цвет
    if (KEYDOWN(keyboard, DIK_1))
       MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

    // Обработка клавиши < 2 >
    // Возвращаем в исходное состояние
    if (KEYDOWN(keyboard, DIK_2))
       MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

    // Обработка клавиши < 3 >
    // Изменяем окружающие освещенние на синий цвет
    if (KEYDOWN(keyboard, DIK_3))
       MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

    // Обработка клавиши < 4 >
    // Изменяем окружающие освещенние на красный цвет
    if (KEYDOWN(keyboard, DIK_4))
      MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);

    return true;
}

// Функция освобождает захваченные ресурсы DeleteInput
void DeleteDirectInput(void)
{
    if (pInput)
    {
        if (pInputDevice)
        {
           if (pInputDevice != NULL)
              pInputDevice->Unacquire();

           if (pInputDevice != NULL)
              pInputDevice->Release();
           pInputDevice = NULL;
        }
        if (pInput != NULL)
           pInput->Release();
        pInput = NULL;
    }
}

А так работает, не правильно

То есть
Вывод сообщений зацикливается сразу при запуске приложения.

Код:
int WINAPI WinMain(HINSTANCE hInst,	HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    ...
    ...
    ...
    InitDirectInput();
   
    return 0;
}

// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
            ...
            ...
            ...
// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
            if (isKeyDown(DIK_1))
   MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
// Возвращаем в исходное состояние
if (isKeyDown(DIK_2))
   MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

            // Обработка клавиши < 3 >
// Изменяем окружающие освещенние на синий цвет
            if (isKeyDown(DIK_3))
   MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

// Обработка клавиши < 4 >
// Изменяем окружающие освещенние на красный цвет
if (isKeyDown(DIK_4))
   MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);
            ...
            ...
            ...
}

// Функция инициализация DirectInput
bool InitDirectInput(void)
{
    // Создание интерфейс устройства
    if FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL))
        return false;

    // Создание устройства клавиатуры
    if FAILED(pInput->CreateDevice(GUID_SysKeyboard, &pInputDevice, NULL))
    {
        DeleteDirectInput();
        return false;
    }

    // Установка формата данных клавиатуры
if FAILED(pInputDevice->SetDataFormat(&c_dfDIKeyboard))
    {
        DeleteDirectInput();
        return false;
    }
    // Установка уровня взаимодействия клавиатуры (совместный доступ)
    if FAILED(pInputDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))
    {
        DeleteDirectInput();
        return false;
    }

    // Захват доступа к клавиатуре (активизировать управление)
    if FAILED(pInputDevice->Acquire())
    {
        DeleteDirectInput();
        return false;
    }

char keyboard[256]; // Буфер для хранения полученных данных от клавиатуры

    // Полученние данных с клавиатуры
    if FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard))
    {
        DeleteDirectInput();
        return false;
    }

    return true;
}

// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(int KeyCode)
{
char KeyState[256];
if (KeyState[KeyCode] & 0x80)
   return true;
else
   return false;
}

// Функция освобождает захваченные ресурсы DeleteInput
void DeleteDirectInput(void)
{
    if (pInput)
    {
        if (pInputDevice)
        {
           if (pInputDevice != NULL)
              pInputDevice->Unacquire();

           if (pInputDevice != NULL)
              pInputDevice->Release();
           pInputDevice = NULL;
        }
        if (pInput != NULL)
           pInput->Release();
        pInput = NULL;
    }
}

В чём же дело?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 01-08-2009 13:35 » 

считаю, что вопрос не ко мне, так как я  - говорил - ещё не разбирался со вводом. Улыбаюсь

но мысли такие
1)
должно быть две функции:
      InitDirectInput() //инитка - настройка, все дела
      CheckDirectInput() //опрос нажатых, буферизирование и тд

2) InitDirectInput() не должен быть в RenderingDirect3D(void)
3)  InitDirectInput()  должен топологически быть где то в начале Main()  (и никак не перед return 0 - ведь тогда функция не вызовется, по сути, во время работы программы)
4) CheckDirectInput() можно вызвать в конце Render()

а что зацикливается - не могу знать ( Не запускал, писал выше, с причиной не разбирался - занят друим проектом щас

Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #16 : 01-08-2009 13:37 » 

Алексей1153++

Спасибо и на этом, буду думать.
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #17 : 12-09-2009 10:10 » 

Алексей1153++

Прошу прощения что так долго не отвечал. Вот взялся дальше за изучение.

Цитата: zuze
А так работает, не правильно

То есть
Вывод сообщений зацикливается сразу при запуске приложения.

С этим я разобрался.

У меня было так

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(int KeyCode)
{
char KeyState[256];
if (KeyState[KeyCode] & 0x80)
   return true;
else
   return false;
}

массив KeyState нужно не объявлять, а брать массив keyboard который уже объявлен.

Я решил вернутся к работающему коду, что его так расковырял что кнопкуи "1", "2", "3", "4" вообще не определяются.

Вот код который относится к DirectInput

Код:
// Для работы с DirectInput
#define DIRECTINPUT_VERSION 0x0800
#define INITGUID
#define KEYDOWN(name, key)(name[key] &0x80)
#include <dinput.h>

// Для работы с DirectInput
#pragma comment (lib, "dinput.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

// Указатель на интерфейс DirectInput
LPDIRECTINPUT8 pInput = NULL;
//  Указатель на устройство ввода
LPDIRECTINPUTDEVICE8 pInputDevice = NULL;
// Буфер для хранения полученных данных от клавиатуры
char keyboard[256];

// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
// Инициализация DirectInput
            InitDirectInput();
            ...
            ...
            ...
             if (SUCCEEDED(InitDirect3D(hwnd)))
            {
               if (SUCCEEDED(InitMesh()))
               {
      ShowWindow(hwnd, SW_SHOWDEFAULT);
                  UpdateWindow(hwnd);

      EnterMsgLoop(EnterKey);
               }
            }

            return 0;
}



// Я решил оставить в этой функцию полностью не убирать строки которые не относятся к DirectInput,
// что бы показать что я использую ещё метод определения клавишь WinAPI
// Функция обработки нажатия клавиш 
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
  TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
  TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
  TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
  TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
  TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
  TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
  TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
  TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
  TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
if (KEYDOWN(keyboard, DIK_1))
  MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
// Возвращаем в исходное состояние
if (KEYDOWN(keyboard, DIK_2))
   MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

// Обработка клавиши < 3 >
// Изменяем окружающие освещенние на синий цвет
if (KEYDOWN(keyboard, DIK_3))
   MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

    // Обработка клавиши < 4 >
// Изменяем окружающие освещенние на красный цвет
if (KEYDOWN(keyboard, DIK_4))
   MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);
}
return true;
}

// Функция синхронизации перемещения камеры по прошедшему с прошлого кадра времени (timeDelta)
void EnterMsgLoop (bool (*ptr_display)(float timeDelta))
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
        {
float currTime  = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

ptr_display(timeDelta);
lastTime = currTime;

RenderingDirect3D();
}
    }
}

// Функция инициализация DirectInput
bool InitDirectInput(void)
{   
    // Создание интерфейс устройства
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL)))
        return false;

    // Создание устройства клавиатуры
    if (FAILED(pInput->CreateDevice(GUID_SysKeyboard, &pInputDevice, NULL)))
    {
        DeleteDirectInput();
        return false;
    }

    // Установка формата данных клавиатуры
if (FAILED(pInputDevice->SetDataFormat(&c_dfDIKeyboard)))
    {
        DeleteDirectInput();
        return false;
    }
    // Установка уровня взаимодействия клавиатуры (совместный доступ)
    if (FAILED(pInputDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
    {
        DeleteDirectInput();
        return false;
    }

    // Захват доступа к клавиатуре (активизировать управление)
    if (FAILED(pInputDevice->Acquire()))
    {
        DeleteDirectInput();
        return false;
    }

    // Полученние данных с клавиатуры
    if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
    {
        DeleteDirectInput();
        return false;
    }
    return true;
}

// Функция освобождает захваченные ресурсы DeleteInput
void DeleteDirectInput(void)
{
    if (pInput)
    {
        if (pInputDevice)
        {
           if (pInputDevice != NULL)
              pInputDevice->Unacquire();

           if (pInputDevice != NULL)
              pInputDevice->Release();
           pInputDevice = NULL;
        }
        if (pInput != NULL)
           pInput->Release();
        pInput = NULL;
    }
}     

Почему же перестали вообще кнопки определятся "1", "2", "3", "4"?

Для лучшего понимания привожу полный код.

* di2.rar (44.07 Кб - загружено 1037 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 12-09-2009 15:13 » 

в причине не разбирался, немного некогда...
но в глаза бросается следующее:

Код:
		if (KEYDOWN(keyboard, DIK_1))
  MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

после подстановки твоего макроса будет
Код:
		if (KEYDOWN(keyboard, DIK_1))
if ((keyboard[DIK_1] &0x80)))
  MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

наверное, выражение  keyboard[DIK_1] &0x80 у тебя всегда == 0

кстати, макрос советую переделать так (а лучше вообще не использовать тут макрос Улыбаюсь )

Код:
enum
{
   e_keys_count=256
};

char keyboard[e_keys_count];

#define KEYDOWN(name, key) (name[ (key<e_keys_count) ? key : 0 ] &0x80)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #19 : 12-09-2009 16:57 » 

Алексей1153++

Учёл твои рекомендации и сделал так.

В место макроса сделал

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
if (keyboard[KeyCode] & 0x80)
  return true;
else
  return false;
}

И изменил функцию bool EnterKey(float timeDelta)

Код:
// Функция обработки нажатия клавиш  
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
 TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
 TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
 TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
 TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
 TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
                      TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
 TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
 TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
 TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
 TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
 TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
 TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
if (isKeyDown(DIK_1))
 MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
// Возвращаем в исходное состояние
if (isKeyDown(DIK_2))
 MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

// Обработка клавиши < 3 >
// Изменяем окружающие освещенние на синий цвет
if (isKeyDown(DIK_3))
 MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

   // Обработка клавиши < 4 >
// Изменяем окружающие освещенние на красный цвет
if (isKeyDown(DIK_4))
 MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);
}
return true;
}

Результат пока тот же, кнопки определятся "1", "2", "3", "4".

* di2_1.rar (43.94 Кб - загружено 1042 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 12-09-2009 17:01 » 

я, как ни силился, не увидел нечто, подобное
Код:
GetAsyncKeyState('1')

.

А если твой массив - это буфер, в котором где то накапливаются флаги нажатых клавиш, то , значит, проверяй, как этот массив заполняется
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #21 : 12-09-2009 17:52 » 

Цитата: Алексей1153++
А если твой массив - это буфер, в котором где то накапливаются флаги нажатых клавиш, то , значит, проверяй, как этот массив заполняется.

Я воспользовался твоим советом, но решил начать проверять ещё глубже, а именно создаётся ли устройство DirectInput

У меня было так:

Код:
// Функция инициализация DirectInput
bool InitDirectInput(void)
{   
    // Создание интерфейс устройства
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL)))
       return false;
    ...
    ...
    ...
}

А стало так:

Код:
// Функция инициализация DirectInput
bool InitDirectInput(void)
{   
    // Создание интерфейс устройства
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL)))
   {
      MessageBox(NULL, "Ошибка", "Сообщение", MB_OK);
      return false;
   }
   else
     MessageBox(NULL, "Успех", "Сообщение", MB_OK);
   ...
   ...
   ...
}

В результате было выясненно, что устройство DirectInput, не создаётся.

Интересно почему?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 12-09-2009 17:56 » 

откуда берёшь hInstance ?

В мсдн в примере делают так
GetModuleHandle(0)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #23 : 12-09-2009 18:13 » 

Алексей1153++

Прошу прощения это я накосячил.

У меня было так

Код:

// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    // Инициализация DirectInput
    InitDirectInput();

    WNDCLASSEX windowsclass;
    hInstance = hInst;

    windowsclass.cbSize = sizeof(WNDCLASSEX);
    windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    windowsclass.lpfnWndProc = MainWinProc;
    windowsclass.cbClsExtra = 0;
    windowsclass.cbWndExtra = 0;
    windowsclass.hInstance = hInst;
    windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    windowsclass.lpszMenuName = NULL;
    windowsclass.lpszClassName = "WINDOWSCLASS";
    windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&windowsclass))
        return 0;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением и камерой", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;
    ...
    ...
    ...
}

А нужно было так

Код:
// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WNDCLASSEX windowsclass;
    hInstance = hInst;

    windowsclass.cbSize = sizeof(WNDCLASSEX);
    windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    windowsclass.lpfnWndProc = MainWinProc;
    windowsclass.cbClsExtra = 0;
    windowsclass.cbWndExtra = 0;
    windowsclass.hInstance = hInst;
    windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    windowsclass.lpszMenuName = NULL;
    windowsclass.lpszClassName = "WINDOWSCLASS";
    windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&windowsclass))
        return 0;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением и камерой", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    // Инициализация DirectInput
    InitDirectInput();
    ...
    ...
    ...
}

Но  кнопки "1", "2", "3", "4" пока не определятся. Буду дальше думать.
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #24 : 12-09-2009 19:28 » 

Выяснил что этот код

Код:
// Получения данных с клавиатуры
if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
{
   DeleteDirectInput();
   return false;
}

Работает только при запуске программы, а потом нет, а надо что бы этот код находился постоянно в работе.

Сейчас думаю куда его нужно перенести, может кто посоветует куда его правельно перенести?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 13-09-2009 02:40 » 

а как понять "этот код работает" ? Улыбаюсь То есть, он выполняется и просиходит вызов

   DeleteDirectInput();

а тогда, я так понимаю, снова надо вызывать

   InitDirectInput();

Точно ничего посоветвать не могу - нет опыта работы с Улыбаюсь

Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #26 : 13-09-2009 09:16 » 

Я разобрался надо код

Код:
// Получения данных с клавиатуры
if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
{
   DeleteDirectInput();
   return false;
}

Перенести в функцию bool isKeyDown(char KeyCode) и вот что получилось

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
   // Полученние данных с клавиатуры
    if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
    {
        DeleteDirectInput();
        return false;
    }

    if (keyboard[KeyCode] & 0x80)
      return true;
    else
      return false;
}

Кнопки "1", "2", "3", "4" стали определятся!!!

Но почему-то после того как кнопка определилась выскакивает ошибка

---------------------------
Загрузка Х-файла с вращением и камерой: di2.exe - Ошибка приложения
---------------------------
Инструкция по адресу "0x00402349" обратилась к памяти по адресу "0x00000000". Память не может быть "read".


"ОК" -- завершение приложения
"Отмена" -- отладка приложения
---------------------------
ОК   Отмена   
---------------------------

Интересно почему и как избавится?

* di2_2.rar (43.96 Кб - загружено 967 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 13-09-2009 16:04 » 

волшебное средство - отладчик Улыбаюсь Особенно при таких вкусных ошибках, как обращение по нулевому указателю.
Где то не заполнен указатель
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #28 : 13-09-2009 19:38 » 

Алексей1153++

Я попытался проанализировать код пока без отладчика.

Вот мои рассуждения маленькие:

1. Без DirectInput X-файл прекрасно загружается;
2. Код относящийся к загрузки X-файл не трогал;
3. Значит дело в коде который относится к DirectInput.

И что же получилось я в место кода (если оставить этот код, то получается ошибка которую я описал в прошлом своём посте)

Код:
// Функция обработки нажатия клавиш  
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
 TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
 TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
 TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
 TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
 TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
 TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
 TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
 TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
 TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
 TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
 TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
 TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
if (isKeyDown(DIK_1))
 MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
if (isKeyDown(DIK_2))
 MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

// Обработка клавиши < 3 >
if (isKeyDown(DIK_3))
 MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

   // Обработка клавиши < 4 >
if (isKeyDown(DIK_4))
 MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);*/
}
return true;
}

Написал код (тогда программа работает без ошибок)

Код:
// Функция обработки нажатия клавиш  
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
 TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
 TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
 TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
 TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
 TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
 TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
 TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
 TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
 TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
 TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
 TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
 TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
if (isKeyDown(DIK_1))
 TheCamera.FirstBack(-4.0f * timeDelta);
}
return true;
}

В принципе я уже проверил, что у меня кнопки определяются при не буферизированном вводе с помощью DirectInput.

Но мне всё равно интересно почему при выводе окна сообщения программа слетает. Может кто знает поясните пожалуйста?
« Последнее редактирование: 14-09-2009 23:43 от zuze » Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #29 : 15-09-2009 00:06 » 

На счёт ошибки "обращение по нулевому указателю" пока не получилось разобраться придётся воспользоваться отладчиком.
Эта функция, где я использую MessageBox, возвращает значение true и используется в моём коде в качестве параметра другой функции.

В связи с этим у меня появился маленький вопрос:
Если функция возвращает значение, а следовательно используется в качестве параметра другой функции, можно ли в ней делать MessageBox, если нельзя то и отлаживать не имеет смысла всё равно ничего не получится?

Ещё один маленький вопрос:
Как проверить правильно ли я сделал DirectInput с буферным вводом?

То есть при нажатии на "1" или на "s", но "s" отпадает так как сделана с помощью WinAPI.
Значит при нажатии на "1" определённое количество раз появляется mesh на экране. При буферизированном вводе он появится быстрее.

Если да, то я так проверю работает у меня буферизированный ввод или нет, если нет то как тогда проверить что буферизированный ввод работает?

« Последнее редактирование: 15-09-2009 01:02 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #30 : 15-09-2009 03:00 » 

>>как тогда проверить что буферизированный ввод работает

в проблему не вник, но есть универсальное средство - лог Улыбаюсь В процедуре, где заполняешь буфер, выводи в текстовый файл введённый символ с меткой о времени ввода. Потом проанализируй
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #31 : 15-09-2009 10:07 » 

А как должен различаться по времени буферизированный ввод и не буферизированный ввод?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #32 : 15-09-2009 10:51 » 

эээ, дело не в различии, а в том, что ты увидишь, как синхронизированы события
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #33 : 15-09-2009 10:55 » 

Алексей1153++
Я не понимаю как это будет видно? Ты бы мог по подробней рассказать?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #34 : 15-09-2009 11:04 » 

сделай функцию-логгер  и поставь вызовы её в том месте, где в буфер складывается клавиша, и в том месте, где проверяется. Не забудь про синхронизацию потоков, если имеется.
В логе будет время событий(можно тики сохранять GetTickCount())

увидишь, как быстро происходит реакция на кнопку, тебе это нужно посмотреть ?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #35 : 15-09-2009 22:32 » 

Алексей1153++

У меня произошла ошибка, как и у тебя котрую ты описал в ответе #7

Цитата: Алексей1153++
Компиляция у меня прошла, только линкер ругается
dxguid.lib(dxguid.obj) : fatal error LNK1103: debugging information corrupt; recompile module

Я выяснил что я использую DirectX SDK за ноябрь 2008, а он не поддерживаеться Microsoft Visual C 6.0 придётся устанавливать Microsoft Visual Studio 2008 Express Edidion или Microsoft Visual Studio 2008 Profession Edidion.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #36 : 16-09-2009 03:03 » 

ну так и поставь 2008 Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #37 : 16-09-2009 17:30 » 

Алексей1153++

Прошу прощения что вопрос не в тему, но он возник из-за того что я установил Microsoft Visual Studio 2008 Profession Edidion.


Код

Код:
HRESULT InitMesh(void)
{
    if (FAILED(D3DXLoadMeshFromX(L"Tiger.x", D3DXMESH_SYSTEMMEM, pDirect3DDevice, NULL, &pMeshBuffer, NULL, &dwNumber, &pMesh)))
   return E_FAIL;

   // Извлекаем свойства материала и названия{имена} структуры
    D3DXMATERIAL *D3DXMeshMaterial = (D3DXMATERIAL *)pMeshBuffer->GetBufferPointer();
    pMeshMaterial = new D3DMATERIAL9[dwNumber];
    pMeshTexture   = new LPDIRECT3DTEXTURE9[dwNumber];
    for (DWORD i = 0; i < dwNumber; i++)
    {
        // Копируем материал
        pMeshMaterial[i] = D3DXMeshMaterial[i].MatD3D;
        // Установить окружающего свет
        pMeshMaterial[i].Ambient = pMeshMaterial[i].Diffuse;
        // Загружаем текстуру
        if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice, D3DXMeshMaterial[i].pTextureFilename, &pMeshTexture[i])))
          pMeshTexture[i] = NULL;
    }
    // Уничтожаем буфер материала
    pMeshBuffer->Release();

    return S_OK;
}

Возникла ошибка в

Error 1   error C2664: 'D3DXCreateTextureFromFileW' : cannot convert parameter 2 from 'LPSTR' to 'LPCWSTR'   c:\di\di.cpp   237   di


Я пробовал решить эту ошибку изменив эту строчку

Код:
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice, D3DXMeshMaterial[i].pTextureFilename, &pMeshTexture[i])))

На эту

Код:
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice, (LPCWSTR)D3DXMeshMaterial[i].pTextureFilename, &pMeshTexture[i])))

или на эту

Код:
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice, reinterpret_cast <LPCWSTR>(D3DXMeshMaterial[i].pTextureFilename), &pMeshTexture[i])))

Это не помогло что же делать, текстура не загружается?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #38 : 16-09-2009 17:43 » 

код не меняй, оставь как было.

А зайди в настройки
(у меня, правда, "русефецырованая", поэтому придётся тебе всё же напрячься, искаючи Улыбаюсь )
меню- проект->свойства->(+)свойства конфигурации , параметр "набор знаков (charset) ", - использовать многобайтовую кодировку (по умолчанию там юникод)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #39 : 16-09-2009 17:50 » 

Пробовал, выскочило ещё целая куча ошибок. Если необходимо могу их здесь привести.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #40 : 16-09-2009 17:51 » 

давай
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #41 : 16-09-2009 18:04 » 

Алексей1153++

Какая-то странность этих ошибок уже нет. Это я что то не так сделал. Но теперь из-за этого компилятора происходит следующие.
Запускаешь программу всё прекрасно работает, но если ты хочешь её закрыть или свернуть такого с тем компилятором небыло не менял код.

---------------------------
Загрузка Х-файла с вращением и камерой: di.exe - Ошибка приложения
---------------------------
Инструкция по адресу "0x00401fcb" обратилась к памяти по адресу "0x00000000". Память не может быть "read".


"ОК" -- завершение приложения
"Отмена" -- отладка приложения
---------------------------
ОК   Отмена   
---------------------------

Почему так получается?

Вот полный код

* di_2008.rar (44.11 Кб - загружено 999 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #42 : 16-09-2009 18:10 » 

запусти на отладку, только точки останова не ставь. Когда оно загнётся, выбери кнопку "повтор" (или что там будет) , потом смотри место, где покажет студия - так у тебя где то нулевой указатель
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #43 : 16-09-2009 18:26 » 

Алексей1153++

Я сделал Debug->Step Into (F11)

И вдруг выскочила ошибка в какойто момент

Unhandled exception at 0x00401fcb in di.exe: 0xC0000005: Access violation reading location 0x00000000.

Странно, но ошибка выскочила совершенно другая. Указывала на код pInputDevice->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
// Буферный ввод
unsigned long BUFFER_SIZE = 64; //размер буфера
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = BUFFER_SIZE;
pInputDevice->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);

ofstream fout("1.txt", ios_base::out | ios_base::app);
fout << GetTickCount(); // Запись в файл
fout << "-";
fout.close();

// Полученние данных с клавиатуры
            if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
            {
               DeleteDirectInput();
               return false;
            }

if (keyboard[KeyCode] & 0x80)
   return true;
else
   return false;
}
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #44 : 16-09-2009 18:29 » 

так надо было во время отладки то посмотреть значения переменных!

скорее всего, pInputDevice==0 было
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #45 : 16-09-2009 18:31 » 

а тут
https://forum.shelek.ru/index.php/topic,21644.0/wap2.html
описано, как включить привычные для VC6 горячки Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #46 : 16-09-2009 18:35 » 

Алексей1153++

Ты всё это сооброзил в уме, ты просто гений!!!

Вот что мне компилятор написал

Код:
		pInputDevice	0x00000000	IDirectInputDevice8A *
- IUnknown {...} IUnknown
__vfptr CXX0030: Error: expression cannot be evaluated
   

Значит что бы избавится от ошибки мне нужно в качестве параметра функции сделать pInputDevice?
« Последнее редактирование: 16-09-2009 18:38 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #47 : 16-09-2009 18:39 » 

так что там соображать то - в окошке ошибки это написано ) Только имени переменной нету.

Вот и разбирайся, где обнулил )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #48 : 16-09-2009 19:41 » 

Алексей1153++

Большое спасибо. Ошибку обнаружил и исправил.

Надо было отовсюду удалить вызовы DeleteDirectInput(); и сделать один вызов после цикла

Код:
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
...
                                    ...
                                    ...
}
else
                        {
            ...
                                    ...
                                    ...
}
    }

Что на счёт буферизированного ввода я сделал запись в функции проверки нажатия символа там каждый раз происходит получение данных с клавиатуры


Код:
ofstream fout("1.txt", ios_base::out | ios_base::app);
fout << GetTickCount(); // Запись в файл
fout << "-\n";
fout.close();

Где я проверяю нажатия

Код:
ofstream fout("1.txt", ios_base::out | ios_base::app);
fout << GetTickCount(); // Запись в файл
fout << "+\n";
fout.close();

Результат нажатия одного раз на кнопку "1".

Цитата
10759140-
10759150-
10759160-
10759180-
10759200-
10759220-
10759230-
10759250-
10759271-
10759281-
10759301-
10759311-
10759331-
10759351-
10759371-
10759381-
10759401-
10759411-
10759431-
10759451-
10759461-
10759481-
10759501-
10759521-
10759531-
10759551-
10759571-
10759581-
10759601-
10759621-
10759631-
10759651-
10759661-
10759681-
10759701-
10759711-
10759731-
10759751-
10759771-
10759781-
10759801-
10759811-
10759831-
10759851-
10759861-
10759881-
10759901-
10759911-
10759931-
10759951-
10759962-
10759982-
10760002-
10760012-
10760032-
10760052-
10760062-
10760082-
10760102-
10760112-
10760132-
10760152-
10760162-
10760182-
10760202-
10760222-
10760232-
10760252-
10760262-
10760282-
10760302-
10760312-
10760332-
10760352-
10760372-
10760382-
10760402-
10760412-
10760432-
10760452-
10760462-
10760482-
10760502-
10760512-
10760532-
10760552-
10760552+
10760562-
10760562+
10760582-
10760582+
10760592-
10760602+
10760612-
10760632-
10760653-
10760663-
10760683-
10760703-
10760713-
10760733-
10760753-
10760763-
10760783-
10760803-
10760813-
10760833-
10760853-
10760863-
10760883-
10760903-
10760913-
10760933-
10760953-
10760963-
10760983-
10760993-
10761013-
10761033-
10761053-
10761063-
10761083-
10761103-
10761113-
10761133-
10761143-
10761163-
10761183-
10761203-
10761213-
10761233-
10761253-
10761263-
10761283-
10761303-
10761313-
10761333-
10761354-
10761364-
10761384-
10761394-


И что это значит у меня правельно сделан буферизированный ввод или нет?

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #49 : 16-09-2009 19:51 » 

ну, всё зависит от

1) что ты понимаешь под этим словом и что ожидаешь от этого понятия
2) невзирая на пункт 1: что ты хотел добиться


анализируем количество срабатываний:  идёт около сотни считываний с клавы (что делал в этот момент ? Жал кнопку или не жал? ), и одна обработка

 потом идёт хорошо сбалансированный участок - нажатие+обработка

потом снова куча считываний.

Итог: считывание с клавы происходит гораздо чаще проверок, что положительно скажется на скорости реакции программы, однако жуткая разбалансировка даёт повод думать, что происходят лишние считывания. Подумать, почему и помешает ли это вообще. Может так оно и надо )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #50 : 16-09-2009 20:08 » 

Алексей1153++

Мне странно что всего много ведь что я сделал:
1. Запустил программу;
2. Нажал один раз (не удерживая) кнопку "1" и отпустил её сразу;
3. Закрыл программу.

А в файле почему то так много информации. Разве такое возможно при правельной работе?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #51 : 16-09-2009 20:16 » 

да возможно то оно возвожно, между записями в среднем по 20мс. Это может означать, что опрос клавиатуры осуществляется слишком часто, гораздо чаще, чем производится реакция программы на нажатие. Попробуй сделать замедлитель для опроса, регулируй замедлитель (скажем, 30...100 мс) и смотри, как будет лог писаться. Я думаю, надо добиваться равномерности событий считывание-обработка. Ну а окончательную полировку всё равно будешь производить при реальном использовании программы - пользователь сразу заметит, что кнопки плохо слушаются (при большом замедлителе) или тормозит программа (без замедлителя, возможно)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #52 : 16-09-2009 20:19 » 

А почему 4 раза есть реакция на нажатия, вроде бы должо быть один раз, ведь я только один раз нажимал или я не прав?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #53 : 16-09-2009 20:25 » 

ну вот как раз "хороший" участок - считалось, обработалось 4 раза равномерно.

Считывание же у тебя в цикле идёт - поэтому ему пофиг, отпустил ты кнопку или нет Улыбаюсь Так же и обработка. Но это всё нормально. Другое дело, если ты предусмотришь ещё набор флагов, где будешь запоминать, отпустили ли кнопку после нажатия. Тогда можно сделать так, чтобы реакция было один раз за одно сколь угодно длительное нажатие
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #54 : 16-09-2009 20:33 » 

То есть из анализа следует что буферизация ввода у меня есть, но не идеальна, так как должо быть 50%/50%?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #55 : 16-09-2009 20:42 » 

ну не обязательно 50/50, лучше даже будет (2 считывания/ 1 обработку)

ты по таймеру опрашиваешь клаву ?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #56 : 16-09-2009 20:45 » 

Я определяю с помощью функции GetTickCount().

Может я опрашиваю не правильно?
Посмотри пожалуйста мой код для опроса в Ответе #48 и дай пожалуйста ответ правельно ли сделал?
Если тебе кажется, что код не очень подробный ты скажи об этом я тебе сразу более подробно напишу.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #57 : 16-09-2009 20:51 » 

напиши подробнее.
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #58 : 16-09-2009 20:58 » 

Хорошо, вот подробно.

Код:
// Функция обработки нажатия клавиш
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
           if (isKeyDown(DIK_1))
           {
    //MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);
    TheCamera.FirstBack(-4.0f * timeDelta);
    ofstream fout("1.txt", ios_base::out | ios_base::app);
    fout << GetTickCount(); // Запись в файл
    fout << "+\n";
    fout.close();
           }
}
return true;
}

// Функция синхронизации перемещения камеры по прошедшему с прошлого кадра времени (timeDelta)
void EnterMsgLoop (bool (*ptr_display)(float timeDelta))
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
                       {
float currTime  = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

ptr_display(timeDelta);
lastTime = currTime;

RenderingDirect3D();
}
            }
DeleteDirectInput();
}

А вот, где это всё вызывается (почти в самом конце функции)

Код:
// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WNDCLASSEX windowsclass;
    hInstance = hInst;

    windowsclass.cbSize = sizeof(WNDCLASSEX);
    windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    windowsclass.lpfnWndProc = MainWinProc;
    windowsclass.cbClsExtra = 0;
    windowsclass.cbWndExtra = 0;
    windowsclass.hInstance = hInst;
    windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    windowsclass.lpszMenuName = NULL;
    windowsclass.lpszClassName = "WINDOWSCLASS";
    windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&windowsclass))
        return 0;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением и камерой", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    // Инициализация DirectInput
    InitDirectInput();

    if (SUCCEEDED(InitDirect3D(hwnd)))
    {
        if (SUCCEEDED(InitMesh()))
        {
           ShowWindow(hwnd, SW_SHOWDEFAULT);
           UpdateWindow(hwnd);

           EnterMsgLoop(EnterKey);
        }
    }

    return 0;
}

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
// Полученние данных с клавиатуры
            if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
            return false;

ofstream fout("1.txt", ios_base::out | ios_base::app);
fout << GetTickCount(); // Запись в файл
fout << "-\n";
fout.close();

if (keyboard[KeyCode] & 0x80)
   return true;
else
   return false;
}
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #59 : 17-09-2009 03:47 » 

у меня этот код выглядел бы так (по понятным причинам не компилировал Улыбаюсь )
Код:
//#include <windows.h>
//#include <fstream>
//------------------------------------------------------------

//логгирование
std::ofstream g_fout;

void OpenLogFile()
{
if(g_fout.is_open())return;
g_fout.open("1.txt", std::ios_base::out | std::ios_base::app);
}

void CloseLogFile()
{
if(g_fout.is_open())
{
g_fout.close();
}
}

void LogToFile(const char* pMarker)
{
if(g_fout.is_open())
{
g_fout << GetTickCount(); // Запись в файл
g_fout << pMarker <<"\r\n";
}
}

//------------------------------------------------------------
enum
{
e_keys_cnt=256,
};

BYTE g_keyboard[e_keys_cnt];

// Функция установки флага для нажатой в данный момент клавиши клавиатуры
bool ReadKeys()
{
// Полученние данных с клавиатуры
if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
{
return false;
}

LogToFile("ReadKeys");
return true;
}

bool IsKeyDown(char KeyCode)
{
LogToFile("-");
return (g_keyboard[min(e_keys_cnt,(BYTE)KeyCode)] & 0x80) != 0;
}

//------------------------------------------------------------

// Функция обработки нажатия клавиш
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)TheCamera.FirstBack(+4.0f*timeDelta);
if (GetAsyncKeyState('S') & 0x8000f)TheCamera.FirstBack(-4.0f*timeDelta);
if (GetAsyncKeyState('A') & 0x8000f)TheCamera.LeftRight(-4.0f*timeDelta);
if (GetAsyncKeyState('D') & 0x8000f)TheCamera.LeftRight(+4.0f*timeDelta);
if (GetAsyncKeyState('R') & 0x8000f)TheCamera.UpDown(+4.0f*timeDelta);
if (GetAsyncKeyState('F') & 0x8000f)TheCamera.UpDown(-4.0f*timeDelta);
if (GetAsyncKeyState(VK_UP) & 0x8000f)TheCamera.RollRightVector(+1.0f*timeDelta);
if (GetAsyncKeyState(VK_DOWN) & 0x8000f)TheCamera.RollRightVector(-1.0f*timeDelta);
if (GetAsyncKeyState(VK_LEFT) & 0x8000f)TheCamera.RollUpVector(+1.0f*timeDelta);
if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)TheCamera.RollUpVector(-1.0f*timeDelta);
if (GetAsyncKeyState('N') & 0x8000f)TheCamera.RollFirstVector(+1.0f*timeDelta);
if (GetAsyncKeyState('M') & 0x8000f)TheCamera.RollFirstVector(-1.0f*timeDelta);

// Полученние данных с клавиатуры
if(!ReadKeys())return false;

if(IsKeyDown(DIK_1))
{
TheCamera.FirstBack(-4.0f * timeDelta);
LogToFile("+");
}

if(IsKeyDown(DIK_2))
{
LogToFile("+");
}

if(IsKeyDown(DIK_3))
{
LogToFile("+");
}
}
return true;
}

// Оконная процедура
void EnterMsgLoop()
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
float currTime  = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

EnterKey(timeDelta);
lastTime = currTime;

RenderingDirect3D();
}
}
DeleteDirectInput();
}

// Главная процедура
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
WNDCLASSEX windowsclass;
hInstance = hInst;

windowsclass.cbSize = sizeof(WNDCLASSEX);
windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
windowsclass.lpfnWndProc = MainWinProc;
windowsclass.cbClsExtra = 0;
windowsclass.cbWndExtra = 0;
windowsclass.hInstance = hInst;
windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
windowsclass.lpszMenuName = NULL;
windowsclass.lpszClassName = "WINDOWSCLASS";
windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if (!RegisterClassEx(&windowsclass))return 0;

hwnd=CreateWindowEx(
0,
"WINDOWSCLASS",
"Загрузка Х-файла с вращением и камерой",
WS_OVERLAPPEDWINDOW|WS_VISIBLE,
0, 0, 770, 500, 0, 0, hInst, 0);

if (!hwnd)return 0;

// Инициализация DirectInput
InitDirectInput();

if (SUCCEEDED(InitDirect3D(hwnd)))
{
if (SUCCEEDED(InitMesh()))
{
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);

::memset(g_keyboard,0,sizeof(g_keyboard));

OpenLogFile();
EnterMsgLoop();
CloseLogFile();
}
}

return 0;
}

« Последнее редактирование: 17-09-2009 03:50 от Алексей1153++ » Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #60 : 21-09-2009 07:40 » 

Алексей1153++

А может можно проверить буферизированный ввод так:
Засунь в главном цикле, где PeekMessage() функцию Sleep( 10000 ); и нажимай/отпускай разные кнопки много раз. Если все нажатия и отпускания кнопок, которые были сделал за эти 10 секунд, придут, значит работает.

Только не совсем понимаю как это реализовать, зато уже не надо будет анализировать текстовый файл, а достаточно его один раз посмотреть или я не прав и почему не прав?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #61 : 21-09-2009 08:22 » 

zuze, меня ещё терзают тузики сомнений... Буферизированный ввод - это , так понимаю, когда раздельно
1) складывается в буфер
2) читается из буфера

то есть в одном потоке значения тупо считываются. То есть тут буфер ReadOny. Во втором потоке , через равные промежутки времени считываются все клавиши, и флаги заносятся в буфер (нажата-не нажата). Если хочется триггер, то вводим ещё буфер, параллельный этому: при переходе флага в первом буфере из 0 в 1 (нажали) сбрасываем флаг во втором (ещё не прочитали в первом потоке). Первый поток , если триггер ещё не защёлкнут, считает, что кнопка только что нажата. Выставляет защёлку и обрабатывает кнопку. Если защёлка уже выставлена - проходит мимо

WM_TIMER, кстати, может плавать, но для управления в игре потянет. А ещё одно кстати - во втором потоке таймер вообще не нужен, можно Sleep() обойтись
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #62 : 24-09-2009 09:38 » 

Я не неправилно сделал функцию isKeyDown и массив  keyboard[256] сделал в место char написал BYTE.

Код:
// Глобальная переменная
BYTE keyboard[256];

// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
            // Чистим буфер, иначе может получиться эфект залипшей клавиши
            ZeroMemory(keyboard, sizeof(keyboard));

// Полученние данных с клавиатуры
            if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
            return false;

if (keyboard[KeyCode] & 0x80)
{
  ofstream fout("1.txt", ios_base::out | ios_base::app);
  fout << GetTickCount(); // Запись в файл
  fout << "-\n";
  fout.close();
  return true;
}
else
  return false;
}

Что в результате записалось в текстовый файл после того как я один раз нажал на клавишу '1':

Цитата
11115583-
11115583+
11115593-
11115593+
11115613-
11115613+
11115623-
11115633+
11115643-
11115643+
11115663-
11115663+
11115673-
11115683+
11115693-
11115693+

Когда в другой раз нажал на клавишу '1' получилось в текстовом файле 12 записей, когда два раза нажал на клавишу '1' получилось в текстовом файле 40 записей.

Это значит что буферизованный ввод есть и он работает правильно?
« Последнее редактирование: 24-09-2009 10:26 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #63 : 24-09-2009 14:36 » 

Цитата
Это значит что буферизованный ввод есть и он работает правильно?

ответ будет такой же, как и на вопрос:

работает ли всё так, как ты задумал ? Ага
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #64 : 24-09-2009 23:23 » 

Я всего лишь хочу знать, данные о нажатых клавишах считываются с буфера и правельно ли это происходит?
Или всё работает также, как если был не буферизированный ввод, тоесть клавишу нажата - клавиша определена.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #65 : 25-09-2009 03:01 » 

я не понимаю вопрос (
Клавиши считываются - это факт. Они правильно считываются (железо исправно, драйвера исправны) - это тоже факт, так как иначе бы они не считывались Отлично
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #66 : 25-09-2009 12:18 » 

Прошу прощения, за плохое объяснение попробую ещё раз объяснить.

Так как можно делать внешне всё правильно, как в теории, но о чём то забыть и уже не будет буферизированного ввода или будет, только он будет работать неправильно (залипание клавиш [от этого я избавился] или будет работать как не буферизированный ввод) при этом ошибок при компиляции и запуске программы могут не быть. Вот я и хочу это проверить практически.
« Последнее редактирование: 25-09-2009 12:21 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #67 : 25-09-2009 14:24 » 

все недостатки, если они есть, обязательно выплывут при активной эксплуатации программы Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #68 : 25-09-2009 14:39 » 

Понятно, спасибо за разъяснение.
Сейчас буду переходить на программирование мышки. К стати, где то писалось что клавиатура может потеряться и надо ещё в функцию проверки клавиши добавлять код для восстановление клавиатуры, но так как у меня она пока ни разу не терялась я это код писать не буду.
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #69 : 25-09-2009 19:10 » 

Алексей1153++

Код:
// Указатель на интерфейс DirectInput для мыши
LPDIRECTINPUT8 pInput2 = NULL;
//  Указатель на устройство ввода мышь
LPDIRECTINPUTDEVICE8 pInputDevice2 = NULL;

// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WNDCLASSEX windowsclass;
    hInstance = hInst;

    windowsclass.cbSize = sizeof(WNDCLASSEX);
    windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    windowsclass.lpfnWndProc = MainWinProc;
    windowsclass.cbClsExtra = 0;
    windowsclass.cbWndExtra = 0;
    windowsclass.hInstance = hInst;
    windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    windowsclass.lpszMenuName = NULL;
    windowsclass.lpszClassName = "WINDOWSCLASS";
    windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&windowsclass))
        return 0;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением и камерой", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    // Инициализация DirectInput
    InitDirectInput();
    InitDirectInputMouse();
    ...
    ...
    ...
}

// Функция обработки нажатия клавиш
bool EnterKey(float timeDelta)
{
if (pDirect3DDevice)
{
 ...
 ...
 ...
              if (isMouseDown(0))
                MessageBox(NULL, "Нажата левая клавиша мыши", "Сообщение", MB_OK);
 if (isMouseDown(1))
                MessageBox(NULL, "Нажата правая клавиша мыши", "Сообщение", MB_OK);
 if (isMouseDown(2))
                MessageBox(NULL, "Нажата центральная клавиша мыши", "Сообщение", MB_OK);
           }
           return true;
}

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
...
                                    ...
                                    ...
}
else
                        {
           ...
                                    ...
                                    ...
}
}
DeleteDirectInput();
DeleteDirectInputMouse();

// Функция инициализация DirectInput мыши
bool InitDirectInputMouse(void)
{
    
    // Создание интерфейс устройства (Мышь)
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput2, NULL)))
        return false;

     // Создание устройства клавиатуры (Мышь)
     if (FAILED(pInput2->CreateDevice(GUID_SysMouse, &pInputDevice2, NULL)))
       return false;

     // Установка формата данных мыши
     if (FAILED(pInputDevice2->SetDataFormat(&c_dfDIMouse)))
       return false;

     // Установка уровня взаимодействия клавиатуры (совместный доступ) [Мышь]
     if (FAILED(pInputDevice2->SetCooperativeLevel(hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
       return false;

     // Захват доступа к клавиатуре (активизировать управление) [мышь]
     if (FAILED(pInputDevice2->Acquire()))
        return false;

     return true;
}

// Функция определения нажатой клавиши на мыши
bool isMouseDown(int Button)
{
// Чистим структуру, иначе может получиться эфект залипшей клавиши на мыши
mouse.lX = 0;
mouse.lY = 0;
mouse.lZ = 0;
ZeroMemory(mouse.rgbButtons, sizeof(mouse.rgbButtons));

// Полученние данных с мыши
    if (FAILED(pInputDevice->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouse)))
       return false;

if (mouse.rgbButtons[Button] & 0x80)
  return true;
else
  return false;
}

// Функция освобождает захваченные ресурсы DeleteInput мыши
void DeleteDirectInputMouse(void)
{
if (pInputDevice2 != NULL)
            {
pInputDevice2->Unacquire();
pInputDevice2->Release();
pInputDevice2 = NULL;

}
}

Почему-то клавиши мыши не определяются, в чём дело и как поправить, я понимаю что с этим ты ещё не разбирался, но вдруг идея придёт?
« Последнее редактирование: 26-09-2009 09:20 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #70 : 26-09-2009 03:30 » 

а где заполнялось c_dfDIMouse ?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #71 : 26-09-2009 03:37 » 

Это же вроде в спецификации DirectInput лежит её заполнять не надо, для клавиатуры я же не заполнял.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #72 : 26-09-2009 03:39 » 

тогда мысли закончились Улыбаюсь Отлаживай, разбирайся... А у меня выходной ))
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #73 : 26-09-2009 03:40 » 

Понятно, хорошо отдохнуть!!!
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #74 : 26-09-2009 09:17 » 

Прошу прощения за свою невнимательность.

Вот в чём дело было. У меня было так

Код:
// Полученние данных с мыши
if (FAILED(pInputDevice->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouse)))
   return false;

А надо так

Код:
// Полученние данных с мыши
if (FAILED(pInputDevice2->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouse)))
   return false;


Так как pInputDevice относится к клавиатуре, а не к мыши.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #75 : 26-09-2009 10:17 » 

к вопросу об глобальных переменных и пустых именах переменных Ага
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #76 : 27-09-2009 04:20 » 

Алексей1153++

Так что теперь перехожу к изучению DirectMusic. Если будут вопросы буду задавать. Ты всегда дельные ответы даёшь.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #77 : 27-09-2009 04:56 » 

со звуком самую малось делал, требовалось всего то wav файл проиграть Улыбаюсь Больше не сталкивался. Только там DirectSound, вроде, было
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #78 : 27-09-2009 05:00 » 

А DirectMusic работает только с WAV и MIDI, а DirectSound тоже есть я его буду затем изучать.
« Последнее редактирование: 27-09-2009 05:04 от zuze » Записан
Страниц: 1 2 3 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines