积极答复者
DefWndProc方法内GetLParam方法异常(System.ArgumentOutOfRangeException was unhandled)

问题
-
我要做一个进程间通信的功能,但是在GetLParam处出现了System.ArgumentOutOfRangeException,不知道这个是什么原因。
发送方(控制台程序)代码:
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Runtime.InteropServices; //[DllImport("user32.dll")]中DllImport的命名空间 using DllTest; namespace Sender { class Program { static void Main(string[] args) { string strDlgTitle = "Receiver"; //接收端的窗口句柄 IntPtr hwndRecvWindow = ImportFromDLL.FindWindow(null, strDlgTitle); if (hwndRecvWindow == IntPtr.Zero) { Console.WriteLine("请先启动接收消息程序"); return; } //自己的窗口句柄 IntPtr hwndSendWindow = ImportFromDLL.GetConsoleWindow(); if (hwndSendWindow == IntPtr.Zero) { Console.WriteLine("获取自己的窗口句柄失败,请重试"); return; } for (int i = 0; i < 10; i++) { string strText = DateTime.Now.ToString(); //填充COPYDATA结构 DllTest.DllTest.COPYDATASTRUCT copydata = new DllTest.DllTest.COPYDATASTRUCT(); copydata.dwData = hwndRecvWindow;//Add 2014-12-03 copydata.cbData = Encoding.Default.GetBytes(strText).Length; //长度 注意不要用strText.Length; copydata.lpData = strText; //内容 ImportFromDLL.SendMessage(hwndRecvWindow, ImportFromDLL.WM_COPYDATA, 2, ref copydata); Console.WriteLine(strText); Thread.Sleep(1000); } } } public class ImportFromDLL { public const int WM_COPYDATA = 0x004A; [DllImport("User32.dll")] public static extern int SendMessage( IntPtr hWnd, int Msg, int wParam, ref DllTest.DllTest.COPYDATASTRUCT lParam ); [DllImport("User32.dll", EntryPoint = "FindWindow")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("Kernel32.dll", EntryPoint = "GetConsoleWindow")] public static extern IntPtr GetConsoleWindow(); } }
接收方(windows窗体程序)代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections; using System.Runtime.InteropServices; using DllTest; namespace Receiver { public partial class Receiver : Form { const int WM_COPYDATA = 0x004A; public Receiver() { InitializeComponent(); } protected override void DefWndProc(ref Message m) { switch (m.Msg) { //接收自定义消息USER,并显示其参数 case WM_COPYDATA: DllTest.DllTest.COPYDATASTRUCT mystr = new DllTest.DllTest.COPYDATASTRUCT(); Type mytype = mystr.GetType(); mystr = (DllTest.DllTest.COPYDATASTRUCT)m.GetLParam(mytype); this.textBox1.Text = mystr.lpData; break; default: base.DefWndProc(ref m); break; } } } }
它们共用的自定义结构体代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace DllTest { public class DllTest { //启用非托管代码 [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } } }
自定义的结构体代码生成了一个dll,并且已经在发送方和接收方中引入了,现在出现了System.ArgumentOutOfRangeException异常提示,请教下这个问题怎么解决?谢谢!
答案
-
问题解决了,我改了下面一段代码
copydata.cbData = Encoding.Default.GetBytes(strText).Length + 1;
也就是给发送的字符串按字节计的长度上加了1。
但是不知道为什么这样做,那个异常就没了。
期待各位详解
- 已标记为答案 CaillenModerator 2014年12月5日 5:55
全部回复
-
问题解决了,我改了下面一段代码
copydata.cbData = Encoding.Default.GetBytes(strText).Length + 1;
也就是给发送的字符串按字节计的长度上加了1。
但是不知道为什么这样做,那个异常就没了。
期待各位详解
- 已标记为答案 CaillenModerator 2014年12月5日 5:55
-
你好:
原因是要发送的字节数组最后要以null结尾,最后应该多出一位"\0"。
参考这篇帖子:
http://stackoverflow.com/questions/6779731/c-sharp-using-sendmessage-problem-with-wm-copydata
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.