2. Interop call C# WinForm by WinMsg
Now we have a COM interop in VB6, VB6 can put the GenInfo and Flag to the C# class. But how can
I notify our WinForm application to get these values?
I decide to to use WinMsg to communicate between the Interop.cs and WinForm.cs, because they are all written in C#. It's an easily way to implement if the VB6 and WinForm located in one machine. But if they are not located in one machine, we must use another way I will mention in next section.
The process is:
Firstly, in the sender side, we use FindWindow to find the WinForm Handler, then send the WM_COPYDATA message to the receiver use the method SendMessage.
The methods FindWindow and SendMessage are Windows API in User32.dll.
Then the receiver side(WinFrom) will get the message in the method DefWndProc.
We can use the overriding method DefWndProc of WinForm to handle customer defined message.
In both sender and receiver we use the same struct COPYDATASTRUCT to deliver the message.
Sender: the Interop.cs
const int WM_COPYDATA = 0x004A;
private string CSHARP_WINDOWTITLE_SERVER = "C#-WinForm";
public void notifyCSharpForm()
{
StringBuilder sbMsg = new StringBuilder();
if (this.GenInfo != null)
{
for (int i = 0; i < GenInfo.Length; i++)
{
if (i == (GenInfo.Length - 1))
sbMsg.Append(GenInfo[i]);
else
sbMsg.Append(GenInfo[i] + "|");
}
}
else
{
sbMsg.Append(Flag.ToString());
}
//Notify the WinForm to get the GenInfo and Flag
int WINDOW_HANDLER = FindWindow(null, CSHARP_WINDOWTITLE_SERVER);
if (WINDOW_HANDLER != 0)
{
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = (IntPtr)100;
cds.lpData = sbMsg.ToString();
cds.cbData = sbMsg.Length + 1;
SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
ref COPYDATASTRUCT lParam // second message parameter
);
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string lpClassName, string
lpWindowName);
Receiver: WinForm.cs
private string CSHARP_WINDOWTITLE_SERVER = "C#-WinForm";
public frmMain()
{
......
this.Text = CSHARP_WINDOWTITLE_SERVER;
}
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
String msg = mystr.lpData;
String[] msgArr = msg.Split('|');
GenInfo = msgArr;
//Do something to display the GenInfo
break;
default:
base.DefWndProc(ref m);
break;
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}