ClipboardをNativeWindowでサブクラス化して楽したい

# 目的
・AddClipboardFormatListener/RemoveClipboardFormatListenerをNativeWindowでサブクラス化したい
・WindowsFormに毎回書くのが面倒臭い、部品化して最低限に留めたい

# 環境
:::note info
実施環境
・Windows 10 Professional
・Visual Studio 2022 Community(x64) Ver.17.7.0
:::

# 実装
```CSharp:ClipboardListener.cs
using System.Runtime.InteropServices;
namespace CSClipboardListener
{
    public class ClipboardEventArgs : EventArgs
    {
        private string text;
        public string Text{get { return this.text; }}
        public ClipboardEventArgs(string str) => this.text = str;
    }

    public delegate void cbEventHandler(object sender, ClipboardEventArgs ev);

    public class ClipboardListener : NativeWindow
    {
        private Form Parent;                            //イベント通知先
        private const int WM_CLIPBOARDUPDATE = 0x031D;  //クリップボードの内容変更時に送信される
        public event cbEventHandler ClipboardHandler;   //
        
        //Win32API
        private static class NativeMethods
        {
            [DllImport("user32.dll", SetLastError = true)]
	        internal extern static void AddClipboardFormatListener(IntPtr hWnd);
	        [DllImport("user32.dll", SetLastError = true)]
	        internal extern static void RemoveClipboardFormatListener(IntPtr hWnd);
        }

#nullable disable warnings
        public ClipboardListener(Form f)
        {
            f.HandleCreated   += new EventHandler(OnHandleCreated);
            f.HandleDestroyed += new EventHandler(OnHandleDestroyed);
            this.Parent = f;
        }
#nullable restore warnings

        internal void OnHandleCreated(object sender, EventArgs e)
        {
            AssignHandle(((Form)sender).Handle);
            NativeMethods.AddClipboardFormatListener(this.Handle);
        }
        internal void OnHandleDestroyed(object sender, EventArgs e)
        {
            NativeMethods.RemoveClipboardFormatListener(this.Handle);
            this.ReleaseHandle();
        }

        protected override void WndProc(ref Message msg)
        {
            if((msg.Msg == WM_CLIPBOARDUPDATE) && Clipboard.ContainsText())
            {
                //if (ClipboardHandler != null) 
                //{   
                //    ClipboardHandler(this, new ClipboardEventArgs(Clipboard.GetText()));
                //}
                ClipboardHandler?.Invoke(this, new ClipboardEventArgs(Clipboard.GetText()));
            }
            base.WndProc(ref msg);
        }
    }
}
```

使用する側は以下の通り
```CSharp:FormClipListener.cs
namespace CSClipboardListener
{
    public partial class FormClipListener : Form
    {
        private readonly ClipboardListener clipListener;

        public FormClipListener()
        {
            clipListener = new ClipboardListener(this);
            clipListener.ClipboardHandler += this.OnClipBoardChanged;
            InitializeComponent();
        }

        private void OnClipBoardChanged(object sender, ClipboardEventArgs args)
        {
            this.textBox1.Text = args.Text;
        }

        private void FormClipListener_FormClosing(object sender, FormClosingEventArgs e)
        {
            clipListener.DestroyHandle();
        }
    }
}
```

# 参考及び改造元のページ
実装迄に探し回った物を雑多に列挙しているので注意

＠IT

https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/848cbviewer/cbviewer.html

https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/875imeyomi/imeyomi.html

＠Qiita内

https://qiita.com/kob58im/items/2697ea4c12c72ecd86c8

https://qiita.com/mitsu_at3/items/94807ee0b3bf34ffb6b2

＠Microsoft公式

https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.nativewindow?view=windowsdesktop-7.0

https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.nativewindow.releasehandle?view=windowsdesktop-7.0

＠外部サイト

https://lets-csharp.com/clipboard-history/

https://lets-csharp.com/how-to-clipboard-listener/

https://takap-tech.com/entry/2022/07/04/003402

http://pinmarch.sakura.ne.jp/blog/archives/2006/10/24_000683.php

https://gogowaten.hatenablog.com/entry/2019/09/22/143931

https://suzulang.com/win32api-listen-clipboard/

[クリップボードを監視してテキストボックスに追加していく感じの。](https://gist.github.com/unarist/6342758)

# 余談
思ったよりNativeWindowの情報が少なくて苦労した・・・探し方が下手なだけだろうか？