初級編な話でにょろーん

イベントハンドラ全てにtry...catch...finallyが書いてあるソースを見て(´・ω・`)にょろーん
予期しない例外発生時の対処や、後は時間のかかる処理を行う際のマウスカーソル変更の処理がこんな風に書かれていまスタ(´д`)

try
{
    // カーソルを砂時計に変更
    this.Cursor = Cursors.WaitCursor;

    ...
}
catch(Exception ex)
{
    // 例外表示
    ...
}
finally
{
    // カーソルを元に戻す
    this.Cursor = Cursors.Default;
}

イベントハンドラ全てにこんなモノを書くなんてメンドクサす。
っというか、こういうコードの書き方に誰か疑問を持たなかったのかしら(´・ω・`)


っと言うわけでめんどくさくない書き方を周知。


予期せぬ例外については、Application.ThreadExceptionを使うにょろーん
こうすれば例外処理は1ヶ所の記述で済むにょろ。

public static void Main(string[] args)
{
    // 例外ハンドラ設定
    Application.ThreadException += new ThreadExceptionEventHandler( OnThreadException );

    ...
}

public static void OnThreadException(object sender, ThreadExceptionEventArgs e)
{
    // 例外表示
    ...

    Application.Exit();
}

MSDNも参照するっス。


マウスカーソルの変更については、RAIIっぽく、Paint.NETのソースを真似てみたり。

public class CursorChanger : IDisposable
{
    private Control control;
    private Cursor oldCursor;

    public CursorChanger(Control control, Cursor newCursor)
    {
        this.control = control;
        this.oldCursor = this.control.Cursor;
        FindTopParent(control).Cursor = newCursor;
    }

    ~CursorChanger()
    {
        Dispose( false );
    }

    public void Dispose()
    {
        Dispose( true );
        GC.SuppressFinalize( this );
    }

    private bool disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if ( !disposed )
        {
            if ( disposing )
            {
                FindTopParent(control).Cursor = oldCursor;
            }

            disposed = true;
        }
    }

    private Control FindTopParent(Control control)
    {
        Control parent = control.Parent;

        if ( parent == null )
        {
            return control;
        }
        else
        {
            return( FindTopParent( parent ) );
        }
    }
}

こいつを使えば時間がかかる処理時のマウスカーソル変更はこんな風にできるっス(・∀・)

using( CursorChanger c = new CursorChanger( this, Cursors.WaitCursor ) )
{
    // 時間のかかる処理
    ...
}

しょうもない話はいいんで、早くインタフェース決めるにょろーん(´・ω・`)