Jump to content
  • Advertisement
Sign in to follow this  
Erzengeldeslichtes

DirectInputDevice8-SetCooperativeLevel == E_NOTIMPL?

This topic is 4832 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Using: Microsoft Visual C++ 2005 Beta 1 Microsoft DirectX 9.0 SDK Update (February 2005) I'm trying to create a device for the system keyboard, and be able to read the keyboard wether the app is in foreground or background. So I use DISCL_NONEXCLUSIVE | DISCL_BACKGROUND. However, when I do this, SetCooperativeLevel returns an HRESULT that it isn't documented to return: E_NOTIMPL. According to the documentation, DISCL_EXLUSIVE | DISCL_BACKGROUND is not valid for the system keyboard, but DISCL_NONESCLUSIVE | DISCL_BACKGROUND is (which is what I'm using). If I use DISCL_FOREGROUND instead, it will set cooperative level fine (but for some reason won't read buffered input). I'm suspecting it has something to do with the console I'm creating. Here's what I have:
//For GetConsoleWindow:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#pragma comment(lib, "user32")

#include <iostream>
#include <string>

#include <dinput.h>
#pragma comment(lib, "dinput8")
#pragma comment(lib, "dxguid")

#include <ipointer.h>	//IPointer is a scope class for COM objects--AddRef when copied, 
			//Release when destroyed, etc.
#include <functor.h>	//Functor# is a templated functor that takes either function pointers 
			//or a pointer to a member function and the class to call on.

#include "hresult_output.h"	//FromHRESULT displays (*[Facility]-) [System Message] 
				//where * only occurs on an error, 
				//[Facility] is the part of the platform SDK, 
				// is the 2 byte hexidecimal code. Search WinError.h for the code.
				//[System Message] is the message found in the lookup table.
extern void RedirectIOToConsole();//This creates a console window and redirects fprint, cout, etc, to it.
IPointer<IDirectInput8> g_Input;
IPointer<IDirectInputDevice8> CreateSysMouse()
{
	IPointer<IDirectInputDevice8> Mouse;
	if(FAILED(g_Input->CreateDevice(GUID_SysMouse, Mouse, 0)))
	{
		std::wcerr << "Error, could not get mouse!" << std::endl;
	}
	else if(FAILED(Mouse->SetDataFormat(&c_dfDIMouse)))
	{
		std::wcerr << "Error, could not set data format on mouse!" << std::endl;
	}
	else if(FAILED(Mouse->SetCooperativeLevel(GetConsoleWindow(), 		DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
	{
		std::wcerr << "Error, could not set cooperative level on mouse" << std::endl;
	}
	else
	{
		DIPROPDWORD buffsize;
		buffsize.diph.dwSize = sizeof(buffsize);
		buffsize.diph.dwHeaderSize = sizeof(buffsize.diph);
		buffsize.diph.dwObj = 0;
		buffsize.diph.dwHow = DIPH_DEVICE;
		buffsize.dwData = 32;
		if(FAILED(Mouse->SetProperty(DIPROP_BUFFERSIZE, &buffsize.diph)))
		{
			std::wcerr << "Error, could not set buffer size." << std::endl;
		}
		else if(FAILED(Mouse->Acquire()))
		{
			std::wcerr << "Error, could not acquire mouse" << std::endl;
		}
		else
		{
			return Mouse;
		}
	}
	return IPointer<IDirectInputDevice8>();
}
#if 0
#define MY_DISCL_GROUND DISCL_FOREGROUND
#else
#define MY_DISCL_GROUND DISCL_BACKGROUND
#endif
IPointer<IDirectInputDevice8> CreateSysKeyboard()
{
	IPointer<IDirectInputDevice8> Keyboard;
	HRESULT hr=0;
	if(FAILED(hr = g_Input->CreateDevice(GUID_SysKeyboard, Keyboard, 0)))
	{
		std::wcerr << "Error, could not get Keyboard! Result: " << FromHRESULT(hr) << std::endl;
	}
	else if(FAILED(hr = Keyboard->SetDataFormat(&c_dfDIKeyboard)))
	{
		std::wcerr << "Error, could not set data format on Keyboard! Result: " << FromHRESULT(hr) 
			<< std::endl;
	}
	else if(FAILED(hr = Keyboard->SetCooperativeLevel(GetConsoleWindow(), 
		DISCL_NONEXCLUSIVE | MY_DISCL_GROUND)))
	{
		std::wcerr << "Error, could not set cooperative level on keyboard, \n\t";
		if(hr == DIERR_INVALIDPARAM)
		{
			std::wcerr << "invalid parameter.";
		}
		else if(hr == DIERR_NOTINITIALIZED)
		{
			std::wcerr << "not initialized.";
		}
		else if(hr == E_HANDLE)
		{
			std::wcerr << "invalid window.";
		}
		else
		{
			std::wcerr << "unknown error (" << FromHRESULT(hr) << ").";
		}
		std::wcerr << std::endl;
	}
	else
	{
		DIPROPDWORD buffsize;
		buffsize.diph.dwSize = sizeof(buffsize);
		buffsize.diph.dwHeaderSize = sizeof(buffsize.diph);
		buffsize.diph.dwObj = 0;
		buffsize.diph.dwHow = DIPH_DEVICE;
		buffsize.dwData = 32;
		if(FAILED(hr = Keyboard->SetProperty(DIPROP_BUFFERSIZE, &buffsize.diph)))
		{
			std::wcerr << "Error, could not set buffer size on keyboard. Result: " << FromHRESULT(hr) 
				<< std::endl;
		}
		else if(FAILED(hr = Keyboard->Acquire()))
		{
			std::wcerr << "Error, could not acquire Keyboard. Result: " << FromHRESULT(hr) << std::endl;
		}
		else
		{
			return Keyboard;
		}
	}
	return IPointer<IDirectInputDevice8>();
}
//void InputCallback(DWORD Data, DWORD TimeStamp, DWORD Sequence)
typedef Functor3<void, DWORD, DWORD, DWORD> InputCallback;
void CheckBufferedData(IPointer<IDirectInputDevice8> BufferedDevice, InputCallback* ArrayOfCallbacks)
{
	DIDEVICEOBJECTDATA TheBuffer[32];
	DWORD NumRead=32;
	HRESULT hr;
CheckBufferedData_Start:
	if(FAILED(hr = BufferedDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), TheBuffer, &NumRead, 0)))
	{
		if(hr == DIERR_NOTACQUIRED)
		{
			Sleep(10);//Yes, I could do this better with window messages, etc, but right now,
				  //that's not the point.
			goto CheckBufferedData_Start;
		}
		else if(hr == DIERR_INPUTLOST)
		{
			BufferedDevice->Acquire();
			goto CheckBufferedData_Start;//Sorry, but would you rather I use a loop, replacing this 
						     //with a continue and putting a break at the end? I thought 
						     //not.
		}
		else if(hr == DIERR_NOTBUFFERED)
		{
			std::wcerr << "Error, device not buffered." << std::endl;
		}
		else if(hr == DIERR_NOTINITIALIZED)
		{
			std::wcerr << "Error, device not initialized." << std::endl;
		}
		else if(hr == DIERR_INVALIDPARAM)
		{
			std::wcerr << "Error, bad parameter." << std::endl;
		}
		else
		{
			std::wcerr << "Unknown Error" <<std::endl;
		}
		return;
	}
	for(unsigned int i=0; i<NumRead; ++i)
	{
		DIDEVICEOBJECTDATA& CurData = TheBuffer;
		InputCallback &TheCallback = ArrayOfCallbacks[CurData.dwOfs];
		if(TheCallback.operator bool()) TheCallback(CurData.dwData, CurData.dwTimeStamp, 
			CurData.dwSequence);
	}
}
void Pause()
{
	char a[256];
	std::cin.getline(a, 256);
}
bool g_Done=false;
void Quit(DWORD, DWORD, DWORD)
{
	g_Done = true;
}
void xChange(DWORD amount, DWORD, DWORD)
{
	std::wcout << L"X: " << (signed long)amount << std::endl;
}
void yChange(DWORD amount, DWORD, DWORD)
{
	std::wcout << L"Y: " << (signed long)amount << std::endl;
}
struct KeyChange
{
	std::wstring MyName;
	KeyChange(const std::wstring& TheName) : MyName(TheName) {}
	void Output(DWORD data, DWORD,DWORD)
	{
		std::wcout << MyName << L": " << (bool)(0x800 & data) << std::endl;
	}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	RedirectIOToConsole();
	if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, 
		(void**)&g_Input,0)))//Yes, operator& returns IDirectInput8**, not IPointer*
	{
		std::wcerr << L"Error, couldn't create DInput!" << std::endl;
	}
	else
	{
		IPointer<IDirectInputDevice8> Mouse = CreateSysMouse();
		IPointer<IDirectInputDevice8> Keyboard = CreateSysKeyboard();
		if((bool)Mouse && (bool)Keyboard)
		{
			InputCallback MouseCallback[sizeof(DIMOUSESTATE)];
			MakeFunctor(&MouseCallback[DIMOFS_X], xChange);
			MakeFunctor(&MouseCallback[DIMOFS_Y], yChange);
			InputCallback KBCallback[256];
			KeyChange* Keys[256];
			for(unsigned int i=0; i<=DIK_Z; ++i)
			{
				wchar_t temp[64];
				Keys = new KeyChange(std::wstring("0x") + std::wstring(_itow(i, temp, 16)));
				MakeFunctor(&KBCallback, *Keys, &KeyChange::Output);
			}
			MakeFunctor(&KBCallback[DIK_ESCAPE], Quit);
			while(!g_Done)
			{
				CheckBufferedData(Mouse, MouseCallback);
				CheckBufferedData(Keyboard, KBCallback);
			}
			for(unsigned int i=0; i<=DIK_Z; ++i)
			{
				delete Keys;
			}
		}
	}
	Pause();
	return 0;
}







The mouse works fine, but the keyboard either doesn't do anything (in foreground mode) or (in background mode) displays "Error, could not set cooperative level on keyboard, unknown error ((*NULL-0x4001) Not Implemented)" If it is the console, I find it interesting that it only messes up the keyboard and not the mouse... [Edited by - Erzengeldeslichtes on March 27, 2005 10:04:27 PM]

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!