Results 1 to 22 of 22

Thread: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Question [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Ive been struggling with the Win32 api call SendMessage and WM_COPYDATA to send strings to e.g. notepad using VB.NET 2005. Anyone has any sample code to share on how to do this?

    With regards,

    A

  2. #2
    Member
    Join Date
    Feb 2008
    Posts
    44

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Post your code please...

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    This is the current code im working on, its really an atempt to port some VB6 code that is working. The development platform is Vista 64-bit.

    The FindWindowWild(TitleBarSearchName) provides a hWnd to the correct window, this has been verified using Spy++...

    Things i need to consider later on is to assure its unicode being sent so


    Code:
         Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As IntPtr, ByVal wMsg As IntPtr, _
                ByVal wParam As IntPtr, <MarshalAs(UnmanagedType.AnsiBStr)> ByVal lParam As String) As IntPtr
    
            <StructLayout(LayoutKind.Sequential)> _
            Private Structure CopyData
                Public dwData As IntPtr
                Public cbData As Integer
                Public lpData As IntPtr
            End Structure
    
            Public Sub SendToApplication(ByVal TitleBarSearchName As String, ByVal strMessage As String)
    
                Dim data As CopyData
    
                ' set up the data...
                data.lpData = Marshal.StringToHGlobalAuto(strMessage)
                data.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
    
                ' send the data
                SendMessage(FindWindowWild(TitleBarSearchName), WM_COPYDATA, IntPtr.Zero, data)
    
                ' free the pointer...
                Marshal.FreeHGlobal(data.lpData)
      
                SendMessage(FindWindowWild(TitleBarSearchName), New IntPtr(WM_COPYDATA), IntPtr.Zero, strMessage)
    
            End Sub

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Oh and here is another version im trying in parallell with..

    VB Code:
    1. Imports System
    2. Imports System.Collections.Generic
    3. Imports System.ComponentModel
    4. Imports System.Data
    5. Imports System.Drawing
    6. Imports System.Text
    7. Imports System.Windows.Forms
    8. Imports System.Runtime.InteropServices
    9.  
    10. Namespace Core.Utils
    11.     Public Structure COPYDATASTRUCT
    12.         Public dwData As Integer
    13.         Public cbData As Integer
    14.         Public lpData As IntPtr
    15.     End Structure
    16.  
    17.     Public Class cMsgStrings
    18.         Const LMEM_FIXED As Integer = 0
    19.         Const LMEM_ZEROINIT As Integer = 64
    20.         Const LPTR As Integer = (LMEM_FIXED Or LMEM_ZEROINIT)
    21.         Const WM_COPYDATA As Integer = 74
    22.  
    23.  
    24.         <DllImport("kernel32.dll")> _
    25.         Public Shared Function LocalAlloc(ByVal flag As Integer, ByVal size As Integer) As IntPtr
    26.         End Function
    27.         <DllImport("kernel32.dll")> _
    28.         Public Shared Function LocalFree(ByVal p As IntPtr) As IntPtr
    29.         End Function
    30.         <DllImport("user32.dll")> _
    31.         Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    32.         End Function
    33.  
    34.         'Create wrappers for the memory API's similar to
    35.         'Marshal.AllocHGlobal and Marshal.FreeHGlobal
    36.  
    37.         Public Shared Function AllocHGlobal(ByVal cb As Integer) As IntPtr
    38.             Dim hMemory As New IntPtr()
    39.             hMemory = LocalAlloc(LPTR, cb)
    40.             Return hMemory
    41.         End Function
    42.  
    43.         Public Shared Sub FreeHGlobal(ByVal hMemory As IntPtr)
    44.             If hMemory <> IntPtr.Zero Then
    45.                 LocalFree(hMemory)
    46.             End If
    47.         End Sub
    48.  
    49.         Public Shared Sub SendMsgString(ByVal hWndDest As IntPtr, ByVal sScript As String)
    50.             Dim oCDS As New COPYDATASTRUCT()
    51.             Dim status As String
    52.  
    53.             oCDS.cbData = (sScript.Length + 1) * 2
    54.             oCDS.lpData = LocalAlloc(64, oCDS.cbData)
    55.             Marshal.Copy(sScript.ToCharArray(), 0, oCDS.lpData, sScript.Length)
    56.             oCDS.dwData = 1
    57.             Dim lParam As IntPtr = AllocHGlobal(oCDS.cbData)
    58.             Marshal.StructureToPtr(oCDS, lParam, False)
    59.             status = SendMessage(hWndDest, WM_COPYDATA, IntPtr.Zero, lParam)
    60.             MsgBox(Hex(hWndDest))
    61.             LocalFree(oCDS.lpData)
    62.             FreeHGlobal(lParam)
    63.         End Sub
    64.  
    65.         Public Shared Function GetMsgString(ByVal lParam As IntPtr) As String
    66.             Dim st As COPYDATASTRUCT = DirectCast(Marshal.PtrToStructure(lParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
    67.             Dim str As String = Marshal.PtrToStringUni(st.lpData)
    68.             Return str
    69.         End Function
    70.     End Class
    71. End Namespace

  5. #5
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    How about the VB 6 Code?
    VB 2005, Win Xp Pro sp2

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Ok same goes here... FindWindowWild(TitleBarSearchName, False) provides the hWnd. This code works like a charm in all environments, its VB6 code. Compiled in VB6 this works on Vista too and does the trick.

    vb Code:
    1. Public Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    2.  
    3. Public Const WM_COPYDATA = &H4A
    4.  
    5.  
    6. Type COPYDATASTRUCT
    7.   dwData As Long
    8.   cbData As Long
    9.   lpData As Long
    10. End Type
    11.  
    12. Public Sub SendToApplication(strMessage As String)
    13.   Dim DataStruct As COPYDATASTRUCT
    14.   Dim strInternal As String
    15.   strInternal = strMessage & vbCr
    16.  
    17.   DataStruct.dwData = 1
    18.   DataStruct.lpData = StrPtr(strInternal)
    19.   DataStruct.cbData = (LenB(strInternal) + 2)
    20.  
    21.   result = SendMessage(FindWindowWild(TitleBarSearchName, False), WM_COPYDATA, 0, DataStruct)
    22. End Sub

  7. #7
    Member
    Join Date
    Feb 2008
    Posts
    44

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    what is FindWindowWild?

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    This function searches for a Window caption and returns a hwnd.

  9. #9
    Member
    Join Date
    Feb 2008
    Posts
    44

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    http://forums.microsoft.com/MSDN/Sho...09916&SiteID=1

    I think this link is going to help...

  10. #10

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Nope, already tried this code but without success...

  11. #11
    Member
    Join Date
    Feb 2008
    Posts
    44

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    I was able to get some unprintable binary garbage into notepad using this code:

    Code:
    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        Private Const WM_COPYDATA As Integer = &H4A
        Private Const WM_SETTEXT = &HC
        Private Const WM_USER As Integer = &H400
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure COPYDATASTRUCT
            Public dwData As Integer
            Public cbData As Integer
            Public lpData As String
        End Structure
    
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function FindWindow( _
             ByVal lpClassName As String, _
             ByVal lpWindowName As String) As IntPtr
        End Function
    
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
        Private Shared Function SendMessage( _
             ByVal hWnd As HandleRef, _
             ByVal Msg As UInteger, _
             ByVal wParam As IntPtr, _
             ByRef lParam As String) As IntPtr
        End Function
    
        Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
    
        Public Sub SendToApplication(ByVal TitleBarSearchName As String, ByVal strMessage As String)
            Dim cds As COPYDATASTRUCT
    
            Dim SnapHandle As IntPtr = FindWindow(TitleBarSearchName, vbNullString)
            Me.Text = SnapHandle.ToInt32.ToString
            If Not SnapHandle = 0 Then
                Dim href As New HandleRef(Me, SnapHandle)
                Dim SnapHandle2 As IntPtr = FindWindowEx(SnapHandle, 0&, "edit", vbNullString)
                Me.Text = SnapHandle.ToInt32.ToString
                If Not SnapHandle2 = 0 Then
                    Dim href2 As New HandleRef(Me, SnapHandle2)
                    cds.lpData = strMessage
                    cds.cbData = cds.lpData.Length + 1
                    Dim I As IntPtr = SendMessage(href2, WM_SETTEXT, 0&, cds.lpData)
                End If
            End If
            GC.KeepAlive(Me)
    
        End Sub
    
        Private Sub sndButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles sndButton.Click
            SendToApplication(Me.searchTxtBox.Text, Me.msgTxtBox.Text)
        End Sub
    End Class

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Yes, but you are using WM_SETTEXT rather than WM_COPYDATA in your code.

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    The code is a bit of a mess but, its hours of trail and error...

    Ive used a similar approach to set or change the Notepad title window caption with WM_SETTEXT... but the end application requires and listens to a WM_COPYDATA. Ive included what i got so far... It contains a lot of junk code an unused sections... Just cant seem to figure this out.

    vb Code:
    1. Option Strict Off
    2. Imports System.Environment
    3. Imports System.Runtime.InteropServices
    4.  
    5.     Module Core
    6.  
    7.         Private Delegate Function CallBack(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
    8.         Private Declare Function EnumWindows Lib "User32" (ByVal lpEnumFunc As CallBack, ByVal lParam As Integer) As Integer
    9.         Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String, ByVal cch As Integer) As Integer
    10.         Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Integer) As Boolean
    11.         Private Declare Function GetParent Lib "user32" (ByVal hwnd As Integer) As Integer
    12.  
    13.         Private Declare Function LocalAlloc Lib "Kernel32" (ByVal uFlags As Integer, ByVal uBytes As Integer) As IntPtr
    14.         Private Declare Function LocalFree Lib "Kernel32" (ByVal hMem As IntPtr) As IntPtr
    15.         '      Private Declare Auto Function SendMessage Lib "User32" (ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As COPYDATASTRUCT) As Integer
    16.         '        Private Declare Auto Function SendMessage Lib "User32" (ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    17.         '       Private Declare Auto Function SendMessage Lib "User32" (ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
    18.         Private Declare Auto Function SendMessageA Lib "user32" (ByVal hwnd As IntPtr, ByVal wMsg As IntPtr, _
    19.             ByVal wParam As IntPtr, <MarshalAs(UnmanagedType.AnsiBStr)> ByVal lParam As String) As IntPtr
    20.  
    21.         Private Declare Auto Function SendMessage Lib "user32" _
    22.             (ByVal hWnd As IntPtr, _
    23.              ByVal Msg As Integer, _
    24.              ByVal wParam As IntPtr, _
    25.              ByRef lParam As CopyData) As Boolean
    26.  
    27.  
    28.         '###############################
    29.         '#      win32api constants     #
    30.         '###############################
    31.         Public Const WM_COPYDATA As Integer = &H4A
    32.         Public Const WM_KEYDOWN As Integer = &H100
    33.         Public Const WM_KEYUP As Integer = &H101
    34.         Public Const WM_GETTEXT As Integer = &HD
    35.         Public Const WM_KILLFOCUS As Integer = &H8
    36.         Public Const WM_SETFOCUS As Integer = &H7
    37.         Public Const WM_NCHITTEST As Integer = &H84
    38.         Public Const WM_PAINT As Integer = &HF
    39.         Public Const WM_ACTIVATE As Integer = &H6
    40.         Public Const WM_NCACTIVATE As Integer = &H86
    41.         Public Const WM_SETCURSOR As Integer = &H20
    42.         Public Const WM_COMMAND As Integer = &H111
    43.         Public Const WM_MENUSELECT As Integer = &H11F
    44.         Public Const WM_SETTEXT = 12
    45.         Public Const GW_CHILD As Integer = 5
    46.         Public Const GW_HWNDFIRST As Integer = 0
    47.         Public Const GW_HWNDLAST As Integer = 1
    48.         Public Const GW_HWNDNEXT As Integer = 2
    49.         Public Const GW_HWNDPREV As Integer = 3
    50.  
    51.  
    52.         <StructLayout(LayoutKind.Sequential)> _
    53.         Private Structure CopyData
    54.             Public dwData As IntPtr
    55.             Public cbData As Integer
    56.             Public lpData As IntPtr
    57.         End Structure
    58.  
    59.  
    60.         Public Event WndH(ByVal hWnd As Integer)
    61.         Dim sPattern As String
    62.         Dim hFind As Integer
    63.         Dim mMatchCase As Boolean = True
    64.  
    65.         Public Function VarPtr(ByVal o As Object) As Integer
    66.             Dim GC As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(o, System.Runtime.InteropServices.GCHandleType.Pinned)
    67.             Dim ret As Integer = GC.AddrOfPinnedObject.ToInt32
    68.  
    69.             GC.Free()
    70.             Return ret
    71.         End Function
    72.  
    73.         Private Function returnHwnd(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
    74.             RaiseEvent WndH(hwnd)
    75.             Dim k As Long, sName As String
    76.             If IsWindowVisible(hwnd) Then
    77.                 sName = Space$(128)
    78.                 k = GetWindowText(hwnd, sName, 128)
    79.                 If k > 0 Then
    80.                     sName = Left$(sName, CInt(k))
    81.                     If Not mMatchCase Then sName = sName.ToUpper()
    82.                     If sName Like sPattern Then
    83.                         hFind = hwnd
    84.                         Return False
    85.                         Exit Function
    86.                     End If
    87.                 End If
    88.             End If
    89.             Return True
    90.         End Function
    91.  
    92.         Public Sub GetWindows()
    93.             Call EnumWindows(AddressOf returnHwnd, 0)
    94.         End Sub
    95.  
    96.         Public Function FindWindowWild(ByVal sWild As String, Optional ByVal bMatchCase As Boolean = True) As Long
    97.             mMatchCase = bMatchCase
    98.             On Error Resume Next
    99.             sPattern = sWild
    100.             hFind = 0
    101.             If Not bMatchCase Then sPattern = UCase(sPattern)
    102.             Call GetWindows()
    103.             Return hFind
    104.         End Function
    105.  
    106.         ' Currently not working!
    107.         Public Sub SendToCommandPrompt(ByVal TitleBarSearchName As String, ByVal strMessage As String)
    108.  
    109.             Dim data As CopyData
    110.  
    111.             ' set up the data...
    112.             data.lpData = Marshal.StringToHGlobalAuto(strMessage)
    113.             data.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
    114.  
    115.             ' send the data
    116.             SendMessage(FindWindowWild(TitleBarSearchName), WM_COPYDATA, IntPtr.Zero, data)
    117.  
    118.             ' free the pointer...
    119.             Marshal.FreeHGlobal(data.lpData)
    120.  
    121.             SendMessageA(FindWindowWild(TitleBarSearchName), New IntPtr(WM_COPYDATA), IntPtr.Zero, strMessage)
    122.  
    123.         End Sub
    124.      
    125.     End Module

  14. #14
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Are you sure your parameters are correct (Notepad is waiting for 1 as dwData etc)? The Message returns false no matter what I try and I tried ways that are supposed to work.

    Here is a C# example that uses WM_COPYDATA. It sends the message but Notepad returns False.

    Another code I changed to work with Notepad fails too:
    Code:
        Dim notepadHWND As IntPtr
        Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
                (ByVal ClassName As String, ByVal WindowName As String) As IntPtr
    
    
        Private Declare Auto Function SendMessage Lib "user32" ( _
                 ByVal hwnd As IntPtr, _
                 ByVal wMsg As Integer, _
                 ByVal wParam As Integer, _
                 ByRef lParam As COPYDATASTRUCT _
                 ) As Integer
    
    
        <System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)> _
            Private Structure COPYDATASTRUCT
            Public dwData As Integer
            Public cbData As Integer
            Public lpData As IntPtr
        End Structure
    
        Private Const WM_COPYDATA As Integer = &H4A
    
    
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    
            'get the handle of Notepad's window
            notepadHWND = FindWindow("Notepad", "z123.txt - Notepad")
    
            Send("HI")
    
        End Sub
    
    
        Public Function Send(ByVal obj As Object) As Integer
    
            ' Try to do a binary serialization on obj.
            ' This will throw and exception if the object to
            ' be passed isn't serializable.
            ' Try to do a binary serialization on obj.
            ' This will throw and exception if the object to
            ' be passed isn't serializable.
            Dim b As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter = _
            New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
    
            Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream()
            b.Serialize(stream, obj)
            stream.Flush()
    
            ' Now move the data into a pointer so we can send
            ' it using WM_COPYDATA:
            ' Get the length of the data:
            Dim dataSize As Integer = CInt(stream.Length)
    
            If (dataSize > 0) Then
                ' This isn't very efficient if your data is very large.
                ' First we copy to a byte array, then copy to a CoTask 
                ' Mem object... And when we use WM_COPYDATA windows will
                ' make yet another copy!  But if you're talking about 4K
                ' or less of data then it doesn't really matter.
                Dim data(dataSize) As Byte
                stream.Seek(0, System.IO.SeekOrigin.Begin)
                stream.Read(data, 0, dataSize)
    
                Dim ptrData As IntPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(dataSize)
                System.Runtime.InteropServices.Marshal.Copy(data, 0, ptrData, dataSize)
    
    
                Dim cds As COPYDATASTRUCT = New COPYDATASTRUCT()
                cds.cbData = dataSize
                cds.dwData = 1
                cds.lpData = ptrData
    
                Dim res As Integer = SendMessage(notepadHWND, WM_COPYDATA, Me.Handle.ToInt32(), cds)
    
                ' Clear up the data:
                System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptrData)
    
            End If
    
            stream.Close()
    
        End Function
    VB 2005, Win Xp Pro sp2

  15. #15

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Well actually im trying to send to AutoCAD. Ive made some sort of successful atempts today although it just sends gibberish characters and im assuming its a unicode problem... Its just that my old VB6 code allows me to send to Notepad without a problem.

    I get this below when sending msg = "asdf" as a string.

    >Unknown command "F獡晤". Press F1 for help.
    >Command: f獡晤
    >Unknown command "F獡晤". Press F1 for help.
    >Command: f獡晤

    Cant believe this.

    /A

  16. #16

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Currently im playing with the code similar to below, which atleast sends something to AutoCAD - but as i mentioned, incorrect characters.

    vb Code:
    1. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    2.     Public Shared Function SendMessage( _
    3.         ByVal hwnd As IntPtr, _
    4.         ByVal wMsg As IntPtr, _
    5.         ByVal wParam As Long, _
    6.         ByRef lParam As COPYDATASTRUCT) As IntPtr
    7.     End Function
    8.     '<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    9.  
    10.     Structure COPYDATASTRUCT
    11.         Dim dwData As Integer
    12.         Dim cbData As IntPtr
    13.         Dim lpData As String
    14.     End Structure
    15.  
    16.     Public Sub SendToCommandPrompt(ByVal strMessage As String)
    17.  
    18.         Dim DataStruct As COPYDATASTRUCT
    19.         DataStruct.dwData = 1
    20.         'DataStruct.cbData = Len(strMessage) * 2
    21.         DataStruct.cbData = Encoding.Unicode.GetByteCount(strMessage)
    22.         DataStruct.lpData = Encoding.Unicode.GetString(Encoding.ASCII.GetBytes(strMessage))
    23.         SendMessage(FindWindowWild("*AutoCAD*"), WM_COPYDATA, 0, DataStruct)
    24.  
    25.     End Sub
    26.  
    27.     Declare Function SendMessageUU Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As COPYDATASTRUCT) As Long
    28.  
    29.     Private Sub SendToCommandPrompt2(ByVal strMessage As String)
    30.         Dim DataStruct As COPYDATASTRUCT
    31.         DataStruct.dwData = 1
    32.         DataStruct.lpData = strMessage
    33.         DataStruct.cbData = (Encoding.Unicode.GetByteCount(strMessage) + 1)
    34.         SendMessageUU(FindWindowWild("*AutoCAD*"), WM_COPYDATA, 0, DataStruct)
    35.     End Sub

  17. #17
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    If it sends something, then it is working
    Try Encoding.Default here and there instead of ASCII & Unicode.
    VB 2005, Win Xp Pro sp2

  18. #18

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Ill give it a try, problem is finding the correct value for .cbData

    DataStruct.cbData = (Encoding.Unicode.GetByteCount(strMessage) + 1)

    and also, the behavior can be kinda sluggish.. i.e. it doesnt work 10 time out of 10, but maybe 8-9 times out of 10.

    /A

  19. #19

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    The Code below does the best job in sending data to my application, however im having issues determining the size of the string and again, everything gets screambled into Chineese unicode characters.

    VB Code:
    1. Declare Function SendMessage Lib "user32" Alias "SendMessageW" _
    2.  (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
    3.     ByRef lParam As COPYDATASTRUCT) As Long    
    4.  
    5.     Structure COPYDATASTRUCT
    6.         Dim dwData As Long
    7.         Dim cbData As Long
    8.         Dim lpData As String
    9.     End Structure
    10.  
    11.     Public Sub SendToCommandPrompt(ByVal strMessage As String)
    12.         Dim DataStruct As COPYDATASTRUCT
    13.         DataStruct.dwData = 1
    14.         DataStruct.lpData = strMessage
    15.         DataStruct.cbData = Marshal.SizeOf(DataStruct)
    16.  
    17.         Dim ByteArray() As Byte
    18.         Dim Ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(DataStruct))
    19.         ReDim ByteArray(Marshal.SizeOf(DataStruct) + 1)
    20.         'now copy strcutre to Ptr pointer
    21.  
    22.         Marshal.StructureToPtr(DataStruct, Ptr, False)
    23.         Marshal.Copy(Ptr, ByteArray, 0, Marshal.SizeOf(DataStruct))
    24.         'now use ByteArray ready for use
    25.         Marshal.FreeHGlobal(Ptr)
    26.  
    27.         SendMessage(hwnd_autocad, WM_COPYDATA, 0, DataStruct)
    28.  
    29.     End Sub

  20. #20
    Addicted Member
    Join Date
    Mar 2008
    Posts
    143

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    How about...
    vb.net Code:
    1. Dim DataStruct As New COPYDATASTRUCT
    2. strMessage = strMessage & Chr(0) 'Null terminated
    3.  
    4. DataStruct.dwData = 0
    5. DataStruct.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
    6. DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)
    7.  
    8. SendMessage(hwnd_autocad, WM_COPYDATA, 0, DataStruct)
    9. Marshal.FreeCoTaskMem(DataStruct.lpData)


    ------------------------------------------------------------------------------------------
    C# sample below is what I use for SendMessage

    [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    internal static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);

    internal struct COPYDATASTRUCT : IDisposable
    {
    public int dwData;
    public int cbData;
    public IntPtr lpData;

    public void Dispose()
    {
    lpData = IntPtr.Zero;
    }
    }

    COPYDATASTRUCT cds = new COPYDATASTRUCT();
    string data = strMessage + "\0";
    cds.cbData = data.Length * Marshal.SystemDefaultCharSize;
    cds.lpData = Marshal.StringToCoTaskMemAuto(data);

    SendMessage(hwnd_autocad, WM_COPYDATA, IntPtr.Zero, ref cds);
    Marshal.FreeCoTaskMem(cds.lpData);
    cds.Dispose();
    Last edited by michaelerice; Mar 10th, 2008 at 01:42 PM.

  21. #21

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Holy Cow! A problem i believed to be unsolvable is now solved...

    With your suggestion plus changing below actually did the trick!

    Code:
            DataStruct.dwData = 1

    Your the man! Im eternally greatful!

  22. #22

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    18

    Re: [2005] Using SendMessage with WM_COPYDATA to send strings to e.g. notepad

    Code:
    Just posting the finished working code as i got it.. 
    
        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 SendToCommandPrompt(ByVal strMessage As String)
    
            Dim DataStruct As New COPYDATASTRUCT
            strMessage = strMessage & Chr(0) 'Null terminated
    
            DataStruct.dwData = 1
            DataStruct.cbData = strMessage.Length * Marshal.SystemDefaultCharSize
            DataStruct.lpData = Marshal.StringToCoTaskMemAuto(strMessage)
    
            SendMessage(hwnd_autocad, WM_COPYDATA, 0, DataStruct)
            Marshal.FreeCoTaskMem(DataStruct.lpData)
    
        End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width