Sign in to follow this  
ArgusMaker

cursor position

Recommended Posts

Hello!
I'm trying to get the cursor position so:
GetCursorPos(&point);
ScreenToClient(hwnd,&point);
cursor_x = point.x;
cursor_y = point.y;

But GetCursorPos doesen't work when the cursor is outside my game window.
How can i access always to the cursor position?

Share this post


Link to post
Share on other sites
If this is for drag and drop then using [url="http://msdn.microsoft.com/en-us/library/ms646262%28v=vs.85%29.aspx"]SetCapture()[/url] might solve your problem.

Share this post


Link to post
Share on other sites
GetCursorPos() works regardless of where the cursor is. The problem is due to your call to ScreenToClient(), which converts screen coordinates to window-space coordinates. And of course if your cursor is outside the window, you don't have valid window-space coordinates [img]http://public.gamedev.net/public/style_emoticons/default/smile.gif[/img]

If you want to get the cursor position in just screen coordinates, remove the ScreenToClient() call entirely. If you want to detect if the cursor is inside or outside your window, check the return value of ScreenToClient() - if I remember correctly, a FALSE return indicates that the screen coordinates provided are outside the window boundary.


Also, it depends on where you are calling this [i]from[/i]. If you do it in, say, your WM_MOUSEMOVE handler, then it won't work because you only get WM_MOUSEMOVE for when the cursor is over your window. In that case you can work around it with capturing as Adam mentioned.

Share this post


Link to post
Share on other sites
Ok I finally understood my problem.
I execute the code to get mouse position here

while (GetMessage (&messages, NULL, 0, 0))
{
[color="#1C2837"][size="2"]GetCursorPos(&point);[/size][/color][color="#1C2837"][size="2"]
cursor_x = point.x;
cursor_y = point.y;
[/size][/color]
TranslateMessage(&messages);
DispatchMessage(&messages);
}

But this code is not executed when there are no messages, and if mouse is outside the window, most of times no messages are sent to the window.
How can i execute a piece of code always? If i put it in a while(true) my application will get stuck

Share this post


Link to post
Share on other sites
[quote name='ArgusMaker' timestamp='1311090251' post='4837447']
Ok I finally understood my problem.
I execute the code to get mouse position here

while (GetMessage (&messages, NULL, 0, 0))
{
[color="#1C2837"][size="2"]GetCursorPos(&point);[/size][/color][color="#1C2837"][size="2"]
cursor_x = point.x;
cursor_y = point.y;
[/size][/color]
TranslateMessage(&messages);
DispatchMessage(&messages);
}

But this code is not executed when there are no messages, and if mouse is outside the window, most of times no messages are sent to the window.
How can i execute a piece of code always? If i put it in a while(true) my application will get stuck
[/quote]

then use [url="http://msdn.microsoft.com/en-us/library/ms644943%28v=vs.85%29.aspx"]PeekMesage[/url]

Share this post


Link to post
Share on other sites
A second, more subtle, bug is that GetMessage returns -1 on an error. If an error occurs you've got an infinite loop.

But that aside, yeah, use PeekMessage instead.

Share this post


Link to post
Share on other sites
This is what i wrote:

[code]
while(true)
{
RenderBegin();
//render stuff
RenderEnd();
TranslateMessage(&messages);
DispatchMessage(&messages);
PeekMessage(&messages,hwnd,0,0,true);

if(game_end) break;
}[/code]
It does work ;D

Share this post


Link to post
Share on other sites
It might "work", but it not how you should be doing those things... Here how it should be done:

[code]
LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//Process quit message
case WM_DESTROY:
case WM_CLOSE:
PostQuitMessage(0);
break;
//Mouse move messages
case WM_MOUSEMOVE:
MouseX = LOWORD(lParam);
MouseY = HIWORD(lParam);
break;
// Process more message here...
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

void GameLoop()
{
MSG msg;
bool done = false;

// Application loop.
while(!done){
if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){
if(msg.message == WM_QUIT)
done = true;
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
UpdateScene(EngineTimer.g_ElapsedTime);
RenderScene();
}
}
}
[/code]

Share this post


Link to post
Share on other sites
Your PeekMessage should come before Translate/Dispatch and the last param isn't a bool; you probably want PM_REMOVE there instead (although I have seen arguments for using PM_NOREMOVE followed by a GetMessage if Peek returns true, forgive me for not having any links to provide).

See here: [url="http://www.mvps.org/directx/articles/writing_the_game_loop.htm"]http://www.mvps.org/...e_game_loop.htm[/url] for a sample game loop.

Edit: scooped!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this