DDE - Dynamic Data Exchange
by Ian Roberts
A requirement of a VB3 development I was working on recently was to set up an interface to allow another program, being developed interstate, to retrieve information and to invoke a form within my app. As it turned out the company responsible for creating the external app hired a talented VB programmer at their end, Peter Wone from GUI. Not surprisingly, we didn't have any trouble understanding each other and what we required, of course no one else understood us but as long as they got what they wanted they left us alone.
Peter and I discussed a number of approaches and finally decided on DDE, and setting up the interface to be almost API in appearance. We also convinced the two companies that it would be an advantage to have the two of us together to get the quickest and most reliable results. Once Peter arrived in Melbourne and we began to look at what was required we found that we had a problem, his app needed an information feed from yet another app that he had running in Sydney. Our clients, now thinking that they have just wasted one of the four remaining days of the project, were a little worried. "It's OK, we will just define an interface and build a test harness to test it. When I get back to Sydney I can implement the link via the defined interface. No problem.", was the cool response from Wone.
Setting up the DDE link in my app involved placing a label on the main form and setting the following properties of that form:
LinkMode = 1 - Source LinkTopic = "frmMain"We then placed a label on the form, set its name to lblDDELink, and placed the following call into the change event.
Call BackChat(vsAWK, lblDDELink)From the above call you may notice we used the Awk control from VS/VBX. This allowed us to set up painless expression parsing (i.e. we didn't need to code it ourselves).
In the DDECOMMS.BAS module we placed the BackChat routine. The following code is only an example skeleton.
Sub BackChat (Awk As VideoSoftAwk, lbl As Label)
Dim s As String
Dim sAccnt As String
Dim flgOK As Integer
Dim OldFS As String
Dim Verb As String
Static OrderNumber As String
Static flagGate%, i%
If flagGate Then Exit Sub ' this flag is to avoid code re-entrance
Let flagGate = True
Let Awk.L = Trim$(lbl.Caption)
Let OldFS = Awk.FS
Let Awk.FS = "|"
Let Verb = UCase$(Awk.F(1))
Select Case Verb
' To retrieve information
Case "GET DATA" ' The calling app passes this command
' write Access username
If trim$(gstrCliName) = "" then ' Check to see if the data is valid
Let lbl.Caption = "NOT AVAILABLE" ' return message to show no valid data
Else
Let lbl.Caption = gstrCliName ' then return valid data
End If
' To pass a value
Case "SET VALUE" ' passed as (SET VALUE|1234)
Let OrderNumber = Trim$(Awk.F(2))
Let lbl.Caption = "OK"
' this command allowed us to request a particular form to be shown
Case "SHOW FORM"
' open order window
' preload form with passed data in OrderNumber
' do any validation and place result in the flgOK
If flgOK Then
Let glfShowForm = True
Let lbl.Caption = "OK"
Else
Let lbl.Caption = "NOT OK"
End If
Case "GET COMMAND SET"
' write Access username
Let lbl.Caption = "GET DATA| SET VALUE|SHOW FORM"
Case Else
' No Action
End Select
Let Awk.FS = OldFS
Let flagGate = False
End Sub
While looking at the above code you may notice that we didn't do a show in the SHOW FORM command. We found that if we did this, the DDE link wouldn't return to the calling app and would cause an error. So we set up a global variable (glfShowForm) which by default is false. A timer control was already being used to update a clock so we added a test to see if our variable got set to true. This allowed the DDE link to complete its conversation and the timer to show the form. The code added to the timer was as simple as
If glfShowOrder Then frmOrder.Show 1All that remained was to build a DDE test app. First as with almost any VB app we started with a form then added some controls and code. The form and code are supplied below. To use the test app set the
LinkTopic = {exe name off the application}|frmMain
LinkItem = lblDDELink
LinkTimeOut = 50
Command=??? ' GET DATA, SET VALUE or GET COMMAND SET
The key press event of the command text box will fire the DDE link
and the result will be displayed in lblReceived.
Option Explicit
Sub Form_Load ()
awk.fs = "|"
End Sub
Sub lblReceived_Change ()
Static flagGate%
Dim nFields As Integer
Dim i As Integer
Dim sCaption As String
If flagGate Then Exit Sub
flagGate = True
Awk.L = Trim$(lblReceived)
nFields = Awk.NF
sCaption = Trim$(Awk.F(1))
If nFields > 1 Then
For i = 2 To nFields
sCaption = sCaption & Chr$(13) & Chr$(10) & Trim$(Awk.F(i))
Next i
End If
lblReceived = sCaption
flagGate = False
End Sub
Sub txtCommand_KeyPress (KeyAscii As Integer)
On Error GoTo Err_txtCommand_KeyPress
If KeyAscii = 13 Then
Let lblReceived.LinkTopic = Trim$(txtLinkTopic.Text)
Let lblReceived.LinkItem = Trim$(txtLinkItem.Text)
Let lblReceived.LinkTimeout = CInt(txtTimeout.Text)
Let lblReceived.LinkMode = 2 '- Manual
Let lblSent.Caption = txtCommand.Text
Let lblReceived.Caption = txtCommand.Text
lblReceived.LinkPoke
DoEvents
DoEvents
lblReceived.LinkRequest
End If
Exit_txtCommand_KeyPress:
Exit Sub
Err_txtCommand_KeyPress:
Beep
MsgBox Error$, 48, "DDE Test Harness"
Resume Exit_txtCommand_KeyPress
End Sub
Sub txtTimeout_KeyPress (KeyAscii As Integer)
Select Case KeyAscii
Case 8, 9
'No action
Case 48 To 57 '0-9
'No action
Case Else
Let KeyAscii = 0
End Select
End Sub