1. 程式人生 > >C#中使用SendMessage在程序間傳遞資料的例項

C#中使用SendMessage在程序間傳遞資料的例項

1 新建解決方案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;
}
}
}
}

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;
}
}
}
}


5 執行結果
執行訊息傳送和訊息接收程式(Sender.exe和Receiver.exe),效果如下圖所示。

 

 


6 例項說明
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。
---------------------
作者:三五月兒
來源:CSDN
原文:https://blog.csdn.net/yl2isoft/article/details/20222679
版權宣告:本文為博主原創文章,轉載請附上博文連結!