1

I searched, but most posts are just telling me what I already have, so below is basically my code right now:

DIKeyboard->Acquire();
DIMouse->Acquire();

DIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouseCurrState);

DIKeyboard->GetDeviceState(sizeof(keyboardState),(LPVOID)&keyboardState);

MousePos.x += mouseCurrState.lX;
MousePos.y += mouseCurrState.lY;

Any post telling me how to get absolute position just says to use those last two lines. But my program is windowed, and the mouse can start anywhere on the screen.

i.e. If my mouse happens to be in the centre of my screen, that becomes position 0,0. I basically just want the top left of my window (not my screen) to be my 0,0 mouse coordinates, but am having a hard time finding anything relevant.

Thanks for any help! :)

Mgetz
  • 5,108
  • 2
  • 33
  • 51
user1539405
  • 111
  • 1
  • 14
  • 1
    Microsoft recommends not using DirectInput for mouse and keyboard, using the Windows Messages instead. See http://msdn.microsoft.com/en-us/library/windows/desktop/ee416842(v=vs.85).aspx . The WM approach has a lot of built-in functions to keep state, and for the keyboard to readily translate keystrokes to characters in a locale-aware way. – MicroVirus May 23 '14 at 00:01
  • And it recommends it for gaming environments? I mean, I use messages and DirectInput atm for keypresses (WM on arrow keys, DInput on WASD) and the DirectInput is so much smoother. – user1539405 May 23 '14 at 02:24
  • Yes, it is recommended for gaming environments. The only way I can imagine DirectInput to be smoother is for the mouse; if you notice a difference for your keyboard then almost certainly your implementation is wrong. With WM you get a message every time a key is pressed/depressed, and you can query if a key is being pressed at any time using `GetKeyState`. – MicroVirus May 23 '14 at 08:58
  • Ahh ok. So does windows messages now support a more complex mouse too? (10 buttons for instance)? Last I heard it had pretty basic support. Reading up, you are probably right about swtiching, but this was a sort of sticking point for me. – user1539405 May 23 '14 at 18:11
  • I'm quite disappointed, but it seems that, while the API structure would directly support it (via `WM_XBUTTONDOWN`, et al.) it seems to have missed this opportunity. So you are right: to support mouses with multiple buttons, you are, for better or for worse, left with DirectInput. I would still advise you to use the Windows Messages for keyboard input, though. – MicroVirus May 23 '14 at 19:25

1 Answers1

0

Following the discussion in the comments, you'll have to decide which method works best for you. Unfortunately, having never worked with DirectInput, I do not know the ins-and-outs of it.

However, Window Messages work best for RTS-style controls, where a cursor is drawn to screen. This is due to the fact that this respects user settings, such as mouse acceleration and mouse speed, whereas DirectInput only uses the driver settings (so not the control panel settings). The user will expect the mouse to feel the same, especially in windowed mode.

DirectInput works better for FPS-style controls, when there is no cursor drawn, as window messages give you only the cursor coordinates, and not offset values. This means that once you are at the edge of the screen, window messages will no longer allow you to detect the mouse being moved further (actually, I am not 100% sure on this, so if someone could verify, please feel free to comment).

For keyboard, I would definitely suggest window messages, because DirectInput offers no advantages, and WM input is easier to use, and quite powerful (the WM_KEYDOWN messages contains a lot of useful data), and it'll allow you (via TranslateMessage) to get good text input, adjusted to locale, etc.).

Solving your problem with DirectInput:


You could probably use GetCursorPos followed by ScreenToClient to initialise your MousePos structure. I'm guessing you'll need to redo this every time you lose mouse input and reacquire it.

Hybrid solution (for RTS like controls):


It might be possible to use a hybrid solution for the mouse if you desire RTS-like controls. If this is the case, I suggest, though I have not tested this, to use WM for the movement of the mouse, which avoids the need for workaround mentioned above, and only use DirectInput to detect additional mouse buttons.

Now one thing I think you should do in such a hybrid approach is not directly use the button when you detect it via DirectInput, but rather post a custom application message to your own message queue (using PostMessage and WM_APP) with the relevant information. I suggest this because using WM you do not get the real-time state of the mouse & keyboard, but rather the state at the time of the message. Posting a message that the button was pressed allows you to handle the extra buttons in the same state-dependent manner (I don't know how noticeable this 'lag' effect is). It also makes the entire input handling very uniform, as every bit of input with this enters as a window message.

MicroVirus
  • 5,324
  • 2
  • 28
  • 53