1
Answer

SendMessage problem

Matt

Matt

17y
5.4k
1
I'm trying to use the SendMessage function in user32.dll using c#.net 2.0.  to send a message from my application to another application by it's window name.  I successfully get a handle.    The problem is, i see a few examples where the parameters are IntPtr and others where they are Ints or Longs.  i'm not sure how to use it.  When i click the button, i get an error on SendMessage:

A call to PInvoke function 'WindowsApplication2!WindowsApplication2.Form1::SendMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

Sounds like my parameter datatypes are incorrect.  What am i doing wrong?  here is my code:

public partial class Form1 : Form
{
String data = "my message";
public const int WM_COPYDATA = 0x4A;
int iHandle;
COPYDATASTRUCT cds;

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public int lpData;
}

[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll",CharSet=CharSet.Auto)]
private static extern int SendMessage(int hWnd, int wMsg, int wParam, COPYDATASTRUCT lParam);

[DllImport("kernel32.dll")]
public static extern void CopyMemory(byte dst, string src, int len);

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
iHandle = FindWindow(null, "window_name");
COPYDATASTRUCT cds;

cds.dwData = 1;
cds.cbData = data.Length;
cds.lpData = VarPtr(data);
}

public static byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}

public int VarPtr(object e)
{
GCHandle GC = GCHandle.Alloc(e, GCHandleType.Pinned);
//int gc = GC.AddrOfPinnedObject().ToInt32();
int gc = GC.AddrOfPinnedObject().ToInt32();
GC.Free();
return gc;
}

private void button1_Click(object sender, EventArgs e)
{
SendMessage(iHandle, WM_COPYDATA, 0, cds);
}
}

Answers (1)