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 の画像しか置けなかったりする。