我已经参考了本文中的代码,使用win32 api(SendMessage,FindWindow,WM_COPYDATA)将消息从1个C#.NET应用程序发送到另一个C#.NET应用程序MSDN code sample application
我的要求是目标应用程序是VB6应用程序(我们可以访问其源代码)..我使用以下代码将消息发送到VB6 exe应用程序。但是,我如何在VB6应用程序中收到消息? (以下是C#.NET中用于发送/接收消息的代码)
发送讯息的代码: -
#region Using directives
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Security;
#endregion
namespace CSSendWM_COPYDATA
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnSendMessage_Click(object sender, EventArgs e)
{
// Find the target window handle.
IntPtr hTargetWnd = NativeMethod.FindWindow(null, "CSReceiveWM_COPYDATA");
if (hTargetWnd == IntPtr.Zero)
{
MessageBox.Show("Unable to find the \"CSReceiveWM_COPYDATA\" window",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Prepare the COPYDATASTRUCT struct with the data to be sent.
MyStruct myStruct;
int nNumber;
if (!int.TryParse(this.tbNumber.Text, out nNumber))
{
MessageBox.Show("Invalid value of Number!");
return;
}
myStruct.Number = nNumber;
myStruct.Message = this.tbMessage.Text;
// Marshal the managed struct to a native block of memory.
int myStructSize = Marshal.SizeOf(myStruct);
IntPtr pMyStruct = Marshal.AllocHGlobal(myStructSize);
try
{
Marshal.StructureToPtr(myStruct, pMyStruct, true);
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.cbData = myStructSize;
cds.lpData = pMyStruct;
// Send the COPYDATASTRUCT struct through the WM_COPYDATA message to
// the receiving window. (The application must use SendMessage,
// instead of PostMessage to send WM_COPYDATA because the receiving
// application must accept while it is guaranteed to be valid.)
NativeMethod.SendMessage(hTargetWnd, WM_COPYDATA, this.Handle, ref cds);
int result = Marshal.GetLastWin32Error();
if (result != 0)
{
MessageBox.Show(String.Format(
"SendMessage(WM_COPYDATA) failed w/err 0x{0:X}", result));
}
}
finally
{
Marshal.FreeHGlobal(pMyStruct);
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct MyStruct
{
public int Number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Message;
}
#region Native API Signatures and Types
/// <summary>
/// An application sends the WM_COPYDATA message to pass data to another
/// application
/// </summary>
internal const int WM_COPYDATA = 0x004A;
/// <summary>
/// The COPYDATASTRUCT structure contains data to be passed to another
/// application by the WM_COPYDATA message.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct COPYDATASTRUCT
{
public IntPtr dwData; // Specifies data to be passed
public int cbData; // Specifies the data size in bytes
public IntPtr lpData; // Pointer to data to be passed
}
/// <summary>
/// The class exposes Windows APIs to be used in this code sample.
/// </summary>
[SuppressUnmanagedCodeSecurity]
internal class NativeMethod
{
/// <summary>
/// Sends the specified message to a window or windows. The SendMessage
/// function calls the window procedure for the specified window and does
/// not return until the window procedure has processed the message.
/// </summary>
/// <param name="hWnd">
/// Handle to the window whose window procedure will receive the message.
/// </param>
/// <param name="Msg">Specifies the message to be sent.</param>
/// <param name="wParam">
/// Specifies additional message-specific information.
/// </param>
/// <param name="lParam">
/// Specifies additional message-specific information.
/// </param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg,
IntPtr wParam, ref COPYDATASTRUCT lParam);
/// <summary>
/// The FindWindow function retrieves a handle to the top-level window
/// whose class name and window name match the specified strings. This
/// function does not search child windows. This function does not
/// perform a case-sensitive search.
/// </summary>
/// <param name="lpClassName">Class name</param>
/// <param name="lpWindowName">Window caption</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}
#endregion
}
}
接收消息的代码: -
#region Using directives
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
#endregion
namespace CSReceiveWM_COPYDATA
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_COPYDATA)
{
// Get the COPYDATASTRUCT struct from lParam.
COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
// If the size matches
if (cds.cbData == Marshal.SizeOf(typeof(MyStruct)))
{
// Marshal the data from the unmanaged memory block to a
// MyStruct managed struct.
MyStruct myStruct = (MyStruct)Marshal.PtrToStructure(cds.lpData,
typeof(MyStruct));
// Display the MyStruct data members.
this.lbNumber.Text = myStruct.Number.ToString();
this.lbMessage.Text = myStruct.Message;
}
}
base.WndProc(ref m);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct MyStruct
{
public int Number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Message;
}
#region Native API Signatures and Types
/// <summary>
/// An application sends the WM_COPYDATA message to pass data to another
/// application.
/// </summary>
internal const int WM_COPYDATA = 0x004A;
/// <summary>
/// The COPYDATASTRUCT structure contains data to be passed to another
/// application by the WM_COPYDATA message.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct COPYDATASTRUCT
{
public IntPtr dwData; // Specifies data to be passed
public int cbData; // Specifies the data size in bytes
public IntPtr lpData; // Pointer to data to be passed
}
#endregion
}
}