Results 1 to 13 of 13

Thread: Passing strings between different apps **RESOLVED**

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288

    Passing strings between different apps **RESOLVED**

    How do I send a string as a message between two apps using SendMessage or PostMessage?
    This is the code I have, but it doesn't work, since I think I will have to use WM_COPYDATA with SendMessage, as suggested by MerrionComputin.
    'In the first project
    VB Code:
    1. 'in a form with a command button
    2. Private Sub Form_Load()
    3.     Me.Caption = "Test Target Window"
    4.     Command1.Caption = "Test_Target_Button"
    5.     'subclass the command button
    6.     lngPrevWndProc = SetWindowLong(Command1.hWnd, GWL_WNDPROC, AddressOf WindowProc)
    7. End Sub
    8.  
    9. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    10.     'set it back to normal before exiting
    11.     SetWindowLong Command1.hWnd, GWL_WNDPROC, lngPrevWndProc
    12. End Sub
    13.  
    14. '=====================
    15. 'in a module
    16. Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    17.  
    18. Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    19.  
    20. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    21. '\\ Pointer validation in StringFromPointer
    22. Private Declare Function IsBadStringPtrByLong Lib "kernel32" Alias "IsBadStringPtrA" (ByVal lpsz As Long, ByVal ucchMax As Long) As Long
    23.  
    24.  
    25. Public Const GWL_WNDPROC = (-4)
    26.  
    27. Public lngPrevWndProc As Long
    28. Public Const WM_USER = &H400
    29. Public Const MY_MSG = WM_USER + 100
    30.  
    31. Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    32.     Select Case uMsg
    33.         Case MY_MSG
    34.             MsgBox StringFromPointer(lParam, 12)
    35.             'what to do here
    36.             'lParam returns a pointer, how do I get the string
    37.         Case Else
    38.             WindowProc = CallWindowProc(lngPrevWndProc, hWnd, uMsg, wParam, lParam)
    39.     End Select
    40. End Function
    41.  
    42. Public Function StringFromPointer(lpString As Long, lMaxLength As Long) As String
    43.  
    44.   Dim sRet As String
    45.   Dim lret As Long
    46.  
    47.   If lpString = 0 Then
    48.     StringFromPointer = ""
    49.     Exit Function
    50.   End If
    51.  
    52.   If IsBadStringPtrByLong(lpString, lMaxLength) Then
    53.     '\\ An error has occured - do not attempt to use this pointer
    54.       StringFromPointer = ""
    55.     Exit Function
    56.   End If
    57.  
    58.   '\\ Pre-initialise the return string...
    59.   sRet = Space$(lMaxLength)
    60.   CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet)
    61.   If Err.LastDllError = 0 Then
    62.     If InStr(sRet, Chr$(0)) > 0 Then sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1)
    63.   End If
    64.  
    65.  
    66.   StringFromPointer = sRet
    67.  
    68. End Function

    In the second project:
    VB Code:
    1. 'in a form with a command button
    2. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
    3. (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As String) As Long
    4.  
    5. Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, _
    6. ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    7.  
    8. Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
    9. (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    10.  
    11. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    12. (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    13.  
    14. Private Const WM_USER = &H400
    15. Private Const MY_MSG = WM_USER + 100
    16.  
    17. Private Sub Command1_Click()
    18. Dim lngFrmHwnd As Long
    19. Dim lngBtnHwnd As Long
    20.     lngFrmHwnd = FindWindow(vbNullString, "Test Target Window")
    21.     lngBtnHwnd = FindWindowEx(lngFrmHwnd, 0&, vbNullString, "Test_Target_Button")
    22.     SendMessage lngBtnHwnd, MY_MSG, 0&, "hello world"
    23.    
    24. End Sub

    I am also attaching the code.

    Thanks
    Amitabh Kant
    Attached Files Attached Files
    Last edited by amitabh; Oct 29th, 2002 at 02:22 PM.

  2. #2
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    #1. Sending the string:

    VB Code:
    1. Option Explicit
    2.  
    3. Private Type COPYDATASTRUCT
    4.     dwData As Long
    5.     cbData As Long
    6.     lpData As Long
    7. End Type
    8. Private Const WM_COPYDATA = &H4A
    9. Private Const MCL_COPYSTRING = &HE
    10.  
    11. Private Declare Function SendString Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As COPYDATASTRUCT) As Long
    12.  
    13.  
    14. Public Function SendStringCrossTask(ByVal TargetWnd As Long, ByVal smessage As String)
    15.  
    16. Dim cpThis As COPYDATASTRUCT
    17.  
    18. Dim sAnsiString As String
    19.  
    20. sAnsiString = StrConv(smessage, vbFromUnicode)
    21.  
    22. With cpThis
    23.     .dwData = MCL_COPYSTRING
    24.     .cbData = LenB(sAnsiString)
    25.     .lpData = StrPtr(sAnsiString)
    26. End With
    27.  
    28. If SendString(TargetWnd, WM_COPYDATA, Me.hwnd, cpThis) Then
    29.     '\\ target window accepted and processed the data
    30. Else
    31.     '\\ target window did not accept the data
    32. End If
    33.  
    34. End Function

    ::EDITTED FOR ANSI / UNICODE CHANGES ::
    Last edited by MerrionComputin; Oct 29th, 2002 at 09:48 AM.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    To think of it, I can use WM_SETTEXT messsage and then look for the same in the Window proc. But still, I would rather like to have a self-defined message to be sent, with the string as a parameter if its possible.

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    A big thanks.
    Didn't see that you had already replied to the thread. I will just test it out in my app.

  5. #5
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    #2 - recieving the string
    Subclass the recieving window and put the following as a replacement for it's windowproc:
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    4. Private Type COPYDATASTRUCT
    5.     dwData As Long
    6.     cbData As Long
    7.     lpData As Long
    8. End Type
    9. Private Const WM_COPYDATA = &H4A
    10. Private Const MCL_COPYSTRING = &HE
    11.  
    12. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    13. Private Declare Sub CopyMemoryCopyDataStruct Lib "kernel32" Alias "RtlMoveMemory" (Destination As COPYDATASTRUCT, ByVal Source As Long, ByVal Length As Long)
    14.  
    15. Private mhOldWndproc As Long
    16.  
    17. Public Function VBWndproc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    18.  
    19. If Msg = WM_COPYDATA Then
    20.     Dim cpThis As COPYDATASTRUCT
    21.     Call CopyMemoryCopyDataStruct(cpThis, lParam, Len(cpThis))
    22.     If cpThis.dwData = MCL_COPYSTRING Then
    23.         Dim smessage As String
    24.         smessage = StringFromPointer(cpThis.lpData, cpThis.cbData)
    25.         Debug.Print smessage
    26.         '\\ tell other window we processed this message
    27.         VBWndproc = 1
    28.     Else
    29.         '\\ pass message on for standard processing
    30.         VBWndproc = CallWindowProc(mhOldWndproc, hWnd, Msg, wParam, lParam)
    31.     End If
    32. Else
    33.     '\\ pass message on for standard processing
    34.     VBWndproc = CallWindowProc(mhOldWndproc, hWnd, Msg, wParam, lParam)
    35. End If
    36.  
    37. End Function
    38.  
    39. Public Function StringFromPointer(lpString As Long, lMaxLength As Long) As String
    40.  
    41.   Dim sRet As String
    42.   Dim lret As Long
    43.  
    44.   If lpString = 0 Then
    45.     StringFromPointer = ""
    46.     Exit Function
    47.   End If
    48.  
    49.   If IsBadStringPtrByLong(lpString, lMaxLength) Then
    50.     '\\ An error has occured - do not attempt to use this pointer
    51.       StringFromPointer = ""
    52.     Exit Function
    53.   End If
    54.  
    55.   '\\ Pre-initialise the return string...
    56.   sRet = Space$(lMaxLength)
    57.   CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet)
    58.   If Err.LastDllError = 0 Then
    59.     If InStr(sRet, Chr$(0)) > 0 Then sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1)
    60.   End If
    61.  
    62.  
    63.   StringFromPointer = sRet
    64.  
    65. End Function

    Hope this helps,
    Duncan
    Last edited by MerrionComputin; Oct 29th, 2002 at 12:13 PM.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    BTW, what to do in the WindowProc of the subcalssed APP. I am currently looking out for WM_COPYDATA, then using the StringFromPointer function given by you earlier. But this is returning failure in the calling app and the data too is not available.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    I am really sorry. I didn't knew that you were in the process of replying to me. . Get back to you in minute.

  8. #8
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    Both posts editted to deal with ANSI/Unicode issues...
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    Merrion
    I have having problems with the code. It is not letting me even subclass the button. I know I must be doing something wrong, but I am not able to pin point it out. Can you take a look at the code, and tell me where am I going wrong. The subclassing line is working properly, but the app terminates when it goes ot the VBWndProc.
    VB Code:
    1. 'form code
    2. Private Sub Form_Load()
    3.     Me.Caption = "Test Target Window"
    4.     Command1.Caption = "Test_Target_Button"
    5.     'subclass the command button
    6.     'lngPrevWndProc = SetWindowLong(Command1.hWnd, GWL_WNDPROC, AddressOf VBWndproc)
    7.     mhOldWndproc = SetWindowLong(Command1.hWnd, GWL_WNDPROC, AddressOf VBWndproc)
    8. End Sub
    9.  
    10. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    11.     'set it back to normal before exiting
    12.     SetWindowLong Command1.hWnd, GWL_WNDPROC, mhOldWndproc
    13. End Sub
    14.  
    15. 'module code
    16. Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
    17. (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    18.  
    19. Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    20. Private Type COPYDATASTRUCT
    21.     dwData As Long
    22.     cbData As Long
    23.     lpData As Long
    24. End Type
    25. Private Const WM_COPYDATA = &H4A
    26. Private Const MCL_COPYSTRING = &HE
    27. Public Const GWL_WNDPROC = (-4)
    28.  
    29. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    30. Private Declare Sub CopyMemoryCopyDataStruct Lib "kernel32" Alias "RtlMoveMemory" (Destination As COPYDATASTRUCT, ByVal Source As Long, ByVal Length As Long)
    31.  
    32. Public mhOldWndproc As Long
    33.  
    34. Public Function VBWndproc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    35.  
    36. If Msg = WM_COPYDATA Then
    37.     Dim cpThis As COPYDATASTRUCT
    38.     Call CopyMemoryCopyDataStruct(cpThis, lParam, Len(cpThis))
    39.     If cpThis.dwData = MCL_COPYSTRING Then
    40.         Dim smessage As String
    41.         smessage = StringFromPointer(cpThis.lpData, cpThis.cbData)
    42.         Debug.Print smessage
    43.         '\\ tell other window we processed this message
    44.         VBWndproc = 1
    45.     Else
    46.         '\\ pass message on for standard processing
    47.         VBWndproc = CallWindowProc(mhOldWndproc, hWnd, wMsg, wParam, lParam)
    48.     End If
    49. Else
    50.     '\\ pass message on for standard processing
    51.     VBWndproc = CallWindowProc(mhOldWndproc, hWnd, wMsg, wParam, lParam)
    52. End If
    53.  
    54. End Function
    55.  
    56. Public Function StringFromPointer(lpString As Long, lMaxLength As Long) As String
    57.  
    58.   Dim sRet As String
    59.   Dim lret As Long
    60.  
    61.   If lpString = 0 Then
    62.     StringFromPointer = ""
    63.     Exit Function
    64.   End If
    65.  
    66.   If IsBadStringPtrByLong(lpString, lMaxLength) Then
    67.     '\\ An error has occured - do not attempt to use this pointer
    68.       StringFromPointer = ""
    69.     Exit Function
    70.   End If
    71.  
    72.   '\\ Pre-initialise the return string...
    73.   sRet = Space$(lMaxLength)
    74.   CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet)
    75.   If Err.LastDllError = 0 Then
    76.     If InStr(sRet, Chr$(0)) > 0 Then sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1)
    77.   End If
    78.  
    79.  
    80.   StringFromPointer = sRet
    81.  
    82. End Function

  10. #10
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849

    Re: Passing strings between different apps

    Originally posted by amitabh
    How do I send a string as a message between two apps using SendMessage or PostMessage?
    Can this help?
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  11. #11
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    My Typo

    VB Code:
    1. VBWndproc = CallWindowProc(mhOldWndproc, hWnd, wMsg, wParam, lParam)

    Should be
    VB Code:
    1. VBWndproc = CallWindowProc(mhOldWndproc, hWnd, Msg, wParam, lParam)
    as wMsg is an undefined variable...
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    Merrion
    No, it's my mistake. I should have noticed it immediately. A simple missing parameter question .I must have gone mad these days.

    KayJay
    It's a nice code. Never gave a thought that Interprocess communications could aslo be used to solve my problems.

    Thank you both.

  13. #13
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    UR Welcome

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

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