none
DefWndProc方法内GetLParam方法异常(System.ArgumentOutOfRangeException was unhandled) RRS feed

  • 问题

  • 我要做一个进程间通信的功能,但是在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异常提示,请教下这个问题怎么解决?谢谢!

    2014年12月4日 5:35

答案

  • 问题解决了,我改了下面一段代码

    copydata.cbData = Encoding.Default.GetBytes(strText).Length + 1;

    也就是给发送的字符串按字节计的长度上加了1。

    但是不知道为什么这样做,那个异常就没了。

    期待各位详解

    2014年12月4日 6:29

全部回复