Author Topic: Out of Process COM server  (Read 5854 times)

0 Members and 1 Guest are viewing this topic.

Offline Jon Eskdale

  • Newbie
  • *
  • Posts: 35
  • User-Rate: +2/-0
Out of Process COM server
« on: September 29, 2014, 11:49:19 AM »
I have a Direct Show video capture application more or less developed in PowerBasic.
I would like to COM enable it as an Out of Process Com server so that it can be controlled from an old VB6 app (Its a big program and rewriting the whole of it is not an option)
As I understand the only way with PowerBasic is to use Low Level Com.  Searching I see that Fred did some work on this back in 2010 with his "CC" server but this was not a GUI app.
Question is - Is this feasible and are there any examples? 

The other possibility I was thinking of doing is using the WM_CopyData message to control and feedback events to VB6 with.
I would have to subclass the windows messages in VB6 but I think that is possible.

The COM solution would be nicest but may be the CopyData message is easiest
Any pointers, Links to examples, or suggestions would be very gratefully received
Jon

Offline Jon Eskdale

  • Newbie
  • *
  • Posts: 35
  • User-Rate: +2/-0
Re: Out of Process COM server
« Reply #1 on: October 12, 2014, 12:58:21 AM »
Hi Patrice,
Thanks for your reply - I use the CopyData message in my Sailwave application to communicate with some enhancements that I've added to it that are written in PowerBasic.  Sailwave itself is written in Clarion, and I use the CopyData to communicate in both directions between the two.  Out of curiosity I just had a look at your sample to see how it compared to mine.  But there seems to be something wrong with yours if I'm correct (Please forgive me if I wrong)

This is your calling code

.
Code: [Select]
    CASE %WM_COPYDATA
       ' wParam holds the string length
       ' lParam holds the Byte array address
         dwData = zGetPrivateMsg(sDataString, wParam, lParam)
         szFileName = ""
         IF dwData = %ZM_STRINGDATA THEN
            IF LEN(sDataString) THEN szFileName = LCASE$(PARSE$(sDataString, $zLim, 1))
         END IF
         CALL CheckMovieName(szFileName)
         FUNCTION = 1: EXIT FUNCTION

Your comment says that wParam holds the length of the string and the code works on this assumption,  but according to MSDN it holds a handle to the window passing the data

Parameters

wParam
A handle to the window passing the data.
lParam
A pointer to a COPYDATASTRUCT structure that contains the data to be passed.

Yours does work but it creates a very large string the size of handle of the calling program and then it parses it which can take a long time.

This is my sample version of your zGetPrivateMsg which I think works as a direct replacement for yours but I note that wParam is not used or needed, but I put it in this sample to make it a drop in replacement for yours

Code: [Select]
FUNCTION zGetPrivateMsg(BYREF sPrivateMsg AS STRING, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG

    local pRecData   AS CopyDataStruct POINTER
   
    pRecData = lParam
    REDIM Buf(@pRecData.cbData) AS BYTE
    Memory COPY @pRecData.lpData, VARPTR(buf(0)), @pRecData.cbData
    sPrivateMsg = PEEK$(VARPTR(buf(0)), @pRecData.cbData)
    FUNCTION = @pRecData.dwData

END FUNCTION

Here is your original just for easy comparison
Code: [Select]
FUNCTION zGetPrivateMsg(BYREF sPrivateMsg AS STRING, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG

    LOCAL cds AS COPYDATASTRUCT

    REDIM Buf(wParam) AS BYTE
    CALL MoveMemory(cds, BYVAL lParam, SIZEOF(cds))
    CALL MoveMemory(buf(0), BYVAL cds.lpData, cds.cbData)
    sPrivateMsg = PEEK$(VARPTR(buf(0)), wParam)
    FUNCTION = cds.dwData

END FUNCTION

Make I take this opportunity to say how much I admire some of you work - you are very talented and creative.

I would still love to do it with Com but the CopyData message will have to do for now

Jon

Offline Jon Eskdale

  • Newbie
  • *
  • Posts: 35
  • User-Rate: +2/-0
Re: Out of Process COM server
« Reply #2 on: October 12, 2014, 09:59:02 AM »
Just looked at my code this morning after last nights late post and realised I didn't need the byte array.  It was a by product of converting my code to fit into your function so now I have, which seems to work fine and is also simpler.

Code: [Select]
FUNCTION zGetPrivateMsg(BYREF sPrivateMsg AS STRING, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG

    local pRecData   AS CopyDataStruct POINTER
   
    pRecData = lParam
    sPrivateMsg = PEEK$(@pRecData.lpData, @pRecData.cbData)
    FUNCTION = @pRecData.dwData

END FUNCTION

Jon