今回は、ちょっとした小ネタです。
フォームを表示する際、非表示にする際
通常は、いつも見る挙動をします。
その挙動をちょっとカスタマイズしてみようという話です。
挙動をカスタマイズするには、標準の.NETのライブラリでは
不可能で、Win32 APIを利用します。
以下のAPIを利用します。
[DllImport("user32")] static extern bool AnimateWindow(IntPtr hwnd, int time, uint flags);
上記のAnimateWindow関数の3つ目の引数にいろいろなパターンの値を設定する事で
挙動をカスタマイズできます。
以下、サンプルです。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Threading; namespace WindowsFormsApplication1 { /// <summary> /// AnimateWindow関数にて利用されるフラグを表す列挙型です。 /// </summary> [Flags] public enum AnimateWindowFlags : uint { AW_HOR_POSITIVE = 0x00000001, AW_HOR_NEGATIVE = 0x00000002, AW_VER_POSITIVE = 0x00000004, AW_VER_NEGATIVE = 0x00000008, AW_CENTER = 0x00000010, AW_HIDE = 0x00010000, AW_ACTIVATE = 0x00020000, AW_SLIDE = 0x00040000, AW_BLEND = 0x00080000 } public partial class Form1 : Form { /// <summary> /// AnimateWindow関数 /// </summary> /// <param name="hwnd">ハンドル</param> /// <param name="time">アニメーションを行う時間</param> /// <param name="flags">挙動を表すフラグ</param> [DllImport("user32")] static extern bool AnimateWindow(IntPtr hwnd, int time, uint flags); public Form1() { InitializeComponent(); } private void btnSlide_Click(object sender, EventArgs e) { // // 以下のアニメーションを行いながら、新たなフォームを表示する. // // ■アニメーションの方向:横方向 // ■アニメーションの種類:スライド // Form1 newForm = new Form1(); AnimateWindow(newForm.Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_SLIDE)); newForm.Show(); } private void btnFadein_Click(object sender, EventArgs e) { // // 以下のアニメーションを行いながら、新たなフォームを表示する. // // ■アニメーションの方向:横方向 // ■アニメーションの種類:フェードイン // Form1 newForm = new Form1(); AnimateWindow(newForm.Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_BLEND)); newForm.Show(); } private void btnCenter_Click(object sender, EventArgs e) { // // 以下のアニメーションを行いながら、新たなフォームを表示する. // // ■アニメーションの方向:横方向 // ■アニメーションの種類:中央から徐々に表示 // Form1 newForm = new Form1(); AnimateWindow(newForm.Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_CENTER)); newForm.Show(); } private void btnSlideHide_Click(object sender, EventArgs e) { // // 以下のアニメーションを行いながら、自分自身を非表示→再表示する. // // ■アニメーションの方向:横方向 // ■アニメーションの種類:スライド // AnimateWindow(Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_SLIDE | AnimateWindowFlags.AW_HIDE)); Hide(); Application.DoEvents(); Thread.Sleep(TimeSpan.FromSeconds(1.0)); AnimateWindow(Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_SLIDE)); Show(); } private void btnFadeinHide_Click(object sender, EventArgs e) { // // 以下のアニメーションを行いながら、自分自身を非表示→再表示する. // // ■アニメーションの方向:横方向 // ■アニメーションの種類:フェードイン // AnimateWindow(Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_BLEND | AnimateWindowFlags.AW_HIDE)); Hide(); Application.DoEvents(); Thread.Sleep(TimeSpan.FromSeconds(1.0)); AnimateWindow(Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_BLEND)); Show(); } private void btnCenterHide_Click(object sender, EventArgs e) { // // 以下のアニメーションを行いながら、自分自身を非表示→再表示する. // // ■アニメーションの方向:横方向 // ■アニメーションの種類:中央から徐々に // AnimateWindow(Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_CENTER | AnimateWindowFlags.AW_HIDE)); Hide(); Application.DoEvents(); Thread.Sleep(TimeSpan.FromSeconds(1.0)); AnimateWindow(Handle, 1000, (uint) (AnimateWindowFlags.AW_HOR_NEGATIVE | AnimateWindowFlags.AW_CENTER)); Show(); } } }
AnimateWindow関数は、ShowまたはHideする前に、実行する必要があります。
また、関数の引数のflagsには、直接uint値を設定することも出来ますが
出来る限り、上記のようにEnumを定義して利用する方がいいです。
[参考資料]
- AnimateWindow関数
- AnimateWindow (P/Invoke.net)
上記のサンプルをアップしておきました。
どんな風な動きになるのか興味がある方は、どうぞ。
- AnimateWindowSample
(補足) すみません。サンプルをVS 2010で作成していました・・・。
開けない場合は、Form1に関わるファイルをコピーして持って行ってもらえればいいかと思います。