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イベントをフックしていろいろと処理を書いているのだが、同イベントが発生することが保障されないのであれあれば、他の手段を考えなくてはならない。つーか、バグにしか見えないのだが。