2

I'm looking to get the cursor position during the main loop of my application/game.

From doing some research there appears to be two methods of doing this: Firstly listening for the WM_MOUSEMOVE event and checking the lParam. Secondly using GetCursorPos() then following it up with ScreenToClient().

I have a window which is set up to be 1680x1050, however when looking at the data that comes through from either method, I end up with a value of around 1660 at the very right side of the window.

I've not been able to find any resource which explains why this may be happening and I'm wondering whether it has anything to do with the window creation?

This is the code I am using to create the window for my application

//Register the window class WNDCLASS windowClass; windowClass = {}; windowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; windowClass.lpfnWndProc = handleWindowMessages; windowClass.hInstance = hInstance; windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW); windowClass.lpszClassName = L"D3D11 Rendering"; if (!RegisterClass(&windowClass)) { return 0; } //Create the window HWND windowHandle = CreateWindowEx(0, windowClass.lpszClassName, L"D3D11 Rendering", (WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME) | WS_VISIBLE, //According to stackoverflow.com WS_OVERLAPPEDWINDOW ^ (XOR) WS_THICKFRAME will prevent window resizing CW_USEDEFAULT, CW_USEDEFAULT, gResolutionX, gResolutionY, 0, 0, hInstance, 0); 

Then in the main loop I am doing the following:

POINT p; GetCursorPos(&p); ScreenToClient(windowHandle, &p); 

Any pointers, tips, or information would be appreciated.

Edit: The applications window is not maximized and/or over the taskbar. The issue occurs on both axis, x and y. I had noticed that the title bar at the top keeps the y position at 0 whilst the cursor is inside it. Is there a way to get to the renderable area of the screen? When creating the window with the resolution I want my game to run at, I expect the bit in the middle (not sure on the actual terminology - the bit without the borders and the title bar) to match the resolution.

1
  • 1
    The maximized window doesn't go over the task bar. Also the client area doesn't include the window title. Commented May 16, 2018 at 16:50

1 Answer 1

2

The area inside the window (excluding title bar and borders, etc) is called the client area. WM_MOUSEMOVE messages will give you coordinates in the client area, which will be at (0, 0) at the top-left of that inside portion.

GetCursorPos will return the mouse cursor position in screen space (so your call to ScreenToClient is correct). Since the window is not maximized, and you're still specifying a border (WS_OVERLAPPEDWINDOW is defined as WS_OVERLAPPED | WS_THICKFRAME | etc..., and you're removing the WS_THICKFRAME but WS_OVERLAPPED still includes a border) my guess is that the window's layout, including the border, will eat up those extra 20 pixels. If you create a full-screen, borderless window (so sized and positioned to fill the screen, and using the WS_POPUP style only), you should see the client area filling the available space.

Sign up to request clarification or add additional context in comments.

2 Comments

Alternatively, call GetWindowRect and subtract the top-left corner from the value returned by GetCursorPos. Handling WM_MOUSEMOVE is usually fine, but it doesn't have a way for you to query the mouse position at a particular point in time, which may be desirable in a game.
Thank you for the information. Making my application fullscreen showed the correct numbers, which implies @Steve Smith was correct with their assumption of the border taking the extra pixels. After doing some more digging around using the information given here, I stumbled across the Windows function 'AdjustWindowRect' which will take a desired client area and provide the 'RECT' to be used when creating the window. Thank you for the help

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.