子窗口的动画移动






4.21/5 (7投票s)
一个简单的类,
引言
ChildWndMover
帮助你制作子控件移动的动画。
背景
我写这个是因为我需要一种方法来告诉用户 我们的一个程序有新版本可用,但我不想使用模态消息框(因为我觉得这很烦人)。相反,当程序启动并检测到有新版本可用时,我使用此代码将一堆控件滑到主窗口的一侧,然后在他们的位置插入一个 CHTMLCtrl 窗口并在对话框上显示一个描述升级的小网页。几秒钟后,我删除 CHTMLCtrl
,其余控件会滑回其原始位置。我发现这比模态对话框更不引人注目;无需点击任何内容,所有原始控件仍然有效 - 它们只是向左移动了几个像素,持续了几秒钟。是的,此通知可以禁用。
本文中的代码描述了我用来移动控件的内容。
Using the Code
这是基本用法
// if it's not already moving...
if (!ChildWndMover::Moving(myControl.GetSafeHwnd()))
{
// ... move it!
ChildWndMover::AddMover(
parentWnd.GetSafeHwnd(), // typically the parent dialog
m_control.GetSafeHwnd(), // HWND of the control you want to move
-50, // move to the left 50 pixels
0, // don't move vertically
10, // grow the width by 10
-20, // reduce the height by 20
.5, // duration of the move is .5 seconds (approximately)
20, // do it in 20 steps
true, // tell the window to redraw itself after each move
false // don't hide at the end
);
}
调用之后,m_control
将开始向左移动,同时改变其形状。
有三个 public
函数调用
AddMover
- 从您的控件信息创建一个 mover 对象,启动一个计时器,并移动控件Moving(HWND)
- 测试以查看是否正在移动特定的控件Moving(void)
- 测试以查看是否正在移动任何东西。在演示应用程序中,OnOK
处理程序会在启动新的 movers 之前检查这一点,以避免中断任何现有的 movers。
命名空间中的其他所有内容都是内部实用程序 - 无需直接调用它。
关注点
它是异步的!当您调用 AddMover
时,会在您要移动的窗口上创建一个计时器,并且控件会响应来自该计时器的事件而移动。因此,即使 AddMover
函数会立即返回,窗口也会开始移动并继续移动,无论您的其余代码在做什么,只要 Windows 可以通过消息队列获取 WM_TIMER
事件。由于此移动将发生在您的 AddMover
调用范围之外,因此控件对象的映射必须是全局的;全局范围是足够大的唯一范围来处理这种异步操作。
我将代码放在一个命名空间中,而不是将其设为 static
类,因为我认为没有理由创建即使是虚拟的 CChildWndMover
对象 - 所有状态都在全局映射和计时器中。 实际上没有对象需要维护,所以我认为没有必要为此烦恼......命名空间同样可以完成这项工作。
就这样。代码非常简单,使用起来也更简单。
历史
- 2009年10月8日th:首次发布