[C#][VB.NET] VB.NET 的程式透過 SendMessage 傳送資訊到 C# 的程式

  • 31450
  • 0
  • 2010-08-03

[C#][VB.NET] VB.NET 的程式透過 SendMessage 傳送資訊到 C# 的程式

 

1. 問題描述

問題網址 : http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/f6fcdc32-c979-43cb-b234-b094e996e927

簡述如下

有兩個程式,分別以 VB.NET 和 C# 開發

如何在 VBNET 程式,點選 Button 後,控制 C# 裡的 Button

 

2. 方法

兩個程式間傳送資料,可以使用的方法蠻多的,例如

1. 二個在不同電腦:使用 .NET Remoting、Socket、SendMessage 或實作 Winsock Client/Server 機制來傳輸資料
2. 二個在同一電腦:實作 Mutex, Semaphore, Memory Buffer 機制來交換資料,這是 Process Synchronized 的議題

 

而以下程式是透過 SendMessage 完成

 

VB.NET 程式碼 : 專案名稱為 VB,Form1.Text 屬性為 VB

Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class Form1

    <StructLayout(LayoutKind.Sequential)> _
Public Structure CopyDataStruct
        Public dwData As Integer  '附加參數
        Public cbData As Integer  '數據大小
        Public lpData As IntPtr  '數據內容
    End Structure

    <DllImport("user32.dll", EntryPoint:="SendMessage")> _
Public Shared Function SendMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    End Function

    Public Const WM_COPYDATA As Integer = &H4A

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim S As String = TextBox1.Text
        If S.Length <= 0 Then
            Console.WriteLine("null")
            Return
        End If
        Dim vProcesses As Process() = Process.GetProcessesByName("CS")

        If vProcesses.Length <= 0 Then
            vProcesses = Process.GetProcessesByName("CS.vshost")
        End If

        If vProcesses.Length <= 0 Then
            Console.WriteLine("找不到目標程式")
            Return
        End If

        Dim vCopyDataStruct As New CopyDataStruct()
        vCopyDataStruct.dwData = 0
        vCopyDataStruct.cbData = S.Length * Len(New Char) + Len(New Char) '最後結束符號 \x00
        vCopyDataStruct.lpData = Marshal.StringToBSTR(S)
        Dim vAddress = Marshal.AllocCoTaskMem(Marshal.SizeOf(vCopyDataStruct))
        Marshal.StructureToPtr(vCopyDataStruct, vAddress, True)
        For Each vProcess As Process In vProcesses
            SendMessage(vProcess.MainWindowHandle, WM_COPYDATA, 0, CInt(vAddress))
        Next
        Marshal.FreeBSTR(vCopyDataStruct.lpData)
        Marshal.FreeCoTaskMem(vAddress)
    End Sub
End Class

 

C# 程式碼 : 專案名稱為 CS,Form1.Text 屬性為 CS

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CS
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CopyDataStruct
        {
            public int dwData;  // 附加參數
            public int cbData;  // 數據大小
            public IntPtr lpData;  // 數據內容
        }

        public const int WM_COPYDATA = 0x004A;

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_COPYDATA:
                    CopyDataStruct vCopyDataStruct = (CopyDataStruct)Marshal.PtrToStructure(
                        m.LParam, typeof(CopyDataStruct));

                    textBox1.Text = Marshal.PtrToStringBSTR(vCopyDataStruct.lpData);
                    if (textBox1.Text == "B1")  // 當從VB程式接收到 B1 的訊息時,呼叫 Button1.Click 事件
                    {
                        button1.PerformClick();
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        public void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Button Click");
        }
    }
}

 

執行結果

 

範例下載

[C#][VB.NET] VB.NET 的程式透過 SendMessage 傳送資訊到 C# 的程式.rar