Odbieranie danych z innego programu, będącego serwerem DDE

0

Hej!
Napisałem mały program, który ma odbierać dane z innego programu będącego serwerem DDE. Mam jednak problem bo otrzymuje jedynie komunikat "Niepoprawny format" a powinien się pokazać kurs WIG'u 20. Mógłby ktoś mi pomóc bo być może muszę po prostu zamienić format otrzymanych danych ale nie wiem jak...

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DDEMan, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function DDE_Read(Service, Topic, Items: string): string;
var
  DDE: TDDEClientConv;
begin
  try
    DDE := TDDEClientConv.Create(nil);
    DDE.SetLink(Service, Topic);
    DDE.OpenLink;
    Result:=DDE.RequestData(Items);
  finally
    DDE.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
Begin
ShowMessage(DDE_Read('Statica', 'kurs', 'wig20'));

end;

end.

dodanie znacznika <code class="delphi"> i poprawienie tytułu wątku - furious programming

1

W innym swoim wątku, gdzie pomoglem Tobie moimi kodami źródlowymi z DDE. Piszesz, że program docelowy potrzebuje takie coś Statica|kurs!'WIG20. Wnioskować po tym można, że potrzeba jeszcze albo tego wykrzyknika. Albo ważna jest wielkość liter w tym słowie wig. Polecalbym skotantkowanie się z producentem ów programu w celu uzyskania dodatkowych informacji, co dokładnie jest Tobie potrzebne do odczytania po DDE tych danych. Żeby mieć pewnośc jaką podawać zarówno nazwę service jak i topic. Niewiele więcej jesteśmy raczej tutaj pomóc. Chyba, że ktoś coś doradzi, kto miał do czynienia z tym programem po DDE.

0

Dzięki, nie wpadłem na to żeby próbować z wykrzyknikiem. Ale wlasnie wpadlem co moze byc nie tak:) Po prostu przestawilem kolejnosc podawanych argumentow i wszystko ladnie smiga.

ShowMessage(DDE_Read('Statica', 'WIG20', 'kurs'));

Dzieki Olesio za pomoc!!

Zastanawiałem się czy nie wrzucić tego do poprzedniego wątku ale to chyba osobna sprawa. Jeżeli ktoś chciałby jeszcze się zagłębić w temat to wkleje fragment z dokumentacji.

Nazwa serwisu: "Statica"

Dostępne walory: dowolne instrumenty obsługiwane przez program (nie muszą być w danej chwili aktywne, ani w tabeli notowań ani na wykresie). W formułach wykorzystywane są zawsze nazwy skrócone instrumentów (ticker’y)

Dostępne pozycje (etykiety): czas, kurs, wolumen, obrot, wrazem, tko, lop, otwarcie, odniesienie, max, min, zamkniecie, kupi, sprzeda, ikupi, isprzeda, nkupi, nsprzeda

Format danych: TXT

Wyjaśnienia wymaga kilka pozycji:

„wrazem” - wolumen łączny 
"kupi", "sprzeda" – cena najlepszej oferty kupna oraz sprzedaży 
"ikupi" i "isprzeda" – wolumen najlepszej oferty kupna oraz sprzedaży
„nkupi” i „nsprzeda” – liczba zleceń najlepszej oferty kupna oraz sprzedaży

Program umożliwia również dostęp do kolejnych czterech linii ofert. Dostęp do nich realizowany jest poprzez następujące pozycje: 
kupi2, sprzeda2, ikupi2, isprzeda2,nkupi2, nsprzeda2,
kupi3, sprzeda3, ikupi3, isprzeda3, nkupi3, nsprzeda3
kupi4, sprzeda4, ikupi4, isprzeda4, nkupi4, nsprzeda4
kupi5, sprzeda5, ikupi5, isprzeda5, nkupi5, nsprzeda5

Przykład realizacji dostępu do aktualnej wartości kursu indeksu WIG20 w programie MS Excel (gdy‘DDE-format’=Statica|etykieta!walor ):

=Statica|kurs!'WIG20'

dodanie znacznika <code class="delphi"> - furious programming

0

Natrafiłem na kolejny problem :)
Znalazlem w Delphi w zakladce System takie cos: DdeClientConv. Łącze się za pomocą tego z serwerem i pobieram dane, które potrzebuje:

DDE.SetLink('Serwer','temat');
DDE.OpenLink;
Result:=DDE.RequestData('dane');
DDE.CloseLink;

Wszystko fajnie smiga z tym, ze mam teraz pytanie. Chcialbym odbierac dane w momencie kiedy sie one zmieniaja. Czy jest jakas elegancka forma (zakladam ze jest np. jakas petla), ktora na to pozwoli? Moglbym wrzucic powyzszy kod do TIMERA i katowac serwer ale wydaje mi sie, ze istnieje jakies gotowe rozwiazanie...

Moze ktos mi pomoc?
Dzieki!

dodanie znacznika <code class="delphi"> - furious programming

0

Nic nie wymyślę spektakularnego. Ale porównywanie w wątku danych z już poprzednio odebranymi, na przykład co około 5 sekund powinno zdać egzamin. Ponieważ nie ma zdaje się mi - gotowych rozwiązań na monitorowanie zmian w aplikacji poprzez DDE.

0

Dzieki! Pytam bo mi chodzi o dane gieldowe które zmieniają się bardzo dynamicznie więc musiałbym ustawić na timerze najnizsza wartosc. Nie zajedzie mi to aplikacji?:)

0

To zależy jak często chcesz pobierać dane - przy pięciosekundowym interwale nie powinno się nic złego dziać, tym bardziej, jeśli mechanizm oprzesz na wątku pobocznym czy timer'ze; Poza tym najpierw zastanów się nad tym, jak często dane faktycznie zmieniają się, bo nie ma sensu pobierać 20x tego samego i męczyć program.

0

No właśnie zastanawialem się jak to rozwiązać bo kiedy np wkleje odpowiednią formule w excelu to dane w komórkach aktualizuja się w czasie rzeczywistym.
Można jakoś kodem zmusić serwer żeby przysylal nam dane przy zmianie i jakoś to odebrac?
Pozdr!

0

Jeżeli nie ma do tego możliwości, aby to DDE wysłalo dane poza wątkiem. A chyba nie ma, z tego co opisujesz. I wtedy pozostaje tylko inwazyjna metoda. Jeżeli serwer jest aplikacją okienkową to można spróbować dostać się do jego kontrolek, które wyświetlają potrzebne Ci dane o WIG20. I jeśli są one w postaci tekstowej to spróbować je przechytywać. Ale tutaj wiadomo, pozostaje albo spoofnięcie dll, albo hook na funkcje API lub injekcja dll w proces ów serwera aby przechwycić komunikaty słane do jego kontrolek w ramach tego procesu. Ewentualnie czytanie z pamięci procesu tego serwera. Także podsumowując kombinowania trochę z tym będzie. I faktycznie moze najłatwiej robić to w wątku, a że dane będą z 3 sekundowym opóźnieniem to chyba nie powinno tak przeszkadzać przy kursach?

0

Dzięki wszystkim za pomoc. Jestem bliski poddania się. Nie wiem o co w ogóle z tym chodzi.

Użyłem komponentu z Delphi DDeClientConv. Podaje wszystkie potrzebne dane i po prostu czasami ładnie wszystko się pobiera a czasami otrzymuję puste pola. Nie mam pojęcia od czego to zależy - wygląda jakby losowo się pobierało...

Ustawiam normlanie ddeServer, ddeTopic potem robię np tak:

temp := dde.RequestData('kurs');

i czasami po prostu dostaję kurs, który chcę a czasami nie otrzymuję nic i nie wiem od czego to zależy.... Od strony serwera wszystko jest ok bo sprawdzałem w Excelu i wszystko śmiga... Po stronie kodu coś musi być nie tak tylko już nie wiem co. Macie może jakieś pomysły?

0

Też nie wiem co może być nie tak. Ale z DDE o ile kojarzę, jak kiedyś coś pisałem pod VCL. Miewałem problemy z jego reagowaniem na danie w Timerze czy też w wątku. Być może za często odpytujesz o te dane. I należało by poczekać dłużej po zwolnieniu DDE poprzez Free. Jednak nic więcej nie jestem w stanie podpowiedzieć. Może ktoś tutaj jeszcze coś więcej Tobie doradzi skutecznego. Kto miał do czynienia z tym programem.

0

Hej!
Dalej walcze z tematem. Zaczalem sie zastanawiac, ze moze sam kod jest ok tylko mam problem z typami zmiennych. Moze tutaj wyjsc moj brak wiedzy ale jak ide w zla strone to prosze mnie poprawcie:)

DDE.RequestData zwraca dane typu PAnsiChar. Wyczytalem gdzies, ze w takiej sytuacji funkcja DDE_Read zwroci tylko adres do wartosci, ktore sa dealokowane po opuszczeniu funkcji. Czy tutaj moze sie kryc problem? Bo moze funkcja pobiera dobrze dane tylko kiedy chce je wyswielic to program 'szuka' ich w zlym miejscu? Pobawilem sie troche typami, nie osiagnalem zamierzonego efektu ale zaczalem otrzymywac oprocz pustego pola takze krzaczki ;) Czy w ogole pomylilem pojecia?

A moze trzebaby zwracana wartosc z DDE.RequestData jakos przekonwertowac przed przypisaniem ich do Result?

P.S.
Lapie sie brzytwy ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1