简体   繁体   中英

c# why sendmessage didn't work

Why C++ WindowProc function don't receive message from c#? C# code call c++ ExeC.exe using SendMessage(). However there is no response in Switch case WM_COPYDATA IN WindowProc function.

C# full code :

public partial class MainWindow : Window
{   
    public const string strFilePath = "C:/Users/gandis/Desktop/Project/ExeC/Release/ExeC.exe";
    public const Int32 WM_COPYDATA = 0x004A;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 message, int wParam, ref int lParam);


    public MainWindow()
    {
        InitializeComponent();
    }

    private void btn_Start_Click(object sender, RoutedEventArgs e)
    {
        IntPtr hWnd = GetHandle(strFilePath);

        if (hWnd.ToInt32() > 0)
        {
            int cdss = 1;
            SendMessage(hWnd, WM_COPYDATA, 1, ref cdss);
        }

    }

    private IntPtr GetHandle(string strFilePath)
    {
        IntPtr hWnd = IntPtr.Zero;

        hWnd = GetProcess(strFilePath).MainWindowHandle;

        return hWnd;
    }

    private Process GetProcess(string strFilePath)
    {
        Process proc = new Process();

        proc.StartInfo.FileName = strFilePath;
        proc.Start();

        proc.WaitForInputIdle();

        return proc;
    }
}

I add only WindowProc virtual furction in MFC.

C++ code :

LRESULT CExeCDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
case WM_COPYDATA:

    AfxMessageBox(_T(__FUNCTION__));
    break;

}

return CDialog::WindowProc(message, wParam, lParam);
}

Your declaration of SendMessage() is wrong. The wParam should be UIntPtr , and the lParam should be IntPtr . And you are missing the SetLastError=true attribute on your DllImport .

And if (hWnd.ToInt32() > 0) should be if (hWnd != IntPtr.Zero) .

And you should call proc.Refresh() after calling proc.WaitForInputIdle() and before querying proc.MainWindowHandle .

But, most importantly, your input values for the WM_COPYDATA message are wrong, so the message is likely failing to be sent at all (but you are ignoring the return values of SendMessage() and Marshal.GetLastWin32Error() , so you wouldn't know that). Read the documentation:

wParam

A handle to the window passing the data.

lParam

A pointer to a COPYDATASTRUCT structure that contains the data to be passed.

You are passing a literal 1 where an HWND is expected, and you are passing a reference to an int where a reference to a COPYDATASTRUCT is expected.

AC# definition of COPYDATASTRUCT , and an example of sending it with SendMessage() , are available on pinvoke.net:

http://www.pinvoke.net/default.aspx/Structures.COPYDATASTRUCT

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
   public IntPtr dwData;    // Any value the sender chooses.  Perhaps its main window handle?
   public int cbData;       // The count of bytes in the message.
   public IntPtr lpData;    // The address of the message.
}

const int WM_COPYDATA = 0x004A;

// An example of sending a message containing a txStruct.
public SendMessage()
{
   IntPtr buffer = IntPtrAlloc(txStruct);
   COPYDATASTRUCT copyData = new COPYDATASTRUCT();
   copyData.dwData = IntPtr.Zero;
   copyData.lpData = buffer;
   copyData.cbData = Marshal.SizeOf(txStruct);
   IntPtr copyDataBuff = IntPtrAlloc(copyData);
   SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, copyDataBuff);
   IntPtrFree(ref copyDataBuff);
   IntPtrFree(ref buffer);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM