Howto:Remote Control - WM_COPYDATA for VB.NET

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
Post Reply
neil9090
Posts: 64
Joined: 28 Jun 2014 00:09

Howto:Remote Control - WM_COPYDATA for VB.NET

Post by neil9090 »

Here is some demo code on how to send/control XYplorer from VB.NET

Code: Select all

Imports System.Runtime.InteropServices

Public Class Form1
    ' From XYplorer Help File - Scripting - RemoteControl
    Public Const xyRemoteControlId As Integer = 4194305 ' cds.dwData: 4194305 (0x00400001) 

    ''' <summary>
    ''' Gets the handle of a running XYplorer process
    ''' </summary>
    ''' <value></value>
    ''' <returns>hWnd of XYplorer</returns>
    ''' <remarks>Multiple instance of XYplorer are ignored, i.e. it finds the first windows identified as XYplorer</remarks>
    Public ReadOnly Property XYHandle As Integer
        Get
            Dim hwnd As Integer
            Dim findWindowName As String = Nothing
            Dim findWindowClass As String = "ThunderRT6FormDC"
            'Get a handle for XY Application main window
            hwnd = Win32.FindWindow(findWindowClass, findWindowName)
            Return hwnd
        End Get
    End Property

    ''' <summary>
    ''' Sends string arguments to running instance of XYplorer.
    ''' </summary>
    ''' <param name="args"></param>
    ''' <returns></returns>
    Public Shared Function SendArgs(targetHWnd As IntPtr, args As String, Optional dwData As Integer = 1) As Boolean
        Dim cds As New Win32.CopyDataStruct()
        Try
            ' bring XY to the front, helps if there is an error with sent data
            Win32.SetForegroundWindow(targetHWnd)

            cds.cbData = (args.Length) * 2  ' length of string (no extra chars)
            cds.lpData = Win32.LocalAlloc(&H40, cds.cbData)
            Marshal.Copy(args.ToCharArray(), 0, cds.lpData, args.Length)
            cds.dwData = New IntPtr(dwData)
            ' attempt to send message to instance of XY
            Win32.SendMessage(targetHWnd, Win32.WM_COPYDATA, IntPtr.Zero, cds)
        Finally
            cds.Dispose()
        End Try

        Return True
    End Function

    ''' <summary>
    ''' Button on form used to test sending a message to XYplorer
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnMsgTest_Click(sender As Object, e As EventArgs) Handles btnMsgTest.Click
        Dim xyCommand As String = "msg ""Hello World!"""
        SendArgs(XYHandle, "::" & xyCommand, xyRemoteControlId)
    End Sub
End Class

Public Class Win32
    Public Const WM_COPYDATA As Integer = &H4A

    Public Structure CopyDataStruct
        Implements IDisposable

        Public dwData As IntPtr
        Public cbData As Integer
        Public lpData As IntPtr

        Public Sub Dispose() Implements IDisposable.Dispose
            If Me.lpData <> IntPtr.Zero Then
                LocalFree(Me.lpData)
                Me.lpData = IntPtr.Zero
            End If
        End Sub

    End Structure

    ''' <summary>
    ''' The SendMessage function sends the specified message to a
    ''' window or windows. It calls the window procedure for the specified
    ''' window and does not return until the window procedure
    ''' has processed the message.
    ''' </summary>
    ''' <param name="hWnd">handle to destination window</param>
    ''' <param name="Msg">message</param>
    ''' <param name="wParam">first message parameter</param>
    ''' <param name="lParam">second message parameter</param>
    ''' <returns></returns>
    <DllImport("User32.dll")> _
    Public Shared Function SendMessage(hWnd As Integer, Msg As Integer, wParam As Integer, <MarshalAs(UnmanagedType.LPStr)> lParam As String) As Int32
    End Function

    ''' <summary>
    ''' Send Message
    ''' </summary>
    ''' <param name="hWnd">handle to destination window</param>
    ''' <param name="Msg">message</param>
    ''' <param name="wParam">first message parameter</param>
    ''' <param name="lParam">second message parameter</param>
    ''' <returns></returns>
    <DllImport("User32.dll")> _
    Public Shared Function SendMessage(hWnd As Integer, Msg As Integer, wParam As Integer, lParam As Integer) As Int32
    End Function

    ''' <summary>
    ''' The SendMessage API
    ''' </summary>
    ''' <param name="hWnd">handle to the required window</param>
    ''' <param name="msg">the system/Custom message to send</param>
    ''' <param name="wParam">first message parameter</param>
    ''' <param name="lParam">second message parameter</param>
    ''' <returns></returns>
    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Public Shared Function SendMessage(hWnd As Integer, msg As Integer, wParam As Integer, lParam As IntPtr) As Integer
    End Function

    ''' <summary>
    ''' The SendMessage API
    ''' </summary>
    ''' <param name="hWnd">handle to the required window</param>
    ''' <param name="Msg">the system/Custom message to send</param>
    ''' <param name="wParam">first message parameter</param>
    ''' <param name="lParam">second message parameter</param>
    ''' <returns></returns>
    <DllImport("user32.dll")> _
    Public Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, ByRef lParam As CopyDataStruct) As Integer
    End Function

    <DllImport("kernel32.dll", SetLastError:=True)> _
    Public Shared Function LocalAlloc(flag As Integer, size As Integer) As IntPtr
    End Function

    <DllImport("kernel32.dll", SetLastError:=True)> _
    Public Shared Function LocalFree(p As IntPtr) As IntPtr
    End Function


    ''' <summary>
    ''' The FindWindow function retrieves a handle to the top-level 
    ''' window whose class name and window name match the specified strings.
    ''' This function does not search child windows. This function does not perform a case-sensitive search.
    ''' </summary>
    ''' <param name="strClassName">the class name for the window to search for</param>
    ''' <param name="strWindowName">the name of the window to search for</param>
    ''' <returns></returns>
    <DllImport("User32.dll")> _
    Public Shared Function FindWindow(strClassName As String, strWindowName As String) As Integer
    End Function


    Public Declare Function SetForegroundWindow Lib "user32.dll" _
        Alias "SetForegroundWindow" (ByVal hwnd As Integer) As Integer
End Class

Post Reply