WM_COPYDATA

  • Thread starter Thread starter James Kunicki
  • Start date Start date
J

James Kunicki

Hi,

I am trying to find if there is a structure in VB.NET that uses
COPDATSTRUCT.
In interfacing to an existing application, the application uses WM_COPYDATA
message
extensively, between applications.
I was able to capture the message loop within a VB.Net application using
WndProc() method,
and was receiving message 74 for WM_COPYDATA message.
The issue I am running into is that the internal message I am looking for is
in the COPYDATASTRUCT
dwData.
So I am looking for a way to reference the message within the
COPYDATASTRUCT from
the WndProc() method.

Example of C++ application...

within message received function
 
James Kunicki said:
Hi,

I am trying to find if there is a structure in VB.NET that uses
COPDATSTRUCT.
In interfacing to an existing application, the application uses WM_COPYDATA
message
extensively, between applications.
I was able to capture the message loop within a VB.Net application using
WndProc() method,
and was receiving message 74 for WM_COPYDATA message.
The issue I am running into is that the internal message I am looking for is
in the COPYDATASTRUCT
dwData.
So I am looking for a way to reference the message within the

Here is a simple example of using WM_COPYDATA that I cooked up a while back...
This is two separate applications, and these are the main forms for each one....

Application 1 - the receiver...

Imports System.Runtime.InteropServices

Public Class MainForm
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Messages As System.Windows.Forms.ListBox
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.Messages = New System.Windows.Forms.ListBox()
Me.SuspendLayout()
'
'Messages
'
Me.Messages.Dock = System.Windows.Forms.DockStyle.Fill
Me.Messages.IntegralHeight = False
Me.Messages.Name = "Messages"
Me.Messages.Size = New System.Drawing.Size(292, 273)
Me.Messages.TabIndex = 0
'
'MainForm
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 273)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Messages})
Me.Name = "MainForm"
Me.Text = "Receive WM_COPYDATA"
Me.ResumeLayout(False)

End Sub

#End Region

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = MainForm.WM_COPYDATA Then
Dim data As CopyData
Dim message As String

' get the data...
data = CType(m.GetLParam(GetType(CopyData)), CopyData)
message = Marshal.PtrToStringAuto(data.lpData, data.cbData \
Marshal.SystemDefaultCharSize)

' add the message
Messages.Items.Add(String.Format("{0}: {1}",
DateTime.Now.ToShortTimeString(), message))

' let them know we processed the message...
m.Result = New IntPtr(1)
Else
MyBase.WndProc(m)
End If
End Sub

Private Const WM_COPYDATA As Integer = &H4A

<StructLayout(LayoutKind.Sequential)> _
Private Structure CopyData
Public dwData As IntPtr
Public cbData As Integer
Public lpData As IntPtr
End Structure
End Class


Application 2 - The sender....

Imports System.Runtime.InteropServices

Public Class MainForm
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents MessageText As System.Windows.Forms.TextBox
Friend WithEvents Send As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.MessageText = New System.Windows.Forms.TextBox()
Me.Send = New System.Windows.Forms.Button()
Me.SuspendLayout()
'
'MessageText
'
Me.MessageText.Anchor = ((System.Windows.Forms.AnchorStyles.Top Or
System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right)
Me.MessageText.Name = "MessageText"
Me.MessageText.Size = New System.Drawing.Size(328, 20)
Me.MessageText.TabIndex = 0
Me.MessageText.Text = ""
'
'Send
'
Me.Send.Anchor = System.Windows.Forms.AnchorStyles.Top
Me.Send.Location = New System.Drawing.Point(127, 32)
Me.Send.Name = "Send"
Me.Send.TabIndex = 1
Me.Send.Text = "Send"
'
'MainForm
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(328, 61)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Send,
Me.MessageText})
Me.Name = "MainForm"
Me.Text = "Send Data To Client Using WM_COPYDATA"
Me.ResumeLayout(False)

End Sub

#End Region

Private Const WM_COPYDATA As Integer = &H4A
Private Const WindowName As String = "Receive WM_COPYDATA"

<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 Auto Function FindWindow Lib "user32" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr

Private Sub Send_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Send.Click
Dim ClientWindow As IntPtr = MainForm.FindWindow(Nothing,
MainForm.WindowName)

' make sure we found an active client window
If Not ClientWindow.Equals(IntPtr.Zero) Then

' if there is text to send
If Me.MessageText.Text.Length > 0 Then
Dim message As String = Me.MessageText.Text
Dim data As CopyData

' set up the data...
data.lpData = Marshal.StringToHGlobalAuto(message)
data.cbData = message.Length * Marshal.SystemDefaultCharSize

' send the data
MainForm.SendMessage(ClientWindow, MainForm.WM_COPYDATA,
Me.Handle, data)

' free the pointer...
Marshal.FreeHGlobal(data.lpData)
End If
Else
MessageBox.Show("Could Not Find Active Client Window.")
End If
End Sub
End Class

HTH,
Tom Shelton
 
Back
Top