C#中使用SendMessage在進程間傳遞數據的實例


新建解決方案SendMessageExample

在解決方案下面新建三個項目:CopyDataStruct,Receiver和Sender。

其中,CopyDataStruct項目的輸出類型為“類庫”,Receiver和Sender項目的輸出類型為“Windows 應用程序”。

整個實例程序的結構如下圖所示。

 

2 CopyDataStruct項目實現

定義結構體COPYDATASTRUCT,代碼如下所示。 

using System;

using System.Runtime.InteropServices;

 

namespace CopyDataStruct

{

    public struct COPYDATASTRUCT

    {

        public IntPtr dwData;

        public int cbData;

        [MarshalAs(UnmanagedType.LPStr)]

        public string lpData;

    }

}

編譯CopyDataStruct項目生成dll,再在Receiver和Sender項目中添加對此dll的引用。

 

3 Sender項目實現

Sender項目僅包含一個名稱為“消息發送者”的窗體,如下圖所示。

 

編寫窗體后端代碼,如下所示。

using System;

using System.Runtime.InteropServices;

using System.Windows.Forms;

using CopyDataStruct;

 

namespace Sender

{

    public partial class frmSender : Form

    {

        //Win32 API函數

        [DllImport("User32.dll", EntryPoint = "SendMessage")]

        private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

 

        [DllImport("User32.dll", EntryPoint = "FindWindow")]

        private static extern int FindWindow(string lpClassName, string lpWindowName);

        

        const int WM_COPYDATA = 0x004A;

 

        public frmSender()

        {

            InitializeComponent();

        }

 

        private void btnSend_Click(object sender, EventArgs e)

        {

            int hWnd = FindWindow(null, @"消息接受者");

            if (hWnd == 0)

            {

                MessageBox.Show("555,未找到消息接受者!");

            }

            else

            {

                byte[] sarr = System.Text.Encoding.Default.GetBytes(txtString.Text);

                int len = sarr.Length;

                COPYDATASTRUCT cds;

                cds.dwData = (IntPtr)Convert.ToInt16(txtInt.Text);//可以是任意值

                cds.cbData = len + 1;//指定lpData內存區域的字節數

                cds.lpData = txtString.Text;//發送給目標窗口所在進程的數據

                SendMessage(hWnd, WM_COPYDATA, 0, ref cds);

            }

        }

    }

}

4  Receiver項目實現

Receiver項目僅包含一個名稱為“消息接受者”的窗體,如下圖所示。

 

編寫窗體的后端代碼,如下所示。

using System;

using System.Windows.Forms;

using CopyDataStruct;

 

namespace Receiver

{

    public partial class frmReceiver : Form

    {

        const int WM_COPYDATA = 0x004A;

        public frmReceiver()

        {

            InitializeComponent();

        }

 

        protected override void DefWndProc(ref Message m)

        {

            switch (m.Msg)

            {

                case WM_COPYDATA:

                    COPYDATASTRUCT cds = new COPYDATASTRUCT();

                    Type t = cds.GetType();

                    cds = (COPYDATASTRUCT)m.GetLParam(t);

                    string strResult = cds.dwData.ToString() + ":" +cds.lpData; 

                    lsvMsgList.Items.Add(strResult);

                    break;

                default:

                    base.DefWndProc(ref m);

                    break;

            }

        }

    }

}

運行結果

運行消息發送和消息接收程序(Sender.exe和Receiver.exe),效果如下圖所示。

 

 

實例說明

6.1 SendMessage方法參數說明

  • hWnd:接收消息的窗口的句柄
  • Msg:消息標識符
  • wParam:32位的特定附加信息,具體取決於消息
  • lParam:32位特定附加信息,具體取決於消息

6.2 WM_COPYDATA消息說明

使用WM_COPYDATA消息,lParam參數可以指向一個 COPYDATASTRUCT結構體類型的變量。

typedef struct COPYDATASTRUCT{

  ULONG_PTR dwData;  //可以是任意值

  DWORD cb_data;  //指定lpData內存區域的字節數

  PVOID lpData;  //發送給目錄窗口所在進程的數據

}COPYDATASTRUCT;

若定義的結構體不滿足上面的定義,在接收端無法正確獲取lParam參數指向的數據。

另外,WM_COPYDATA消息的標識符為0x004A。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM