/// <summary> /// アニメーション処理 /// </summary> private async void GHFormAnimation(CancellationToken token) { await Task.Run(() => { int loopMax = 0; int slideDistance = 0; long totalTime = 0; bool slide = false; bool fade = false; bool reverse = GHManager.Settings.Launcher.Pos >= 2; bool visible = (bool)Invoke(new DelegateGetVisible(GetVisible)); int srcPos = (int)Invoke(new DelegateGetSrcPosition(GetGetSrcPosition)); int destPos = (int)Invoke(new DelegateGetDestPosition(GetGetDestPosition)); long animateTime = (long)Invoke(new DelegateGetAnimateTime(GetAnimateTime)); IntPtr handle = (IntPtr)Invoke(new DelegateGetHandle(GetFormHandle)); DelegateAnimationInitial animationInitial = AnimationInitial; DelegateAnimationFinal animationFinal = AnimationFinal; DelegateSetLeftOrTop setLeftOrTop = SetLeftOrTop; DelegateGetLeftOrTop getLeftOrTop = GetLeftOrTop; DelegateGetAlpha getAlpha = GetAlpha; DelegateSetAlpha setAlpha = SetAlpha; DelegateGetTotalTime getTotalTime = GetTotalTime; // スライド・フェードのフラグを取得 slide = (bool)Invoke(new DelegateGetSlideFlag(GetSlideFlag)); fade = (bool)Invoke(new DelegateGetFadeFlag(GetFadeFlag)); bool slideEnd = slide; bool fadeEnd = fade; // ループ回数 loopMax = (int)(animateInfo._AnimateTime / AnimationSleepMili); if (!slideEnd && !fadeEnd) { loopMax = 0; } for (int i = 0; i < loopMax; ++i) { if (token.IsCancellationRequested) { return; } Invoke(animationInitial); totalTime = (long)Invoke(getTotalTime); slideEnd = slide ? GHFormSlider(visible, srcPos, destPos, loopMax, i, animateTime, totalTime, ref handle, ref slideDistance, ref getLeftOrTop, ref setLeftOrTop) : false; fadeEnd = fade ? GHFormFader(visible, srcPos, destPos, loopMax, i, animateTime, totalTime, ref getAlpha, ref setAlpha) : false; Invoke(animationFinal, new object[] { slideEnd, fadeEnd }); // 指定時間待つ Thread.Sleep(AnimationSleepMili); } // 正確な位置に修正 if (slide) { if (!visible) { Invoke(setLeftOrTop, srcPos); } if (visible) { Invoke(setLeftOrTop, destPos); } } else { if (!visible) { Invoke(setLeftOrTop, destPos); } if (visible) { Invoke(setLeftOrTop, destPos); } } Invoke(new DelegateEndAnimation(EndAnimation)); }, token); }
/// <summary> /// ウィンドウをスライドさせる /// </summary> /// <param name="visible">ウィンドウの表示・非表示</param> /// <param name="loopMax">ループ回数</param> /// <param name="loopCount">現在のループ数</param> /// <param name="handle">ウィンドウハンドル</param> /// <param name="slideDistance">スライドした距離</param> /// <param name="getLeftOrTop">位置を取得する関数のデリゲート</param> /// <param name="setLeftOrTop">位置を設定する関数のデリゲート</param> /// <returns>スライドが終了したか</returns> private bool GHFormSlider(bool visible, int srcPos, int destPos, int loopMax, int loopCount, long animateTime, long totalTime, ref IntPtr handle, ref int slideDistance, ref DelegateGetLeftOrTop getLeftOrTop, ref DelegateSetLeftOrTop setLeftOrTop) { int BasePos = (int)Invoke(getLeftOrTop); bool reverse = GHManager.Settings.Launcher.Pos >= 2; // 全体距離 int total = Math.Abs(destPos - srcPos); // 進む距離 int spd = (int)Math.Ceiling((decimal)total / loopMax); // 距離の進んだ割合 double progressDistance = (slideDistance == 0 ? 0 : ((double)slideDistance) / total); // ループの進んだ割合 double progressLoop = (loopCount == 0 ? 0 : ((double)loopCount / loopMax)); // ループより先に進んでいた場合、速度を0にする if (progressDistance > progressLoop) { spd = 0; } if (reverse) { spd *= -1; } // 非表示なら逆向きにする if (!visible) { spd *= -1; } BasePos += spd; slideDistance += Math.Abs(spd); // 位置を補正 if (reverse) { if (BasePos > srcPos) { BasePos = srcPos; } if (BasePos < destPos) { BasePos = destPos; } } else { if (BasePos < srcPos) { BasePos = srcPos; } if (BasePos > destPos) { BasePos = destPos; } } // 移動させる Invoke(setLeftOrTop, BasePos); // 経過時間がアニメーション時間を超えたら終了 if (totalTime > animateTime) { return(false); } else { return(true); } }