CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jul 2001
    Location
    Tijuana, Mexico.
    Posts
    5

    Variable Sharing

    How do I share variable data between 2 VB programs ?
    One is running as a service (using NtSvc.ocx) and since it does not use the LocalSystem account it can't interact with the Desktop.
    I'm trying to write another app that will communicate with it and serve as it's GUI, just haven't found how to share the share data between them. DDE does not work, using sockets and TCP/IP works but not very well with large strings.

    Thanks in advance.



  2. #2
    Join Date
    Jan 2000
    Location
    Olen, Belgium
    Posts
    2,477

    Re: Variable Sharing

    I see two more possibilities,

    1) the first is COM, if you manage to create a COM interface for your service (so it actually is an Activex Exe), you could use the methods you expose to comunicate. This however will probabkly require you to redevelop most of the application, but is by far the most reliable way.

    2) Files. You can comunicate using files. Say you have a client and a server (the service in this case). Let the service look at the data in a file (like say c:\SERVICE-IN.TXT), and let the client look at the data in another file (like say c:\CLIENT-IN.TXT). Both programs need to write to the others IN file, resulting in a way to comunicate. This might not be a clean solution, but it is probably one of the easiest to implement.

    Tom Cannaerts
    [email protected]

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning -- Rich Cook
    Tom Cannaerts
    email: [email protected]
    www.tom.be (dutch site)

  3. #3
    Join Date
    Dec 1999
    Location
    Dublin, Ireland
    Posts
    1,173

    Re: Variable Sharing

    You could use RegisterWindowMessage() API to create a new message and send it to your GUI app using the SendMessage() API?

    HTH,
    D.

    -------------------------------------------------
    Ex. Datis: Duncan Jones
    Merrion Computing Ltd
    http://www.merrioncomputing.com
    Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
    '--8<-----------------------------------------
    NEW -The printer usage monitoring application
    '--8<------------------------------------------

  4. #4
    Join Date
    Jul 2001
    Location
    Tijuana, Mexico.
    Posts
    5

    Re: Variable Sharing

    I though Activex EXEs can only be initiated by the client APP. Since my server APP needs to run as a service it has to be able to start on its own, but somehow sharing it's data. Right now I'm using SocketWrench from Catalyst to comunicate both APPs via TCP/IP, but what I really want to do is share the variable data in a more elegant way.


  5. #5
    Join Date
    Jul 2001
    Location
    Tijuana, Mexico.
    Posts
    5

    Re: Variable Sharing

    This is a good suggestion, where can I find examples on how to do it ?
    What I really need, though, is a way to have a single shared data area where mutiple apps can see and/or change the variable values.



  6. #6
    Join Date
    Dec 1999
    Location
    Dublin, Ireland
    Posts
    1,173

    Re: Variable Sharing

    In order to pass memory between threads it must be global memory.


    '\\ Global memory management functions
    private Declare Function GlobalLock Lib "kernel32" (byval hMem as Long) as Long

    private Declare Function GlobalSize Lib "kernel32" (byval hMem as Long) as Long

    private Declare Function GlobalUnlock Lib "kernel32" (byval hMem as Long) as Long

    private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest as Any, lpvSource as Any, byval cbCopy as Long)

    private Declare Function GlobalAlloc Lib "kernel32" (byval wFlags as Long, byval dwBytes as Long) as Long

    private Declare Function GlobalFree Lib "kernel32" (byval hMem as Long) as Long
    private mMyData() as Byte
    private mMyDataSize as Long
    private mHmem as Long


    public Enum enGlobalmemoryAllocationConstants
    GMEM_FIXED = &H0
    GMEM_DISCARDABLE = &H100
    GMEM_MOVEABLE = &H2
    GMEM_NOCOMPACT = &H10
    GMEM_NODISCARD = &H20
    GMEM_ZEROINIT = &H40
    End Enum
    '**************************************
    ' Name: Global memory
    ' Description:Allows you to read and wri
    ' te global memory blocks, which in turn a
    ' llows you to pass big chunks of data bet
    ' ween applications easily.
    ' By: Duncan Jones
    '
    '
    ' Inputs:None
    '


    '\\ --[CopyFromHandle]---------------------------
    '\\ Copies the data from a global memory handle
    '\\ to a private byte array copy
    '\\ ---------------------------------------------

    public Sub CopyFromHandle(byval hMemHandle as Long)
    Dim lRet as Long
    Dim lPtr as Long
    lRet = GlobalSize(hMemHandle)


    If lRet &gt; 0 then
    mMyDataSize = lRet
    lPtr = GlobalLock(hMemHandle)


    If lPtr &gt; 0 then
    ReDim mMyData(0 to mMyDataSize - 1) as Byte
    CopyMemory mMyData(0), byval lPtr, mMyDataSize
    Call GlobalUnlock(hMemHandle)
    End If
    End If
    End Sub
    '\\ --[CopyToHandle]-----------------------------
    '\\ Copies the private data to a memory handle
    '\\ passed in
    '\\ ---------------------------------------------

    public Sub CopyToHandle(byval hMemHandle as Long)
    Dim lSize as Long
    Dim lPtr as Long
    '\\ Don't copy if its empty


    If Not (mMyDataSize = 0) then
    lSize = GlobalSize(hMemHandle)
    '\\ Don't attempt to copy if zero size..

    If lSize &gt; 0 then
    lPtr = GlobalLock(hMemHandle)
    If lPtr &gt; 0 then
    CopyMemory byval lPtr, mMyData(0), lSize
    Call GlobalUnlock(hMemHandle)
    End If
    End If
    End If
    End Sub




    Of course, you still need to pass the global handles bewteen your applications and should probably implement some kind of MutEx protection to prevent one app writing memory that another is reading...

    HTH,
    Duncan



    -------------------------------------------------
    Ex. Datis: Duncan Jones
    Merrion Computing Ltd
    http://www.merrioncomputing.com
    Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
    '--8<-----------------------------------------
    NEW -The printer usage monitoring application
    '--8<------------------------------------------

  7. #7
    Join Date
    Jul 2001
    Location
    Tijuana, Mexico.
    Posts
    5

    Re: Variable Sharing

    This is great !!!, Thanks, Duncan.

    Now, How do each app find each other in memory, so the data can be exchanged ??
    I'm still thinking about the way it used to be in assembler, where all you had to do was pass the starting address of the memory block that contained the shared data (usually with an interrupt call), and from then on all symbolic variables in both apps referred to the exact same memory location. I guess in VB is a bit more convoluted (or is it because of Windows?).

    Coco Loco

  8. #8
    Join Date
    Dec 1999
    Location
    Dublin, Ireland
    Posts
    1,173

    Re: Variable Sharing

    One of the huge security advances in windows NT/9x over 3.1 is that in the new world order, evrey thread has its own local storage and to simplify slightly that storage is not visible outside of that thread. This is good because when threads (and therefore applications) are allowed to mess around with each other's memory then a GPF is never far behind.

    However, you do sometimes need to pass bits of memory between applications - for instance if you use the clipboard. For this case you need to allocate some global memory in one application which will give you an unique Global Memory handle then copy your data to the memory thus allocated.
    Then you need to inform the second application that memory is available and pass across that global memory handle and the recipient should then copy the data from that handle and then inform the first application that it has done so so that it may free up the allocated global memory.

    There are a number of ways to pass the handle between two applications, but in my opinion the best way is using SendMessage.

    First you need to register two new messages that you will use to communicate between your applications with the RegisterWindowsMessage() API call:


    'Declarations:
    Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (byval lpString as string) as Long

    'Use
    public Function MSG_NewDataAvailable() as Long

    static wmsg as Long

    If wmsg = 0 then
    wmsg = RegisterWindowMessage("NEWGLOBALMEMORY")
    End If

    MSG_NewDataAvailable = wmsg

    End Function

    public Function MSG_AcknowledgeData() as Long

    static wmsg as Long

    If wmsg = 0 then
    wmsg = RegisterWindowMessage("ACKNOWLEDGEGLOBALMEMORY")
    End If

    MSG_AcknowledgeData= wmsg

    End Function





    This code will need to be added in a common .bas module in both your applications...


    -------------------------------------------------
    Ex. Datis: Duncan Jones
    Merrion Computing Ltd
    http://www.merrioncomputing.com
    Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
    '--8<-----------------------------------------
    NEW -The printer usage monitoring application
    '--8<------------------------------------------

  9. #9
    Join Date
    Dec 1999
    Location
    Dublin, Ireland
    Posts
    1,173

    Re: Variable Sharing

    Then, in order to use this you need to subclass the WNDPROC of both your application's windows.
    There are plenty of examples of subclassing - including http://www.MerrionComputing.com/OnlineIssue2.htm

    In the WNDPROC:


    'declarations...
    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

    Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (byval hwnd as Long, byval wMsg as Long, byval wParam as Long, byval lParam as Long) as Long

    '\\ --[VB_WindowProc]-------------------------------------------------------------------
    '\\ 'typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
    '\\ Parameters:
    '\\ hwnd - window handle receiving message
    '\\ wMsg - The window message (WM_..etc.)
    '\\ wParam - First message parameter
    '\\ lParam - Second message parameter
    '\\ Note:
    '\\ When subclassing a window proc using this, set the eventhandler's
    '\\ hOldWndProc property to the window's previous window proc address.
    '\\ ----------------------------------------------------------------------------------------
    '\\ You have a royalty free right to use, reproduce, modify, publish and mess with this code
    '\\ I'd like you to visit http://www.merrioncomputing.com for updates, but won't force you
    '\\ ----------------------------------------------------------------------------------------
    public Function VB_WindowProc(byval hwnd as Long, byval wMsg as Long, byval wParam as Long, byval lParam as Long) as Long


    If wMsg = MSG_NewDataAvailable() then
    'lParam is the memory handle,
    'wParam is the window sending the message
    '\\ Copy the meory from the handle..

    '\\ Acknowledge that we got the memory
    Call SendMessageLong(wParam,MSG_AcknowledgeGlobalMemory(), hwnd,lParam)

    ElseIf wMsg = MSG_AcknowledgeGlobalMemory() then
    'lParam is the memory handle,
    'wParam is the window sending the message
    '\\ Free the memory in lParam

    else
    VB_WindowProc = CallWindowproc(hOldProc, hWnd,lParam,wParam)
    End If

    End Function





    The allocating and freeing of memory is as per the first post in this thread....

    HTH,
    Duncan

    -------------------------------------------------
    Ex. Datis: Duncan Jones
    Merrion Computing Ltd
    http://www.merrioncomputing.com
    Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
    '--8<-----------------------------------------
    NEW -The printer usage monitoring application
    '--8<------------------------------------------

  10. #10
    Join Date
    Jul 2005
    Posts
    6

    Question Re: Variable Sharing

    Sup!

    I'am from Brazil but I'll try to write in English.

    Could someone give us a complete code that works?
    I am writing these examples in VB6 without success...

    note: i don't need an example to pass the handle using sendmessage, i can do this givind the value from one executable and writing the exact value to another executable trought a textbox. I just need the code to write and load the memory because I am trying and trying...but didn't work yet

    I am using windows xp sp2

    thanks,
    Last edited by KaDuKa; August 11th, 2005 at 09:51 AM.

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

Featured