Results 1 to 19 of 19

Thread: Communicate between apps

  1. #1

    Thread Starter
    New Member
    Join Date
    Sep 2001
    Location
    The ocean
    Posts
    2

    Communicate between apps

    I need a way to communicate between 2 apps on the same system. One fellow programmer suggested API call SendMessage but how does the receiving app receive the message to write it to a textbox. Any help or example appreciated.

  2. #2
    Megatron
    Guest
    Sending the message is easy. Just create a message, and send it.
    Code:
    WM_MYMESSAGE = WM_USER + 100
    SendMessage(hwnd_of_window,  WM_MYMESSAGE, 0,0)
    To recieve the message:

    (Add to a module)
    VB Code:
    1. Public Declare Function SetWindowLong& Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long)
    2. 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
    3. Public Const GWL_WNDPROC = (-4)
    4. Public Const WM_USER = &H400
    5. Public Const WM_MYMESSAGE = WM_USER + 100
    6. Public WndProcOld As Long
    7.  
    8. Public Function WindProc(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    9.        
    10.     If wMsg = WM_MYMESSAGE Then
    11.         MsgBox "Message recieved"
    12.         Exit Function
    13.     End If
    14.    
    15.     WindProc = CallWindowProc(WndProcOld&, hwnd&, wMsg&, wParam&, lParam&)
    16.    
    17. End Function
    18.  
    19. Sub SubClassWnd(hwnd As Long)
    20.     WndProcOld& = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindProc)
    21. End Sub
    22.  
    23. Sub UnSubclassWnd(hwnd As Long)
    24.     SetWindowLong hwnd, GWL_WNDPROC, WndProcOld&
    25.     WndProcOld& = 0
    26. End Sub

    Add to a Form:
    VB Code:
    1. Private Sub Form_Load()
    2.     SubClassWnd hwnd
    3. End Sub
    4.  
    5. Private Sub Form_Unload(Cancel As Integer)
    6.     UnSubclassWnd hwnd
    7. End Sub

  3. #3
    Guru Aaron Young's Avatar
    Join Date
    Jun 1999
    Location
    Red Wing, MN, USA
    Posts
    2,177
    Here's an example I gave a while ago on using an ActiveX EXE to perform cross-application communication.

  4. #4
    Member docHoliday's Avatar
    Join Date
    Sep 1999
    Location
    Stamford, CT, USA
    Posts
    48
    OK Megatron, Code looks cool, but how do I select the EXE I want to call and pass it my data. Within the SendMessage call? I haven't really ever used that call before so forgive me if I'm missing the obvious here. The other set of code simply listens for a message back from the EXE and displays a message box, do I have that right?
    "A balm? That's a dangerous animal. Throw it in the trough!"
    - Monty Python

  5. #5
    Member docHoliday's Avatar
    Join Date
    Sep 1999
    Location
    Stamford, CT, USA
    Posts
    48
    Aaron, I tried you code, but it keeps breaking on compile this line telling me user defined type not defined:

    Code:
    Private WithEvents oCommandLine As AppExtender.CommandLine
    I followed all the instructon, what am I doing wrong?
    "A balm? That's a dangerous animal. Throw it in the trough!"
    - Monty Python

  6. #6

    Thread Starter
    New Member
    Join Date
    Sep 2001
    Location
    The ocean
    Posts
    2

    Try this. Best example I've seen.


  7. #7
    Megatron
    Guest
    Originally posted by docHoliday
    OK Megatron, Code looks cool, but how do I select the EXE I want to call and pass it my data. Within the SendMessage call? I haven't really ever used that call before so forgive me if I'm missing the obvious here. The other set of code simply listens for a message back from the EXE and displays a message box, do I have that right?
    First you need to use FindWindow to get the handle of the window
    Code:
    hwndWin = FindWindow("ThunderRT6Form", "Form caption")
    SendMessage hwndWin, WM_MYMESSAGE, 0, 0

  8. #8
    Guru Aaron Young's Avatar
    Join Date
    Jun 1999
    Location
    Red Wing, MN, USA
    Posts
    2,177
    You need to make sure the ActiveX EXE is compiled with the correct name and that the modules are named as specified and that the class modules are setup as specified.

    Here's a ZIP file containing the complete project files:
    Attached Files Attached Files

  9. #9
    Member docHoliday's Avatar
    Join Date
    Sep 1999
    Location
    Stamford, CT, USA
    Posts
    48
    Meagtron - What if it doesn;t run within a window but as a background process or application? This exe does not have a GUI. it only performs functions and spits out the output, usually to STDOUT I believe. I'll admit to not knowing much about the process with how it interacts other than it usually does so with a web server.
    "A balm? That's a dangerous animal. Throw it in the trough!"
    - Monty Python

  10. #10
    Hyperactive Member noble's Avatar
    Join Date
    Nov 2000
    Location
    Philly
    Posts
    471
    Megatron, how would you accomplish that as a single application?
    Not using two different apps but just using one that finds out if
    a previous instance is running and if it does send a message to
    it saying something?
    Bababooey
    Tatatoothy
    Mamamonkey

  11. #11
    Member docHoliday's Avatar
    Join Date
    Sep 1999
    Location
    Stamford, CT, USA
    Posts
    48
    Would DDE come into play here?
    "A balm? That's a dangerous animal. Throw it in the trough!"
    - Monty Python

  12. #12
    Hyperactive Member noble's Avatar
    Join Date
    Nov 2000
    Location
    Philly
    Posts
    471
    i was thinking maybe DDE but i wouldn't know how exactly to employ it, any help?
    Bababooey
    Tatatoothy
    Mamamonkey

  13. #13
    Member docHoliday's Avatar
    Join Date
    Sep 1999
    Location
    Stamford, CT, USA
    Posts
    48
    Me neither. I had seen a post in this forum that DDE is a complicated technology that is difficult to implement. I am always up for a challenge, however.

    Any of the Fanatics know any good resources to look into whether this is the answer to this question.
    "A balm? That's a dangerous animal. Throw it in the trough!"
    - Monty Python

  14. #14
    Hyperactive Member noble's Avatar
    Join Date
    Nov 2000
    Location
    Philly
    Posts
    471
    i was doing what megatron suggested earlier with the messages
    but it's very hard to test sometimes as I have two VBs running
    concurrently and neither of them know that a "previous instance"
    of the program is running. I think i was on the right track but
    there has got to be an easier way.
    Bababooey
    Tatatoothy
    Mamamonkey

  15. #15
    Member docHoliday's Avatar
    Join Date
    Sep 1999
    Location
    Stamford, CT, USA
    Posts
    48
    I am actually not looking to communicate between two instance of the same app.

    What I am after is being able to communicate between my VB app and another external program that receives input via STDIN and returns output via STDOUT, as I currently believe. I can;t be totally sure. The program interacts with web servers such as Apache and IIS. It receives input in the form of a file, does it's job, and sends it output back to the server to be delivered. I'm hoping to interface with this app somehow. That's the dilema.
    "A balm? That's a dangerous animal. Throw it in the trough!"
    - Monty Python

  16. #16
    Megatron
    Guest
    Originally posted by noble
    Megatron, how would you accomplish that as a single application?
    Not using two different apps but just using one that finds out if
    a previous instance is running and if it does send a message to
    it saying something?
    In that case, all you need is this:
    VB Code:
    1. 'Put this in the load event
    2. If App.PrevInstance Then Unload Me

  17. #17
    Hyperactive Member noble's Avatar
    Join Date
    Nov 2000
    Location
    Philly
    Posts
    471
    Megatron, I knew how to do that part but there were some other
    dilemmas. Here is what i did.

    First of all, my application is MDI. My program also has an
    assocation with a certain file type. When more than one file is
    selected an opened two instances of my program are shelled
    instead of one opened with the files being opened within the
    MDI.

    Therefore, all of the message sending has to be done in the form
    load event. This asks the question: when i check to see if the
    app is already running and whether commands() = true, shouldn't
    i set the hook after the checking?

    Code:
    If App.PrevInstance = True and Commands() <> "" then
         'Put Code Here to Send Message
          
         Unload Me
    End If
    
    SubClass hwnd
    Also, I'm sending text as a message so I have to send a byte
    array instead of just numbers too.

    Tell me if this sounds correct because I was doing just this but
    it wasn't working correctly.
    Bababooey
    Tatatoothy
    Mamamonkey

  18. #18
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    I forgot where I got this code from but this will 'activate' a previous instance of the same application instead of opening a new one.


    VB Code:
    1. 'in a standard module
    2.  
    3. 'activate previous instance
    4. Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    5. Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    6. Declare Function OpenIcon Lib "user32" (ByVal hWnd As Long) As Long
    7. Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
    8.          
    9. Public Const GW_HWNDPREV = 3
    10.  
    11. Public Sub ShowPrevInstance()
    12.     On Error Resume Next
    13.     Dim OldTitle As String
    14.     Dim ll_WindowHandle As Long
    15.     'saving the current title in OldTitle variable
    16.     'and changing the application title
    17.     OldTitle = App.Title
    18.     App.Title = "New App - This App Will Be Closed"
    19.     'finding the previous instance. if you are using VB 5.0,
    20.     'change "ThunderRT6Main" to "ThunderRT5Main"
    21.     ll_WindowHandle = FindWindow("ThunderRT6Main", OldTitle)
    22.     'if there is no old instances of your application - exit.
    23.     If ll_WindowHandle = 0 Then Exit Sub
    24.     'Find the window we need to restore
    25.     ll_WindowHandle = GetWindow(ll_WindowHandle, GW_HWNDPREV)
    26.     'Now restore it
    27.     Call OpenIcon(ll_WindowHandle)
    28.     'And Bring it to the foreground
    29.     Call SetForegroundWindow(ll_WindowHandle)
    30.     End
    31. End Sub
    32.  
    33.  
    34. Public Sub Main()
    35.     'goto prev instance if there is one
    36.     If App.PrevInstance Then ShowPrevInstance
    37.    
    38.     frmPrevInst.Show
    39.  
    40. End Sub

  19. #19
    New Member
    Join Date
    Sep 2001
    Location
    Montreal
    Posts
    2

    Different Approaches

    I've done this in many different apps in different ways, the real question is not how but which way would you like to do it. I would recommend direct Named Pipes. it's not extremely difficult and is very fast except can cause system lockups if you're not careful (synchronization issues).

    The other way which is difficult but most likely the most efficient way of doing it is MemoryMapped Files. Think of it as shared memory.

    The Simplest way is through an ActiveX EXE (always hated that solution). It's the VB solution to the problem, except if speed is not an issue...it's the BEST solution

    Direct process memory reading...NOT RECOMMENDED but produces fabulous CRASHES (Open the Process, will involve some NT Security and use Readprocessmemory and WriteprocessMemory...then expect some fireworks)

    Another Simple way is to register a windows message and simply send messages...can't be much easier then that except that now both your apps need at least one window handle.

    The last way, that I know of,is to use GetProp/SetProp to insert info on a communication method. You can set object pointers and they can retrieve info via the object (COMish solution).

    I have examples of a lot of these in my archives...I can try and dig some up if you want...let me know....

    Good Luck
    Lior Amar
    http://www.ostnet.com

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