A#とVisualStudio2005による.NETプログラミング・イベントハンドラ編
Formの次はイベントハンドラが必要だろう。実装してみた。
- Main_Form.ads
with MSSyst.Windows.Forms.Form; with MSSyst.Windows.Forms.Button; with MSSyst.Object; with MSSyst.EventArgs; package Main_Form is type Typ is new MSSyst.Windows.Forms.Form.Typ with private; type Ref is access all Typ'Class; function new_Main_Form(This : Ref := null) return Ref; pragma MSIL_Constructor(new_Main_Form); procedure Exit_k(This : Ref; Object : MSSyst.Object.Ref; E : MSSyst.EventArgs.Ref); private type Typ is new MSSyst.Windows.Forms.Form.Typ with record Close_Button : MSSyst.Windows.Forms.Button.Ref; end record; end Main_Form;
- Main_Form.adb
with MSSyst.String; with MSSyst.EventHandler; with Mssyst.Windows.Forms.Application; with MSSyst.Windows.Forms.Control.ControlCollection; with MSSyst.Drawing.Point; with Mssyst.Drawing.Size; package body Main_Form is function new_Main_Form(This : Ref := null) return Ref is use type MSSyst.String.Ref; Super : MSSyst.Windows.Forms.Form.Ref := MSSyst.Windows.Forms.Form.new_Form(MSSyst.Windows.Forms.Form.Ref(This)); begin This.set_Text("Steady Talk"); This.Close_Button := Mssyst.Windows.Forms.Button.new_Button; This.Close_Button.set_Location(Mssyst.Drawing.Point.new_Point(152, 32)); This.Close_Button.set_Name("close"); This.Close_Button.set_Size(Mssyst.Drawing.Size.new_Size(75, 23)); This.Close_Button.set_TabIndex(1); This.Close_Button.set_Text("&Close"); This.Close_Button.set_UseVisualStyleBackColor(True); This.Close_Button.add_Click(Mssyst.EventHandler.new_EventHandler(object => This, method => Main_Form.Exit_k'Address)); MSSyst.Windows.Forms.Control.ControlCollection.Add(This.get_Controls, This.Close_Button); return This; end; procedure Exit_k(This : Ref; Object : MSSyst.Object.Ref; E : MSSyst.EventArgs.Ref) is begin Mssyst.Windows.Forms.Application.Exit_k; end Exit_k; end Main_Form;
エントリポイントのSteady_Talk.adbは前回のを使い回す感じで。
コード自体はC#でフォームデザイナを使うと吐き出されるものをA#に書き換えただけだ。ただし、デリゲートの部分がちょっと分かりにくかった。SPEC的には
function new_EventHandler(
This : Ref := null;
object : access MSSyst.Object.Typ'Class;
method : MSIL_Types.native_int) return Ref;
となっており、object
とMSIL_Types.native_int
が中々意味不明である。実験してみたところ、前者はJavaScriptで言うレシーバオブジェクトということらしい。A#の場合、メソッドも所詮はprocedure
なので、アドレスだけ渡されてもThisが特定できない。そのため、別のパラメータとして渡すことになっているらしい。MSIL_Types.native_int
はmod 2**32
なのでどう見てもアドレスだろう。適当に'Address
を渡してみたら問題なく動いた。
イベントハンドラは良いとして、イベントを受け取るメソッドの定義も謎である。C#の定義を元に適当に実験してみたところ、Thisを足せば良い感じに受け取れることが分かった。
というわけで、イベントも渡すことができた。ここまで来ればもう後はコードを書くだけである。