Как программно перемещать окно медленно, как если бы это делал пользователь? - PullRequest
2 голосов
/ 31 мая 2009

Мне известны функции MoveWindow () и SetWindowPos (). Я знаю, как правильно их использовать. Однако я пытаюсь медленно и плавно перемещать окно, как будто пользователь его перетаскивает.

Мне еще нужно, чтобы это работало правильно. Я попытался получить текущие координаты с помощью GetWindowRect () и затем использовать функции setwindow и movewindow, увеличивая значение Right на 10 пикселей при каждом вызове.

Есть идеи?

Вот то, что я имел помимо всех моих определений.

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

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

Ответы [ 4 ]

5 голосов
/ 01 июня 2009

Если вы хотите плавную анимацию, вам нужно будет сделать ее основанной на времени и позволить Windows обрабатывать сообщения между движениями. Установите таймер и ответьте на уведомления WM_TIMER , переместив окно на расстояние, основанное на истекшем времени с момента запуска анимации. Для естественного движения не используйте линейную функцию для определения расстояния - вместо этого попробуйте что-то вроде предложенной функции Роберта Харви.

псевдокод:

//
// 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);
}
4 голосов
/ 01 июня 2009

Я нашел этот код, который должен делать то, что вы хотите. Это в c #, но вы должны быть в состоянии адаптировать его:

увеличить переменную в диапазоне от 0 до 1 (давайте назовем ее "inc" и сделать ее глобальной) с небольшими приращениями (.03?) И использовать приведенную ниже функцию для плавного движения.

Математика выглядит так:

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 голосов
/ 01 июня 2009

Естественно движущееся окно будет ускоряться при начале движения и замедляться при остановке. График зависимости скорости от времени будет выглядеть как кривая колокола или, возможно, вершина треугольной волны . Треугольную волну было бы проще реализовать.

При перемещении блока вам нужно постоянно увеличивать количество пикселей, которые вы перемещаете блок каждый раз по циклу, пока не достигнете середины точки между точкой a и точкой b, на которой вы будете постепенно уменьшать число пикселей, по которым вы перемещаете поле. Здесь нет особой математики; это просто сложение и вычитание.

0 голосов
/ 01 июня 2009

Если вам достаточно скучно, вы можете сделать VNC loopback, чтобы перетащить мышь самостоятельно.

Теперь, почему вы хотите, я не знаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...