    #include <ads/adscpp.h>

    #include <ads/ddeinc.h>

    #include <ads/adsinc.h>

    #include <afc/cybernet.h>

    #include <ads/Lists.h>

    #include <ads/ListIter.h>

    #include "pline.h"

    #include "block.h"

    #define DDE

    static char *CybName= "2037551666__HMI_KYCAD";

    const double max_distance = 0.5; // 0.5 metra za simbol

    class WaterWay : public ADS_APP
    {
    public:
      WaterWay(int argc, char **argv);

    private:
      BASIC_CPP_STUFF(WaterWay);
    };

    DDE_CLIENT_CONNECTION *chnl;

    void PanTo(struct resbuf *)
    {
      struct resbuf *rb;
      char handle[17];
      rb = ads_getargs();

      if (rb == NULL)
        {
          ads_printf("manjka argument handle\n");
          return;
        }

      ads_printf("rrestype = %d, resval %s\n", rb->restype, rb->resval.rstring);

      strcpy(handle, rb->resval.rstring);
      ads_relrb(rb);

      ads_name entres;
      int status = ads_handent(handle, entres);
      if (status != RTNORM)
        {
          ads_printf("Gradnik ne obstaja\n");
          return;
        }
    vertex:
      rb = ads_entget(entres);
      assert(rb != NULL);
      struct resbuf *pos;
      for(pos = rb; pos != NULL; pos = pos->rbnext)
        {
          if (pos->restype == 0)
            {
              if ((strcmp(pos->resval.rstring, "LWPOLYLINE") == 0)
                 || (strcmp(pos->resval.rstring, "POLYLINE") == 0))
                {
                  // premakni se na prvi vertex

                  ads_name head;
                  ads_relrb(rb);
                  head[0] = entres[0];
                  head[1] = entres[1];
                  status = ads_entnext(head, entres);
                  assert( status == RTNORM);
                  goto vertex;
                }
            }
          else if (pos->restype == 10)
            {
              ads_printf("Premik na %lf, %lf\n", pos->resval.rpoint[0], pos->resval.rpoint[1]);
              ads_command(RTSTR, "ZOOM", RTSTR, "C", RTPOINT, pos->resval.rpoint, RTSTR, "",  NULL);
              break;
            }
        }
      assert(pos != NULL);
      ads_relrb(rb);
    }

    void InsertPline(struct resbuf *)
    {
      int status;
      static int plineCounter = 0;

      ads_name ss, ssInsert;
      struct resbuf *rb;
      long ssLength, ssInsertLength;

      rb = ads_buildlist (RTDXF0, "POLYLINE",  NULL);

      assert(rb != NULL);

      status = ads_ssget (NULL, NULL, NULL, rb, ss);

      ads_relrb (rb);

      if (status != RTNORM)         /* Prazen izbor */
        {
          ads_printf("Izbira preklicana\n");
          return;
        }

      rb = ads_buildlist(RTDXF0, "INSERT", NULL);

      status = ads_ssget("X", NULL, NULL,  rb, ssInsert);
      if (status != RTNORM)
        {
          ads_printf("Ni blokov v risbi\nIzbira ni mozna!");
          ads_relrb(rb);
          return;
        }

      Lists<cblock> blocks;

      status = ads_sslength (ssInsert, &ssInsertLength);
    //  ads_printf("Total blocks %ld\n", ssInsertLength);

      for (long j = 0; j < ssInsertLength; j++)
        {
          ads_name name;
          struct resbuf *block_rb;
          ads_ssname(ssInsert, j, name);
          block_rb = ads_entget(name);
          blocks.append(cblock(block(block_rb)));
          ads_relrb(block_rb);
        }
      status = ads_sslength (ss, &ssLength);
      ads_printf("Total blocks %ld\n", ssLength);

      struct resbuf *temp_rb;

      for (long i = 0; i < ssLength; ++i) // za vse PLINE

        {
          ads_name name;
          vec3 first, last;
          int firstExist, lastExist;
          pline *p;
          ads_ssname(ss, i, name);
          temp_rb = ads_entget(name);
          p = new pline(temp_rb);
          ADS_STRING msg;
          msg = "ODS," + p->handle();
          chnl->BeginSend();
          chnl->SendString(msg);
          chnl->EndSend();

    #if 1

          first = p->first(); firstExist = 0; // ali je zacetni vozel na PLINE

          last = p->last();   lastExist = 0;  // ali je koncni vozel na PLINE

    #endif

          ListIterators<cblock> iterator(blocks);
          for (iterator.reset(); !iterator.isDone(); iterator.next()) // za vse bloke

            {
              double distance;
    //          ads_printf("item: [%lf %lf]\n",

    //                     iterator.currentItem()->origin()[X],

    //                     iterator.currentItem()->origin()[Y]);

              distance = p->nearest(iterator.currentItem()->origin());
              if (distance < max_distance)
                {
                ads_printf("Handle= %s, name = %s\n",
                           iterator.currentItem()->handle().CString(),
                           iterator.currentItem()->name().CString(),
                           distance);
                msg =   iterator.currentItem()->name() + ","
                               + iterator.currentItem()->handle();
                chnl->BeginSend();
                chnl->SendString(msg);
                chnl->EndSend();

                }
    #if 1

              if ((iterator.currentItem()->origin() - first).length() < max_distance)
                  firstExist++;
              if ((iterator.currentItem()->origin() - last).length() < max_distance)
                  lastExist++;
    #endif

            }
          if (!firstExist)   // dodaj nov  zacetni vozel in ga poslji

            {
              ads_point origin;
              ads_name  result;
              origin[0] = first[0];
              origin[1] = first[1];
              origin[2] = first[2];
              ads_printf("Nov blok na zacetku: [%lf %lf]\n",
                         origin[X],
                         origin[Y]);
              ads_command(RTSTR, "INSERT",  RTSTR, "KV", RTPOINT, origin, RTSTR, "17",
                          RTSTR, "17", RTSTR, "0", NULL);
              ads_entlast(result);
              struct resbuf *block_rb = ads_entget(result);
              block newblock(block_rb);
              blocks.append(cblock(newblock));
              msg =   newblock.name() + "," + newblock.handle();
              chnl->BeginSend();
              chnl->SendString(msg);
              chnl->EndSend();
              ads_relrb(block_rb);
            }
          if (!lastExist)   // dodaj nov  KONCNI vozel in ga poslji

            {
              ads_point origin;
              ads_name  result;
              origin[0] = last[0];
              origin[1] = last[1];
              origin[2] = last[2];
              ads_printf("Nov blok na koncu: [%lf %lf]\n",
                         origin[X],
                         origin[Y]);
              ads_command(RTSTR, "INSERT",  RTSTR, "KV", RTPOINT, origin, RTSTR, "17",
                          RTSTR, "17", RTSTR, "0", NULL);
              ads_entlast(result);
              struct resbuf *block_rb = ads_entget(result);
              block newblock(block_rb);
              blocks.append(cblock(newblock));
              msg =   newblock.name() + "," + newblock.handle();
              chnl->BeginSend();
              chnl->SendString(msg);
              chnl->EndSend();
              ads_relrb(block_rb);
            }
          char txtbuf[18];
          sprintf(txtbuf, "%d", ++plineCounter);
          p->Mark(txtbuf, "OZNAKE", 5);
          delete p;
          ads_relrb(temp_rb);
        }
    }

    void InsertContainer(struct resbuf *)
    {
      int status;
      static int plineCounter = 0;

      ads_name ss;
      struct resbuf *rb;
      long ssLength;

      rb = ads_buildlist (RTDXF0, "INSERT",  NULL);

      assert(rb != NULL);

      status = ads_ssget (NULL, NULL, NULL, rb, ss);

      ads_relrb (rb);

      if (status != RTNORM)         /* Prazen izbor */
        {
          ads_printf("Izbira preklicana\n");
          return;
        }

      Lists<cblock> blocks;

      status = ads_sslength (ss, &ssLength);

    //  ads_printf("Total blocks %ld\n", ssInsertLength);

      for (long j = 0; j < ssLength; j++)
        {
          ads_name name;
          struct resbuf *block_rb;
          ads_ssname(ss, j, name);
          block_rb = ads_entget(name);
          blocks.append(cblock(block(block_rb)));
          ads_relrb(block_rb);
        }

      ads_printf("Total blocks %ld\n", ssLength);

      struct resbuf *temp_rb;

      ListIterators<cblock> iterator(blocks);
      for (iterator.reset(); !iterator.isDone(); iterator.next()) // za vse bloke

        {
            ADS_STRING msg;
    //      ads_printf("item: [%lf %lf]\n",

    //                 iterator.currentItem()->origin()[X],

    //                 iterator.currentItem()->origin()[Y]);

            ads_printf("Handle= %s, name = %s\n",
                       iterator.currentItem()->handle().CString(),
                       iterator.currentItem()->name().CString());
            msg =   "+" + iterator.currentItem()->name() + ","
                           + iterator.currentItem()->handle();
            chnl->BeginSend();
            chnl->SendString(msg);
            chnl->EndSend();

        }
    }

    void FindObject(struct resbuf *)
    {
      int status;
      ads_name  ename;
      ads_point ptres;

      status = ads_entsel("Izberi gradnik>", ename, ptres);
      if (status != RTNORM)
        {
          ads_printf("Prekinjeno\n");
          return;
        }
      struct resbuf *rb, *rb_temp;

      ADS_STRING handle, oznaka, msg;
      rb = ads_entget(ename);
      assert (rb != NULL);
      for (rb_temp = rb;  rb_temp != NULL; rb_temp = rb_temp->rbnext)
        {
          switch (rb_temp->restype)
            {
              case 5:
                handle = ADS_STRING(rb_temp->resval.rstring);
                break;
              case 0:
                oznaka = ADS_STRING(rb_temp->resval.rstring);
                break;
            }
        }

     msg =  "_" + oznaka + "," + handle;
     chnl->BeginSend();
     chnl->SendString(msg);
     chnl->EndSend();
     ads_relrb(rb);

    }

    WaterWay::WaterWay(int argc, char **argv) : ADS_APP(argc, argv)
    {
       InsertExternFunc(ADS_FUNC_INFO( ADS_FUNC( PanTo ),
                                      ADS_VOID_FUNC,  "pantohandle"));
       InsertExternFunc(ADS_FUNC_INFO( ADS_FUNC( InsertPline ),
                                      ADS_VOID_FUNC,  "c:ip" ));
       InsertExternFunc(ADS_FUNC_INFO( ADS_FUNC( InsertContainer ),
                                      ADS_VOID_FUNC,  "c:ic" ));
       InsertExternFunc(ADS_FUNC_INFO( ADS_FUNC( FindObject ),
                                      ADS_VOID_FUNC,  "c:fo" ));
    }

    void main (int argc, char *argv[])
    {
      WaterWay *app = new WaterWay(argc, argv);
    #if 0

      chnl =  new DDE_CLIENT_CONNECTION(SERVER_INFO("c:/tmp", UNKNOWNSERVER));

      if (chnl->Init(ADS_STRING("WaterWay"), ADS_STRING("System"),
                ADS_STRING("HANDLE")) != TRUE)
        {
          ads_printf("Cannot initiate channel\n");
          return;
        }

      if (chnl->SetupConnection())
        {
          ads_printf("DDE Connection OK\n");
        }
    #endif

      app->Run();
    #if 0

      delete chnl;
    #endif

    }

syntax highlighted by Code2HTML, v. 0.9.1