[SOLVED] Connect to DDE Server



  • Hi all,

    Is there any way I can connect to a DDE server? I know DDE is dated tech, but it's the only option I have for what I'm attempting to do.

    I've found http://permalink.gmane.org/gmane.comp.lib.qt.general/91 but it only works in Qt 3 and I'm too inexperienced to convert it forwards. Any help?

    Thanks,
    James



  • It only Qt dependency is QString. It is very easy to port it to Qt4.

    For example, instead of
    @command.ascii()@
    use
    @command.toAscii().data()@



  • That's a good start. I've also fixed some other problems by using (LPCSTR) val.utf16() which solved a couple of problems.

    That being said, can you see why this wont work?

    @DDEComm *cyDesk;
    QString result;
    cyDesk->ddeConnect("CYDESK", "Data");
    cyDesk->ddeExecute("CALL NUMBER", result);@

    I always get the following:

    @C:\Users\James.Brooks\Desktop\BLUI-BUILD-DBG..\BLUI\ddecomm.cpp:100: error: C2511: 'QString DDEComm::ddeExecute(const QString &,const QString &)' : overloaded member function not found in 'DDEComm'@



  • change function declaration in ddecomm.h from
    @QString ddeExecute(QString command, QString result); /!< Executa um comando no servidor dde/@
    to
    @QString ddeExecute(const QString &command, const QString &result) /!< Executa um comando no servidor dde/@



  • We're getting closer! Now I made the changes you said about .ascii().data() but I get 'ascii' is not a member of QString.

    Has this got something to do with the changes I made earlier?

    @hszRequest = DdeCreateStringHandleA(pidInst, (LPCSTR)item.utf16(), CP_WINANSI);@

    I added the (LPCSTR)item.utf16() part, which shut some errors up.

    So I've tried the following:

    @QString DDEComm::ddeExecute(const QString &command, const QString &result)
    {
    char *commandName = NULL;
    strcpy(commandName, (LPCSTR)command.toAscii());
    transactionData = DdeCreateDataHandle(pidInst, (LPBYTE) commandName, strlen(commandName), 0, 0L, CF_TEXT, NULL);
    DdeClientTransaction((LPBYTE) transactionData, -1, hConv, 0L, 0, XTYP_EXECUTE, 1000, NULL);

    QString returnData = ddeRequest(result);
    
    DdeFreeDataHandle(transactionData);
    
    return returnData;
    

    }@

    But now I get a hell load of errors:
    !http://dl.dropbox.com/u/7323096/QTDDE.PNG!



  • Here is patched DDEComm class:

    ddecomm.cpp
    @#include "ddecomm.h"

    DDEComm* DDEComm::_instance = NULL;

    DDEComm* DDEComm::instance()
    {
    if(_instance == NULL)
    _instance = new DDEComm();

    return _instance;
    }

    DDEComm::DDEComm()
    {
    connStatus = false;
    callback = NULL;
    pidInst = 0;
    hConv = 0L;
    }

    DDEComm::~DDEComm()
    {
    //Empty
    }

    bool DDEComm::ddeConnect(const QString &service, const QString &topic)
    {
    if(callback == NULL)
    {
    if(DdeInitializeA(&pidInst, NULL, APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0L) != DMLERR_NO_ERROR)
    return false;
    }
    else
    {
    if(DdeInitializeA(&pidInst, (PFNCALLBACK) callback, APPCLASS_STANDARD | APPCMD_CLIENTONLY | MF_CONV | MF_ERRORS, 0L) != DMLERR_NO_ERROR)
    return false;
    }

    hszService = DdeCreateStringHandleA(pidInst, service.toAscii().data(), CP_WINANSI);
    hszTopic = DdeCreateStringHandleA(pidInst, topic.toAscii().data(), CP_WINANSI);
    hConv = DdeConnect(pidInst, hszService, hszTopic, NULL);

    DdeFreeStringHandle(pidInst, hszService);
    DdeFreeStringHandle(pidInst, hszTopic);

    if(!hConv)
    return false;

    connStatus = true;

    return true;
    }

    void DDEComm::ddeDisconnect()
    {
    DdeDisconnect(hConv);
    DdeUninitialize(pidInst);
    connStatus = false;
    }

    void DDEComm::setDDECallback(PFNCALLBACK ddeCallback)
    {
    callback = ddeCallback;
    }

    QString DDEComm::ddeRequest(const QString &item)
    {
    if(!connStatus)
    return NULL;

    hszRequest = DdeCreateStringHandleA(pidInst, item.toAscii().data(), CP_WINANSI);
    recData = DdeClientTransaction(NULL, 0, hConv, hszRequest, CF_TEXT, XTYP_REQUEST, 1000, NULL);
    byte = DdeAccessData(recData, &dwLength);

    char data = (char) byte;
    QString retStr = data;
    DdeFreeStringHandle(pidInst, hszRequest);
    DdeFreeDataHandle(recData);
    return retStr;
    }

    QString DDEComm::ddeExecute(const QString &command, const QString &result)
    {

    transactionData = DdeCreateDataHandle(pidInst, (LPBYTE) command.toAscii().data(), command.length(), 0, 0L, CF_TEXT, NULL);
    DdeClientTransaction((LPBYTE) transactionData, -1, hConv, 0L, 0, XTYP_EXECUTE, 1000, NULL);

    QString returnData = ddeRequest(result);

    DdeFreeDataHandle(transactionData);

    return returnData;
    } @

    ddecomm.h
    @/*

    • ddecomm.h
    • Defines the interface for DDE communication class.
    • (C) 2005 Insite Comercio e Servicos.
    • Author: Rafael Roquetto
    • Qt4 patch: AcerExtensa
    • Created on 2005-06-03.
    • This is GPL software

    */

    #ifndef DDECOMM_H
    #define DDECOMM_H

    #include <windows.h>
    #include <QString>

    /*!

    • Classe singleton que fornece métodos para comunicacao via DDE
      */

    class DDEComm
    {
    public:

    static DDEComm* instance(); /*!< retorna um ponteiro para a instancia de DDEComm */

         bool ddeConnect(const QString & service, const QString & topic); /*!< Connecta ao servico DDE, no topico desejado */
    

    void ddeDisconnect(); /!< Desconecta do servico DDE/
    void setDDECallback(PFNCALLBACK ddeCallback); /*!< Seta uma funcao de callback a ser chamada na ocorrencia de eventos DDE */

         QString ddeRequest(const QString & item); /*!< Faz um request dde para o item fornecido */
         QString ddeExecute(const QString & command, const QString & result); /*!< Executa um comando no servidor dde*/
    

    protected:
    DDEComm();
    ~DDEComm();

    private:
    bool connStatus;
    PFNCALLBACK callback; //pointer to callback

         HCONV hConv;
         HSZ hszService;
         HSZ hszTopic;
         HDDEDATA recData;
         HDDEDATA transactionData;
         HSZ hszRequest;
         LPDWORD result;
         DWORD dwLength;
         LPBYTE byte;
    

    DWORD pidInst;

    static DDEComm *_instance;

    };
    #endif /DDECOMM_H/ @



  • I've updated my sources, yet I'm now getting a lot of LNK errors.

    ddecomm.obj:-1: error: LNK2019: unresolved external symbol _DdeFreeStringHandle@8 referenced in function "public: bool __thiscall DDEComm::ddeConnect(class QString const &,class QString const &)" (?ddeConnect@DDEComm@@QAE_NABVQString@@0@Z)
    ddecomm.obj:-1: error: LNK2019: unresolved external symbol _DdeCreateStringHandleA@12 referenced in function "public: bool __thiscall DDEComm::ddeConnect(class QString const &,class QString const &)" (?ddeConnect@DDEComm@@QAE_NABVQString@@0@Z)
    ddecomm.obj:-1: error: LNK2019: unresolved external symbol _DdeCreateStringHandleA@12 referenced in function "public: bool __thiscall DDEComm::ddeConnect(class QString const &,class QString const &)" (?ddeConnect@DDEComm@@QAE_NABVQString@@0@Z)
    ddecomm.obj:-1: error: LNK2019: unresolved external symbol _DdeUninitialize@4 referenced in function "public: void __thiscall DDEComm::ddeDisconnect(void)" (?ddeDisconnect@DDEComm@@QAEXXZ)

    ... etc



  • Add
    @#pragma comment(lib,"User32.lib")@
    somewhere in header



  • Wahey! Thank you very much AcerExtensa :) No errors compiling, however:

    @DDEComm *cyDesk;
    QString result;
    cyDesk->ddeConnect("CYDESK", "Data");
    cyDesk->ddeExecute("CALL ###", result);@

    Causes my app to crash. Is this is the wrong syntax?



  • Your cyDesk ponter is not initialized and points somewhere in the universe... :)

    try something like this:

    @
    #include <QDebug>
    #include "ddecomm.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    DDEComm * test = DDEComm::instance();
    const QString service = "CYDESK";
    const QString topic = "Data";
    const QString command = "CALL ###";
    QString result;

    if(test->ddeConnect(service,topic))
    {
    qDebug() << "RESULT: " << test->ddeExecute(command,result);
    }
    else qDebug() << "Can't connect to service";

    return a.exec();
    }@



  • You sir, are awesome! Thank you very, very much :)



  • Hi!

    I'ld also like to implement something with this lib. Could you please make the editted version public to download?

    Thanks very much!

    Momergil


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.