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

时间:2015-06-10 02:46:48

标签: c# wpf sendmessage wm-copydata findwindowex

我想我已经使用中文和英文搜索了这个星球上的所有相关主题,但找不到解决方案。

我创建了一个仅消息窗口来接收和处理来自WM_COPYDATA的数据,但是我找不到发送端的窗口,下面是demo(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);
        }
    }
}

发送中的BtnSend_Click方法,在这里找不到合适的窗口句柄,这个托盘中有人可以帮忙吗?

PS:我应该首先描述我的要求:我想在C#中创建一个Windows服务,它是接收器并处理来自WM_COPYDATA的数据,所以我认为只有消息窗口是必要的,因为Windows服务中没有窗口。

所以在Sender中,我需要首先找到这个消息窗口,将窗口句柄传递给SendMessage,这就是重点。

谢谢你们

0 个答案:

没有答案