Results 1 to 24 of 24

Thread: Sending messages between VB-created apps

  1. #1

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Sending messages between VB-created apps

    Supposing I have made an app, or several apps, in VB.
    I want send a message to one app from the other one, or from one instance to another. What are the methods I can use, apart from DDE?

  2. #2
    Giants World Champs!!!! Mark Gambo's Avatar
    Join Date
    Sep 2003
    Location
    Colorado
    Posts
    2,965

    Re: Sending messages between VB-created apps

    I found this application on VBForums, it uses winsock connection


    Play around with it
    Attached Files Attached Files
    Regards,

    Mark

    Please remember to rate posts! Rate any post you find helpful. Use the link to the left - "Rate this Post". Please use [highlight='vb'] your code goes in here [/highlight] tags when posting code. When a question you asked has been resolved, please go to the top of the original post and click "Thread Tools" then select "Mark Thread Resolved."


  3. #3

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    OK thanks, that works. So thats one method. But Winsock is a pretty inefficient method unless you are sending messages to a different computer, which I'm not.

    I'm looking for something more like a API call or similar. Any ideas?

  4. #4
    Frenzied Member David.Poundall's Avatar
    Join Date
    Sep 2002
    Location
    Robin Hood Land
    Posts
    1,457

    Re: Sending messages between VB-created apps

    Why not use a shared registry area.
    David

    Learn the Rules so that you know how to break them properly.

    Printing dll dBTools MZTools Winsock API WinsockVB More Winsock SGrid2 MSChart Mail2Web

    If you have found this thread useful then read this

  5. #5

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    Quote Originally Posted by David.Poundall
    Why not use a shared registry area.
    Because then I would need notifications sent to all apps when the registry was updated. Which brings me back to my original problem.

  6. #6
    Frenzied Member David.Poundall's Avatar
    Join Date
    Sep 2002
    Location
    Robin Hood Land
    Posts
    1,457

    Re: Sending messages between VB-created apps

    So how fast do you want it to be ? Game speed or real time ?
    David

    Learn the Rules so that you know how to break them properly.

    Printing dll dBTools MZTools Winsock API WinsockVB More Winsock SGrid2 MSChart Mail2Web

    If you have found this thread useful then read this

  7. #7
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    Re: Sending messages between VB-created apps

    What type of message are you looking to send?

  8. #8

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    A message from one instance/app telling the other to execute a command.
    For example, "Open a New Window", or "Close Now" or similar. It needs to be immediate, like the SendMessage API. I was wondering if there was a way to use that, but not sure where to start.

  9. #9
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    Re: Sending messages between VB-created apps

    Manipulating another window is fairly simple, using FindWindow and PostMessage and/or SendMessage. If you could give me some specific examples of what you want, I'll whip something together that should, at the very least, get you started.

  10. #10

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    Here is an scenario where I need it:

    User opens my app (web browser).

    User then manages to open it again, possibly by opening a .url link file or somehow doing some form of ShellExecute. I then want the 2nd instance to send the 1st instance a message, telling it to open a new window and passing the URL to open as a string, before closing itself (leaving the user with only 1 instance still and none the wiser).

    I didn't think this was possible using PostMessage etc. (thought you could only use the specific constants as messages)

  11. #11
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    Re: Sending messages between VB-created apps

    Quote Originally Posted by penagate
    Here is an scenario where I need it:

    User opens my app (web browser).

    User then manages to open it again, possibly by opening a .url link file or somehow doing some form of ShellExecute. I then want the 2nd instance to send the 1st instance a message, telling it to open a new window and passing the URL to open as a string, before closing itself (leaving the user with only 1 instance still and none the wiser).
    For this, it seems the easiest thing to do is have your app check to see if it is already running, and it so, then not allow a second instance to be executed.
    Quote Originally Posted by penagate
    I didn't think this was possible using PostMessage etc. (thought you could only use the specific constants as messages)
    Yes, you are right about that and now that I know the specifics of your request, those APIs I mentioned would not do you any good.

  12. #12
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    Re: Sending messages between VB-created apps


  13. #13

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    Quote Originally Posted by Hack
    For this, it seems the easiest thing to do is have your app check to see if it is already running, and it so, then not allow a second instance to be executed.
    Yeah, I already do that, but the problem is I need the 1st instance to open the URL passed in the 2nd instance's command arguments. Otherwise the user will be getting frustrated when their URLs don't open

  14. #14

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    Thanks, that looks interesting. But my problem is, I want to send a string message... not a constant representing a specific string.

    As it is a URL there is no way I can register it beforehand, it needs to be sent as is.

  15. #15
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Sending messages between VB-created apps

    Actually you don't need to register a message. You don't even have to send the string. Since what you want to do is to notify an earlier instance of your program of a file to open (or in this case an URL). All you then have to do is to send a unique user defined message to the previous instance window. Of course you could use RegisterWindowMessage to get such a unique message but you could just as well pick any value above WM_USER that will be unique for your program.

    You also need to know the hWnd of the main window of the first started application so you can send a message to that. You could use FindWindow if you want but an easier way is that when the application starts, check if a previous instance exists. If not save the hWnd of your main window to the registry or anyother repository you want to use. If a previous instance of your application exists read the hWnd of that instance main window and send it your unique message using SendMessage.

    Now how will the program get the URL to open when it gets the message? Well. again you could use the Registry to write the URL to use before sending the message. Another approach could be to create a Global Atom using the GlobalAddAtom message. The return value for that call should be sent to your previous instance, in for example the wParam argument. You can then use this value with the GlobalGetAtomName to get the URL, just make sure you call GlobalDeleteAtom when you have the URL.

    Now for all of this to work you must of course subclass your main window and listen for your own unique message.

  16. #16

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    Thanks for that mate. I'll have a look at making atoms.

    and, more subclassing...
    Can you show me, or point me to a link where I can find out, how to listen for the message? I already have some subclassing in my app but the technique hasn't really stuck.... it was a copy & paste job

  17. #17
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Sending messages between VB-created apps

    VB Code:
    1. Private Declare Function SetWindowLong _
    2.  Lib "user32" Alias "SetWindowLongA" ( _
    3.  ByVal hwnd As Long, _
    4.  ByVal nIndex As Long, _
    5.  ByVal dwNewLong As Long) As Long
    6.  
    7. Private Declare Function CallWindowProc _
    8.  Lib "user32" Alias "CallWindowProcA" ( _
    9.  ByVal lpPrevWndFunc As Long, _
    10.  ByVal hwnd As Long, _
    11.  ByVal msg As Long, _
    12.  ByVal wParam As Long, _
    13.  ByVal lparam As Long) As Long
    14.  
    15. Private Const GWL_WNDPROC = (-4)
    16. Private Const WM_DESTROY = &H2&
    17.  
    18. Private lngHwnd As Long
    19. Private lngPrevWndProc As Long
    20.  
    21. Public Sub HookForm(frmHandle As Long)
    22.     lngHwnd = frmHandle
    23.     lngPrevWndProc = SetWindowLong(lngHwnd, GWL_WNDPROC, AddressOf WinProc)
    24. End Sub
    25.  
    26. Public Sub UnhookForm()
    27.     SetWindowLong lngHwnd, GWL_WNDPROC, lngPrevWndProc
    28. End Sub
    29.  
    30. Public Function WinProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lparam As Long) As Long
    31.     Select Case uMsg
    32.         Case WM_DESTROY
    33.             'the window has been closed
    34.             UnhookForm
    35.     End Select
    36.     WinProc = CallWindowProc(lngPrevWndProc, hw, uMsg, wParam, lparam)
    37. End Function
    Add the above in a Module. You can start the subclassing by calling the HookForm Sub and pass the hWnd of the Form. You stop subclassing by calling the UnhookForm. You check for the messages in the WinProc function, I've already put in code to check for the WM_DESTROY message which your form gets before it is unloaded. I then stop the subclassing. This is for safety reasons in the case you would forget to call the UnhookForm before your window is closed.

    Remember when you subclass a Form not to use the End statement or clicking the End button in VB since it will then crash and burn.

  18. #18
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Sending messages between VB-created apps

    I would use SendMessage to send a WM_COPYDATA message betwen apps. This message uses the COPYDATASTRUCT structure.
    VB Code:
    1. Type COPYDATASTRUCT
    2.     dwData as long
    3.     cbData as long
    4.     lpData as long
    5. End Type
    where
    dwData is a long you may want to pass
    ldData is a pointer to your string
    cdData is the length or your string

  19. #19
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Sending messages between VB-created apps

    Quote Originally Posted by moeur
    I would use SendMessage to send a WM_COPYDATA message betwen apps. This message uses the COPYDATASTRUCT structure.
    VB Code:
    1. Type COPYDATASTRUCT
    2.     dwData as long
    3.     cbData as long
    4.     lpData as long
    5. End Type
    where
    dwData is a long you may want to pass
    ldData is a pointer to your string
    cdData is the length or your string
    That's all fine moeur... Have you tried that between two VB processes? I'm most intrested to learn how you've created a VB string and passed the address of it in the ldData member.

    Don't think that I'm trying to ridicule you or your answer because I don't! I just want to know how you passed on the string because I've tried that before but never succeeded.

  20. #20
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Sending messages between VB-created apps

    Create two Apps

    App 1 Sender
    Form
    VB Code:
    1. Option Explicit
    2. Private Type COPYDATASTRUCT
    3.         dwData As Long
    4.         cbData As Long
    5.         lpData As Long
    6. End Type
    7.  
    8. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
    9.     ByVal hwnd As Long, _
    10.     ByVal wMsg As Long, _
    11.     ByVal wParam As Long, _
    12.     lParam As Any _
    13. ) As Long
    14.  
    15. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    16.     ByVal lpClassName As String, _
    17.     ByVal lpWindowName As String _
    18. ) As Long
    19. Private Const WM_COPYDATA = &H4A
    20.  
    21. Private Sub cmdSend_Click()
    22. Dim hWndREC As Long
    23. Dim MyData As COPYDATASTRUCT
    24. Dim strToSend As String
    25.  'get handle of receiver
    26.  hWndREC = FindWindow(vbNullString, "Receiver")
    27.  While hWndREC = 0
    28.     If MsgBox("Start Receiver Program", vbOKCancel) = vbCancel Then Exit Sub
    29.     hWndREC = FindWindow(vbNullString, "Receiver")
    30.  Wend
    31.  'string we want to pass
    32.  strToSend = "Aussies love ABBA"
    33.  
    34.  MyData.dwData = 100 'any number you want
    35.  MyData.lpData = StrPtr(strToSend)
    36.  MyData.cbData = Len(strToSend) * 2 'wide data
    37.  
    38.  SendMessage hWndREC, WM_COPYDATA, Me.hwnd, MyData
    39.  
    40. End Sub

    App 2 Receiver
    Form
    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Form_Load()
    4.  EnableSubclass Me.hwnd
    5.  Label1.Caption = "Message goes here."
    6.  Me.Caption = "Receiver"
    7. End Sub
    8.  
    9. Private Sub Form_Unload(Cancel As Integer)
    10.  DisableSubclass Me.hwnd
    11. End Sub
    Module
    VB Code:
    1. Option Explicit
    2.  
    3. Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
    4.     ByVal lpPrevWndFunc As Long, _
    5.     ByVal hwnd As Long, _
    6.     ByVal Msg As Long, _
    7.     ByVal wParam As Long, _
    8.     ByVal lParam As Long _
    9. ) As Long
    10.  
    11. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    12.     Destination As Any, _
    13.     Source As Any, _
    14.     ByVal Length As Long _
    15. )
    16.  
    17. Private Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" ( _
    18.     ByVal hwnd As Long, _
    19.     ByVal nIndex As Long, _
    20.     ByVal dwNewLong As Long _
    21. ) As Long
    22.  
    23. Private Const GWLP_WNDPROC = (-4)
    24. Private Const WM_COPYDATA = &H4A
    25. Dim lOrigWndProc As Long
    26.  
    27. Public Function NewWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    28. Dim cbData As Long
    29. Dim dwData As Long
    30. Dim lpData As Long
    31. Dim bTemp As Byte
    32. Dim i As Long
    33. Dim x As String
    34.    
    35.     If uMsg = WM_COPYDATA Then
    36.         'get dwData
    37.         CopyMemory dwData, ByVal lParam, 4
    38.         'get len of string
    39.         CopyMemory cbData, ByVal (lParam + 4), 4
    40.         'get pointer to string
    41.         CopyMemory lpData, ByVal (lParam + 8), 4
    42.         'get string itself
    43.         x = ""
    44.         For i = 0& To cbData - 1 Step 2
    45.             CopyMemory bTemp, ByVal lpData + i, 1
    46.             x = x & Chr(bTemp)
    47.         Next i
    48.        Form1.Label1 = x
    49.     End If
    50.        
    51.     NewWndProc = CallWindowProc(lOrigWndProc, hwnd, uMsg, wParam, lParam)
    52. End Function
    53.  
    54. Public Function EnableSubclass(lhWnd As Long) As Boolean
    55.     If lOrigWndProc <> 0 Then
    56.         MsgBox "Error: Already subclassed"
    57.     Else
    58.         lOrigWndProc = SetWindowLongPtr(lhWnd, GWLP_WNDPROC, AddressOf NewWndProc)
    59.     End If
    60.    
    61.     If lOrigWndProc <> 0 Then
    62.         EnableSubclass = True
    63.     Else
    64.         EnableSubclass = False
    65.     End If
    66. End Function
    67.  
    68. Public Function DisableSubclass(lhWnd As Long) As Boolean
    69.     If lOrigWndProc = 0 Then
    70.         DisableSubclass = False
    71.     Else
    72.         SetWindowLongPtr lhWnd, GWLP_WNDPROC, lOrigWndProc
    73.         lOrigWndProc = 0
    74.         DisableSubclass = True
    75.     End If
    76. End Function

    There is a limitation with WM_COPYDATA, the data pointer can point to anything including a data structure, but the data structure cannot contain any pointers itself.

  21. #21
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Sending messages between VB-created apps

    Cool thanks!

  22. #22

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Sending messages between VB-created apps

    Thanks, nice looking code moeur, I'll try that!

  23. #23
    Addicted Member
    Join Date
    Aug 2008
    Posts
    136

    Re: Sending messages between VB-created apps

    I'm really sorry for replying this 4 years old thread. I was just reading around forum and got interested on this one..

    In my beginner's mind, why this task is so hard to do? why must use subclassing (which is difficult for me)?
    with SendMessageByString i can send string between my 2 apps:

    App 1 Sender
    Code:
    Option Explicit
    
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
    
    Private Const WM_SETTEXT = &HC
    
    Private Sub cmdSend_Click()
        Dim thunderrtformdc As Long, thunderrttextbox As Long
        
        thunderrtformdc = FindWindow("thunderrt6formdc", "Receiver")
        
        If thunderrtformdc <> 0 Then
            thunderrttextbox = FindWindowEx(thunderrtformdc, thunderrttextbox, "thunderrt6textbox", vbNullString)
            Call SendMessageByString(thunderrttextbox, WM_SETTEXT, 0&, "Text sent by sender")
        End If
    End Sub
    App 2 Receiver:
    only 1 textbox

    thank you for explanation..
    and sorry for bringing up this old thread..

  24. #24
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Sending messages between VB-created apps

    What you are doing here is sending a Set Text message to another window (form). This will change the caption of the form to your new message and you can then retrieve the message by reading the caption property.

    Let's say that you don't want your string showing up on your form, then you can't use the Set Text windows message.

    In addition, suppose you want to send something more complicated than a string such as a user defined type. Now the job becomes more complicated.

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