入門編 ~秀丸マクロを改めて実行(メソッド編)~

概要

さて、前節ではHm.Macro.Exec.Eval(...)を使った文字列での実行をしました。

これまでの秀丸の様々なメソッドの半数ほどは、「秀丸マクロ実行中のみ実行可能」というものが散見されたはずです

すなわち、一般的には「非同期中」は「秀丸マクロ実行中ではない」ため、

このため、Hm.Macro.Exec.Eval(...)のマクロへと値を伝達しようとしても、「マクロ実行中ではない」ため、Hm.Macro.Var などが利用できず、
値を伝搬するのも難しいという状況になります。

この問題を一気に解決するのが、「Hm.Macro.Exec.Method(...)」です。

Hm.Macro.Exec.Method(...)は、指定のC#メソッドを「改めて新規の秀丸マクロ実行中」にしつつ呼び出せ、
という命令となります。

秀丸マクロを改めて実行

マクロを実行していない時にのみ、実行することが出来ます。

Hm.Macro.Exec.Method(string message_parameter, Delegate delegate_method)

呼び出せるメソッドは

public static IntPtr your_method(string message_parameter)

の形です。

  • C#側のソース

    MyTestForm.cs
    using System;
    using System.Reflection;
    using System.Windows.Forms;
    using Hidemaru;
    
    namespace HmTest
    {
        // (public static IntPtr abc)がマクロから見えるようにするため、publicにする
        public partial class HmTestForm
        {
            protected void MethodCreate()
            {
                System.Diagnostics.Trace.WriteLine("フォーム生成時");
            }
    
            // 呼び出せるメソッドは「IntPtr your_method(string message_parameter)の形
            delegate IntPtr TMacroScopeMethod(string message_parameter);
    
            protected void MethodTick()
            {
                try
                {
                    // デリゲートを使った関数オブジェクトを作り、
                    TMacroScopeMethod method = new TMacroScopeMethod(HmTest.HmTestForm.abc);
                    // TMacroScopeMethod method = abc; // と記述するのが普通かも
                    // Func<String, IntPtr> method = abc; // と記述してもOKです。
    
                    // この返り値の型は Hm.Macro.Exec.Eval(...) と同じ
                    // message_parametr に入れる文字列の用途は好きにしてよい。分岐判別用途に使ったり、伝達パラメータに使ってもよい。
                    var ret = Hm.Macro.Exec.Method("my test param", method);
    
                    System.Diagnostics.Trace.WriteLine(ret.Message);
                   //  Hm.OutputPane.Output(ret.Message);
                } catch(Exception e)
                {
                    System.Diagnostics.Trace.WriteLine(e.Message);
                }
            }
    
            // 非同期中から呼び出されたこのメソッドは「新たなマクロ実行中」という形で呼び出される。
            // 「マクロ実行中」であるため、このメソッドの間だけ秀丸に対して同期となり、hm.NETのメソッド群をおおいに利用することが可能となる。
            public static IntPtr abc(string message_parameter)
            {
                Hm.Macro.Var["$myvar"] = "abc";
                Hm.OutputPane.Output(message_parameter + "\r\n");
                Hm.OutputPane.Output(Hm.Macro.Var["column"].ToString() + "\r\n");
                Hm.OutputPane.Output(Hm.Macro.Var["$myvar"] + "\r\n");
                Hm.Macro.Statement("moveto", 3, 2);
    
                return (IntPtr)1;
            }
    
            protected void MethodDestroy()
            {
                System.Diagnostics.Trace.WriteLine("フォームクローズ時");
            }
        }
    
    }
    

Methodの別の指定の方法

関数のdelegateではなく、次のように文字列ベースで「dll」や「クラス」や「メソッド名」を指定してもかまいません。
これはちょうど、秀丸マクロでhm.NETを使う際の「CallMethod」と似た引数だと気づくことでしょう。
通常は、別の.dllを指定するような場合、あるいは、何か「動的」で事前にはdelegateオブジェクトでは指定しにくい場合に利用できるかもしれません。
ただし一般的には、1番目で解説したDelegateを使った引数の方が「型チェック」や「存在チェック」が明白であるため、適しています。

Hm.Macro.Exec.Method(string message_parameter, string dllfullpath, string typefullname, string methodname)
  • C#側のソース

    MyTestForm.cs
            using System;
            using System.Reflection;
            using System.Windows.Forms;
            using Hidemaru;
            
            namespace HmTest
            {
                // (public static IntPtr abc)がマクロから見えるようにするため、publicにする
                public partial class HmTestForm
                {
                    protected void MethodCreate()
                    {
                        System.Diagnostics.Trace.WriteLine("フォーム生成時");
                    }
            
                    protected void MethodTick()
                    {
                        try
                        {
                            // この返り値の型は Hm.Macro.Exec.Eval(...) と同じ
                            // message_parametr に入れる文字列の用途は好きにしてよい。分岐判別用途に使ったり、伝達パラメータに使ってもよい。
                            var ret = Hm.Macro.Exec.Method("mytest", Assembly.GetExecutingAssembly().Location, "HmTest.HmTestForm", "abc");
            
                            System.Diagnostics.Trace.WriteLine(ret.Message);
                        } catch(Exception e)
                        {
                            System.Diagnostics.Trace.WriteLine(e.Message);
            
                        }
                    }
            
                    // 非同期中から呼び出されたこのメソッドは「新たなマクロ実行中」という形で呼び出される。
                    // 「マクロ実行中」であるため、このメソッドの間だけ秀丸に対して同期となり、hm.NETのメソッド群をおおいに利用することが可能となる。
                    public static IntPtr abc(string message_parameter)
                    {
                        Hm.Macro.Var["$myvar"] = "abc";
                        Hm.OutputPane.Output(message_parameter + "\r\n");
                        Hm.OutputPane.Output(Hm.Macro.Var["column"].ToString() + "\r\n");
                        Hm.OutputPane.Output(Hm.Macro.Var["$myvar"] + "\r\n");
                        Hm.Macro.Statement("moveto", 3, 2);
            
                        return (IntPtr)1;
                    }
            
                    protected void MethodDestroy()
                    {
                        System.Diagnostics.Trace.WriteLine("フォームクローズ時");
                    }
                }
            
            }
            
    • 返り値のMessageプロパティ

      Hm.Macro.Exec.Methodが最後まで実行できたならば、Messageプロパティに「message_parameter」で渡した値が入っていることでしょう。

      返り値のErrorプロパティ

      途中でなんらかのエラーが発生した場合は、ErrorプロパティになんらかのExceptionオブジェクトが入っています。
      何もエラーがなければ、nullが入っています。

  • 秀丸マクロ側のソース

    前章の「HmNETTest.mac」と同一です。
    一度マクロを実行し、「デバッグモニター」にどのように順次表示されるか確認しましょう。