Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Connect to DDE Server
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Connect to DDE Server

Scheduled Pinned Locked Moved General and Desktop
12 Posts 3 Posters 9.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jbrooksuk
    wrote on last edited by
    #1

    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

    1 Reply Last reply
    0
    • A Offline
      A Offline
      AcerExtensa
      wrote on last edited by
      #2

      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()@

      God is Real unless explicitly declared as Integer.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jbrooksuk
        wrote on last edited by
        #3

        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'@

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AcerExtensa
          wrote on last edited by
          #4

          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/@

          God is Real unless explicitly declared as Integer.

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jbrooksuk
            wrote on last edited by
            #5

            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!

            1 Reply Last reply
            0
            • A Offline
              A Offline
              AcerExtensa
              wrote on last edited by
              #6

              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/ @

              God is Real unless explicitly declared as Integer.

              1 Reply Last reply
              1
              • J Offline
                J Offline
                jbrooksuk
                wrote on last edited by
                #7

                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

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  AcerExtensa
                  wrote on last edited by
                  #8

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

                  God is Real unless explicitly declared as Integer.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jbrooksuk
                    wrote on last edited by
                    #9

                    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?

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      AcerExtensa
                      wrote on last edited by
                      #10

                      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();
                      }@

                      God is Real unless explicitly declared as Integer.

                      1 Reply Last reply
                      1
                      • J Offline
                        J Offline
                        jbrooksuk
                        wrote on last edited by
                        #11

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

                        1 Reply Last reply
                        0
                        • MomergilM Offline
                          MomergilM Offline
                          Momergil
                          wrote on last edited by
                          #12

                          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

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved