DOBON.NETプログラミング道掲示板

ログ内検索
・キーワードを複数指定する場合は 半角スペース で区切ってください。
・検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
・[返信]をクリックすると返信ページへ移動します。 (*過去ログは表示されません)
・過去ログから探す場合は検索範囲から過去ログを選択。
過去ログより前の全過去ログはこちらで検索できます。

キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
投稿日時/ 日以内
大文字と小文字を区別する

No.33255 の関連記事表示

<< 0 >>
■33255  Re[3]: C# 製COMをJavaScriptから使う時のイベントフック
□投稿者/ 魔界の仮面弁士 -(2016/02/22(Mon) 04:04:05)
  • アイコン
    No33250に返信(ぺんたごんさんの記事)
    > scriptのfor、event属性でフックする方法が大量に出てきてたのですが
    VBA で参照設定 + WithEvents した場合に相当するのがその記述です。
    実装する場合は ComSourceInterfacesAttribute ですね。
    
    
    > C#で言う +=、VBでいうAddHandler的な何かがないかな、という点でした。
    VBA や VBScript、JScript にはそのための仕組みがないので、
    遅延バインディングにしたいなら、自前で用意しないと駄目でしょうね。
    
    無いのなら
    作ってしまえ
    ホトトギス
    
    
    ―――ということで、
     _obj.AttachEvent( "callback", onCallback  ) ;
    のように、関数オブジェクトを受け取るメンバーを作ってみました。
    (簡略化のため、C# や VBA から使うための event 実装は省略しています)
    
    
    CD /D C:\SAMPLE\20160222\
    csc Orator.Sample.cs /t:library /platform:AnyCPU /out:Orator.Sample.dll
    regasm /codebase Orator.Sample.dll /tlb:Orator.Sample.tlb
    
    
    
    【Orator.Sample.cs】
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    [assembly: ComVisible(true)]
    namespace Orator
    {
        // JScript の関数オブジェクト用
        [ComVisible(false)]
        public delegate object Function(object sender, params object[] args);
    
    
        [ComVisible(true)]
        [ProgId("Orator.Sample")]
        [Guid("A17FC5F2-0EC7-4A8F-A648-9075E5976359")]
        [ClassInterface(ClassInterfaceType.None)]
        [ComDefaultInterface(typeof(Orator.ISample))]
        public sealed class Sample : ISample
        {
            // JScript はイベント呼び出しの構文を備えていないので、
            // 関数オブジェクトを受け取ってコールバックさせる
            private Dictionary<string, Function> events;
            public Sample()
            {
                events = new Dictionary<string, Function>();
                events.Add("NameChanging", null);
                events.Add("NameChanged", null);
            }
    
            #region AttachEvent メソッド
            void ISample.AttachEvent(string eventName, object functionObject)
            {
                // 関数オブジェクトをイベントハンドラとして割り当て
                events[eventName] += new Function((caller, args) =>
                    // 関数オブジェクトの実行
                    functionObject.GetType().InvokeMember(
                        "[DispID=0]",
                        System.Reflection.BindingFlags.InvokeMethod,
                        System.Type.DefaultBinder,
                        functionObject,
                        args
                    )
                );
            }
            #endregion
    
            #region Name プロパティ
            private string name = "Sample";
            string ISample.Name
            {
                get { return name; }
                set
                {
                    string oldName = name;
                    string newName = value;
                    if (oldName != newName)
                    {
                        if (events["NameChanging"] != null)
                        {
                            events["NameChanging"](this, oldName, newName);
                        }
                        name = value;
                        if (events["NameChanged"] != null)
                        {
                            events["NameChanged"](this);
                        }
                    }
                }
            }
            #endregion
        }
    
        #region COMオブジェクトのメンバー定義
        [Guid("02A9900A-EB12-4189-B8FF-396CF80EF78A")]
        public interface ISample
        {
            // JScript の関数オブジェクトや、VBScript の GetRef を
            // イベントに割り当てるためのヘルパー
            void AttachEvent(string eventName, object functionObject);
    
            // Name プロパティ
            string Name { get; set; }
        }
        #endregion
    }
    
    
    
    【Orator.Sample.hta】
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=9" />
    <title>Sample</title>
    <script language="JScript">
    var _obj;
    window.onload = function()
    {
      window.resizeTo(400, 250);
      _obj = new ActiveXObject("Orator.Sample");
      text1.value = _obj.Name;
    
      _obj.AttachEvent("NameChanging", fnNameChanging ) ;
      _obj.AttachEvent("NameChanged", fnNameChanged ) ;
    
      button1.onclick = function()
      {
        if(_obj.Name != text1.value)
        {
          _obj.Name = text1.value;
        }
        else
        {
          alert("元のNameと同じです");
        }
      };
    }
    
    function fnNameChanging(oldName, newName)
    {
        alert("NameChanging:\r\n" + oldName + " => " + newName);
    }
    
    function fnNameChanged()
    {
        alert("NameChanged");
    }
    
    </script>
    <hta:application border="dialog" contextmenu="no" scroll="no" selection="no" singleInstance="yes">
    </head>
    <body style="background-color:ButtonFace;color:ButtonText">
    <p>
    <input type="text" id="text1" value="undefined">
    <input type="button" id="button1" value="set">
    </p>
    </body></html>
記事No.33246 のレス /過去ログ1より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/


- Child Tree -