Visual Studio | WPF > Window Message の送受信

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

Window Message(以下WM)の処理を調べた。

### 参考

- 受信
    - [WPFアプリケーションでウィンドウプロシージャをフックする](https://qiita.com/hugo-sb/items/86141bc33c0e06e9d2e9) by @hugo-sb さん
- 送信
    - https://stackoverflow.com/questions/5083954/send-message-in-c-sharp
    - http://tarulab.blogspot.jp/2014/03/messagebox.html
        - by GuruKさん

情報感謝です。

### 処理内容

- ボタン押下
    - WM_USERを送信
- WM_USER受信
    - コンソールにメッセージ表示

### プロジェクト設定

[Visual Studio / WPF > WindowsアプリケーションにてSystem.Console.WriteLine()をコンソールに出力する](https://qiita.com/7of9/items/66b78fa9ad8510d52712)

### code

```MainWindow.xaml
<Window x:Class="_171110_t1825_windowMessage.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_171110_t1825_windowMessage"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Name="B_send" Content="Send" Width="100" Height="30" Click="B_send_Click"/>
    </Grid>
</Window>
```

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// 以下を追加
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace _171110_t1825_windowMessage
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private static readonly int WM_USER = 0x0400;

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, String lpWindowName);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        public MainWindow()
        {
            InitializeComponent();

            Loaded += (o, e) =>
            {
                var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
                source.AddHook(new HwndSourceHook(WndProc));
            };
        }
        private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_USER)
            {
                string timstr = DateTime.Now.ToLongTimeString();
                Console.WriteLine("Mouse Wheel : " + timstr);
            }
            return IntPtr.Zero;
        }

        private void B_send_Click(object sender, RoutedEventArgs e)
        {
            IntPtr win = FindWindow(null, "MainWindow");
            SendMessage(win, (int)WM_USER, IntPtr.Zero, IntPtr.Zero);
        }
    }
}
```
    
### 結果

ボタン押下時にコンソールにメッセージが表示される。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7b6343e8-e91c-2810-f2ea-00569fd72c74.png)

元々MOUSE_WHEELの処理をしていたので、メッセージがMouse Wheelになってしまっている。