MessageHandlerAttribute の作成

これは簡単に Attribute 化できそうです。

[AttributeUseage(AttributeTargets.Method)]
public class MessageHandlerAttribute : Attribute
{
  public int id;
  public MessageHandlerAttribute(int msgId)
  {
    id = msgId;
  }
}

完成……、というのはあまりにもなので、メソッドの検索と呼び出し処理を追加することにしましょう。

/// メッセージハンドラを検索しメソッドを呼び出す
/// メソッドの検索を行うオブジェクト
/// ハンドリングを行う Message
public static void Invoke(object obj, ref Message msg)
{
  Invoke(obj.GetType(), obj, ref msg);
}

/// 継承階層の指定されたタイプ以降のメッセージハンドラを検索し、メソッドを呼び出す
/// 検索を開始する継承階層
/// メソッドの検索を行うオブジェクト
/// ハンドリングを行う Message
public static void Invoke(Type t, object obj, ref Message msg)
{
  Debug.Assert(t.IsInstanceOfType(obj));

  while (InvokeOne(t, obj, ref msg) == false)
  {
    t = t.BaseType;
    if (t.Equals(typeof(Object))) break;
  }
}

/// 継承階層の指定されたタイプのメッセージハンドラを検索し、メソッドを呼び出す
/// 検索を行う継承階層
/// メソッドの検索を行うオブジェクト
/// ハンドリングを行う Message
/// メッセージをハンドリングした場合は true
public static bool InvokeOne(Type t, object obj, ref Message msg)
{
  Debug.Assert(t.IsInstanceOfType(obj));

  // インスタンスメソッドをすべて得る
  //    複数のメソッドが同じ Windows Message ID に対するハンドラを提供していた場合、その処理順序は
  //    GetMethods() の実装に依存する。
  foreach (MethodInfo method in t.GetMethods(BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Instance))
  {
    // アトリビュートに MessageHandlerAttribute があるか調べる
    foreach (MessageHandlerAttribute attr in method.GetCustomAttributes(typeof(MessageHandlerAttribute), false))
    {
      // 適切なハンドラであるか調べる
      if (attr.MsgId == msg.Msg)
      {
        // 適切な型のメソッドであるか調べる
        CheckMethodSignature(method);

        // メソッド呼び出し
        bool handled = (bool) method.Invoke(obj, new Object[1]{ msg });

        // Windows Message がハンドリングされたらメソッドの検索を終了する
        if (handled) return true;
      }
    }
  }

  return false; // not handled
}

/// 
/// 指定されたメソッドが bool METHOD(byref Message msg) であることを確認する
/// 
/// 検査するメソッド
[Conditional("DEBUG")]
private static void CheckMethodSignature(MethodInfo method)
{
  ParameterInfo[] pi =  method.GetParameters();

  Debug.Assert(method.ReturnType.Equals(typeof(bool)));   // bool
  Debug.Assert(pi.Length == 1);                           //    method(         )
  Debug.Assert(pi[0].ParameterType.IsByRef);              //         byref
//Debug.Assert(pi[0].ParameterType.Equals(typeof(Message&))); //           Message msg
}

ちょっと長くなってしまいましたが、こんな感じでしょうか。
最後の部分、System.Windows.Forms.Message& 型の typeof() は許されないようで、どうするのが良いのかわかりませんでした。
IsByRef が true なんだから、System.Windows.Forms.Message 型でいいんじゃ?とか思うのですけどね。あと、最初の掲載部は

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class MessageHandlerAttribute : Attribute
{
    /// メソッドに関連付けられた Windows Message ID
    private int id;

    /// コンストラク
    /// 関連付ける Windows Message ID
    public MessageHandlerAttribute(int msgId) : base()
    {
        this.id = msgId;
    }

    /// 関連付けられた Windows Message ID
    public int MsgId
    {
        get { return id; }
    }

こんな感じに修正しております。全文を日記添付ファイルとしたいけど、はてなでは JPEG、GIF、PNG の画像しか置けなかったりする。