VB.NET Sending Strings via Postmessage - vb.net

OK, this problem has been bugging me for a long time.
I have the code for the service which communicates a string to the client via PostMessage:
Public Sub SendToClient(msgs As String, types As Integer, hwnd As Long)
postMessage(hwnd, 0, Nothing, msgs)
End Sub
Then I have the client that receives the string:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If (m.Msg = 0) Then
Dim a as string
a = Marshal.PtrToStringAuto(m.LParam)
end if
MyBase.WndProc(m)
End Sub
However, the client sends an error, or some jumble of binary data or even just a blank string sometimes. By the way, the m.LParam is a number.
Can someone tell me what is the right way to send/receive strings via postmessage.

I do it like this:
Public Sub SendMessageToApp(ByVal NombreVentana As String, ByVal Mensaje As String, ByVal sender As Form)
Dim hWnd As IntPtr
Dim mCopyData As COPYDATASTRUCT
hWnd = CType(FindWindow(Nothing, NombreVentana), IntPtr)
Dim message As New System.Text.StringBuilder
If (CInt(hWnd) <> 0) Then
message.Append(Mensaje)
Dim pCopyData As IntPtr = Marshal.AllocHGlobal(message.Length() + 40)
mCopyData.lpData = Marshal.StringToHGlobalAnsi(message.ToString)
mCopyData.cbData = message.Length
mCopyData.dwData = CType(_messageID, IntPtr)
Marshal.StructureToPtr(mCopyData, pCopyData, False)
SendMessage(hWnd, WM_COPYDATA, CInt(sender.Handle), pCopyData)
Marshal.FreeHGlobal(mCopyData.lpData)
Marshal.FreeHGlobal(pCopyData)
End If
End Sub
Receiver window:
Declarations and definitions:
Const WM_COPYDATA As Integer = 74
Const SIG_LENGTH As Integer = 36
Const MAX_COPY_LENGTH As Integer = 128
Const SigConnect As String = "F7B82657-BD18-4ee6-B182-78721293821C"
Dim CDCount As Integer
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _
ByVal lParam As IntPtr) As Integer
Dim hWndSender As Integer
Private Const _messageID As Integer = 10
'Estructura obligatoria para poder utilizar el API CopyData
<StructLayout(LayoutKind.Sequential)> _
Private Structure COPYDATASTRUCT
Public dwData As IntPtr
Public cbData As Integer
Public lpData As IntPtr
End Structure
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_COPYDATA Then
Dim Estructura As COPYDATASTRUCT
Dim tipo As Type = Estructura.GetType
Dim message As String
Estructura = CType(m.GetLParam(GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
'Here you get the message
message = Marshal.PtrToStringAnsi(Estructura.lpData, Estructura.cbData)
End If

Related

Convert an Image

I Tried to convert this code into vb.net and add a little code to make a file... but the file's resolution became crap and i cant seem to insert it into the Crystal report, Did i do something wrong while converting it into vb.net? thanks in advance :)
Here is the original link Convert an image into WMF with .NET?
<Flags>
Private Enum EmfToWmfBitsFlags
EmfToWmfBitsFlagsDefault = &H0
EmfToWmfBitsFlagsEmbedEmf = &H1
EmfToWmfBitsFlagsIncludePlaceable = &H2
EmfToWmfBitsFlagsNoXORClip = &H4
End Enum
Private Shared MM_ISOTROPIC As Integer = 7
Private Shared MM_ANISOTROPIC As Integer = 8
<DllImport("gdiplus.dll")>
Private Shared Function GdipEmfToWmfBits(_hEmf As IntPtr, _bufferSize As UInteger, _buffer As Byte(), _mappingMode As Integer, _flags As EmfToWmfBitsFlags) As UInteger
End Function
<DllImport("gdi32.dll")>
Private Shared Function SetMetaFileBitsEx(_bufferSize As UInteger, _buffer As Byte()) As IntPtr
End Function
<DllImport("gdi32.dll")>
Private Shared Function CopyMetaFile(hWmf As IntPtr, filename As String) As IntPtr
End Function
<DllImport("gdi32.dll")>
Private Shared Function DeleteMetaFile(hWmf As IntPtr) As Boolean
End Function
<DllImport("gdi32.dll")>
Private Shared Function DeleteEnhMetaFile(hEmf As IntPtr) As Boolean
End Function
Private Function MakeMetafileStream(image As Bitmap) As Byte()
Dim metafile As Metafile = Nothing
Using g As Graphics = Graphics.FromImage(image)
Dim hDC As IntPtr = g.GetHdc()
metafile = New Metafile(hDC, EmfType.EmfOnly)
g.ReleaseHdc(hDC)
End Using
Using g As Graphics = Graphics.FromImage(metafile)
g.DrawImage(image, 0, 0)
End Using
Dim _hEmf As IntPtr = metafile.GetHenhmetafile()
Dim _bufferSize As UInteger = GdipEmfToWmfBits(_hEmf, 0, Nothing, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault)
Dim _buffer As Byte() = New Byte(_bufferSize - 1) {}
GdipEmfToWmfBits(_hEmf, _bufferSize, _buffer, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault)
Dim hmf As IntPtr = SetMetaFileBitsEx(_bufferSize, _buffer)
Dim tempfile As String = Path.GetTempFileName()
CopyMetaFile(hmf, tempfile)
DeleteMetaFile(hmf)
DeleteEnhMetaFile(_hEmf)
Dim stream = New MemoryStream()
Dim data As Byte() = File.ReadAllBytes(tempfile)
Return data
End Function
Private Sub Convert()
Dim src As New Bitmap("C:\Users\Sample\Desktop\Logos\LogoTransparent\Transparentlogo.png")
Dim Msteam As Byte() = MakeMetafileStream(src)
Dim newF As String = "C:\Users\Alvin Rodriguez\Desktop\Logos\new logo transparent\Transparentlogo.wmf"
System.IO.File.WriteAllBytes(newF, Msteam)
Msteam = Nothing
End Sub
Some interface are to be modifed:
Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As IntPtr, ByVal lpszFile As String) As IntPtr
Declare Function DeleteEnhMetaFile Lib "gdi32" (ByVal hemf As IntPtr) As Integer
Private Declare Function GdipEmfToWmfBits Lib "gdiplus.dll" (ByVal hEmf As IntPtr, ByVal bufferSize As UInteger, ByVal buffer() As Byte, ByVal mappingMode As Integer, ByVal flags As EmfToWmfBitsFlags) As UInteger

How to retrieve open excel filename from remote pc using vb.net

Hi currently I'm having this code below.
It retrieves the filename of open excel document from process and displays it.
For now it can retrieve it from my own pc, but when I wanted to remotely retrieves it from other pc, it doesn't work.
I have authorized access and I could actually get the process id and name of remote pcs only.
Dim w As Object
Dim processQ As String
Dim processes As Object
Dim processA As Object
Dim pname As String
w = GetObject("winmgmts:{impersonationLevel=impersonate}\\" & pc & "\root\cimv2")
processQ = "SELECT * FROM win32_process WHERE name = 'EXCEL.EXE'"
processes = w.execquery(processQ)
For Each processA In processes
activeprocess = Process.GetProcessById(processA.processid)
MsgBox(processA.processid & processA.name)
Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(processA.processid)
MsgBox(windows.Count())
For Each kvp As KeyValuePair(Of IntPtr, String) In windows
Dim value As String = kvp.Value.ToString
If InStr(value, "Excel") = False Then
MsgBox(value)
End If
Next
Next
Can anyone tell me what should I do and what's wrong with this?
<DllImport("USER32.DLL")>
Private Shared Function GetShellWindow() As IntPtr
End Function
<DllImport("USER32.DLL")>
Private Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("USER32.DLL")>
Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
End Function
<DllImport("USER32.DLL", SetLastError:=True)>
Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, <Out()> ByRef lpdwProcessId As UInt32) As UInt32
End Function
<DllImport("USER32.DLL")>
Private Shared Function IsWindowVisible(ByVal hwnd As IntPtr) As Boolean
End Function
Private Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
<DllImport("USER32.DLL")>
Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
End Function
Private hShellWindow As IntPtr = GetShellWindow()
Private dictWindows As New Dictionary(Of IntPtr, String)
Private currentProcessID As Integer
Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
dictWindows.Clear()
currentProcessID = processID
EnumWindows(AddressOf enumWindowsInternal, 0)
Return dictWindows
End Function
Public Function enumWindowsInternal(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
If (hwnd <> hShellWindow) Then
Dim windowPid As UInt32
If Not IsWindowVisible(hwnd) Then
Return True
End If
Dim length As Integer = GetWindowTextLength(hwnd)
If (length = 0) Then
Return True
End If
GetWindowThreadProcessId(hwnd, windowPid)
If (windowPid <> currentProcessID) Then
Return True
End If
Dim stringBuilder As New StringBuilder(length)
GetWindowText(hwnd, stringBuilder, (length + 1))
dictWindows.Add(hwnd, stringBuilder.ToString)
End If
Return True
End Function
Sorry I'm quite new to vb.net.. but I'm learning thanks!

Show ToolTips on ListView first row in Framework 4.0

I have a WinForm application developed in Framework 2.0 with VB.Net which was using the event MouseMove on all the ListView objects to display ToolTip text on the first row of the ListViews - as it's not possible to have ToolTips on ColumnHeader, as far as I know, without third part tools.
The problem is that since I converted the application to Framework 4.0 this "trick" is not working and the ToolTips are not displayed anymore.
Does anyone know a solution or, even better, a way to display ToolTips on ListView ColumnHeaders?
Here's my code snippet:
Private Sub ShowTooltip(ByVal sender As Object, ByVal e As MouseEventArgs)
Handles myListView.MouseMove
Dim iColumn As System.Int32 = FindListViewColumnHeader(e.X, e.Y)
If Me.myListView.Columns.Count > 0 AndAlso iColumn >= 0 AndAlso
iColumn <= Me.myListView.Columns.Count - 1 Then
Me.myToolTip.Active = True
Me.myToolTip.UseAnimation = True
Me.myToolTip.UseFading = True
Me.myToolTip.AutomaticDelay = 10000
Me.myToolTip.AutoPopDelay = 10000
Me.myToolTip.InitialDelay = 0
Me.myToolTip.ReshowDelay = 2000
Dim sTooltipText As System.String = SomeText(...)
If sTooltipText <> DirectCast(Me.myToolTip.Tag, System.String) Then
Me.myToolTip.Tag = sTooltipText
Me.myToolTip.SetToolTip(Me.myListView, sTooltipText)
End If
Else
Me.myToolTip.Active = False
End If
End Sub
Protected Overridable Function FindListViewColumnHeader(ByVal X As System.Int32,
ByVal Y As System.Int32) As System.Int32
If Y > 20 And Y < 40 Then
Dim iCount As System.Int32
Dim iLeft As System.Int32
For iCount = 0 To myListView.Columns.Count - 1
iLeft = iLeft + myListView.Columns(iCount).Width
If X <= iLeft Then
Return iCount
Exit For
End If
Next
Return iCount
Else
Return -1
End If
End Function
Note: myToolTip is
Friend WithEvents myToolTip As System.Windows.Forms.ToolTip
and myListView is
Protected WithEvents myListView As System.Windows.Forms.ListView
Please notice that, as suggested in the question:
How to set tooltip for a ListviewItem, ShowItemToolTips is already set to True.
You can get the handle of the header column and subclass it:
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function CallWindowProc(lpPrevWndFunc As IntPtr, hWnd As IntPtr, Msg As UInteger, wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function
Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const GWL_WNDPROC As Integer = -4
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_MOUSEMOVE As Integer = &H200
Private oldWndProc As IntPtr = IntPtr.Zero
Private newWndProc As Win32WndProc = Nothing
Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
'hWnd is the window you want to subclass...,
'create a new delegate for the new wndproc
newWndProc = New Win32WndProc(AddressOf MyWndProc)
'subclass
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
End Sub
Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Select Case Msg
Case WM_LBUTTONDOWN
'The lower 2 bytes of lParam are the x coordinate
'and the higher 2 bytes the y.
ToolTip1.Show("My tooltip", ListView1, lParam And &HFFFF, (lParam >> 16) And &HFF, 2000)
Exit Select
Case Else
Exit Select
End Select
Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
End Function
To subclass the header use:
'LVM_GETHEADER = &H101F
Dim hwndHeader As IntPtr = SendMessage(ListView1.Handle, &H101F, 0, 0)
SubclassHWnd(hwndHeader)
I used the WM_LBUTTONDOWN event for convenience. You can use the WM_MOUSEMOVE event and check which column the mouse is etc... and show the tooltip
The code for subclassing: Subclass an Unmanged Window in C#

Get Text From Specific Textboxes From External Application - Visual Basic .Net

I can get text from external application text box but now I want to get text from my desired text box from external application.
My English is not so good that's why see Image Below.
The Below Code Return The First Text Box Value Only.
Imports System.Runtime.InteropServices
Public Class Form1
Private Const WM_GETTEXT As Integer = &HD
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, _
ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, _
ByVal childAfter As IntPtr, _
ByVal lclassName As String, _
ByVal windowTitle As String) As IntPtr
End Function
Declare Auto Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Find the running notepad window
Dim Hwnd As IntPtr = FindWindow(Nothing, TextBox1.Text)
'Alloc memory for the buffer that recieves the text
Dim Handle As IntPtr = Marshal.AllocHGlobal(100)
'send WM_GWTTEXT message to the notepad window
Dim NumText As Integer = SendMessage(Hwnd, WM_GETTEXT, 50, Handle)
'copy the characters from the unmanaged memory to a managed string
Dim Text As String = Marshal.PtrToStringUni(Handle)
'Display the string using a label
Label1.Text = Text
'Find the Edit control of the Running Notepad
Dim ChildHandle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, "Edit", Nothing)
'Alloc memory for the buffer that recieves the text
Dim Hndl As IntPtr = Marshal.AllocHGlobal(200)
'Send The WM_GETTEXT Message
NumText = SendMessage(ChildHandle, WM_GETTEXT, 200, Hndl)
'copy the characters from the unmanaged memory to a managed string
Text = Marshal.PtrToStringUni(Hndl)
'Display the string using a label
Label2.Text = Text
End Sub
End Class
You'll have to loop through children of the main window (External Application) and get their properties.
You'll use the following:
<DllImport("User32.dll")> _
Public Function EnumChildWindows _
(ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
ByVal lParam As IntPtr) As Boolean
End Function
Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Public Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Try
EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return ChildrenList.ToArray
End Function
For for details, check this How can I get properties of controls contained in a popup message box using VB.Net
' try this on excel vbe
External_application_handle=findwindow(vbNullString,"External_application")
textbox_1_handle=findwindowex(External_application_handle,0&,"Edit",vbNullString)
next_handle=textbox_1_handle
textbox_2_handle=findwindowex(External_application_handle,next_handle,"Edit",vbNullString")
Length = SendMessage(textbox_2_handle, WM_GETTEXTLENGTH, 0,0)
buffer$=space(Length)
call sendmessage(textbox_2_handle,Length+1,buffer$)
msgbox buffer

Convert C++ to VB.NET

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
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
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