フォームを使って「同期」タイマー

概要

フォームのタイマーを使うことで、同期タイマーを使うことが出来ます。
同期するということは、並列処理ではないということです。

即ち、タイマーのTick処理の中で重い処理をすると、
秀丸が一瞬止まったかのようになってしまうということです。

一方同期タイマーは並列処理の落とし穴について考慮する必要がほとんど無いため、
取り扱いがしやすいというメリットがあります。

フォームのタイマー

  • C#側のソース

    .NETのフォームアプリではタイマーが非常に頻繁に利用されますので、
    フォームアプリケーションを制作したことがある人であれば、自然に受け入れられるでしょう。

    フォームが破棄される際には、タイマーも止める処理入れておきましょう。

    NET4COMServer.cs
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using HmNetCOM;
    
    namespace NET4COMServer
    {
            class MonitorForm : Form
            {
                Timer timer;
    
                public MonitorForm()
                {
                    this.FormClosing += form_FormClosing;
                    CreateTimer();
                }
    
                private void CreateTimer()
                {
                    timer = new Timer()
                    {
                        Interval = 1000
                    };
    
                    timer.Tick += timer_Tick;
                    timer.Enabled = true;
                    timer.Start();
                }
    
                private void DeleteTimer()
                {
                    if (timer != null)
                    {
                        timer.Stop();
                        timer = null;
                    }
                }
    
                private void timer_Tick(object sender, EventArgs e)
                {
                    Hm.OutputPane.Output("定期実行\r\n");
                }
    
                private void form_FormClosing(object sender, FormClosingEventArgs e)
                {
                    StopMonitor();
                    Hm.OutputPane.Output("Formを閉じます\r\n");
                }
    
            private void StopMonitor()
                {
                    try
                    {
                        DeleteTimer();
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Trace.WriteLine(e.Message);
                    }
                }
    
            }
    
    
        [ComVisible(true)]
        [Guid("BD55F2A6-9ED0-4F4F-9D37-E6B84BE63272")]
        public class NET4COMServer : Hm.IComSupportX64, Hm.IComDetachMethod
        {
            static Form form;
    
            public bool X64MACRO()
            {
                return true;
            }
    
            public int CreateForm()
            {
                if (form != null)
                {
                    form.Close();
                    form = null;
                }
    
                if (form == null || !form.Visible)
                {
                    form = new MonitorForm();
                }
    
                form.Show();
                return 1;
            }
    
            private void DestroyForm()
            {
                if (form != null)
                {
                    form.Close();
                    form = null;
                }
            }
    
            public void OnReleaseObject(int reason = 0)
            {
                DestroyForm();
                System.Windows.Forms.MessageBox.Show("COMオブジェクトは破棄されます\r\n");
            }
        }
    }
    
    
  • 秀丸マクロ側のソース

    test01.macなどと適当に名前を付ける
    #obj = createobject( currentmacrodirectory + @"\NET4COMServer.dll", "NET4COMServer.NET4COMServer");
    keepobject #obj, 1;
    setcomdetachmethod #obj, "OnReleaseObject";
    #created = member(#obj, "CreateForm");
    
    message("マクロは終了しました");
    // 秀丸のプロセスを閉じた際に、C#のOnReleaseObjectが実行される。複数回マクロを実行した場合には秀丸を閉じた際にまとめて実行される。
    

    「定期実行」といった表示が、1秒に1回ずつアウトプット枠に表示され、フォームを閉じた際、あるいは秀丸エディタを終了させた際に、
    表示される内容を確認出来ることでしょう。