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.