Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Direct Input Device -> GetDeviceState mysteriously fails

363 views
Skip to first unread message

Allen W. Ingling

unread,
Jan 22, 2002, 7:44:54 PM1/22/02
to

Dear comp.os.ms-windows.programmer.win32,

I've written a DLL which reads the keyboard using the GetDeviceState
method of a DirectInput keyboard object. Although no calls to
DirectInput methods return error messages, GetDeviceState nonetheless
fails to detect keypresses. GetDeviceState accepts a 256-element
array of chars. It should set those elements of the array which
correspond to down keys to 0x80. It does not do this. Instead, all
elements of the array remain 0.

Here are some details: My dll file is an extension to the Matlab
application. Matlab calls my .dll, which acquires and stores a handle
to itself, of type HINSTANCE, when it loads. Passing this HINSTANCE
value to DirectInputCreate, it creates a direct input object. The
CreateDevice method of the direct input object is then used to create
a keyboard device object. The SetDataFormat method of the that
keyboard device object is called to set the format to that for the
keyboard. The SetCooperativeLevel method the keyboard device object
is called with a handle to a window which was opened by the Matlab
application, and with flags DISCL_NONEXCLUSIVE | DISCL_BACKGROUND.
Acquire(), Poll(), and GetDeviceState() methods of the keyboard device
object are then called.

This is all pretty much "by the book". Note that if I create a direct
input device object for the mouse, setting the data format
accordingly, I can read the mouse buttons. Again, with the keyboard,
I do check the return values with every DirectInput method I call and
no call returns an error, including Acquire.

Anything at all here would be helpful: Ideas about why this does not
work, idle speculation, suggestions for things to try to make it work,
hints about how to go about diagnosing the problem, etc.

Best,

Allen


Allen W. Ingling
Assistant Research Scientist
Center for Neural Science
New York University


Serve Laurijssen

unread,
Jan 23, 2002, 2:42:41 AM1/23/02
to

"Allen W. Ingling" <Allen....@nyu.edu> wrote in message
news:3C4E0786...@nyu.edu...
>
> Dear comp.os.ms-windows.programmer.win32,

> Anything at all here would be helpful: Ideas about why this does not
> work, idle speculation, suggestions for things to try to make it work,
> hints about how to go about diagnosing the problem, etc.

it would help if you show the setup and GetDeviceState code
Or try another cooperative level: DISCL_NONEXCLUSIVE | DISCL_FOREGROUND
works for me


Paul Carrington

unread,
Jan 23, 2002, 7:44:25 PM1/23/02
to
In article Allen W. Ingling <Allen....@nyu.edu> writes

>GetDeviceState code

//read the keyboard state

hr = lpDIDevice->GetDeviceState(sizeof(keys),&keys);

try this..

hr = lpDIDevice->GetDeviceState(sizeof(keys),keys);

Paul Carrington
Vulcan Software Ltd

http://www.vulcan.co.uk
http://www.vulcan-portal.co.uk
http://www.valhalla-online.co.uk
http://www.mother3d.co.uk

Allen W. Ingling

unread,
Jan 24, 2002, 3:04:27 PM1/24/02
to

Paul Carrington wrote:

> In article Allen W. Ingling <Allen....@nyu.edu> writes
>
> >GetDeviceState code
>
> //read the keyboard state
>
> hr = lpDIDevice->GetDeviceState(sizeof(keys),&keys);
>
> try this..
>
> hr = lpDIDevice->GetDeviceState(sizeof(keys),keys);

Using "keys" looks better than using "&keys", but its the same thing,
so changing it does not make anything work.

Of course generally a variable "keys" and "&keys" are not the same
thing. The only exceptions, when "keys == &keys" tests true, are
where keys is an array or when its a numerical type holding its own
address.

Best,

Allen

Paul Carrington

unread,
Jan 25, 2002, 3:30:40 AM1/25/02
to
> lpDIDevice->GetDeviceState(sizeof(keys),keys);
>
>Using "keys" looks better than using "&keys", but its the same thing,
>so changing it does not make anything work.

mmm, the only thing that quickly springs to mind (without looking at your code
again in detail) is that you are initialising DirectInput as part of your dll call? And
perhaps resetting the key array to 0 after input had already occurred?

Might explain why mouse works as this is based upon the button still being
pressed?

Allen W. Ingling

unread,
Jan 25, 2002, 8:42:46 PM1/25/02
to

Paul Carrington wrote:

> > lpDIDevice->GetDeviceState(sizeof(keys),keys);
> >
> >Using "keys" looks better than using "&keys", but its the same thing,
> >so changing it does not make anything work.
>
> mmm, the only thing that quickly springs to mind (without looking at your code
> again in detail) is that you are initialising DirectInput as part of your dll call? And
> perhaps resetting the key array to 0 after input had already occurred?
>
> Might explain why mouse works as this is based upon the button still being
> pressed?

Good theory, but I'm afraid that's not it either.

In fact, DirectX initialization occurs only once, when the .dll is loaded. As part of the
initialization I reset a flag, ("firstTime"), and subsequent calls test this flag and know
not to reinitialize DirectX. Those later calls to my .dll, which do not initialize
DirectX, also fail to detect down keys.

After the first call, which loads the .dll and initializes DirectX, later calls invoke only
Acquire(), Poll(), and GetDeviceState().

Another bit of evidence against your theory is that when I call my .dll from the Matlab
environment, I can hold down some keys such as <shift> from before I make the call until
after it returns. Doing that makes no difference.

Anyway, thanks for thinking about it. Unlike most debugging exercises, I'm having trouble
thinking up reasons why it might fail, and things to try.

Best,

Allen

Paul Carrington

unread,
Jan 26, 2002, 2:32:26 AM1/26/02
to
In Allen W. Ingling <Allen....@nyu.edu> writes

>Anyway, thanks for thinking about it. Unlike most debugging exercises, I'm having trouble
>thinking up reasons why it might fail, and things to try.

Well, I looked at your code again and it's doing everything as it should!

Question: why not simply incorporate the code within the main program? My hunch
is that as an external dll it's somehow not being used in the main thread of things?

Allen W. Ingling

unread,
Jan 26, 2002, 8:50:54 PM1/26/02
to

Paul Carrington wrote:

>
> Question: why not simply incorporate the code within the main program?

Good idea but: The main program is Matlab, it's closed source. The Matlab maker, Mathworks,
supplies libraries and headers in case anyone wants to write a .dll to extend Matlab
functionality.


> My hunch
> is that as an external dll it's somehow not being used in the main thread of things?
>

That's crossed my mind. Here's how I'm breaking down the space of possibilities:

1- It's a dumb bug in my .dll source. (Thanks for looking it over carefully, it diminishes the
likelihood of that that.)
2- It's something Matlab is doing to screw up DirectInput. (I can't imagine what that would be,
except using DirectInput within Matlab. According to Mathworks, Matlab doesn't do that.).
3- As you suggest, it's simply because I am making the DirectInput call from a .dll, outside of
the main application. But it should still work to do that. The Microsoft documentation for
the call which creates the direct input object says specifically that if you create the direct
input object in a dll that you should pass the handle of the .dll and not the handle of the
parent application. That sure implies that you should be able to use DirectInput from a dll
outside of the main app.
4- I can Spy on Matlab and see that it runs multiple threads. I can't find anything in the
DirectX documentation suggesting that this should cause a problem, but who knows ?


That matlab is closed-source prevents me from testing the last three of these possibilities.
So I'm writing a fake Matlab which just opens a window and loads my .dll and calls its
MexFunction() to read the keyboard. There is some work here in implementing the C mex and mx
functions which my .dll calls, but not much. (mx and mex are usually supplied by the Matlab
executable.) This should let me home in on the source of trouble by modifying the calling
application.

Best,

Allen

Paul Carrington

unread,
Jan 27, 2002, 12:05:34 AM1/27/02
to
Allen W. Ingling <Allen....@nyu.edu> writes

>1- It's a dumb bug in my .dll source.

I'd go for a 5% chance on that... although how about using your source in a small
exe to run and simply check that the code is all working? (ignore Matlab for now)

>2- It's something Matlab is doing to screw up DirectInput.

20% but first check that Direct Input is working with another program that uses
direct input whilst Matlab is running? Would you like me to send you an exe that
uses direct input? (as a test)

>3- simply because I am making the DirectInput call from a .dll, outside

75% probability and rising to 95% if 1 and 2 pass okay

>So I'm writing a fake Matlab which just opens a window and loads my .dll and calls its
>MexFunction() to read the keyboard.

Yes, good idea!

Allen W. Ingling

unread,
Jan 29, 2002, 5:39:52 PM1/29/02
to

Paul Carrington wrote:

> Allen W. Ingling <Allen....@nyu.edu> writes
>
> >1- It's a dumb bug in my .dll source.
>
> I'd go for a 5% chance on that... although how about using your source in a small
> exe to run and simply check that the code is all working? (ignore Matlab for now)
>
> >2- It's something Matlab is doing to screw up DirectInput.
>
> 20% but first check that Direct Input is working with another program that uses
> direct input whilst Matlab is running? Would you like me to send you an exe that
> uses direct input? (as a test)
>
> >3- simply because I am making the DirectInput call from a .dll, outside
>
> 75% probability and rising to 95% if 1 and 2 pass okay
>
> >So I'm writing a fake Matlab which just opens a window and loads my .dll and calls its
> >MexFunction() to read the keyboard.
>
> Yes, good idea!
>

Thanks for the additional comments. I've had to set this aside for just a few days. I'll
be back at it the end of the week.

best,

Allen

the.real.fra...@gmail.com

unread,
Dec 12, 2017, 12:22:11 PM12/12/17
to
Nearly 16 years too late, but somebody might still end up here, so I'll answer it: Calling DirectX functions within a DLL is fine, but initialising DirectX withing a DLL is not. The objects must be created within an EXE, but the devices can be created and worked with within a DLL. To clarify, DirectInput8Create() must be called within the EXE file, but DInput8->CreateDevice/SetDataFormat/Acquire() and DInputDevice8->GetDeviceState() can be called within the DLL.

JJ

unread,
Dec 12, 2017, 7:06:03 PM12/12/17
to
On Tue, 12 Dec 2017 09:22:06 -0800 (PST),
the.real.fra...@gmail.com wrote:
>
> Nearly 16 years too late, but somebody might still end up here, so I'll
> answer it: Calling DirectX functions within a DLL is fine, but
> initialising DirectX withing a DLL is not. The objects must be created
> within an EXE, but the devices can be created and worked with within a
> DLL. To clarify, DirectInput8Create() must be called within the EXE file,
> but DInput8->CreateDevice/SetDataFormat/Acquire() and
> DInputDevice8->GetDeviceState() can be called within the DLL.

Are you sure about that? Cause there's a game console emulator which uses
plugins to render the console screen. They're all DLL files, and a plugin
can either be a display renderer using Direct3D, OpenGL, GDI, or no output
at all. The host application doesn't and can't know whether the plugin uses
which graphics rendering engine. So, for the plugin which uses Direct3D, it
initializes it from the plugin DLL, not from the host EXE.

Kaz Kylheku

unread,
Dec 12, 2017, 8:32:12 PM12/12/17
to
On 2017-12-12, the.real.fra...@gmail.com <the.real.fra...@gmail.com> wrote:
> Nearly 16 years too late, but somebody might still end up here, so

And 16 miles wide of the mark.

> DLL. To clarify, DirectInput8Create() must be called within the EXE
> file, but DInput8->CreateDevice/SetDataFormat/Acquire() and
> DInputDevice8->GetDeviceState() can be called within the DLL.

There is no such restriction; you're misreading the MSDN doc.

This API function takes a module handle. There is a requirement that
whoever is calling it must supply their module handle.

Direct (no pun intended) quote:

hInst Instance handle to the application or dynamic-link library (DLL)
that is creating the DirectInput object. DirectInput uses this
value to determine whether the application or DLL has been
certified and to establish any special behaviors that might be
necessary for backward compatibility.

See? Application or dynamic-link library: either one can call. Whatever
calls has to use its its own instance handle.

--
TXR Programming Lanuage: http://nongnu.org/txr
Music DIY Mailing List: http://www.kylheku.com/diy
ADA MP-1 Mailing List: http://www.kylheku.com/mp1
0 new messages