Solved
Passing of structure in interprocess communication(NOT STRING)
Posted on 2006-07-09
hi to all and best of luck. :)) I'm stuck-up here with the problem .. I could manage to pass string to another process/application using WM_COPYDATA but it takes v. long to pass a structure. Do remember that one p'mtr of structure is an object and doing that giving errors..
i wish if you can give me any code that allows passing "structure" between 2 applications
------------this is class one - sending message
Imports System.Runtime.InteropServices
Public Class clsIPC
Inherits System.Windows.Forms.NativeWindow Implements IDisposable
Private Const GLOBAL_IDENTITY_ONE = "GLOBAL_IDENTITY_ONE"
Private Const GLOBAL_IDENTITY_TWO = "GLOBAL_IDENTITY_TWO"
Private Const MESSAGE_FOR_ONE = "MESSAGE_ONE"
Private Const MESSAGE_FOR_TWO = "MESSAGE_TWO"
Private Const WM_COPYDATA As Integer = &H4A
#Region "API Declaration"
<StructLayout(LayoutKind.Sequential)> _
Private Structure CopyData
Public dwData As IntPtr
Public cbData As Integer
Public lpData As IntPtr
End Structure
Private Declare Auto Function SendMessage Lib "user32" _
(ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As IntPtr, _
ByRef lParam As CopyData) As Boolean
Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" _
(ByVal lpString As String) As IntPtr
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As IntPtr, ByVal wMsg As IntPtr, ByVal wParam As Integer, _
ByVal lParam As Integer) As IntPtr
#End Region
#Region "process for messanging to application GLOBAL_IDENTITY_TWO"
'get handle of globlal application named GLOBAL_IDENTITY_TWO
Public ReadOnly Property GET_HANDLE_TWO() As IntPtr
Get
Return FindWindow(vbNullString, GLOBAL_IDENTITY_TWO)
End Get
End Property
Structure PT
Dim x As Object
Dim y As Char
Dim xy As String
End Structure
Dim MyVariable As New PT
Public Function sendMessageToTwo()
Dim data As CopyData
Dim message As String = "this is to be sent"
Dim hwndTarget As IntPtr
Dim MessageId As IntPtr
hwndTarget = Me.GET_HANDLE_TWO
MessageId = ONE_TO_TWO_MESSAGEID()
MyVariable.x = message
MyVariable.y = "c"
MyVariable.xy = "String is here"
System.GC.KeepAlive(MyVariable)
data.lpData = Marshal.AllocHGlobal(Marshal.SizeOf(MyVariable))
data.cbData = Marshal.SizeOf(MyVariable)
Dim MyPointer As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(MyVariable))
Marshal.StructureToPtr(MyVariable, data.lpData, True)
SendMessage(hwndTarget, WM_COPYDATA, Me.Handle, data)
MsgBox("WM_COPYDATA")
Exit Function
If Not System.IntPtr.Zero.Equals(hwndTarget) Then
Call PostMessage(hwndTarget, MessageId, 0, 0)
MsgBox("Message sent")
Else
MsgBox("Unable to send Message ! probably GLOBAL_IDENTITY_TWO Not found")
End If
End Function
Public ReadOnly Property ONE_TO_TWO_MESSAGEID() As IntPtr
Get
Static objONE_TO_TWO_MESSAGEID As IntPtr
If IntPtr.Zero.Equals(ONE_TO_TWO_MESSAGEID) Then
objONE_TO_TWO_MESSAGEID = RegisterWindowMessage(MESSAGE_FOR_TWO)
End If
Return objONE_TO_TWO_MESSAGEID
End Get
End Property
#End Region
Region "dispose method and new()/constructor"
Public Sub Dispose() Implements IDisposable.Dispose
If Not Me.Handle.Equals(IntPtr.Zero) Then
Me.ReleaseHandle()
End If
End Sub
Public Sub New()
Dim Params As CreateParams = New CreateParams
Params.Caption = GLOBAL_IDENTITY_ONE
Me.CreateHandle(Params)
End Sub
#End Region
End Class
--------------------------------------xxxxxxxxxxxxxxxxxxxxxxxxxx----------------------------------
----this is class two-listening to message-----------
Imports System.Runtime.InteropServices
Public Class clsIPC
Inherits System.Windows.Forms.NativeWindow Implements IDisposable
Private Const GLOBAL_IDENTITY_ONE = "GLOBAL_IDENTITY_ONE"
Private Const GLOBAL_IDENTITY_TWO = "GLOBAL_IDENTITY_TWO"
Private Const MESSAGE_FOR_ONE = "MESSAGE_ONE"
Private Const MESSAGE_FOR_TWO = "MESSAGE_TWO"
Private Const WM_COPYDATA As Integer = &H4A
Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" _
(ByVal lpString As String) As IntPtr
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As IntPtr, ByVal wParam As Integer,ByVal lParam As Integer) As IntPtr
<StructLayout(LayoutKind.Sequential)> _
Private Structure CopyData
Public dwData As IntPtr
Public cbData As Integer
Public lpData As IntPtr
End Structure
Structure PT
Dim x As Object '<<<----- whenever i use object as member of a structure i get an exception An unhandled exception
'of type 'System.ExecutionEngineException' occurred in mscorlib.dll if i use string as a
'member there is no error
Dim y As Integer
Dim xy As Integer
End Structure
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_COPYDATA
Dim data As CopyData
Dim message As String
Dim MyPoint As New PT
data = CType(m.GetLParam(GetType(CopyData)), CopyData)
MyPoint = Marshal.PtrToStructure(data.lpData, GetType(PT)) <<<---- @ this point i'm getting the error [debug]
'MyPoint = Marshal.PtrToStructure(CType(m.GetLParam(GetType(CopyData)), CopyData).lpData, GetType(PT))
MsgBox(CType(MyPoint.x, String))
Case TWO_TO_ONE_MESSAGEID().ToInt32
MessageBox.Show("GOT A MESSAGE FROM ONE--- CALLING METHOD A", "VBNETMessaging")
Call A()
End Select
MyBase.WndProc(m)
End Sub
Private Sub A()
MsgBox("Message from Method A")
End Sub
Public ReadOnly Property TWO_TO_ONE_MESSAGEID() As IntPtr
Get
Static objTWO_TO_ONE_MESSAGEID As IntPtr
If IntPtr.Zero.Equals(objTWO_TO_ONE_MESSAGEID) Then
objTWO_TO_ONE_MESSAGEID = RegisterWindowMessage(MESSAGE_FOR_TWO)
End If
Return objTWO_TO_ONE_MESSAGEID
End Get
End Property
#Region "dispose method and new()/constructor"
Public Sub Dispose() Implements IDisposable.Dispose
If Not Me.Handle.Equals(IntPtr.Zero) Then
Me.ReleaseHandle()
End If
End Sub
Public Sub New()
Dim Params As CreateParams = New CreateParams
Params.Caption = GLOBAL_IDENTITY_TWO
Me.CreateHandle(Params)
End Sub
#End Region
End Class
--------------------------------------xxxxxxxxxxxxxxxxxxxxxxxxxx----------------------------------