How to find message only window in C# by using FindWindowEx?

1.1k views Asked by At

I think I've searched all of related topics on this planet by using Chinese and English but cannot find the solution.

I've created one message only window to receive and process the data from WM_COPYDATA, but I cannot find the window in send side, below is demo (WPF of C#):

Receive:

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;
    }
}

Send:

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 method in Send, cannot find the right window handle here, could someone in this pallet can help?

PS: I should describe my requirement first: I want to create a windows service in C#, which is receiver and deal with the data from WM_COPYDATA, so I think message only window is necessary because there is NO window in windows service.

So in Sender, I need to find this message only window to pass the window handle into SendMessage at first, here is the point.

Thanks guys

0

There are 0 answers