Introduction
ChildWndMover
helps you to animate the movement child controls.
Background
I wrote this because I needed a way to tell users that a new version of one of our programs was available, but I didn't want to do a modal message box (because I find that annoying). Instead, when the program starts-up and detects that there's a new version available, I use this code to slide a bunch of controls to the side of the main window, then I insert a CHTMLCtrl window on the dialog in their place and show a little web page describing the upgrade. After a few seconds, I remove the CHTMLCtrl
and the rest of the controls slide back to their original position. I find this to be much less obtrusive than a modal dialog; there's nothing to click, all the original controls still work - they've just moved a few pixels to the left, for a couple of seconds. And yes, this notification can be disabled.
The code in this article describes what I use to move the controls.
Using the Code
Here's the basic usage:
if (!ChildWndMover::Moving(myControl.GetSafeHwnd()))
{
ChildWndMover::AddMover(
parentWnd.GetSafeHwnd(), m_control.GetSafeHwnd(), -50, 0, 10, -20, .5, 20, true, false );
}
After that call, m_control
will start moving to the left while changing its shape.
There are three public
function calls:
AddMover
- Creates a mover object from your control information, starts a timer, and moves the control
Moving(HWND)
- Test to see if a specific control is currently being moved
Moving(void)
- Test to see if anything is moving. In the demo app, the OnOK
handler checks this before starting new movers, to avoid interrupting any existing movers.
Everything else in the namespace is an internal utility - no need to call it directly.
Points of Interest
It's asynchronous! When you call AddMover
, a timer is created on the window you're moving, and the control is moved in response to events from that timer. So, even though the AddMover
function will return immediately, the window will start moving and continue to move, regardless of what the rest of your code is doing, as long as Windows can get WM_TIMER
events through the message queue. Because this movement will occur outside the scope of your AddMover
call, the map of control objects has to be global; global scope is the only scope big enough to handle this kind of asynchronous operation.
I put the code in a namespace rather than make it a static
class, because I didn't see any reason to create even a dummy CChildWndMover
object - all state is in the global map and the timers. There really is no object to maintain, so I saw no need to bother with the concept ... a namespace does the job just as well.
That's it. The code is very simple and using it is even simpler.
History
- Oct 8th 2009: First release