如何使用FindWindowEx在C#中查找消息专用窗口?

如何使用FindWindowEx在C#中查找消息专用窗口?,c#,wpf,sendmessage,wm-copydata,findwindowex,C#,Wpf,Sendmessage,Wm Copydata,Findwindowex,我想我已经用中文和英文搜索了这个星球上所有相关的话题,但找不到解决办法 我创建了一个仅消息窗口来接收和处理来自WM_COPYDATA的数据,但在发送端找不到该窗口,下面是演示(C#的WPF): 接收: public partial class MainWindow : Window { private readonly IntPtr sourceHandle; private const int WM_COPYDATA = 0x004A; [StructLayout(L

我想我已经用中文和英文搜索了这个星球上所有相关的话题,但找不到解决办法

我创建了一个仅消息窗口来接收和处理来自WM_COPYDATA的数据,但在发送端找不到该窗口,下面是演示(C#的WPF):

接收:

public partial class MainWindow : Window
{
    private readonly IntPtr sourceHandle;
    private const int WM_COPYDATA = 0x004A;

    [StructLayout(LayoutKind.Sequential)]
    public struct CopyDataStruct
    {
        public IntPtr dwData;
        public int cbData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
    }

    public MainWindow()
    {
        InitializeComponent();
        sourceHandle = this.CreateMessageOnlyWindow();
        this.btnReceive.Content = sourceHandle;
    }

    private IntPtr CreateMessageOnlyWindow()
    {
        IntPtr HWND_MESSAGE = new IntPtr(-3);
        HwndSourceParameters sourceParam = new HwndSourceParameters() { ParentWindow = HWND_MESSAGE };
        var source = new HwndSource(sourceParam);
        source.AddHook(WndProc);
        return source.Handle;
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    {
        if (msg == WM_COPYDATA)
        {
            MessageBox.Show(lparam.ToInt32().ToString());
            handled = true;
            return new IntPtr(20);
        }
        return IntPtr.Zero;
    }
}
public partial class MainWindow : Window
{
    IntPtr WM_COPYDATA = new IntPtr(0x004A);
    IntPtr HWND_MESSAGE = new IntPtr(-3);

    [DllImport("User32.dll")]
    public static extern IntPtr SendMessage(IntPtr hwnd, IntPtr msg, IntPtr wParam, ref COPYDATASTRUCT IParam);

    [DllImport("User32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    public struct COPYDATASTRUCT
    {
        public IntPtr dwData;
        public int cData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
    }

    public MainWindow()
    {
        InitializeComponent();
    }

    private void BtnSend_Click(object sender, RoutedEventArgs e)
    {
        //Here cannot find the target message only window in receiving
        IntPtr WINDOW_HANDLE = FindWindowEx(HWND_MESSAGE, IntPtr.Zero, null, null);

        if (WINDOW_HANDLE != IntPtr.Zero)
        {
            byte[] arr = System.Text.Encoding.Default.GetBytes(txtMessage.Text);
            int len = arr.Length;
            COPYDATASTRUCT cdata;
            cdata.dwData = (IntPtr)100;
            cdata.lpData = txtMessage.Text;
            cdata.cData = len + 1;
            SendMessage(WINDOW_HANDLE, WM_COPYDATA, IntPtr.Zero, ref cdata);
        }
    }
}
发送:

public partial class MainWindow : Window
{
    private readonly IntPtr sourceHandle;
    private const int WM_COPYDATA = 0x004A;

    [StructLayout(LayoutKind.Sequential)]
    public struct CopyDataStruct
    {
        public IntPtr dwData;
        public int cbData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
    }

    public MainWindow()
    {
        InitializeComponent();
        sourceHandle = this.CreateMessageOnlyWindow();
        this.btnReceive.Content = sourceHandle;
    }

    private IntPtr CreateMessageOnlyWindow()
    {
        IntPtr HWND_MESSAGE = new IntPtr(-3);
        HwndSourceParameters sourceParam = new HwndSourceParameters() { ParentWindow = HWND_MESSAGE };
        var source = new HwndSource(sourceParam);
        source.AddHook(WndProc);
        return source.Handle;
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    {
        if (msg == WM_COPYDATA)
        {
            MessageBox.Show(lparam.ToInt32().ToString());
            handled = true;
            return new IntPtr(20);
        }
        return IntPtr.Zero;
    }
}
public partial class MainWindow : Window
{
    IntPtr WM_COPYDATA = new IntPtr(0x004A);
    IntPtr HWND_MESSAGE = new IntPtr(-3);

    [DllImport("User32.dll")]
    public static extern IntPtr SendMessage(IntPtr hwnd, IntPtr msg, IntPtr wParam, ref COPYDATASTRUCT IParam);

    [DllImport("User32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    public struct COPYDATASTRUCT
    {
        public IntPtr dwData;
        public int cData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
    }

    public MainWindow()
    {
        InitializeComponent();
    }

    private void BtnSend_Click(object sender, RoutedEventArgs e)
    {
        //Here cannot find the target message only window in receiving
        IntPtr WINDOW_HANDLE = FindWindowEx(HWND_MESSAGE, IntPtr.Zero, null, null);

        if (WINDOW_HANDLE != IntPtr.Zero)
        {
            byte[] arr = System.Text.Encoding.Default.GetBytes(txtMessage.Text);
            int len = arr.Length;
            COPYDATASTRUCT cdata;
            cdata.dwData = (IntPtr)100;
            cdata.lpData = txtMessage.Text;
            cdata.cData = len + 1;
            SendMessage(WINDOW_HANDLE, WM_COPYDATA, IntPtr.Zero, ref cdata);
        }
    }
}
BtnSend\u发送中的单击方法,在此处找不到正确的窗口句柄,此托盘中的某人可以帮助吗

PS:我应该先描述一下我的需求:我想在C#中创建一个windows服务,它是接收和处理来自WM#U COPYDATA的数据的工具,所以我认为只有消息窗口是必要的,因为windows服务中没有窗口

因此,在Sender中,我首先需要找到这个仅限消息的窗口,以便将窗口句柄传递到SendMessage中,重点如下

谢谢各位