如何以编程方式缓慢移动窗口,就好像用户正在这样做?

时间:2009-05-31 19:45:28

标签: c++ c winapi

我知道MoveWindow()和SetWindowPos()函数。我知道如何正确使用它们。但是,我想要完成的是缓慢平滑地移动窗口,就好像用户正在拖动它一样。

我还没有让它正常工作。我尝试的是使用GetWindowRect()获取当前坐标,然后使用setwindow和movewindow函数,每次调用向右递增10个像素。

有什么想法吗?

这是我所有定义旁边的内容。

while(1)
{
     GetWindowRect(notepad,&window);

     Sleep(1000);
     SetWindowPos(
        notepad,
        HWND_TOPMOST,
        window.top - 10,
        window.right,
        400,
        400,
        TRUE
        );
}

4 个答案:

答案 0 :(得分:5)

如果你想要流畅的动画,你需要让它基于时间,并允许Windows在两个动作之间处理消息。 Set a timer,并在动画开始后根据WM_TIMER notifications将窗口移动一段距离,以回复elapsed time。对于看起来很自然的动作,不要使用线性函数来确定距离 - 而是尝试类似Robert Harvey's建议的函数。

伪代码:

//
// animate as a function of time - could use something else, but time is nice.
lengthInMS = 10*1000; // ten second animation length
StartAnimation(desiredPos)
{
   originalPos = GetWindowPos();
   startTime = GetTickCount();
   // omitted: hwnd, ID - you'll call SetTimer differently 
   // based on whether or not you have a window of your own
   timerID = SetTimer(30, callback); 
}

callback()
{
   elapsed = GetTickCount()-startTime;
   if ( elapsed >= lengthInMS )
   {
      // done - move to destination and stop animation timer.
      MoveWindow(desiredPos);
      KillTimer(timerID);
   }

   // convert elapsed time into a value between 0 and 1
   pos = elapsed / lengthInMS; 

   // use Harvey's function to provide smooth movement between original 
   // and desired position
   newPos.x = originalPos.x*(1-SmoothMoveELX(pos)) 
                  + desiredPos.x*SmoothMoveELX(pos);
   newPos.y = originalPos.y*(1-SmoothMoveELX(pos)) 
                  + desiredPos.y*SmoothMoveELX(pos);       
   MoveWindow(newPos);
}

答案 1 :(得分:4)

我发现这个代码应该做你想要的。它在c#中,但你应该能够适应它:

使用小增量(.03?)增加0到1之间的变量(让我们称之为“inc”并使其成为全局变量)并使用下面的函数来提供平滑运动。

数学是这样的:

currentx = x1 *(1-smoothmmoveELX(inc))+ x2 * smoothmmoveELX(inc)

currenty = y1 *(1-smoothmmoveELX(inc))+ y2 * smoothmmoveELX(inc)

代码:

public double SmoothMoveELX(double x) 
{ 
    double PI = Atn(1) * 4;
    return (Cos((1 - x) * PI) + 1) / 2; 
} 

http://www.vbforums.com/showthread.php?t=568889

答案 2 :(得分:2)

自然移动的窗口会在开始移动时加速,并在停止时减速。速度与时间的关系图看起来像bell curve,或者可能是triangle wave的顶部。三角波将更容易实现。

当您移动框时,您需要每次循环时稳定地增加移动框的像素数,直到达到a点和b点之间的中间点,此时您将稳定地减少数量您正在移动框的像素。没有涉及特殊的数学;它只是加法和减法。

答案 3 :(得分:0)

如果你觉得无聊,你可以做环回VNC自己拖动鼠标。

现在,至于为什么你想要我不知道。