How do I make a custom system wide mouse cursor animation? - c++

I write software for the disabled. One of the problems is difficulty tracking the mouse pointer. I want to have the mouse cursor glow (or similar effect. Maybe water like ripples around it) when the user needs to locate it. How is this done? I know it's possible because it's used in a variety of software.

You can create custom animated cursors "on the fly" by using CreateIconFromResource and painstakingly creating the cursor data structures yourself. I recently added some tests to the Wine project for creating cursors in this way, you can take a look at the structure of the cursor data by looking at this example for a three-frame cursor:
http://source.winehq.org/source/dlls/user32/tests/cursoricon.c?v=wine-1.3.16#L222

Have a look at Realworld Cursor Editor found here.
Edit: As the OP pointed out, the OP was looking for a way of creating an animated cursor programmatically, using Win32API. AFAIK it cannot be done or is long-winded way of doing it, the 'LoadCursor' function can load the cursor from an embedded resource or a file on disk with an extension .ani, hence my answer in support for the usage of Realworld Cursor Editor which can create an .ani file containing animated cursors, the other way of doing it is to use the 'Control Panel' > 'Mouse', click on 'Pointers' tab-page on the dialog itself to set it as system-wide settings. Here is a sample of how an animated cursor gets loaded here.
Hope this helps,
Best regards,
Tom.

An alternative approach is to leave the cursor as-is, and instead add some effects around it, using, for example, a temporary topmost layered window that you draw some animation on. (eg. alpha-blended circles to get a glow effect around the cursor position.)
This has the advantage of leaving the cursor unchanged, so if it's conveying information (eg. hourglass or size handle), you're not interfering with that.

If all you need to do is make ripples appear around the cursor, there is a setting you can change in the mouse section of control panel such that ripples appear around the cursor when the CTRL key is pressed.

Related

How to extend the existing mouse cursor in Windows app with some additional little image indications (may be multiple ones) based on the context?

As an example, imagine a complex snap operation, consisting of two active snappings in a context. Here two indicators on the second image show, that we are snapping perpendicularly and that we are snapping to any point of the line. When we drag out from the snapping intersection, we are not snapping to a point anymore, but we are still snapping perpendicularly to the reference line. For such and similar situations I would like to extend the cursor with different indicators, based on the context, like on these images.
Is it possible in MFC? Or otherwise in a Windows application?
Extending the cursor is not supported, you can only load one. So the best approach is to create all the cursors as .CUR files and then load them as needed.
Cursors can be created programmatically in Win32. The CreateCursor() function creates a cursor taking its dimensions, its hot spot and its AND (black) and XOR (invert) masks as parameters. Therefore you can create or load the basic pointer cursor masks and then add the indicators (either draw them using GDI, if they are simple, or load them from resources), creating the additional cursors you may need. I think it's a quite heavy job to do all these on the fly, so it would best to create all possible indicators during initialization.
The CreateCursor() function seems to create only monochrome cursors, maybe the CreateIconIndirect() function can create color cursors. Also take a look into this Win32 documentation topic: Using Cursors.
Of course this is quite an amount of work. You decide if it's worth or not...

How to turn cursor(mouse pointer object) into an automated sequence of bmp images?

I want to create a an hour glass movie to display as the mouse pointer when it is waiting for something to complete. How can I do this. thank you
You do this by creating an animated cursor, and then instructing Windows to display that cursor.
This is precisely how the hourglass cursor is implemented in Windows.
More information about cursors can be found here on MSDN.
Using a software package to create and edit your animated cursor files (*.ani) makes this process much easier. I use and recommend IcoFX. Using such software, you can even open the Windows cursors and see how they are constructed.

How do I display dynamic text at the mouse cursor via C++/MFC in a Win32 application

I would like to be able to display some dynamic text at the mouse
cursor location in a win32 app, for instance to give an X,Y coordinate that
would move with the cursor as though attached. I can do this during a
mousemove event using a TextOut() call for the window at the mouse
coordinates and invalidate a rectange around a stored last cursor position
to clear up the previous output. However this can suffer from flickering and
cause problems with other things being drawn in a window such as tracker
boxes. Is there a better way to do this, perhaps using the existing cursor
drawing/invalidating mechanism ?
You can do this via ToolTips - check out CToolTipCtrl.
If you want flicker free tracking ToolTips then you will need to derive your own classes from CToolTipCtrl that use the trackActivate messages.
You may want to consider a small transparent window that you move to follow the mouse. In particular, since Windows 2000, Layered windows seem to be the weapon of choice (confession: no personal experience there).
You can overwrite OnSetCursor to get a dynamic mouse cursor. I just found a German tutorial.
German tutorial
English translated tutorial

Where's the Win32 resource for the mouse cursor for dragging splitters?

I am building a custom win32 control/widget and would like to change the cursor to a horizontal "splitter" symbol when hovering over a particular vertical line in the control. IE: I want to drag this vertical line (splitter bar) left and right (WEST and EAST).
Of the the system cursors (OCR_*), the only cursor that makes sense is the OCR_SIZEWE. Unfortunately, that is the big, awkward cursor the system uses when resizing a window. Instead, I am looking for the cursor that is about 20 pixels tall and around 3 or 4 pixel wide with two small arrows pointing left and right.
I can easily draw this and include it as a resource in my application but the cursor itself is so prevalent that I wanted to be sure it wasn't missing something.
For example: when you use the COM drag and drop mechanism (CLSID_DragDropHelper, IDropTarget, etc) you implicitly have access to the "drag" icon (little box under the pointer). I didn't see an explicit OCR_* constant for this guy ... so likewise, if I can't find this splitter cursor outright, I am wondering if it is part of a COM object or something else in the win32 lib.
There are all sorts of icons, cursors, and images in use throughout the Windows UI which are not publicly available to 3rd-party software. Of course, you could still load up the module in which they reside and use them, but there's really no guarantee your program will keep working after a system update / upgrade.
Include your own. The last thing you want is adding an extra dependency over a tiny little cursor.
I had this exact problem. When I looked back over some old code for a vertical splitter thinking I had an easy answer, it turned out that I had build and loaded my own resource:
SetCursor( LoadCursor( ghInstance, "IDC_SPLITVERT" ));
I vaguely remember investing some considerable time and effort into find the system way of doing it, so (my guess) is that there is not a system ICON readily available to do the job, so you are better off rolling your own.
This is one of those times when I would like to be wrong, as I would have liked there to be a system icon for this job.

How to fix an MFC Painting Glitch?

I'm trying to implement some drag and drop functionality for a material system being developed at my work. Part of this system includes a 'Material Library' which acts as a repository, divided into groups, of saved materials on the user's hard drive.
As part of some UI polish, I was hoping to implement a 'highlight' type feature. When dragging and dropping, windows that you can legally drop a material onto will very subtly change color to improve feedback to the user that this is a valid action.
I am changing the bar with 'Basic Materials' (Just a CWnd with a CStatic) from having a medium gray background when unhighlighed to a blue background when hovered over. It all works well, the OnDragEnter and OnDragExit messages seem robust and set a flag indicating the highlight status. Then in OnCtrlColor I do this:
if (!m_bHighlighted) {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kBackgroundColour);
}
else {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kHighlightedBackgroundColour);
}
However, as you can see in the screenshot, the painting 'glitches' below the dragged object, leaving the original gray in place. It looks really ugly and basically spoils the whole effect.
Is there any way I can get around this?
Remote debugging is a godsend for debugging visual issues. It's a pain to set up, but having a VM ready for remote debugging will pay off for sure.
What I like to do is set a ton of breakpoints in my paint handling, as well as in the framework paint code itself. This allows you to effectively "freeze frame" the painting without borking it up by flipping into devenv. This way you can get the true picture of who's painting in what order, and where you've got the chance to break in a fill that rect the way you need to.
It almost looks like the CStatic doesn't know that it needs to repaint itself, so the background color of the draggable object is left behind. Maybe try to invalidate the CStatic, and see if that helps at all?
Thanks for the answers guys, ajryan, you seem to always come up with help for my questions so extra thanks.
Thankfully this time the answer was fairly straightforward....
ImageList_DragShowNolock(FALSE);
m_pDragDropTargetWnd->SendMessage(WM_USER_DRAG_DROP_OBJECT_DRAG_ENTER, (WPARAM)pDragDropObject, (LPARAM)(&dragDropPoint));
ImageList_DragShowNolock(TRUE);
This turns off the drawing of the dragged image, then sends a message to the window being entered to repaint in a highlighted state, then finally redraws the drag image over the top. Seems to have done the trick.