Cursor style doesn't stay updated - c++

I have a normal Windows GUI application (made using the API, not MFC) and as I move my mouse on and off the application and the mouse changes styles (like when you move it over the border, it changes to a resize arrow, etc.) but sometimes it "sticks" in that style, so that I can move the mouse around and it will stay in a resize arrow or whatever, even after it's off the window border. It fixes itself if I move it over another control.
It's just an inconvenience, but it looks unprofessional and I would like to fix it. How can I make it where it stays up to date all the time?

Set a valid cursor handle when you register your window class. See WNDCLASSEX::hCursor. Use LoadCursor to load a valid cursor. Like,
WNDCLASSEX wc = {0};
...
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
...
RegisterClassEx(&wc);

tenfour's answer is correct. Here's a little more background.
When the mouse moves within a window, and it's not captured, the window will get a WM_SETCURSOR message. The message name can be a little confusing. It's basically the window's opportunity to set the cursor, not an instruction to set the cursor.
A window can handle this message by calling SetCursor and returning.
A window can also punt by passing the message to DefWindowProc to get the default behavior. The default behavior is to look at the hCursor field in the WNDCLASS for the window. This is why tenfour's answer works.
(It's actually a bit more complicated than that, since the DefWindowProc first gives the parent window a chance to intervene.)
If you want to do something dynamic, like choose a cursor depending on some state variable, then you should have to handle the WM_SETCURSOR so that it calls SetCursor with whatever cursor is appropriate and then returns TRUE.
See SetCursor for details.

Related

How to check if my current window is the top most visible window

I have a window which is set to AlwaysOnTop using the WS_EX_TOPMOST flag. Now, it is possible that some other application might also have a window which has WS_EX_TOPMOST set and override the topmost flag for my window.
How should I check if my window is indeed the window that is the top most window and nothing is being painted over it (the nothing is being painted over my window is the important part). If something is painting over my window, I want to hide my window and show it again when I can make it the top most window (but that's probably the second step)
Call GetWindow passing your topmost window's handle and the GW_HWNDFIRST flag. The window returned will be the topmost window that is highest in the Z-order. You can then use the GW_HWNDNEXT flag to walk through the topmost windows in order of decreasing Z-order until you find yours. If any of the windows overlap your window, then your window is underneath.
The old standard way was to call WindowFromPoint for a point on your supposedly visible window and compare the returned handle against your own window handle. There is a better way using the clipping system. I discuss this here.

HWND Change cursor when mouse Hover

I need to change the cursor icon when the mouse hovers a certain HWND. I achieved the mouse cursor change with
SetClassLong(hWindow, GCL_HCURSOR, (LONG)LoadCursor (NULL, IDC_CROSS));
But it applies the cursor to each element which share the same class with the specified HWND. For example, in my case, the HWND is a Button element, and it's class is "Button", so all the buttons in my window will have the same cursor. How can I just change the cursor to a specified HWND? Something like this:
SetHwndCursor(hWindow, GCL_CURSOR, Cursor); //Invented function, just to make the example
Thanks.
To show a different cursor than the class's default cursor, you need to handle the WM_SETCURSOR message for the window and call SetCursor in response to WM_SETCURSOR. For a brief example, see Displaying a Cursor.
You'll need to subclass the button to override the button's WndProc to handle WM_SETCURSOR. Use SetWindowSubclass to subclass the window (and then remove the subclassing with RemoveWindowSubclass when the button is destroyed, in response to WM_NCDESTROY—see Raymond Chen's Safer subclassing for details). SetWindowLongPtr is no longer recommended for subclassing windows.
Thanks to #IInspectable and #JonathanPotter for the information on SetWindowSubclass.
I accomplish this by handling WM_SETCURSOR for the window in question and use SetCursor.

Create a window using the WS_EX_NOACTIVATE flag ,but it can't be dragged until I release the mouse

I have created a window using the WS_EX_NOACTIVATE flag and it works great as far as not taking focus when you click the window. However when I drag the window or try to resize it, it doesn't redraw the window as your are moving and resizing it, only at the very end once you release the mouse button. Is there a way around this? I would like to see the window as I am resizing it. I have searched many documents, but I still don't find the resolution...
If you need a window that doesn't take focus when clicked, but can still be interacted with, you need to handle the WM_MOUSEACTIVATE, and return MA_NOACTIVATE.
Additional information and fully working sample code has been published by Raymond Chen. See How can I have a window that rejects activation but still receives pointer input?
It's a Windows bug. You need to call SetWindowPos(hwnd, 0, x, y, width, height, 0) on WM_MOVING. The coordinates to set are given to you in lParam which is a RECT*.
Note that doing this will activate the owned window and deactivate the owner, which is not what you want (and SWP_NOACTIVATE has no effect either).
To avoid that, you need to set WS_CHILD on the owned window. But set it after you created the window, via SetWindowLong(), otherwise your owned window will get clipped, like any child window.
And, as you probably already figured out, this only works for windows with WS_EX_TOOLWINDOW ex style. I wasn't able to make the owned window stay deactivated with any other style combination that doesn't include WS_EX_TOOLWINDOW.
That's winapi for you :(

WINAPI / c++: Moving borderless window

I have created a borderless window using these styles: WS_VISIBLE | WS_POPUP | WS_OVERLAPPED
The problem is that the window can't be moved. I know that I could do something like getting mouse click position, and then calculate where the window would end up everytime there comes a WM_MOUSEMOVE.
But this solution is not stable, because when I move my mouse too fast, it gets out of the window, and then it won't react. I dont want to set up a hook, because they are too slow. I have searched the internet, but nothing came up at all.
What I ideally want to, is to create a window, that is able to be moved without borders or captions, where I don't need to track the mouse myself, but where Windows does it for me, like making the whole window a caption.
I know that I could do something like getting mouse click position, and then calculate where the window would end up everytime there comes a WM_MOUSEMOVE. But this solution is not stable, because when I move my mouse too fast, it gets out of the window, and then it won't react.
You can fix that by calling SetCapture when you receive the mouse click. You then will continue to receive WM_MOUSEMOVE even after the mouse cursor leaves your window. When the user is finished dragging and release the mouse cursor, you then should call ReleaseCapture.
What I ideally want to, is to create a window, that is able to be moved without borders or captions, where I don't need to track the mouse myself, but where Windows does it for me, like making the whole window a caption.
If you really want to do that, you could respond to the WM_NCHITTEST message and return HTCAPTION.
try PostMessage(hwnd,WM_SYSCOMMAND,SC_SIZE+9,0) on WM_LBUTTONDOWN.

Constraining window position to desktop working area

I want to allow a user to drag my Win32 window around only inside the working area of the desktop. In other words, they shouldn't be able to have any part of the window extend outside the monitor(s) nor should the window overlap the taskbar.
I'd like to do it in a way that does cause any stuttering. Handling WM_MOVE messages and calling MoveWindow() to reposition the window if it goes off works, but I don't like the flickering effect that's caused by MoveWindow().
I also tried handling WM_MOVING which prevents the need to call MoveWindow() by altering the destination rectangle before the move actually happens. This resolves the flickering problem, but another issue I run into is that the cursor some times gets aways from the window when a drag occurs allowing the user to drag the window around while the cursor is not even inside the window.
How do I constrain my window without running into these issues?
Windows are, ultimately, positioned via the SetWindowPos API.
SetWindowPos starts by validating its parameters by sending the window being sized or moved a WM_WINDOWPOSCHANGING message, and then a WM_WINDOWPOSCHANGED message notifying the window proc of the changed size and/or position.
DefWindowProc handling of these messages is to, in turn, send WM_GETMINMAXINFO and then WM_SIZE or WM_MOVE messages.
Anyway, handle WM_WINDOWPOSCHANGING to filter both user, and code, based attempts to position a window out of bounds.
Keep in mind that users with multi-monitor setups may have a desktop that extends into negative x- and y-coordinates, or that is not rectangular. Also, some users use alternative window managers such as LiteStep, which implement virtual desktops by moving them off-screen; if you try to fight this, your application will break for these users.
You can do this by handling the WM_MOVING message and changing the RECT pointed to by the lParam.
lParam: Pointer to a RECT structure with the current position of the window, in screen coordinates. To change the position of the drag rectangle, an application must change the members of this structure.
you may also want to handle WM_ENTERSIZEMOVE to know when the window is beginning to move, and WM_EXITSIZEMOVE
WM_GETMINMAXINFO is what you seem to be looking for.