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;

となっており、objectMSIL_Types.native_intが中々意味不明である。実験してみたところ、前者はJavaScriptで言うレシーバオブジェクトということらしい。A#の場合、メソッドも所詮はprocedureなので、アドレスだけ渡されてもThisが特定できない。そのため、別のパラメータとして渡すことになっているらしい。MSIL_Types.native_intmod 2**32なのでどう見てもアドレスだろう。適当に'Addressを渡してみたら問題なく動いた。

イベントハンドラは良いとして、イベントを受け取るメソッドの定義も謎である。C#の定義を元に適当に実験してみたところ、Thisを足せば良い感じに受け取れることが分かった。

というわけで、イベントも渡すことができた。ここまで来ればもう後はコードを書くだけである。