2010-12-02 65 views
2

我有兩個mdi應用程序,它們都從同一個數據庫中檢索它們的數據。 這兩個應用程序需要能夠互相發送消息以保持同步。 來回傳遞的消息只包含一個字符串,告訴接收應用程序應該查看數據庫中的哪一部分數據(作業號和一些其他相關信息)。 這兩個應用程序都有一個消息處理程序,當每個程序啓動時實例化。c#和VB6 mdi應用程序之間的消息交互

當消息從VB6應用程序發送到C#應用程序時,它會看到消息,並且行爲恰當,但是當我從C#應用程序向VB6應用程序發送相同類型的消息時,它似乎看到消息事件,但在解包時只能看到部分數據,然後忽略該消息。

我想我可能會格式化C#結尾上的錯誤。 這裏是發送消息的方法:

namespace InterProcessMessaging 
{ 
[StructLayout(LayoutKind.Sequential)] 
    public struct COPYDATASTRUCT 
    { 
     public IntPtr dwData;//a pointer to a number use this to identify your message 
     public IntPtr lpData;//a pointer to the address of the data 
     public IntPtr cbData;//a pointer to the number of bytes to be transferred 

    } 
public class clsMessaging : System.Windows.Forms.NativeWindow, IDisposable 
{ 
//API function to send async. message to target application 
     [DllImport("user32.dll", CharSet = CharSet.Ansi)] 
     public static extern IntPtr SendMessageA(IntPtr hwnd, Int32 wMsg, Int32 wParam, COPYDATASTRUCT lParam); 

    public void SendMessageToVB6(string sendMsg, string WindowsAppTitle) 
    { 
      try 
      { 

       IntPtr hwndTarget = FindWindow(null, WindowsAppTitle); 

       IntPtr pDWData = Marshal.AllocHGlobal(sizeof(Int32));//a pointer to a number used this to identify your message 
       Marshal.StructureToPtr(3, pDWData, true);//place the value 3 at this location 

       IntPtr pLPData = Marshal.StringToHGlobalAnsi(sendMsg.Trim());//a pointer to the address of the data 

       IntPtr pCBData = Marshal.AllocHGlobal(sizeof(Int32));//a pointer to the number of bytes to be transferred 
       Marshal.StructureToPtr(sendMsg.Trim().Length+1, pCBData, true);//place the size of the string at this location 

       COPYDATASTRUCT cds;//a structure containing the three pointers above 
       cds.dwData = pDWData;//a pointer to a number used this to identify your message (3) 
       cds.lpData = pLPData;//a pointer to the address of the data 
       cds.cbData = pCBData;//a pointer to the number of bytes to be transferred 

       if (!System.IntPtr.Zero.Equals(hwndTarget)) 
       { 
        SendMessageA(hwndTarget, 74, 0, cds); 
       } 
      } 
      catch (Exception ex) 
      { 
       Debug.Print(ex.InnerException.ToString()); 
      } 
    } 
} 
} 

回答

1

這工作:

public struct COPYDATASTRUCT 
{ 
    public IntPtr dwData; 
    public UInt32 cbData; 
    [MarshalAs(UnmanagedType.LPStr)] 
    public string lpData; 
} 

[DllImport("User32.dll", EntryPoint = "SendMessage")] 
     public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam); 

IntPtr result; 

      byte[] sarr = System.Text.Encoding.Default.GetBytes(sendMsg); 
      int len = sarr.Length; 
      COPYDATASTRUCT cds; 

      cds.dwData = (IntPtr)3; 
      cds.lpData = sendMsg; 
      cds.cbData = (UInt32)len + 1; 
      result = SendMessage(hwndTarget, WM_COPYDATA, 0, ref cds); 

信用這個解決方案去吉姆·坎普......誰是尚未成爲會員。 謝謝吉姆!

1

我會建議尋找到命名管道。在.NET中,您可以使用System.IO.Pipes來實現此目的。在VB6中,您可以使用Win32API輕鬆實現它。與Windows消息傳遞相比,命名管道是製作IPC的更好方式。另外IPC通過SendMessage對Vista和Win7有限制。

+0

我同意,並已在當地也有類似的建議。大部分這是繼承。 – 2010-12-02 22:12:16

+0

我不知道你是否可以更多地闡述Windows 7上的Windows消息傳遞的侷限性。當傳統應用程序遷移到Windows 7 - 64位環境時,出現了這種情況。我現在想要做的就是讓它工作,這樣我就可以花時間來替換它,可能是基於Web的應用程序。 – 2010-12-03 13:45:23

1

你有這個錯誤。只有COPYDATASTRUCT.lpData是一個指針。 dwData表示消息編號。你選擇你自己的,如果你只有一個,則使用0。 cbData是指向數據的大小。

更多的問題,你泄漏的內存。您分配的內存量與您傳遞的大小不匹配。字符串轉換是有損的,可能不會產生與string.Length()一樣多的字節。 FindWindow臭名昭着地不可靠。使用套接字或命名管道,因此您不必猜測名稱,WCF是最好的。

  COPYDATASTRUCT cds; 
      cds.dwData = (IntPtr)3; 
      cds.lpData = Marshal.StringToHGlobalUni(sendMsg); 
      cds.cbData = 2 * (sendMsg.Length + 1); 
      SendMessageA(hwndTarget, 74, 0, cds); 
      Marshal.FreeHGlobal(cds.lpData); 
相關問題