Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Реализация DDE сервера, где hszItem? 
:(
    Опции темы
JavaCraft
  Дата 4.3.2009, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 8.2.2007

Репутация: нет
Всего: 1



Покажите пожалуйста на примере, как на стороне DDE-сервера
Получить hszItem, посланный клиентом

В параметрах функции обратного вызова нет такого параметра
HDDEDATA __stdcall DDEServer::Callback(UINT wType, UINT wFmt, HCONV hConv,
    HSZ hsz1, HSZ hsz2, HDDEDATA hData,ULONG_PTR dwData1, ULONG_PTR dwData2)

hConv - канал
hsz1 - раздел
hsz2 - сервис

Поиск по гуглу и докам пока не помог, там этот вопрос почему-то стороной обходят.

PM MAIL   Вверх
sergshabal
Дата 14.3.2009, 21:24 (ссылка) |  (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 6.1.2009

Репутация: нет
Всего: нет



Вот пытался реализовать дде сервер который бы принимал данные в формате xlTable и выводил их в StringGrid... но увы мои познания в программировании огорчили мня. есть также живой, работающий пример на делфи. Если у когото есть предложения как это все можно собрать на с++ builder буду рад выслушатьsmile

Код

main.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#include <ddeml.h>
#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HWND hDde;
unsigned long idInst;
AnsiString sTopic;
TPokeAction action;
PDdeQueItem p=new TDdeQueItem;
static const Word WM_DDE_ADDQUE = 0x402;
HSZ ServiceHSz,TopicHSz;
TThreadList *fDdeQue=new TThreadList;
int dataSize;
unsigned char szDDEData;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
HDDEDATA CALLBACK CallbackProc(UINT uType, UINT uFmt,HCONV hconv,HSZ hsz1,HSZ hsz2,
   HDDEDATA hdata,DWORD dwData1,DWORD dwData2)
{   /* TODO : Дописать фунцию обратного вызова */
    char buf[256];

    switch (uType) {
        case XTYP_CONNECT: {
          return (HDDEDATA)1;
        }
        case XTYP_POKE:{
          DdeQueryString(idInst,hsz1,buf,sizeof(buf),CP_WINANSI);
          sTopic=buf;
          //action=paPass;
          Form1->Memo1->Lines->Add("XTYP_POKE");
          if (&Form1->OnDdePoke) Form1->OnDdePoke(&sTopic,&action);
          //ShowMessage(action);
          switch (action){
              case paAccept: {
                 DdeQueryString(idInst,hsz2,buf,sizeof(buf),CP_WINANSI);
                 p->sTopic=sTopic;
                 p->sCells=buf;
                 p->size=DdeGetData(hdata,NULL,4,0);
                 DdeGetData(hdata,(unsigned char*)p->data,p->size,0);
                 try {
                   fDdeQue->LockList();
                   fDdeQue->Add(p);
                   Form1->Memo1->Lines->Add(p->sTopic+" "+p->sCells+" "+p->size);
                 }
                 __finally {
                   fDdeQue->UnlockList();
                 }
                 if (Form1->Handle!=0) {
                   PostMessageA(Form1->Handle,WM_DDE_ADDQUE,0,0);
                   Form1->AddQ();
                 }
                 return (HDDEDATA)dde_Ack;
              };
              case paPass: {
                 return (HDDEDATA)dde_Ack;
              };
              case paReject: {
                 return (HDDEDATA)dde_Busy;
              };
          }
        }
    }
    return (HDDEDATA)0;
};
void __fastcall TForm1::FormCreate(TObject *Sender)
{  Memo2->Lines->Add("in FormCreate");
   idInst=0;
   if (DdeInitializeA(&idInst,(PFNCALLBACK)CallbackProc,APPCLASS_STANDARD,0)==
       DMLERR_NO_ERROR) {
     ServiceHSz=DdeCreateStringHandleA(idInst,"rob",CP_WINANSI);
     TopicHSz=DdeCreateStringHandleA(idInst,"Topic",CP_WINANSI);
     if (DdeNameService(idInst,ServiceHSz,0,DNS_REGISTER)==0)
       ShowMessage("Не удалось зарегестрировать имя DDE сервера.");
   }
   else
     ShowMessage("Не удалось выполнить инициализацию DDE.");
   //fOnPoke=OnDdePoke;
   //fOnData=OnDdeData;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   DdeNameService(idInst,ServiceHSz,0,DNS_UNREGISTER);
   fDdeQue->Free();
   DdeFreeStringHandle(idInst,ServiceHSz);
   DdeUninitialize(idInst);
}
//---------------------------------------------------------------------------
TVariantTable __fastcall TForm1::XLTDecodeV(void * data, int datasize)
{ Memo2->Lines->Add("in XLTDecodeV");
  TVariantTable vtResult;
  int i;
  Pointer curr;
  Word BlockType, BlockSize;
  Byte StringSize;
  float RealData;
  ShortString StringData;
  int DataNum=0;
  AnsiString s;

  curr=addp(data, 4);
  vtResult.RowCount=(int)curr;
  curr=addp(curr, 2);
  vtResult.ColCount=(int)curr;
  vtResult.Cells.Length=vtResult.RowCount;
  for (i=0;vtResult.RowCount;i++){
    vtResult.Cells[i].Length=vtResult.ColCount;
  }
  while((int)subp(curr,data)<datasize) {
    BlockType=(int)curr;
    curr=addp(curr, 2);
    BlockSize=(int)curr;
    curr=addp(curr, 2);
    switch (BlockType){
      case 1: { //число
        while(BlockSize>0) {
          RealData=(int)curr;
          curr=addp(curr,8);
          BlockSize-=8;
          vtResult.Cells[DataNum/vtResult.ColCount][DataNum%vtResult.ColCount]=RealData;
          DataNum++;
        } ;
      } break;
      case 2: { //текст
        while(BlockSize>0) {
          StringSize=(Byte)curr;
          curr=addp(curr);
          StringData[0]=(char)StringSize;
          for (i=1;i<StringSize;i++){
            StringData[i]=(char)curr;
            curr=addp(curr);
          }
          vtResult.Cells[DataNum/vtResult.ColCount][DataNum%vtResult.ColCount]=StringData;
          DataNum++;
          BlockSize-=(StringSize+1);
        } ;
      } break;
    }
  };
  s.SetLength(datasize);
  for (i=0;i<datasize;i++){
    s[i+1]=(char)addp(data,i);
  }
  return vtResult;
}
//------------------------------------------------------------------------------
extern PACKAGE void * __fastcall addp(void * p, int increment = 0x1)/* overload */
{
  return (Pointer)((int)p+increment);
}
extern PACKAGE void * __fastcall addp(void * p, void * increment)/* overload */
{
  return (Pointer)((int)p+(int)increment);
}
extern PACKAGE void * __fastcall subp(void * p, int decrement = 0x1)/* overload */
{
  return (Pointer)((int)p-decrement);
}
extern PACKAGE void * __fastcall subp(void * p, void * decrement)/* overload */
{
  return (Pointer)((int)p-(int)decrement);
}
//--------------------------------------------------------------------------
Types::TRect __fastcall TForm1::DecodeCellAddr(AnsiString CellAddr)
{ Memo2->Lines->Add("in DecodeCellAddr");
  TRect rResult;
  int tmp1,tmp2;
  CellAddr=UpperCase(CellAddr);
  tmp1=PosEx("R", CellAddr, 1);
  tmp2=PosEx("C", CellAddr,tmp1);
  try {
    rResult.Top=StrToInt(CellAddr.SubString(tmp1+1,tmp2-tmp1-1))-1;
  }
  catch(...)
  { exit; }
  tmp1=PosEx("R", CellAddr, tmp2);
  try {
    rResult.Left=StrToInt(CellAddr.SubString(tmp2+1,tmp1-tmp2-1-1))-1;
  }
  catch(...)
  { exit; }
  tmp2=PosEx("C", CellAddr,tmp1);
  try {
    rResult.Bottom=StrToInt(CellAddr.SubString(tmp1+1,tmp2-tmp1-1))-1;
    rResult.Right=StrToInt(CellAddr.SubString(tmp2+1,CellAddr.Length()-tmp2))-1;
  }
  catch(...)
  { exit; }
  return rResult;
}
//--------------------------------------------------------------------------
extern PACKAGE int __fastcall PosEx(AnsiString SubStr, AnsiString MainString, int i)
{
  if (i == 1) return AnsiPos(SubStr, MainString);
  else {
    int LenSubStr=SubStr.Length();
    int Len = MainString.Length() - LenSubStr + 1;
    while (i <= Len) {
      if (MainString[i] == SubStr[1]){
        int X = 1;
        while ((X < LenSubStr)&&(MainString[i + X] == SubStr[X + 1])) X++;
        if (X == LenSubStr) return i;
      }
      i++;
    }
    return 0;
  }
}
//--------------------------------------------------------------------------
MESSAGE void __fastcall TForm1::AddQue(Messages::TWMSysCommand & Message)
{  Memo2->Lines->Add("in AddQue");
   TVariantTable vt;
   TRect Cells;
   int i;
   try {
     p=(TDdeQueItem*)fDdeQue->LockList()->Items[fDdeQue->LockList()->Count-1];
     Cells=DecodeCellAddr(p->sCells);
     vt=XLTDecodeV(p->data,p->size);
     if (fOnData) {
       fOnData(p->sTopic,Cells, vt);
     }
     for (i=fDdeQue->LockList()->Count-1;i>0;i--) {
       p->data=fDdeQue->LockList()->Items[i];
       memset(p->data,0,p->size);
     }
   }
   __finally {
     fDdeQue->UnlockList();
   }
}
//------------------------------------------------------------------------------
void __fastcall TForm1::OnDdePoke(AnsiString * Topic, TPokeAction * action)
{
  action=paAccept;
  Memo2->Lines->Add("in OnDdePoke");
}
//------------------------------------------------------------------------------
void __fastcall TForm1::OnDdeData(AnsiString Topic, TRect Cells, TVariantTable Data)
{
  Memo2->Lines->Add("in OnDdeData");
  int i, j;
  // фиксируем для какой таблицы и какие ячейки обновлены
  Memo1->Lines->Add(TimeToStr(Now())+ ": Данные для темы "+Topic+", в ячейки R"+IntToStr(Cells.Top)+
      "C"+IntToStr(Cells.Left)+":R"+IntToStr(Cells.Bottom)+"C"+IntToStr(Cells.Right));
  // меняем размер сетки
  StringGrid1->RowCount = max(StringGrid1->RowCount, Cells.Bottom+1);
  StringGrid1->ColCount = max(StringGrid1->ColCount, Cells.Right+1);
  // заполняем сетку значенями не равными 0
  for (i=Cells.Top; i<Cells.Bottom;i++){
    for (j=Cells.Left;j<Cells.Right;j++){
        StringGrid1->Cells[j][i] = Data.Cells[i-Cells.Top][j-Cells.Left];
    }
  }
}
//----------------------------------------------------------------------------


void __fastcall TForm1::AddQ()
{
   Memo2->Lines->Add("in AddQ");
   TVariantTable vt;
   TRect Cells;
   int i;
   try {
     p=(TDdeQueItem*)fDdeQue->LockList()->Items[fDdeQue->LockList()->Count-1];
     Cells=DecodeCellAddr(p->sCells);
     vt=XLTDecodeV(p->data,p->size);
     if (fOnData) {
       fOnData(p->sTopic,Cells, vt);
     }
     for (i=fDdeQue->LockList()->Count-1;i>0;i--) {
       p->data=fDdeQue->LockList()->Items[i];
       memset(p->data,0,p->size);
     }
   }
   __finally {
     fDdeQue->UnlockList();
   }
}



Код

main.h
//---------------------------------------------------------------------------
#ifdef __cplusplus
   int max (int value1, int value2);
   int max(int value1, int value2)
   {return ( (value1 > value2) ? value1 : value2);}
#endif

#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
enum TPokeAction {paAccept, paPass, paReject};
typedef DynamicArray< DynamicArray< Variant > >  TDoubleVariant;


struct TVariantTable
{
   TDoubleVariant Cells;
   int RowCount;
   int ColCount;
};

typedef void __fastcall (__closure *TDdePokeEvent)(AnsiString *Topic, TPokeAction *Action);
typedef void __fastcall (__closure *TDdeDataEvent)(AnsiString Topic, TRect Cells, const TVariantTable Data);


struct TDdeQueItem;
typedef TDdeQueItem *PDdeQueItem;
struct TDdeQueItem
{
   void * data;
   int size;
   AnsiString sTopic;
   AnsiString sCells;
} ;

class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TStringGrid *StringGrid1;
        TSplitter *Splitter1;
        TMemo *Memo1;
        TMemo *Memo2;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
        //__property TDdePokeEvent OnPoke = {read=fOnPoke, write=fOnPoke};
    //__property TDdeDataEvent OnData = {read=fOnData, write=fOnData};
private:    // User declarations
public:
             // User declarations
        __fastcall TForm1(TComponent* Owner);
        TVariantTable __fastcall XLTDecodeV(void * data, int datasize);
        Types::TRect __fastcall DecodeCellAddr(AnsiString CellAddr);
        MESSAGE void __fastcall AddQue(Messages::TWMSysCommand & Message);
        TDdePokeEvent fOnPoke;
        TDdeDataEvent fOnData;
        void __fastcall OnDdePoke(AnsiString * Topic, TPokeAction * action);
        void __fastcall OnDdeData(AnsiString Topic, TRect Cells, TVariantTable Data);
        void __fastcall AddQ();

};
//---------------------------------------------------------------------------
namespace Ddeexlunt
{
extern PACKAGE void * __fastcall addp(void * p, int increment = 0x1);
extern PACKAGE void * __fastcall addp(void * p, void * increment);
extern PACKAGE void * __fastcall subp(void * p, int decrement = 0x1);
extern PACKAGE void * __fastcall subp(void * p, void * decrement);
extern PACKAGE int __fastcall PosEx(AnsiString SubStr, AnsiString MainString, int i);

}
using namespace Ddeexlunt;

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------
#endif




Присоединённый файл ( Кол-во скачиваний: 529 )
Присоединённый файл  Delphi_simpleDDE.zip 262,29 Kb
PM MAIL   Вверх
true25
Дата 6.12.2009, 02:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 30.11.2009

Репутация: нет
Всего: нет



Ты нашел ошибку??? получилось??? просто я что-то подобное пишу, и ничего не получается(((
PM MAIL   Вверх
MasterLom
Дата 21.9.2010, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 21.9.2010

Репутация: нет
Всего: нет



Цитата(sergshabal @ 14.3.2009,  21:24)
Вот пытался реализовать дде сервер который бы принимал данные в формате xlTable и выводил их в StringGrid... но увы мои познания в программировании огорчили мня. есть также живой, работающий пример на делфи. Если у когото есть предложения как это все можно собрать на с++ builder буду рад выслушатьsmile

Код

main.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#include <ddeml.h>
#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HWND hDde;
unsigned long idInst;
AnsiString sTopic;
TPokeAction action;
PDdeQueItem p=new TDdeQueItem;
static const Word WM_DDE_ADDQUE = 0x402;
HSZ ServiceHSz,TopicHSz;
TThreadList *fDdeQue=new TThreadList;
int dataSize;
unsigned char szDDEData;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
HDDEDATA CALLBACK CallbackProc(UINT uType, UINT uFmt,HCONV hconv,HSZ hsz1,HSZ hsz2,
   HDDEDATA hdata,DWORD dwData1,DWORD dwData2)
{   /* TODO : Дописать фунцию обратного вызова */
    char buf[256];

    switch (uType) {
        case XTYP_CONNECT: {
          return (HDDEDATA)1;
        }
        case XTYP_POKE:{
          DdeQueryString(idInst,hsz1,buf,sizeof(buf),CP_WINANSI);
          sTopic=buf;
          //action=paPass;
          Form1->Memo1->Lines->Add("XTYP_POKE");
          if (&Form1->OnDdePoke) Form1->OnDdePoke(&sTopic,&action);
          //ShowMessage(action);
          switch (action){
              case paAccept: {
                 DdeQueryString(idInst,hsz2,buf,sizeof(buf),CP_WINANSI);
                 p->sTopic=sTopic;
                 p->sCells=buf;
                 p->size=DdeGetData(hdata,NULL,4,0);
                 DdeGetData(hdata,(unsigned char*)p->data,p->size,0);
                 try {
                   fDdeQue->LockList();
                   fDdeQue->Add(p);
                   Form1->Memo1->Lines->Add(p->sTopic+" "+p->sCells+" "+p->size);
                 }
                 __finally {
                   fDdeQue->UnlockList();
                 }
                 if (Form1->Handle!=0) {
                   PostMessageA(Form1->Handle,WM_DDE_ADDQUE,0,0);
                   Form1->AddQ();
                 }
                 return (HDDEDATA)dde_Ack;
              };
              case paPass: {
                 return (HDDEDATA)dde_Ack;
              };
              case paReject: {
                 return (HDDEDATA)dde_Busy;
              };
          }
        }
    }
    return (HDDEDATA)0;
};
void __fastcall TForm1::FormCreate(TObject *Sender)
{  Memo2->Lines->Add("in FormCreate");
   idInst=0;
   if (DdeInitializeA(&idInst,(PFNCALLBACK)CallbackProc,APPCLASS_STANDARD,0)==
       DMLERR_NO_ERROR) {
     ServiceHSz=DdeCreateStringHandleA(idInst,"rob",CP_WINANSI);
     TopicHSz=DdeCreateStringHandleA(idInst,"Topic",CP_WINANSI);
     if (DdeNameService(idInst,ServiceHSz,0,DNS_REGISTER)==0)
       ShowMessage("Не удалось зарегестрировать имя DDE сервера.");
   }
   else
     ShowMessage("Не удалось выполнить инициализацию DDE.");
   //fOnPoke=OnDdePoke;
   //fOnData=OnDdeData;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   DdeNameService(idInst,ServiceHSz,0,DNS_UNREGISTER);
   fDdeQue->Free();
   DdeFreeStringHandle(idInst,ServiceHSz);
   DdeUninitialize(idInst);
}
//---------------------------------------------------------------------------
TVariantTable __fastcall TForm1::XLTDecodeV(void * data, int datasize)
{ Memo2->Lines->Add("in XLTDecodeV");
  TVariantTable vtResult;
  int i;
  Pointer curr;
  Word BlockType, BlockSize;
  Byte StringSize;
  float RealData;
  ShortString StringData;
  int DataNum=0;
  AnsiString s;

  curr=addp(data, 4);
  vtResult.RowCount=(int)curr;
  curr=addp(curr, 2);
  vtResult.ColCount=(int)curr;
  vtResult.Cells.Length=vtResult.RowCount;
  for (i=0;vtResult.RowCount;i++){
    vtResult.Cells[i].Length=vtResult.ColCount;
  }
  while((int)subp(curr,data)<datasize) {
    BlockType=(int)curr;
    curr=addp(curr, 2);
    BlockSize=(int)curr;
    curr=addp(curr, 2);
    switch (BlockType){
      case 1: { //число
        while(BlockSize>0) {
          RealData=(int)curr;
          curr=addp(curr,8);
          BlockSize-=8;
          vtResult.Cells[DataNum/vtResult.ColCount][DataNum%vtResult.ColCount]=RealData;
          DataNum++;
        } ;
      } break;
      case 2: { //текст
        while(BlockSize>0) {
          StringSize=(Byte)curr;
          curr=addp(curr);
          StringData[0]=(char)StringSize;
          for (i=1;i<StringSize;i++){
            StringData[i]=(char)curr;
            curr=addp(curr);
          }
          vtResult.Cells[DataNum/vtResult.ColCount][DataNum%vtResult.ColCount]=StringData;
          DataNum++;
          BlockSize-=(StringSize+1);
        } ;
      } break;
    }
  };
  s.SetLength(datasize);
  for (i=0;i<datasize;i++){
    s[i+1]=(char)addp(data,i);
  }
  return vtResult;
}
//------------------------------------------------------------------------------
extern PACKAGE void * __fastcall addp(void * p, int increment = 0x1)/* overload */
{
  return (Pointer)((int)p+increment);
}
extern PACKAGE void * __fastcall addp(void * p, void * increment)/* overload */
{
  return (Pointer)((int)p+(int)increment);
}
extern PACKAGE void * __fastcall subp(void * p, int decrement = 0x1)/* overload */
{
  return (Pointer)((int)p-decrement);
}
extern PACKAGE void * __fastcall subp(void * p, void * decrement)/* overload */
{
  return (Pointer)((int)p-(int)decrement);
}
//--------------------------------------------------------------------------
Types::TRect __fastcall TForm1::DecodeCellAddr(AnsiString CellAddr)
{ Memo2->Lines->Add("in DecodeCellAddr");
  TRect rResult;
  int tmp1,tmp2;
  CellAddr=UpperCase(CellAddr);
  tmp1=PosEx("R", CellAddr, 1);
  tmp2=PosEx("C", CellAddr,tmp1);
  try {
    rResult.Top=StrToInt(CellAddr.SubString(tmp1+1,tmp2-tmp1-1))-1;
  }
  catch(...)
  { exit; }
  tmp1=PosEx("R", CellAddr, tmp2);
  try {
    rResult.Left=StrToInt(CellAddr.SubString(tmp2+1,tmp1-tmp2-1-1))-1;
  }
  catch(...)
  { exit; }
  tmp2=PosEx("C", CellAddr,tmp1);
  try {
    rResult.Bottom=StrToInt(CellAddr.SubString(tmp1+1,tmp2-tmp1-1))-1;
    rResult.Right=StrToInt(CellAddr.SubString(tmp2+1,CellAddr.Length()-tmp2))-1;
  }
  catch(...)
  { exit; }
  return rResult;
}
//--------------------------------------------------------------------------
extern PACKAGE int __fastcall PosEx(AnsiString SubStr, AnsiString MainString, int i)
{
  if (i == 1) return AnsiPos(SubStr, MainString);
  else {
    int LenSubStr=SubStr.Length();
    int Len = MainString.Length() - LenSubStr + 1;
    while (i <= Len) {
      if (MainString[i] == SubStr[1]){
        int X = 1;
        while ((X < LenSubStr)&&(MainString[i + X] == SubStr[X + 1])) X++;
        if (X == LenSubStr) return i;
      }
      i++;
    }
    return 0;
  }
}
//--------------------------------------------------------------------------
MESSAGE void __fastcall TForm1::AddQue(Messages::TWMSysCommand & Message)
{  Memo2->Lines->Add("in AddQue");
   TVariantTable vt;
   TRect Cells;
   int i;
   try {
     p=(TDdeQueItem*)fDdeQue->LockList()->Items[fDdeQue->LockList()->Count-1];
     Cells=DecodeCellAddr(p->sCells);
     vt=XLTDecodeV(p->data,p->size);
     if (fOnData) {
       fOnData(p->sTopic,Cells, vt);
     }
     for (i=fDdeQue->LockList()->Count-1;i>0;i--) {
       p->data=fDdeQue->LockList()->Items[i];
       memset(p->data,0,p->size);
     }
   }
   __finally {
     fDdeQue->UnlockList();
   }
}
//------------------------------------------------------------------------------
void __fastcall TForm1::OnDdePoke(AnsiString * Topic, TPokeAction * action)
{
  action=paAccept;
  Memo2->Lines->Add("in OnDdePoke");
}
//------------------------------------------------------------------------------
void __fastcall TForm1::OnDdeData(AnsiString Topic, TRect Cells, TVariantTable Data)
{
  Memo2->Lines->Add("in OnDdeData");
  int i, j;
  // фиксируем для какой таблицы и какие ячейки обновлены
  Memo1->Lines->Add(TimeToStr(Now())+ ": Данные для темы "+Topic+", в ячейки R"+IntToStr(Cells.Top)+
      "C"+IntToStr(Cells.Left)+":R"+IntToStr(Cells.Bottom)+"C"+IntToStr(Cells.Right));
  // меняем размер сетки
  StringGrid1->RowCount = max(StringGrid1->RowCount, Cells.Bottom+1);
  StringGrid1->ColCount = max(StringGrid1->ColCount, Cells.Right+1);
  // заполняем сетку значенями не равными 0
  for (i=Cells.Top; i<Cells.Bottom;i++){
    for (j=Cells.Left;j<Cells.Right;j++){
        StringGrid1->Cells[j][i] = Data.Cells[i-Cells.Top][j-Cells.Left];
    }
  }
}
//----------------------------------------------------------------------------


void __fastcall TForm1::AddQ()
{
   Memo2->Lines->Add("in AddQ");
   TVariantTable vt;
   TRect Cells;
   int i;
   try {
     p=(TDdeQueItem*)fDdeQue->LockList()->Items[fDdeQue->LockList()->Count-1];
     Cells=DecodeCellAddr(p->sCells);
     vt=XLTDecodeV(p->data,p->size);
     if (fOnData) {
       fOnData(p->sTopic,Cells, vt);
     }
     for (i=fDdeQue->LockList()->Count-1;i>0;i--) {
       p->data=fDdeQue->LockList()->Items[i];
       memset(p->data,0,p->size);
     }
   }
   __finally {
     fDdeQue->UnlockList();
   }
}



Код

main.h
//---------------------------------------------------------------------------
#ifdef __cplusplus
   int max (int value1, int value2);
   int max(int value1, int value2)
   {return ( (value1 > value2) ? value1 : value2);}
#endif

#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
enum TPokeAction {paAccept, paPass, paReject};
typedef DynamicArray< DynamicArray< Variant > >  TDoubleVariant;


struct TVariantTable
{
   TDoubleVariant Cells;
   int RowCount;
   int ColCount;
};

typedef void __fastcall (__closure *TDdePokeEvent)(AnsiString *Topic, TPokeAction *Action);
typedef void __fastcall (__closure *TDdeDataEvent)(AnsiString Topic, TRect Cells, const TVariantTable Data);


struct TDdeQueItem;
typedef TDdeQueItem *PDdeQueItem;
struct TDdeQueItem
{
   void * data;
   int size;
   AnsiString sTopic;
   AnsiString sCells;
} ;

class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TStringGrid *StringGrid1;
        TSplitter *Splitter1;
        TMemo *Memo1;
        TMemo *Memo2;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
        //__property TDdePokeEvent OnPoke = {read=fOnPoke, write=fOnPoke};
    //__property TDdeDataEvent OnData = {read=fOnData, write=fOnData};
private:    // User declarations
public:
             // User declarations
        __fastcall TForm1(TComponent* Owner);
        TVariantTable __fastcall XLTDecodeV(void * data, int datasize);
        Types::TRect __fastcall DecodeCellAddr(AnsiString CellAddr);
        MESSAGE void __fastcall AddQue(Messages::TWMSysCommand & Message);
        TDdePokeEvent fOnPoke;
        TDdeDataEvent fOnData;
        void __fastcall OnDdePoke(AnsiString * Topic, TPokeAction * action);
        void __fastcall OnDdeData(AnsiString Topic, TRect Cells, TVariantTable Data);
        void __fastcall AddQ();

};
//---------------------------------------------------------------------------
namespace Ddeexlunt
{
extern PACKAGE void * __fastcall addp(void * p, int increment = 0x1);
extern PACKAGE void * __fastcall addp(void * p, void * increment);
extern PACKAGE void * __fastcall subp(void * p, int decrement = 0x1);
extern PACKAGE void * __fastcall subp(void * p, void * decrement);
extern PACKAGE int __fastcall PosEx(AnsiString SubStr, AnsiString MainString, int i);

}
using namespace Ddeexlunt;

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------
#endif

Привет. Спасибо огромное за работающий пример на делфи. у меня вопрос возник: отображение в таблице выводимых данных запаздывает из за постоянного изменения данных? ну на примере стакана? или из за графической прорисовки в мемо и стринггриде?

PM MAIL   Вверх
DrMcSheen
Дата 18.12.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 18.12.2010

Репутация: нет
Всего: нет



А что нужно писать в диалоге квика, чтоб подключиться к приложенному примеру на делфи?
user posted image

Это сообщение отредактировал(а) DrMcSheen - 18.12.2010, 18:03
PM MAIL   Вверх
MasterLom
Дата 20.12.2010, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 21.9.2010

Репутация: нет
Всего: нет



Exel
Книга1
Лист1
PM MAIL   Вверх
DrMcSheen
Дата 21.12.2010, 03:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 18.12.2010

Репутация: нет
Всего: нет



 smile 
PM MAIL   Вверх
DrMcSheen
Дата 23.1.2011, 13:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 18.12.2010

Репутация: нет
Всего: нет



Кароч, вот что получилось.
Имя сервера My_DDE
Имена таблиц Table_1, Table_2 и т.д.
В квике - на таблице правой кнопкой - вывод через DDE.
Проект на 6-м билдере.
По просьбам трудящихся немножко подредактировал и картинку вставил.


Это сообщение отредактировал(а) DrMcSheen - 14.2.2012, 20:08

Присоединённый файл ( Кол-во скачиваний: 222 )
Присоединённый файл  DDE.rar 514,94 Kb
PM MAIL   Вверх
Miller1981
Дата 24.1.2011, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 7.8.2010

Репутация: нет
Всего: нет



sergshabal - у тебя в коде почти в каждой строчке ошибка. Ты такими темпами не перепишешь.  Там есть канечно свои заморочки по сообщениям и преобразованиям, но в общем у меня где то 2 дня ушло на переписку, если вышеуказанные вещи знать изначально(про сообщения и преобразования) то часов за 4-5 переписать можно. Кому нада обращайтесь, могу предоставить код на Builder c++: [email protected]  icq:340-553-273
PM MAIL   Вверх
Miller1981
Дата 24.1.2011, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 7.8.2010

Репутация: нет
Всего: нет



такой вопрос появился - а можно ли несколько таблиц одновременно считывать. По этому коду - всегда будет читатся только одна.
PM MAIL   Вверх
AntonBV
Дата 28.7.2011, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 26.7.2011

Репутация: нет
Всего: нет



При попытке вывода таблицы параметров из квика в пример на билдере вылетает исключение DynArrayOutOfRange. С чем может быть связано? В таблице всего 3 инструмента и несколько столбцов, причем стакан сделок выводится на ура...

user posted image




Заранее спасибо.


Перестало вылетать как только отключил галочку в квике "Передавать с названиями столбцов". Почему, так и не понял. ищу дальше, может кто сталкивался?
Оставил всего 3 столбца, тоже заработало все хорошо...


Miller1981
 для того что-бы передавать несколько таблиц, достаточно настроить для каждой разные темы и по ним сортировать в своей программе данные. 

Это сообщение отредактировал(а) AntonBV - 28.7.2011, 16:05
PM MAIL   Вверх
AntonBV
Дата 28.7.2011, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 26.7.2011

Репутация: нет
Всего: нет



Ну так что, товарищи, кто-нибудь может найти в чем ошибка, эксперементальным методом выяснил, что количество строк не играет роли, а количество столбцов максимально 11 не считая столбца названия инструмента.. 
PM MAIL   Вверх
виктор2009
Дата 3.11.2015, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 3.11.2015

Репутация: нет
Всего: нет



Цитата(DrMcSheen @ 23.1.2011,  13:22)
Кароч, вот что получилось.
Имя сервера My_DDE
Имена таблиц Table_1, Table_2 и т.д.
В квике - на таблице правой кнопкой - вывод через DDE.
Проект на 6-м билдере.
По просьбам трудящихся немножко подредактировал и картинку вставил.

 smile  smile  smile  smile  smile Чувак, респект))))Бился 2 дня, пока нашел твою прогу)))))Воть сейчас модифицировать буду.Спасибо за труд!!!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0983 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.