HandleCreatedイベントの不思議
拙作のフレームワークで作ったサンプルアプリケーションが、突然正常に動かなくなった。
そのアプリケーションは、内部の各種オブジェクトをDIコンテナの自動登録機能で生成しており、その各種オブジェクトが関連したコントロールをForm上に生成する作りになっているのだが、自動登録されたはずのオブジェクトの生成に抜けがあり、表示されるはずのコントロールが表示されなくなってしまったのである。
4時間かけて原因を探ったのだが、原因はFormクラスのオブジェクトの生成〜表示に至るまでのイベントが期待通りに発生しないことだった。解りやすいように、最小限の状態で再現してみよう。
通常のアプリケーションであれば、WindowsFormsのFormクラスはその生成〜表示に至るまで、つまり、Formのインスタンスを生成して、Application.Run(form);を実行して、実際にFormが表示されるまでは以下の順序でイベントが発生する。(一部関係の無いイベントは省いている)
サンプルコード
Form form = new Form(); Application.Run(form);
発生するイベントと順序
- HandleCreated
- Load
- Activated
- Shown
Shownは見慣れないイベントだが、WindowsForms2.0から追加された、Formが表示された際に一度だけ発生するイベントだ。
では、次はサンプルコードに一行だけ追加して、再度発生するイベントを見てみよう。
サンプルコード
Form form = new Form();
IntPtr handle = form.Handle
Application.Run(form);
発生するイベントと順序
-
- Load
- Activated
- Shown
なんと、メッセージループが開始する前に、HandleプロパティにアクセスしてしまうとHandleCreatedイベントは発生しないのである。
拙作のフレームワークでは、Formがロードされる以前に、いろいろと前処理を行いたいという理由で、HandleCreatedイベントをフックしていろいろと処理を書いているのだが、同イベントが発生することが保障されないのであれあれば、他の手段を考えなくてはならない。つーか、バグにしか見えないのだが。