Maybe there is already a threat about this, but I did a forum search and couldn't find my answer.
I have a window with a grey and a white area. I want the cursor to be a cross in the white area, and a normal arrow in the grey one. I tried this:
// ...
case WM_SETCURSOR:
if(_ptMouse.y>600) //grey area
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
else
{
SetCursor(LoadCursor(NULL, IDC_CROSS));
}
// ...
ptMouse is a POINT structure in which I store the mouse position each WM_MOUSEMOVE. But my window doesn't fill the entire screen and when I move the mouse over the caption of the window, the border of the window or just the desktop, the cursor is still a cross.
Is it a bad idea to set the cursor (with SetCursor(LoadCursor(NULL, IDC ...) just every mousemove? Doesn't that cause flickering?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You might have to define the area where you want the cursor to change better, and test for the non-default cursor condition, in other words since the default cursor is an arrow, instead of testing for when it should be set to an arrow test for when you want it to be a cross, the 'else' should be the default condition.
Also, the SetCursor function is quite fast, you shouldn't have any trouble with flicker.
case WM_SETCURSOR:
if(_ptMouse.y > 0 && _ptMouse < 600) //NOT grey area, make it a cross
{
SetCursor(LoadCursor(NULL, IDC_CROSS));
}
else // default to arrow
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
b_a
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you very much.
But I still have one problem: _ptMouse contains the value passed by the lParam of WM_MOUSEMOVE. So it's relative to the window, and I can't check if the mouse is not on the window. I will problably have to use GetMousePos(). But is that a normal way of doing something simple like this?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I don't know that it would be a good idea to use SetClassLong for changing the cursor on-the-fly like what the original poster is doing.
A case where you'd use it would be if you had some predefined child windows controls where you don't define the window class yourself, like maybe edits, and you want to have a different cursor when the mouse is over them.
Otherwise you should call SetCursor during processing of the WM_MOUSEMOVE message.
At least that's what Petzold says :)
The question about when the mouse is outside the window... exactly why do you need to know when it is? Are you talking about when dragging the mouse with the button down, or just generally moving it outside the window? If you mean when dragging you'll probably want to look into capturing the mouse with SetCapture(hwnd).
b_a
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
But when the cursor is on the border of the window, or on the caption, it is still a cross. I don't know how to change that because _ptMouse is updated at WM_MOUSEMOVE so it's relative to the window. That means also that either if the mouse is outside the win, _ptMouse still contains the latest pos on the window. If I change the cursor during mousemove it will be reset as I click. I'm thinking about using GetMousePos() to get the absolute mouse position, but I don't know the position of my own window, so that won't help.
Ideas? Thank you very much!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yeah, that's going to be the perfect solution, when I know how to use it. I'm still wondering if there's no simpler way of handling different cursors, but this will probably work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There's a TrackMouseEvent function that's supposed to notify you when the mouse hovers over or leaves a window, I haven't tried it yet so I'm not sure exactly how it works, I'll look into it as soon as I get a chance. You can also look on msdn, search for mouse.
I have found an answer that doesn't seem bad at all,
although I'm not sure if it is or not. I set the window class cursor to NULL,
so it won't show up at any mouse event. My code is this:
// WinMain...
wincl.hCursor = NULL;
// WinProc...
case WM_CREATE:
SetCursor(LoadCursor(NULL, IDC_ARROW));
Maybe there is already a threat about this, but I did a forum search and couldn't find my answer.
I have a window with a grey and a white area. I want the cursor to be a cross in the white area, and a normal arrow in the grey one. I tried this:
// ...
case WM_SETCURSOR:
if(_ptMouse.y>600) //grey area
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
else
{
SetCursor(LoadCursor(NULL, IDC_CROSS));
}
// ...
ptMouse is a POINT structure in which I store the mouse position each WM_MOUSEMOVE. But my window doesn't fill the entire screen and when I move the mouse over the caption of the window, the border of the window or just the desktop, the cursor is still a cross.
Is it a bad idea to set the cursor (with SetCursor(LoadCursor(NULL, IDC ...) just every mousemove? Doesn't that cause flickering?
You might have to define the area where you want the cursor to change better, and test for the non-default cursor condition, in other words since the default cursor is an arrow, instead of testing for when it should be set to an arrow test for when you want it to be a cross, the 'else' should be the default condition.
Also, the SetCursor function is quite fast, you shouldn't have any trouble with flicker.
case WM_SETCURSOR:
if(_ptMouse.y > 0 && _ptMouse < 600) //NOT grey area, make it a cross
{
SetCursor(LoadCursor(NULL, IDC_CROSS));
}
else // default to arrow
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
b_a
Thank you very much.
But I still have one problem: _ptMouse contains the value passed by the lParam of WM_MOUSEMOVE. So it's relative to the window, and I can't check if the mouse is not on the window. I will problably have to use GetMousePos(). But is that a normal way of doing something simple like this?
I don't know that it would be a good idea to use SetClassLong for changing the cursor on-the-fly like what the original poster is doing.
A case where you'd use it would be if you had some predefined child windows controls where you don't define the window class yourself, like maybe edits, and you want to have a different cursor when the mouse is over them.
Otherwise you should call SetCursor during processing of the WM_MOUSEMOVE message.
At least that's what Petzold says :)
The question about when the mouse is outside the window... exactly why do you need to know when it is? Are you talking about when dragging the mouse with the button down, or just generally moving it outside the window? If you mean when dragging you'll probably want to look into capturing the mouse with SetCapture(hwnd).
b_a
I don't know how to use SetCapture() and what it does.
I now have the following code:
case WM_SETCURSOR:
if(_ptMouse.y<600)
{
SetCursor(LoadCursor(NULL, IDC_CROSS));
}
else
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
But when the cursor is on the border of the window, or on the caption, it is still a cross. I don't know how to change that because _ptMouse is updated at WM_MOUSEMOVE so it's relative to the window. That means also that either if the mouse is outside the win, _ptMouse still contains the latest pos on the window. If I change the cursor during mousemove it will be reset as I click. I'm thinking about using GetMousePos() to get the absolute mouse position, but I don't know the position of my own window, so that won't help.
Ideas? Thank you very much!
Yeah, that's going to be the perfect solution, when I know how to use it. I'm still wondering if there's no simpler way of handling different cursors, but this will probably work.
Is it a good idea to change the window cursor using SetClassLong?
There's a TrackMouseEvent function that's supposed to notify you when the mouse hovers over or leaves a window, I haven't tried it yet so I'm not sure exactly how it works, I'll look into it as soon as I get a chance. You can also look on msdn, search for mouse.
http://msdn1.microsoft.com/en-us/default.aspx
b_a
I have found an answer that doesn't seem bad at all,
although I'm not sure if it is or not. I set the window class cursor to NULL,
so it won't show up at any mouse event. My code is this:
// WinMain...
wincl.hCursor = NULL;
// WinProc...
case WM_CREATE:
SetCursor(LoadCursor(NULL, IDC_ARROW));
// ...
case WM_MOUSEMOVE:
// ...
if(_ptMouse.y<600)
{
SetCursor(SetCursor(LoadCursor(NULL, IDC_CROSS));
}
else
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
It seems to work.
Thank you all for your help!!