2009-05-31 6 views
2

私は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 
     ); 
} 
+0

あなたの質問にはより良いタイトルを付けてください。 –

+1

あなたが試したことがうまくいかなかった理由も教えてください。それはあなたがループでそれをやったように聞こえるかもしれません。おそらく、一時停止を与えずに処理するGUIイベントループを知らせることなく。 – TheSoftwareJedi

+0

正常に動作しなかった理由が分かりません –

答えて

2

自然に移動するウィンドウは、移動を開始すると加速し、停止すると減速します。速度対時間のグラフは、bell curve、またはtriangle waveのようになります。三角波は簡単に実装できます。

ボックスを移動するときは、ポイントaとポイントbの中間点に達するまで、ループを繰り返すたびにボックスを移動するピクセル数を着実に増やす必要があります。ボックスを移動するピクセル数。特別な数学は必要ありません。それは単に加算と減算です。

+0

これは、参照用に使用できるコードのスニペットに実装できますか? –

+0

数学のものは厳しい正弦です – kenny

+0

nodave、コードの新しい投稿をご覧ください。 –

5

スムーズなアニメーションが必要な場合は、時間ベースで作成し、Windowsがムーブメント間のメッセージを処理できるようにする必要があります。 Set a timerを入力し、アニメーションを開始してからelapsed timeに基づいてウィンドウを移動させてWM_TIMER notificationsに応答します。自然な動きのためには、距離を決定するための線形関数を使用しないでください。代わりに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); 
} 
+0

実装がありますか?これは私の頭の上に少しあるようです –

+0

@nodave、彼らはあなたに必要なものすべてを与えました。あなたのコールバックタイマー機能は、経過時間といくつかの数学関数(三角波やベルカーブのような)に基づいてウィンドウを移動させる。 – mmcdole

+0

@nodave:Simucalが言ったこと。 Harveyはあなたに関数を与えました、それは実際にはこのプロジェクトの唯一の非trival側面です。私があなたに与えたリンクをたどって、タイマーの仕組みを学び、何かを書いてください。何か問題が生じたら、もう一度質問を投稿してください。私は擬似コードの例を追加しましたが、大まかなアイデアを与える必要があります。正確な実装はプログラムの構造に依存します。 – Shog9

4

私はあなたが欲しいものを行う必要があり、このコードを発見しました。

小さなインクリメント(.03?)を使用して変数を0から1の間でインクリメント(incと呼び、グローバルにする)し、以下の関数を使用して滑らかな動きを与える。

数学は、このように書きます:

currentx =×1 *(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

0

あなたがもしあなたはループバックVNCを自分でマウスをドラッグすることができます十分な退屈です。

今、なぜあなたは私が知りたくないと思うのですか?

関連する問題