Есть стороннее приложение, работающее на directinput(7). Мне нужно немного изменить логику работы directinput в данном приложении. Контроллеры - только клавиатура и мышь. Вопрос первый - по какому принципу работает dinput? На сколько я понял - он читает очередь сообщений и возвращает инфо в удобном для приложения виде? Вопрос второй - в данном случае лучше хукать directinput или написать эмуляцию его?
float Нет, откуда там очередь сообщений, оно читает состояние. Что значит эмуляция DI? Напиши обёртку.
ну dinput зачем-то постоянно вызывает PeekMessage с PM_REMOVE, т.е. из очереди сообщений главного окна извлекает сообщения. Насчет состояния - там в нескольких местах вызывается GetAsyncKeyState. Вот не понятно, откуда изначально он берет данные о нажатиях. Насчет эмуляции - я наверное все же имел в виду обертку.
он просто заполняет буфер состояния (значения всех клавиш в текущий момент или данные о мыши, в какую сторону ее двинули и насколько + какие клавиши нажали) и программа его должна просматривать сама в цикле или еще как.
это то понятно, вопрос откуда эти данные берет сам динпут. Насколько я понял (совершенно не уверен в этом), он берет из очереди сообщений главного окна и читает состояние через GetAsyncKeyState
честно говоря уверен что вы ошибаетесь. на скорую руку в отладчике посмотрел он при создании девайса усилено юзает hid.dll а вот при вызове метода c получением данных в буфер выдает ошибку так как предполагаю что фокус уходит с окна на отладчик. Глубже пока времени нет разбираться, а так да, я тоже заинтересовался откуда он их берет. Знатоки поделитесь.
для имитации например нажатия клавиши для динпута8 я писал вот такой вот код. отправная точка - перехват вызова DirectInput8Createб где определяется таблица интерфейсов, в которой перехватывается CreateDevice в которой (в свою очередь) перехватывается GetDeviceState. и в обработчике выставляется бит нажатия. Код (Text): ULONG oldGetDeviceData;//buffered method HRESULT WINAPI xGetDeviceData(DWORD d1, DWORD d2, DWORD d3, DWORD d4, DWORD d5) { HRESULT hr = ((HRESULT(WINAPI*)(DWORD,DWORD,DWORD,DWORD,DWORD))oldGetDeviceData)(d1,d2,d3,d4,d5); return hr; } ULONG oldGetDeviceState;//immediate method HRESULT WINAPI xGetDeviceState(DWORD d1, DWORD bufsize, DWORD lpbuf) { HRESULT hr = ((HRESULT(WINAPI*)(DWORD,DWORD,DWORD))oldGetDeviceState)(d1,bufsize,lpbuf); if(!FAILED(hr)){ char *pkbbuf = (char*)lpbuf; pkbbuf[0x3B] = pkbbuf[0x3B] | 0x80; } return hr; } ULONG oldCreateDevice; HRESULT WINAPI xCreateDevice(DWORD d1, DWORD d2, DWORD d3, DWORD d4) { HRESULT hr = ((HRESULT(WINAPI*)(DWORD,DWORD,DWORD,DWORD))oldCreateDevice)(d1,d2,d3,d4); // hook only if keyboard requested if(*(DWORD*)d2 != GUID_SysKeyboard) return hr; DWORD dwKeybTable = *(DWORD*)(*(DWORD*)d3); DWORD oldprot; VirtualProtect((LPVOID)dwKeybTable, 0x2C, PAGE_EXECUTE_READWRITE, &oldprot); // already hooked? if((DWORD)xGetDeviceState == *((DWORD*)(dwKeybTable+0x24))) goto ex1; // hook it! oldGetDeviceState = *((DWORD*)(dwKeybTable+0x24)); *((DWORD*)(dwKeybTable+0x24)) = (DWORD)xGetDeviceState; ex1: // already hooked? if((DWORD)xGetDeviceData == *((DWORD*)(dwKeybTable+0x28))) goto ex2; // hook it! oldGetDeviceData = *((DWORD*)(dwKeybTable+0x28)); *((DWORD*)(dwKeybTable+0x28)) = (DWORD)xGetDeviceData; ex2: return hr; } ULONG oldDirectInput8Create; HRESULT WINAPI xDirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, VOID **ppvOut, LPUNKNOWN punkOuter) { HRESULT ret = ((HRESULT(WINAPI*)(HINSTANCE,DWORD,REFIID,VOID**,LPUNKNOWN))oldDirectInput8Create)(hinst,dwVersion,riidltf,ppvOut,punkOuter); DWORD dwFuncTable = (DWORD)*((DWORD*)*ppvOut); DWORD oldprot; VirtualProtect((LPVOID)dwFuncTable, 0x10, PAGE_EXECUTE_READWRITE, &oldprot); //already hooked? if((DWORD)xCreateDevice == *((DWORD*)(dwFuncTable+0x0c))) goto ex; //hook it oldCreateDevice = *((DWORD*)(dwFuncTable+0x0c)); *((DWORD*)(dwFuncTable+0x0c)) = (DWORD)xCreateDevice; ex: return ret; }