Fading the cursor - windows

I have a Windows application for which I would like to indicate that the content is dead/frozen/not interactable by fading it to 50%.
Is there a way to take the standard Windows cursor and fade it?

I have never seen a case of the Windows cursor being anything but 100% opaque, and I heavily suspect that there's no option to make it transparent because the uses are limited and the abuses are many (i.e. make cursor invisible, would cause massive frustration).

I don't know of any way to do that, and it makes sense there's none - it is not a part of Window's look and feel. You'd usually fade the dead/frozen/not interactable control rather than the cursor, and/or change the cursor to a standard hourglass or so.
Having that say, if fading the cursor is definitively what you want, you can create a faded image of the standard cursor, and load it when needed.

Related

How to properly use setPatternOffset to fix NSColor colorWithPatternImage insanity

I'm trying to draw a tiled pattern inside a NSScrollView which is itself inside a resizable window (on Mac OS X). The code simply calls [NSColor colorWithPatternImage], CGContextSetFillColorWithColor, and CGContextFillRect.
The problem is that the pattern is drawn relative to the bottom-left corner of the window. This is documented behavior, but causes two unpleasant effects:
When the window is resized, the pattern scrolls up or down in a very surprising manner.
When the scroll view is scrolled, and then scrolled back, the newly drawn pattern doesn't line up with the scrolled (buffered) part of the pattern.
I'm able to mostly fix problem 2 by calling CGContextConvertPointToDeviceSpace, passing in 0,0, and seeing what I get back -- this tells me my scroll offset, which I can then use with CGContextSetPatternPhase to fix the problem. (Though it doesn't completely fix it -- when I scroll quickly, I still see mismatched patterns, for reasons I haven't sorted out yet.)
But addressing problem 1 is proving really thorny. From my drawing code, which only knows the CGContext, I can't find any way to get the window height. (The Device/User space conversion routines seem completely unaffected by window height.)
Short of adding a bunch of plumbing to all the drawing code to pass around a window reference, is there any way to figure out the correct offset so that my pattern will stay put when the window is resized, and scroll properly when the scrollview is scrolled?
Oops -- shortly after posting this, I found at least a partial answer: the current transformation matrix (from CGContextGetCTM) reflects both the window height, and the scroll offset.
(Or at least, it does in my app; I set the CTM very early in the pipeline to give me a top-down coordinate system so I can use much the same code on iOS.)
So, if I just call CGContextGetCTM, and then pass the .x0 and .y0 values of the result to CGContextSetPatternPhase, it mostly works.
I'm still running into some visual glitches when I scroll quickly horizontally, though not vertically -- a very odd effect, which suggests to me that it might be something in my code, or perhaps related to how wide the content area is. I'll dig further.

Shadow for custom mouse cursor

On "newer" Windows systems there is an option to make the OS draw a shadow beneath the mouse cursor:
However the custom cursors in my Delphi app don't show a shadow even if this setting is enabled. Do you have any idea how to arrange it so that Windows adds the shadow automagically? Or do I really have to check the user's preferences and conditionally draw the shadow myself like Mike Lischke did?
(This is a question that has been bugging me and others for some time:
Custom mouse cursor shadow
Custom cursor shadow
Custom cursor with shadow)
No, you don't need to check the user's global setting and draw the cursor yourself. You just need to provide a cursor with the alpha channel. Windows will either use alpha blending to draw your cursor or not, depending on the user's setting. Your cursors probably don't include the alpha channel so the shadow is never shown.

Shadow for custom mouse cursor (2)

After reading the answer to the Shadow for custom mouse cursor question, I did some testing.
From my Delphi application I loaded both 32bit and 24bit versions of my cursor. Never a shadow. I did the same with the standard Windows arrow pointer. No shadow either.
Also I tried the opposite and assigned my custom cursors to the "Normal select" pointer in the Windows mouse settings. Both the 24bit and 32bit pointer were given a shadow.
So, it appears having an alpha channel in a cursor doesn't influence the shadow behaviour. But what am I doing wrong in my application?
First step is adding the cursor to the application's resources via an .rc file with
CUR_EDGE_R Cursor DISCARDABLE "edge_r.cur"
And in the application it is loaded with:
const
crEdgeR = TCursor(135);
.
.
Screen.Cursors[crEdgeR] := LoadCursor(HInstance, 'CUR_EDGE_R');
So, what is the way to have Windows add a shadow to a custom cursor?
Note: I have seen posts on the internet suggesting to create two version of the mouse cursor, one with and one without shadow, and load the appropriate cursor, depending on the user's settings. This is not the solution I'm looking for.
In order to place a shadow under your custom cursor, you simply design the cursor with an Alpha channel (which enables semi transparency) and draw your shadow in place. You can even use Photoshop/GIMP (or any other capable graphics editor) to produce your cursor with a "Drop Shadow" effect, save it as a PNG, then use an Icon Editor (such as Microangello) to convert the PNG to a cursor.
As I understand it, none of the cursors shipped with Windows Vista/7 are designed as "flat", using some system effect to generate their shadows.

Is it possible to use AnimateWindow with AW_BLEND when using a layered window?

I am displaying a window using UpdateLayeredWindow and would like to add transition animations. AnimateWindow works if I use the slide or roll effects (though there is some flickering). However, when I try to use AW_BLEND to produce a fade effect, I not only lose any translucency after the animation (per-pixel and on the entire image), but a default window border also appears. Is there a way to prevent the border from appearing?
Since I'm using UpdateLayeredWindow, SetLayeredWindowAttributes will not work. The diagram here was pretty useful. Instead, I just need to call UpdateLayeredWindow in a loop while decreasing the SourceConstantAlpha member of the BLENDFUNCTION structure. In fact, the pointer to the BLENDFUNCTION structure, the handle to the layered window, and the flags are the only things I needed to pass into UpdateLayeredWindow if the alpha is all that is changing.
The only way I've found to successfully fade up/down a window (without the complications you're describing) is by first creating a window with the WS_EX_LAYERED extended style. I then start a timer (30ms) that gradually fades the window by calling something like:
SetLayeredWindowAttributes(0,
(BYTE)(m_nAnimationCount * WINDOW_ALPHA),
LWA_ALPHA);
where WINDOW_ALPHA is 23 (seems to look the best), and m_nAnimationCount is a count from 0 to 10 (or 10 to 0 if fading down).
If you discover a better way of doing this, I'd be interested to find out.

Creating a quick look style zooming effect

I would like to create an effect than an image zooms up from a thumbnail size to full screen.
I am not sure what's the right steps to achieve this. Should I create a transparent full screen window and animate a layer on top of it?
Take a look at this CoreGraphics example. Specifically, take a look at the "grow" and "shrink" animations. That's how Apple does it, and that's what you'll want to do too.
Your solution of a transparent window with a CALayer inside is probably the best supported way to do it.
One thing that seems like it should be a good solution (at least it's the first thing I thought of when I wanted to do this) but isn't is NSView's enterFullScreenMode:withOptions:. If memory serves, it was originally meant to do what you're talking about here, but the animation was taken out and it generally doesn't work that well now.

Resources