Has anyone a simple example of using dde? I do not need to do any sort of execution in excel or similar.
Just read some data from a server. The server in this case is an old program for trading forex (MT4). The exefile’s name is terminal.exe and I am just going to read some values from the program. I will use a timer to update the window/link.
I have source code in VB6/Delphi where this is easily implemented, but I would like to do it in Clarion.
In C1 -C6 the Clarion IDE could be driven by DDE so you could try to find source for a Batch compiler like Gordon Smith’s or SParker’s Go To Lunch.
I found this code to export a DCT
OpenTXD = CLIP(ShortPath()) & '\~' & Clock() & '.TXD'
Glo:FileSpec = OpenTXD
REMOVE(AsciiFile)
CWServer = DDECLIENT('ClarionWin')
IF NOT CWServer
MESSAGE('Unable to make DDE Connection to CW.|You will have to start CW.|Be sure to exit the pick screen.', |
'CW NOT RUNNING', ICON:Hand)
DO ProcedureReturn
END
!DDEEXECUTE(Server,'[ExportDct(MyDCT.DCT,MyTXD.TXD,0)]')
SYSTEM{PROP:DDETimeOut}=6000
DDEEXECUTE(CWServer,'[ExportDct(' & CLIP(SHORTPATH(ImportFile)) & ',' & CLIP(OpenTxd) & ',1)]')
IF ~ERRORCODE()
DDEClose(CWServer)
Exit
END
DDEClose(CWServer)
MESSAGE('An error occured trying to export a dictionary:'&|
'||DCT: '&ImportFile&|
'|TXD: '&OpenTxd&|
'||Error: '&ERRORCODE()&' '&CLIP(ERROR()), |
'DDE ERROR', ICON:Hand)
DO ProcedureReturn
EXIT
I still havent been able to make this to work in Clarion. It seems I am not able to find the correct server.
The exefil is ‘terminal.exe’, the description in the task manager is ‘MetaTrader’. I have tried to use ‘MT4’,'terminal. and ‘MetaTrader’. Nothing works.
In my 25 year old VB6 , it works without any problems. Strange.
Try DDEQuery(< server > , < topic> ) to get a list of servers and topics?
Maybe WinAPI has way to ask EXE for List of Server annd Topic Names.
WinOne WINDOW,AT(0,0,160,400)
END
SomeServer LONG
ServerString STRING(200)
CODE
OPEN(WinOne)
LOOP
ServerString = DDEQUERY() !Return all registered servers
IF NOT INSTRING('SomeApp:MyTopic',ServerString,1,1)
MESSAGE('Open SomeApp, Please')
ELSE
BREAK
END
END
SomeServer = DDECLIENT('SomeApp','MyTopic') !Open as client
ACCEPT
END
DDECLOSE(SomeServer)
In past I used DDE for other things. DDE is long unsupported protocol and it was finally stopped working from some 3 years ago, at least in my experience. Clarion can not help here, it is windows thing.
Carl,
I tested your code, and I inserted a message showing ‘Serverstring’ into the loop to be kept advised about dde servers running…
I tested to open/close various programs like excel, word, access etc to see how the serverstring changed. The serverstring showed these correctly.
But when I tried to open/close ‘MT4’ there was now change in the serverstring. It only showed something called ‘progman’. The ‘MT4’ is set up to act as a ddeserver, and I can as said read it with vb6 using dde.
But Clarion does not pick it up. I know DDE is old fashioned and not used much any more, but MT4 is a very widely used Forex program and many times it is used together with Excel to obtain quotes using DDE into Excel.
But no luck with Clarion, so I guess this is as far as I can get with Clarion.
If Clarion DDE is not working then I would resort to calling the DDE functions in the WinAPI like a C++ programmer. I did a quick search and it seems well documented. Found DdeConnectList() appears to be like DDEQuery(). I would start by trying to get that to show MT4
HCONVLIST hconvList; // conversation list
DWORD idInst; // instance identifier
HSZ hszSystem; // System topic
HCONV hconv = NULL; // conversation handle
CONVINFO ci; // holds conversation data
UINT cConv = 0; // count of conv. handles
HSZ *pHsz, *aHsz; // point to string handles
// Connect to all servers that support the System topic.
hconvList = DdeConnectList(idInst, NULL, hszSystem, NULL, NULL);
// Count the number of handles in the conversation list.
while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL)
cConv++;
// Allocate a buffer for the string handles.
hconv = NULL;
aHsz = (HSZ *) LocalAlloc(LMEM_FIXED, cConv * sizeof(HSZ));
// Copy the string handles to the buffer.
pHsz = aHsz;
while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL)
{
DdeQueryConvInfo(hconv, QID_SYNC, (PCONVINFO) &ci);
DdeKeepStringHandle(idInst, ci.hszSvcPartner);
*pHsz++ = ci.hszSvcPartner;
}
// Use the handles; converse with the servers.
// Free the memory and terminate the conversations.
LocalFree((HANDLE) aHsz);
DdeDisconnectList(hconvList);