Part 2 of DDE/Netscape/Binary Arrays

For Alamo:

Via DDE, Netscape can return a list of its open windows (WWW_ListWindows). The value returned is a long word array. If I pass a long to WWW_GetWindowInfo, I'll get back the URL and the title,
             which I want.

             My question is how within the confines of VB DDE handling do I parse
             what WWW_List Window returns?

             Here's netscapes Doc: see
             http://developer.netscape.com/library/documentation/communicator/DDE/ddeapi.htm
cellphoneAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

alamoCommented:
It turns out that in fact you can call the DDE API from VB, at least for a simple request.

Here's the code:

' DDE API declares
Private Declare Function DdeInitialize Lib "user32" Alias "DdeInitializeA" (pidInst As Long, ByVal pfnCallback As Long, ByVal afCmd As Long, ByVal ulRes As Long) As Integer
Private Declare Function DdeCreateStringHandle Lib "user32" Alias "DdeCreateStringHandleA" (ByVal idInst As Long, ByVal psz As String, ByVal iCodePage As Long) As Long
Private Declare Function DdeFreeStringHandle Lib "user32" (ByVal idInst As Long, ByVal hsz As Long) As Long
Private Declare Function DdeDisconnect Lib "user32" (ByVal hConv As Long) As Long
Private Declare Function DdeUninitialize Lib "user32" (ByVal idInst As Long) As Long
Private Declare Function DdeGetLastError Lib "user32" (ByVal idInst As Long) As Long

' The following declares I needed to change to make the types work out (we are passing 0 for all of these)
'Private Declare Function DdeConnect Lib "user32" (ByVal idInst As Long, ByVal hszService As Long, ByVal hszTopic As Long, pCC As CONVCONTEXT) As Long
 Private Declare Function DdeConnect Lib "user32" (ByVal idInst As Long, ByVal hszService As Long, ByVal hszTopic As Long, ByVal pCC As Long) As Long
'Private Declare Function DdeClientTransaction Lib "user32" (pData As Byte, ByVal cbData As Long, ByVal hConv As Long, ByVal hszItem As Long, ByVal wFmt As Long, ByVal wType As Long, ByVal dwTimeout As Long, pdwResult As Long) As Long
 Private Declare Function DdeClientTransaction Lib "user32" (ByVal pData As Long, ByVal cbData As Long, ByVal hConv As Long, ByVal hszItem As Long, ByVal wFmt As Long, ByVal wType As Long, ByVal dwTimeout As Long, ByVal pdwResult As Long) As Long
'Private Declare Function DdeGetData Lib "user32" Alias "DdeGetDataA" (ByVal hData As Long, pDst As Byte, ByVal cbMax As Long, ByVal cbOff As Long) As Long
 Private Declare Function DdeGetData Lib "user32" (ByVal hData As Long, ByVal pDst As String, ByVal cbMax As Long, ByVal cbOff As Long) As Long

' DDE API Constants used here
Const APPCMD_CLIENTONLY = &H10&
Const CP_WINANSI = 1004
Const XCLASS_DATA = &H2000
Const XTYP_REQUEST = (&HB0 Or XCLASS_DATA)
Const CF_TEXT = 1

Private Sub Command1_Click()

'I had to change the loop to parse the returned data, turns out it  fails when it hits the final array entry of 0

    t$ = RequestDDEBinaryData("netscape", "WWW_ListWindows", "doesn't matter")
    Do While Len(t$) > 0
        win& = GetNextDW&(t$)
        If win& = 0 Then Exit Do
        MsgBox "Window " & win& & ": " & GetWindowInfo(win&)
    Loop
End Sub

' Function GetNextDW& and GetWindowInfo is unchanged from last message (http://www.experts-exchange.com/topics/bin/ShowQ?qid=8630022627)

Public Sub CheckForDDEError(idInst&, context$)
Dim errnum As Long
    errnum = DdeGetLastError(idInst)
    If errnum <> 0 Then
        MsgBox "Error: " & errnum & " (" & Hex$(errnum) & ") after " & context$
    End If
End Sub

Public Function RequestDDEBinaryData(service$, topic$, item$) As String

Dim idInst As Long         ' DDE Instance handle
Dim hcnv As Long           ' Conversation handle
Dim hszData  As Long        ' StringHandles
Dim hszItem  As Long
Dim hszService As Long
Dim hszTopic As Long
Dim retVal As Integer

    'Though it's undocumented, DdeInitialize seems to be fine with a null callback function. If needed, write a callback using VB5
    idInst = 0
    retVal = DdeInitialize(idInst, 0, APPCMD_CLIENTONLY, 0)
    If retVal <> 0 Then
        MsgBox "Unable to initialize DDE, error =" & retVal & " " & Hex$(retVal)
        Exit Function
    End If
   
    ' Create some string objects we can use for service, topic, item
    hszService = DdeCreateStringHandle(idInst, service$, CP_WINANSI)
    CheckForDDEError idInst, "DdeCreateStringHandle(service)" ' a little overboard on the error checking but this is for test
    hszTopic = DdeCreateStringHandle(idInst, topic$, CP_WINANSI)
    CheckForDDEError idInst, "DdeCreateStringHandle(topic)"
    hszItem = DdeCreateStringHandle(idInst, item$, CP_WINANSI)
    CheckForDDEError idInst, "DdeCreateStringHandle(item)"
   
    ' Connect to the service / topic
    hcnv = DdeConnect(idInst, hszService, hszTopic, 0)
    CheckForDDEError idInst, "DdeConnect"
   
    ' Request the item from the server - we get handle to resulting data object back
    hszData = DdeClientTransaction(0, 0, hcnv, hszItem, CF_TEXT, XTYP_REQUEST, 1000, 0)
    CheckForDDEError idInst, "DdeClientTransaction"
   
    ' get the returned data
    buffer$ = Space$(256)
    retVal = DdeGetData(hszData, buffer$, Len(buffer$), 0)
    RequestDDEBinaryData = Left$(buffer$, retVal)
    CheckForDDEError idInst, "DdeGetData"
   
    ' Done, free everything we created and we are done
    retVal = DdeFreeStringHandle(idInst, hszService)
    CheckForDDEError idInst, "DdeFreeStringHandle(hszService)"
    retVal = DdeFreeStringHandle(idInst, hszTopic)
    CheckForDDEError idInst, "DdeFreeStringHandle(hszTopic)"
    retVal = DdeFreeStringHandle(idInst, hszItem)
    CheckForDDEError idInst, "DdeFreeStringHandle(hszItem)"
    retVal = DdeDisconnect(hcnv)
    CheckForDDEError idInst, "DdeDisconnect"
    retVal = DdeUninitialize(idInst)
End Function

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
alamoCommented:
Cellphone, I assume no news is good news, and the above code worked? If not, let me know - if so, please grade this question (so it doesn't get autograded to C due to inactivity). Thanks!
cellphoneAuthor Commented:
have'nt had time to try it ... but won't hold you up.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.