Reputation: 87
the purpose is to send a message from an vb.net application to another application using winapi sendmessage. I cannot get it to work. Your help is greatly appreciated
This is what I have, but it does not seems to work
Public Class WinAPI
Private hwnd As Integer
Private Declare Auto Function FindWindow Lib "user32" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
'FindWindowByClass
Private Declare Auto Function FindWindow Lib "user32" _
(ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
'FindWindowByCaption
Private Declare Auto Function FindWindow Lib "user32" _
(ByVal zero As IntPtr, _
ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" _
(ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As IntPtr, _
ByRef lParam As COPYDATASTRUCT) As Boolean
Public Const WM_COPYDATA As Integer = &H4A
<StructLayout(LayoutKind.Sequential)> _
Structure COPYDATASTRUCT
Dim dwData As Long
Dim cbData As Long
Dim lpData As IntPtr
End Structure
Public Sub SendToeSignal(ByVal strMessage As String)
hwnd = FindWindow(vbNullString, "eSignalSink")
' hwnd = FindWindow("eSignalSink", "vbNullString")
Dim DataStruct As New COPYDATASTRUCT
' strMessage = "1" & "," & strMessage & Chr(0) & vbCr 'Null terminated & carriage return
strMessage = "1" & "," & strMessage & vbCr 'Null terminated & carriage return
DataStruct.dwData = 1
DataStruct.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)
SendMessage(hwnd, WM_COPYDATA, 0, DataStruct)
Marshal.FreeCoTaskMem(DataStruct.lpData)
End Sub
End Class
Upvotes: 0
Views: 875
Reputation: 1
Thanks for the first example that almost worked for my application. The receiver application need the string in ANSI ( WinAmp ) so I had to change the line:
DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)
to
DataStruct.lpData = Marshal.StringToCoTaskMemAnsi(strMessage)
Besides that it worked like a charm, first example that got the pointers correctly for x64 - x32. Just wish I found this first in my 24 hr quest
Win 10. Visualstudio2017 vb.net
Upvotes: 0
Reputation: 54532
It looks like you have a VB6 style definition of your COPYDATASTRUCT
try this instead.
From above PInvoke link:
<StructLayout(LayoutKind.Sequential)> _
Structure COPYDATASTRUCT
Public dwData As IntPtr
Public cdData As Integer
Public lpData As IntPtr
End Structure
First of all do yourself a favor and enable Option Strict
expecially when you are working with API functions. You are sending a structure between your applications and will need to make sure you can retrieve it at the receiving application. I made some changes to your example code and it does work, receiving the data in a test program that the main Form is named TestApp
.
Your example with modifications
Option Strict On
Imports System.Runtime.InteropServices
Public Class Form1
Public Sub New()
' This call is required by the designer.
InitializeComponent()
Dim myWinAPI As WinAPI = New WinAPI
myWinAPI.SendToeSignal("Hello World")
' Add any initialization after the InitializeComponent() call.
End Sub
End Class
Public Class WinAPI
Private hwnd As IntPtr
Private Declare Auto Function FindWindow Lib "user32" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
'FindWindowByClass
Private Declare Auto Function FindWindow Lib "user32" _
(ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
'FindWindowByCaption
Private Declare Auto Function FindWindow Lib "user32" _
(ByVal zero As IntPtr, _
ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" _
(ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As IntPtr, _
ByRef lParam As COPYDATASTRUCT) As Boolean
Public Const WM_COPYDATA As Integer = &H4A
<StructLayout(LayoutKind.Sequential)> _
Structure COPYDATASTRUCT
Dim dwData As IntPtr
Dim cbData As Integer
Dim lpData As IntPtr
End Structure
Public Sub SendToeSignal(ByVal strMessage As String)
hwnd = FindWindow(IntPtr.Zero, "TestApp")
Dim DataStruct As New COPYDATASTRUCT
strMessage = "1" & "," & strMessage & vbCr 'Null terminated & carriage return
DataStruct.dwData = CType(1, IntPtr)
DataStruct.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)
SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, DataStruct)
Marshal.FreeCoTaskMem(DataStruct.lpData)
End Sub
Public Sub New()
End Sub
End Class
Receiving Application
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
<StructLayout(LayoutKind.Sequential)> _
Structure COPYDATASTRUCT
Dim dwData As IntPtr
Dim cbData As Integer
Dim lpData As IntPtr
End Structure
Public Const WM_COPYDATA As Integer = &H4A
Dim split() As String = New String() {",", " "}
Dim myData() As String
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_COPYDATA Then
Dim CD As COPYDATASTRUCT = DirectCast(m.GetLParam(GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
Dim B As Byte() = New Byte(CD.cbData - 1) {}
Dim lpData As IntPtr = CD.lpData
Marshal.Copy(lpData, B, 0, CD.cbData)
Dim strData As String = Encoding.[Default].GetString(B)
myData = strData.Split(split, StringSplitOptions.None)
End If
End Sub
End Class
Upvotes: 2