我看到一种方法:
[DllImport("user32.dll", EntryPoint="SendMessageA")]
private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, string lParam);
上面这种方法把lParam直接定义成string,在调用的时候是成功的
  string strReceive = "advise";
  SendMessage((int)Handle, WM_USER, 0, strReceive);
但是在消息响应那里,该怎么把这个字符串取出来呢?
         protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case frmMain.WM_USER:
                    string str = m.lParam.ToString();//这个方法不对,请指教
                    MessageBox.Show(str);                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }请大大们帮我解答,谢谢!

解决方案 »

  1.   

    DefWndProc
    //这个方法相当恐怖,
      

  2.   

    MessageBox.Show(str); 是好不要出现这玩意,不然不知道怎么收场
      

  3.   

    同进程比较简单,直接用静态字段,赋值后通知。[DllImport("User32.DLL")]
    public static extern int SendMessage(IntPtr hWnd,
        uint Msg, int wParam, int lParam);static string myText;
    const int WM_USER = 0x0400;
    private void button1_Click(object sender, EventArgs e)
    {
        myText = "Zswang 路过" + DateTime.Now.ToLongTimeString();
        SendMessage(Handle, WM_USER, 0, 0);
    }protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_USER:
                MessageBox.Show(myText);
                break;
            default :
                base.WndProc(ref m);
                break;
        }
    }
    跨进程再说
      

  4.   

    使用pointer:
     [DllImport("user32.dll", EntryPoint = "SendMessageA")]
     unsafe static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, void* lParam);
    //----------------------------------------------------------
                unsafe
                {
                    string strReceive = "advise";
                    fixed (char* ptr = &(strReceive.ToCharArray()[0]))
                    {
                        SendMessage(Handle, 0x0400, IntPtr.Zero, ptr);
                    }
                }
    //----------------------------------------
                if (m.LParam != IntPtr.Zero && m.Msg == 0x0400)
                {
                    unsafe
                    {
                        char* ptrLParam = (char*)m.LParam.ToPointer();
                        string s = "";
                        for(int i=0;i<6;i++)
                            s+=ptrLParam[i].ToString();
                        MessageBox.Show(s);
                    }
                }
      

  5.   

    关于C#中使用消息获取Message.LParam所包含的数据在C#中也可以使用Windows 消息,包括系统消息和自定义消息。对于自定义消息中,对于LParam可以在发中或者接收过程中使用自定义结构来传递数据如:public struct MyStruct{    public int i;    public string str;} 发送消息调用WindowsAPI SendMessageMyStruct myst = new MyStruct();SendMessage(hWnd, WM_USER, 0,ref myst);
    接收消息可通过重写DefWndProc来实现protected override void DefWndProc(ref System.Windows.Forms.Message m)
      {
       switch(m.Msg)
       {
        case WM_USER:  // 任何消息     int iWPara = (int)m.WParam;     MyStruct myStr = new MyStruct();     Type myType=myType.GetType();     myType = (MyStruct)m.GetLParam(myType);
         break;    default:
         base.DefWndProc(ref m);//调用基类函数处理非自定义消息。
         break;
       }
      }但是对于一些非自定义的消息, 如WM_SETTEXT,或者一些第三方应用所发出的消息,其中的LParam中可能包含的是一个指向字符串的指针,如char *,那么这时候如何取得LParam中的实际数据呢?以一自定义消息为例,通过该消息的m.LParam.ToString()得知存储的数据类型为"String",但是使用GetLParam获取会出现错误,因为GetLParam只接受结构类型,那怎么办呢?那就是使用Marshal.Copy,将数据从非托管内存指针复制到托管 8 位无符号整数数组.如下:byte[] ch = new byte[256]System.Runtime.InteropServices.Marshal.Copy(m.LParam,ch,0,255);string str = System.Text.Encoding.Default.GetString(ch);这样,就成功获得了m.LParam所包含的字符数据
      

  6.   

    原则上, Marshal.Copy最好不要Copy太长的范围, 不然, 会得到LParam里面的一些额外的没用的Data可以在Send的时候, 把放在LParam的String计算下长度
    string myStr="Test LParam";
    int testBytes=Encoding.Default.GetByteCount(myStr);
    SendMessage(Handle,0,IntPtr.Zero,myStr);然后, 在WndProc里面, Case WM_USER:
      byte[] myBytes=new byte[testBytes];
      Marshal.Copy(m.LParam,myBytes,0,testBytes);
      string myTestResult=Encoding.Default.GetString(myBytes);
    break;
      

  7.   

    原则上, Marshal.Copy最好不要Copy太长的范围, 不然, 会得到LParam里面的一些额外的没用的Data可以在Send的时候, 把放在LParam的String计算下长度
    string myStr="Test LParam";
    int testBytes=Encoding.Default.GetByteCount(myStr);
    SendMessage(Handle,0,IntPtr.Zero,myStr);然后, 在WndProc里面, Case WM_USER:
      byte[] myBytes=new byte[testBytes];
      Marshal.Copy(m.LParam,myBytes,0,testBytes);
      string myTestResult=Encoding.Default.GetString(myBytes);
    break;
      

  8.   

    err...CSDN抽了一下, 结果就发重复了, 汗汗.....
      

  9.   

    谢谢各位的帮助,特别是LeoMaya,受教了。
    因为我不想使用Unsafe 代码,所以GenLinux的回答不是正解,在C#中,我认为Unsafe代码也是要尽量避免的吧。