Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Use DDE in fortran

jinny
Beginner
1,327 Views
Hi, I want to exchange information with a DDE server using FORTRAN. Is it possible? How to do it? Is there any simple ways to do it like in MATLAB? Thanks a lot!!
0 Kudos
8 Replies
Jugoslav_Dujic
Valued Contributor II
1,327 Views
Uhm, DDE is the least preferred way for data exchange -- it is being suppressed even by Microsoft and slowly dying. The only reason I can think of for using it is for communication with some oldish software. I could blow off the dust from some codes I wrote long time ago, but I'd prefer if you could give some more info why do you need it -- better ways involve shared memory, WM_COPYDATA mechanism, COM etc.

Jugoslav
0 Kudos
jinny
Beginner
1,327 Views
Hi, Thank you for your information. Yeah, I am trying to use DDE to talk with a very old software (METALINK - a software that can bring data from a data colleting system). I have successfully set up DDE communication with METALINK in VBA environment. But since most of my calculation is in FORTRAN, I am wondering whether I can set up similar communication with METALINK as I did in VBA. Thanks a lot and have a good day!

Jinny
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,327 Views
Uh, I know I shouldn't have responded :-). OK, here's what I wrote once (some 5 years ago...), and what I recall about it. Please take it more as a guideline in which help topics to look at than as a working sample. It used to exchange data with DDE server application "SCADASim". IIRC it assumed that the application was already running.
INTEGER(2)::            aApp,aTopic
!Initiating conversation with the server (in WinMain):
aApp = GlobalAddAtom('SCADASim'C) 
aTopic = GlobalAddAtom('System'C) 
iSt = SendMessage(-1,WM_DDE_INITIATE,hFrame,aTopic.OR.ISHL(aApp,-16))
iSt = GlobalDeleteAtom(aApp)
iSt = GlobalDeleteAtom(aTopic)
SCADASim has a built-in timer which bombed my client with WM_DDE_DATA periodically. Upon receiving first reply from the server (WM_DDE_ACK) it sends back a WM_DDE_ADVISE telling it how to write the data using piece of memory with handle hOptions (FrameWindowProc):
INTEGER,SAVE::          nRecMsg=0
INTEGER(2)::            aData
CHARACTER*10::          szDDEMsg
TYPE(T_DDEADVISE)::     DDEA; POINTER(pDDEA,DDEA)
...
CASE (WM_DDE_ACK)
   !Receive first response & send ADVISE message
   IF (.NOT.bConnected) THEN
      bConnected=.TRUE.
      hServer=wParam
      hOptions=GlobalAlloc(GMEM_MOVEABLE.OR.GMEM_DDESHARE,4)
      pDDEA=GlobalLock(hOptions)
      DDEA%cfFormat=CF_TEXT
      DDEA%Bits=IBSET(DDEA%Bits,14)
      DDEA%Bits=IBCLR(DDEA%Bits,15)
      bSt=GlobalUnlock(hOptions)
      iError=GetLastError()
      aData=GlobalAddAtom('Measurement'C)
      lpm=PackDDElParam(WM_DDE_ADVISE,hOptions,aData)
      bSt=PostMessage(hServer,WM_DDE_ADVISE,hFrame,lpm)
      IF (.NOT.bSt) THEN
          iSt=GlobalDeleteAtom(lParam)
          iSt=GlobalFree(hOptions)
          bSt=FreeDDElparam(WM_DDE_ADVISE,lpm)
      END IF
   END IF

The server sends a WM_DDE_DATA periodically. I think bits of extracting DDEDATA structure, which contains the real info, are missing from the code (and I'm not willing to reconstruct it at 11 P.M.)
CASE (WM_DDE_DATA)
   !Receiving data from the server. 
   nRecMsg=nRecMsg+1
   bSt=UnpackDDElparam(Msg,lparam,LOC(hOptions),LOC(aData))
   !Hmm, some code appears to be missing. I think 
   !hOptions should be GlobalUnlocked, dereferenced to a 
   !T_DDEDATA structure using a Cray pointer, 
   !and data are in its Value member.
   bSt=FreeDDElparam(Msg,lparam)


Huhh... as you can see, 1) it is plain ugly 2) it requires lot of fiddling with LOCs and Cray pointers 3) Pack/Unpack/Free DDElParam is an ugly tweak to pack a bottle into a glass 4) it requires careful reading of docs (which I did at the time but, fortunately, forgot mostly what it was about :-)).

Hope it still helps a bit,
Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,327 Views
...(after I wasted half an hour reconstructing that code)... as a conclusion, it looks like a better idea to retain the DDE communication in VB (especially if it's as simple as you say) and combine it with a Fortran dll than to try to write it in Fortran (actually, that is plain API which looks more to C than to Fortran). I'm not aware of existence of any 3rd-party wrapper libraries that could ease the job, and my own code looks scarying to me...
0 Kudos
jinny
Beginner
1,327 Views
:> You are funny :). Thanks a lot for replying to my question, and the time to write the codes! I tried to combine FORTRAN and VB and use VB as the interface. But it's not easy to share data between these two unless you exchange all the data through parameters. VB and MATLAB have good wrappings for DDE but it's a tough job for FORTRAN to share data with them. :(

Thanks a lot and Happy New Year.

Jinny
0 Kudos
esterquest
Beginner
1,327 Views
We are trying to find a simple example of two Fortran programs, one creates a named shared memory area and the other accesses that same named shared memory area.
The opearting system wouykd be Windows 2000, NT, or XP.

We are trying to get multiple Fortran programs to share the same area of main memory.

Any help is much appreciated.
Thanks
0 Kudos
gfthomas8
Novice
1,327 Views
The CVF sample SHAREMEM will get you started. Look at Richter's 'Developing Windows Applications' (in C++ of course) under memory mapped files.

HTH,
Gerry T.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,327 Views
See also ShareBufferWin32 module at Fortran Library -- it is a wrapper ready for use.

Jugoslav
0 Kudos
Reply