 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Sonnich Jensen Guest
|
Posted: Fri Feb 27, 2004 2:22 pm Post subject: DDE Call back and it's parameters and values |
|
|
Hi all!
I am playing around with DDE inspired by the article here:
http://bdn.borland.com/article/0,1410,16177,00.html
(correct TCallBack to TFNCallBack - other changes can be done too)
Also, I have problems when having more than 14 items on a
TDDEClientConv. (I run 42 at the moment)
I have a connection and can get data and poke them too. I use Excel as
a server for now. But I cannot get my programme to respond when data
changes.
My problem is that CallType is always 0 or 1 in:
function CallbackProc(CallType, Fmt: Word; Conv: HConv; hsz1, hsz2:
HSZ;
Data: HDDEData; Data1, Data2: Longint): HDDEData; export;
Even when looking at Delphi own's function (in DdeMan) I am convinced
that it should work, but not. I tried to look for a detailed
describtion of this function and it parameters, is there such on the
net?
I also found that Conv seems to hold the parameter I need sometime.
When CallBack is 1, it is when data changes, when callback is 0 it is
when the connection is closed, or - sometimes just at random?
This has been mentioned before here, in 1997, but there is no answer.
BR
Sonnich Jensen
|
|
| Back to top |
|
 |
Sonnich Jensen Guest
|
Posted: Mon Mar 01, 2004 7:10 am Post subject: Re: DDE Call back and it's parameters and values |
|
|
"Bjørge Sæther" <bjorge (AT) hahaha_itte (DOT) no> wrote
| Quote: | Sonnich Jensen wrote:
Hi all!
I am playing around with DDE inspired by the article here:
http://bdn.borland.com/article/0,1410,16177,00.html
(correct TCallBack to TFNCallBack - other changes can be done too)
Also, I have problems when having more than 14 items on a
TDDEClientConv. (I run 42 at the moment)
I have a connection and can get data and poke them too. I use Excel as
a server for now. But I cannot get my programme to respond when data
changes.
My problem is that CallType is always 0 or 1 in:
function CallbackProc(CallType, Fmt: Word; Conv: HConv; hsz1, hsz2:
HSZ;
Data: HDDEData; Data1, Data2: Longint): HDDEData; export;
Even when looking at Delphi own's function (in DdeMan) I am convinced
that it should work, but not. I tried to look for a detailed
describtion of this function and it parameters, is there such on the
net?
I also found that Conv seems to hold the parameter I need sometime.
When CallBack is 1, it is when data changes, when callback is 0 it is
when the connection is closed, or - sometimes just at random?
This has been mentioned before here, in 1997, but there is no answer.
Do yourself a favor - drop DDE development in favour of COM. It simply
doesn't work properly anymore, at least with Excel. There are severe timing
problems, for one.
|
Some people might not like my answer, but here it goes.
This is not something I can use, as in many cases certain
specifications are given by the client or simply needed.
I have to say that I dont like when people suggest to use another DB
system or something like that, cause it does not help.
It might be so, that it is what the client uses or what has been
decided, or simply an old project which stays as it is, not giving
these options to the programmer.
All we have to do is to get it work - as it is. This is not to harm
anyone, simply the world as it is.
I still need to know more about DDE to get this to work.
BR
Sonnich
|
|
| Back to top |
|
 |
J French Guest
|
Posted: Mon Mar 01, 2004 9:17 am Post subject: Re: DDE Call back and it's parameters and values |
|
|
On 29 Feb 2004 23:10:48 -0800, [email]sonnich.jensen (AT) elektrobit (DOT) com[/email] (Sonnich
Jensen) wrote:
<snip>
| Quote: | Some people might not like my answer, but here it goes.
This is not something I can use, as in many cases certain
specifications are given by the client or simply needed.
I have to say that I dont like when people suggest to use another DB
system or something like that, cause it does not help.
It might be so, that it is what the client uses or what has been
decided, or simply an old project which stays as it is, not giving
these options to the programmer.
All we have to do is to get it work - as it is. This is not to harm
anyone, simply the world as it is.
I still need to know more about DDE to get this to work.
|
I suspect that there is more to your story than you have let on
You say you are using 'Excel as the Server for now'
- which suggests that you want to use something else as the server
later - what ?
I think Bjørge missed that point when he gave you sound advice on how
to talk to Excel
Personally I have /deliberately/ forgotton everything I knew about DDE
- it is a lousy way of skinning a cat
If you tell us what you /really/ want to do, then we may have some
simple solutions for your /real/ problem
- which, I suspect, is nothing to do with Excel
|
|
| Back to top |
|
 |
J French Guest
|
Posted: Mon Mar 01, 2004 1:40 pm Post subject: Re: DDE Call back and it's parameters and values |
|
|
On Mon, 1 Mar 2004 12:34:14 +0100, "Bjørge Sæther"
<bjorge (AT) hahaha_itte (DOT) no> wrote:
<snip>
| Quote: | If you tell us what you /really/ want to do, then we may have some
simple solutions for your /real/ problem
- which, I suspect, is nothing to do with Excel
You're perfectly right, Jerry, I was talking about Excel specifically.I
worked a lot with DDE and Excel some 3-4 years ago, just to find out it
doesn't work properly. It *also* lead me to the conclusion that if MS don't
care about Excel and DDE, this is a sign that is to be taken into
concideration...
|
It really narks me when people post a problem 'disguised' as something
else.
This lad is obviously looking for inter-App communication
- but is afraid of the 'COM' route
(that I can understand, my trips into the AX Factory remind me of a
midnight visit to an aluminium smelting plant - Breugelesque )
It is utterly pointless using an obsolete mechanism for inter-App
communication, especially when (as I suspect) he has to write the
server.
And his response was ... ungratious - well f***ing impolite.
|
|
| Back to top |
|
 |
Sonnich Jensen Guest
|
Posted: Mon Mar 01, 2004 2:58 pm Post subject: Re: DDE Call back and it's parameters and values |
|
|
"Bjørge Sæther" <bjorge (AT) hahaha_itte (DOT) no> wrote
| Quote: | J French wrote:
On 29 Feb 2004 23:10:48 -0800, [email]sonnich.jensen (AT) elektrobit (DOT) com[/email] (Sonnich
Jensen) wrote:
snip
Some people might not like my answer, but here it goes.
This is not something I can use, as in many cases certain
specifications are given by the client or simply needed.
I have to say that I dont like when people suggest to use another DB
system or something like that, cause it does not help.
It might be so, that it is what the client uses or what has been
decided, or simply an old project which stays as it is, not giving
these options to the programmer.
All we have to do is to get it work - as it is. This is not to harm
anyone, simply the world as it is.
I still need to know more about DDE to get this to work.
I suspect that there is more to your story than you have let on
You say you are using 'Excel as the Server for now'
- which suggests that you want to use something else as the server
later - what ?
I think Bjørge missed that point when he gave you sound advice on how
to talk to Excel
Personally I have /deliberately/ forgotton everything I knew about DDE
- it is a lousy way of skinning a cat
If you tell us what you /really/ want to do, then we may have some
simple solutions for your /real/ problem
- which, I suspect, is nothing to do with Excel
You're perfectly right, Jerry, I was talking about Excel specifically.I
worked a lot with DDE and Excel some 3-4 years ago, just to find out it
doesn't work properly. It *also* lead me to the conclusion that if MS don't
care about Excel and DDE, this is a sign that is to be taken into
concideration...
|
We are using Hirata DDE server (to connect to external hardware). Also
in some case other programmes using DDE.
In general I just need to get DDE to work.
I have tried this now, which _sometimes_ work. The final thing to do
is to get a response when something changes on the server.
Current:
function CallbackProc(CallType, Fmt: Word; Conv: HConv; hsz1, hsz2:
HSZ;
Data: HDDEData; Data1, Data2: Longint): HDDEData; export;
var
i : integer;
hDdeTemp : HDDEData;
DataStr : PChar; // was TDataString;
begin
CallbackProc := 0; { See if proved otherwise }
// Form1.Memo1.Lines.Add(IntToStr(CallType) + ', ' + IntToStr(Fmt)
// + ', ' + IntToStr(Conv) + ', ' + IntToStr(hsz1)
// + ', ' + IntToStr(hsz2) + ', ' + IntToStr(Data)
// + ', ' + IntToStr(Data1) + ', ' + IntToStr(Data2) ); //sjj
// new part
if (CallType in [0, 1]) then
i := Conv
else
i := CallType;
case i of
xtyp_Register:
begin
{ Nothing ... Just return 0 }
end;
xtyp_Unregister:
begin
{ Nothing ... Just return 0 }
end;
xtyp_xAct_Complete:
begin
{ Nothing ... Just return 0 }
end;
xtyp_Request, Xtyp_AdvData:
begin
Form1.Request(Conv);
CallbackProc := dde_FAck;
// ShowMessage('hello!');
for I := 1 to NumValues do
if Form1.ItemHSz[I] = hsz1 then
begin
hDdeTemp := DdeClientTransaction(nil, 0, form1.ConvHdl
{HConversation}
, form1.ItemHSz[I], cf_Text, xtyp_Request, 0, nil);
if hDdeTemp <> 0 then
begin
GetMem(DataStr, 21); // sjj
DdeGetData(hDdeTemp, DataStr, SizeOf(DataStr), 0);
Form1.Memo1.Lines.Add(DataItemNames[I] + '=' +
StrPas(DataStr));
end;
end; {}
end;
xtyp_Disconnect:
begin
ShowMessage('Disconnected!');
// Form1.Close;
end;
end;
end;
|
|
| Back to top |
|
 |
Bruce Roberts Guest
|
Posted: Mon Mar 01, 2004 5:42 pm Post subject: Re: DDE Call back and it's parameters and values |
|
|
"Sonnich Jensen" <sonnich.jensen (AT) elektrobit (DOT) com> wrote
| Quote: | "Bjørge Sæther" <bjorge (AT) hahaha_itte (DOT) no> wrote
J French wrote:
|
There was no need to quote the entirety of the previous post. Please watch
your quoting as it is extremely annoying to have to scroll through dozens of
lines that are not germane to your response.
|
|
| Back to top |
|
 |
Sonnich Jensen Guest
|
Posted: Tue Mar 02, 2004 2:06 pm Post subject: Re: DDE Call back and it's parameters and values |
|
|
"Bjørge Sæther" <bjorge (AT) hahaha_itte (DOT) no> wrote
| Quote: | Sonnich Jensen wrote:
We are using Hirata DDE server (to connect to external hardware). Also
in some case other programmes using DDE.
In general I just need to get DDE to work.
I have tried this now, which _sometimes_ work. The final thing to do
is to get a response when something changes on the server.
The problem that made me abandon Excel via DDE, was the fact that there
seems to be timing problems, making the intercommunication unstable. The
faster the machine, the longer delays are needed to keep communication
going. I don't know whether the problem lies within DDE generally or if it's
Excel-specific.
To check out this, add a Sleep() line between all of your lines. If this
makes it stable/reliable, it may be the same problem.
Also, I remember having read a few postings about problems with Delphi's DDE
components. This was back in D3, I believe, and I haven't seen it mentioned
for quite a while. Was the problem fixed, or have people stopped using DDE ?
|
Thanks, this was waht I needed. The sleep did help, but not as much as
I needed - I tried to add a number of sleep(10)'s, with
applciation.processmessages in between, and that was the trick.
Otherwise it would only update the first item, eventually the one
changed, and in some cases the new value would not be present when
asking for it.
Someone complained that I included the whole code, so here I only add
what I changed in case clause:
case...
xtyp_Request, Xtyp_AdvData:
begin
Application.ProcessMessages;
CallbackProc := dde_FAck;
GetMem(DataStr, 21); // sjj
hDdeTemp := DdeClientTransaction(nil, 0, data, hsz1, cf_Text,
xtyp_Request, 0, nil);
if hDdeTemp <> 0 then
begin
StrPCopy(DataStr,
#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0);
DdeGetData(hDdeTemp, DataStr, SizeOf(DataStr), 0);
res := StrPas(DataStr);
i := Pos(#13, res);
res := Copy(res, 1, i-1);
for I := 1 to NumValues do
if Form1.ItemHSz[I] = hsz1 then
Form1.Memo1.Lines.Add(TimeToStr(now) + ',
'+DataItemNames[I]+'=' + res);
end;
FreeMem(DataStr); // sjj
end;
This works.
When one item is updated, all are sent again, and fast enough for me.
If one wants the complete code, one might write directlt to me.
Next step now is to create some components
BR & thanks for the help
S
|
|
| Back to top |
|
 |
J French Guest
|
Posted: Tue Mar 02, 2004 3:18 pm Post subject: Re: DDE Call back and it's parameters and values |
|
|
On 2 Mar 2004 06:06:30 -0800, [email]sonnich.jensen (AT) elektrobit (DOT) com[/email] (Sonnich
Jensen) wrote:
<snip>
| Quote: | Someone complained that I included the whole code, so here I only add
what I changed in case clause:
|
No - Bruce complained that you posted the previous post
in other words /old/ postings
I've a few comments here
| Quote: |
case...
xtyp_Request, Xtyp_AdvData:
begin
Application.ProcessMessages;
CallbackProc := dde_FAck;
GetMem(DataStr, 21); // sjj
|
Are you sure you cannot use a simple string for DataStr
- it can be sent as a PChar
Procedure Test( Const P :PChar );
Begin
P^ := 'A';
End;
procedure TForm1.Button1Click(Sender: TObject);
Var
S :String;
begin
S := 'BBBB'; // or S := StringOfChar( 'B', 4 )
Test( PChar(S) );
ShowMessage( S );
end;
| Quote: |
hDdeTemp := DdeClientTransaction(nil, 0, data, hsz1, cf_Text,
xtyp_Request, 0, nil);
if hDdeTemp <> 0 then
begin
StrPCopy(DataStr,
#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0);
All those #0s are a bit nasty
DdeGetData(hDdeTemp, DataStr, SizeOf(DataStr), 0);
I expect this would work |
S := StringOfChar( #0, 21 )
DdeGetData(hDdeTemp, PChar(S), Length(S), 0);
| Quote: | res := StrPas(DataStr);
Res := DataStr StrPas is obsolete
i := Pos(#13, res);
And what happens if there is no #13 ?
res := Copy(res, 1, i-1);
Ah ! res := Copy( res, 1, -1 ) <---- Nasty |
Copy() is pretty tolerant, but I doubt this is deliberate
| Quote: | for I := 1 to NumValues do
if Form1.ItemHSz[I] = hsz1 then
Form1.Memo1.Lines.Add(TimeToStr(now) + ',
'+DataItemNames[I]+'=' + res);
end;
FreeMem(DataStr); // sjj
With a String you don't need to use FreeMem
end;
|
I think that you would be well advised to look at some of the later
Delphi constructs
- they would simplify your code
- and that would make it more robust
|
|
| Back to top |
|
 |
Sonnich Jensen Guest
|
Posted: Fri Mar 05, 2004 7:25 am Post subject: Re: DDE Call back and it's parameters and values |
|
|
[email]erewhon (AT) nowhere (DOT) com[/email] (J French) wrote in message news:<4044a099.2989913 (AT) news (DOT) btclick.com>...
| Quote: | On 2 Mar 2004 06:06:30 -0800, [email]sonnich.jensen (AT) elektrobit (DOT) com[/email] (Sonnich
Jensen) wrote:
snip
Someone complained that I included the whole code, so here I only add
what I changed in case clause:
No - Bruce complained that you posted the previous post
in other words /old/ postings
|
Sorry got it wrong then...
| Quote: |
I've a few comments here
case...
xtyp_Request, Xtyp_AdvData:
begin
Application.ProcessMessages;
CallbackProc := dde_FAck;
GetMem(DataStr, 21); // sjj
Are you sure you cannot use a simple string for DataStr
- it can be sent as a PChar
Procedure Test( Const P :PChar );
Begin
P^ := 'A';
End;
|
I tried, did not work that well. I also found that I had to change the
SizeOf to a static number.
| Quote: |
procedure TForm1.Button1Click(Sender: TObject);
Var
S :String;
begin
S := 'BBBB'; // or S := StringOfChar( 'B', 4 )
Test( PChar(S) );
ShowMessage( S );
end;
hDdeTemp := DdeClientTransaction(nil, 0, data, hsz1, cf_Text,
xtyp_Request, 0, nil);
if hDdeTemp <> 0 then
begin
StrPCopy(DataStr,
#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0);
All those #0s are a bit nasty
DdeGetData(hDdeTemp, DataStr, SizeOf(DataStr), 0);
I expect this would work
|
The problem here is SizeOf(DataStr), which is always 4. This works:
GetMem(DataStr, 256);
DdeGetData(hDdeTemp, DataStr, 256, 0);
| Quote: |
S := StringOfChar( #0, 21 )
DdeGetData(hDdeTemp, PChar(S), Length(S), 0);
res := StrPas(DataStr);
Res := DataStr StrPas is obsolete
i := Pos(#13, res);
And what happens if there is no #13 ?
res := Copy(res, 1, i-1);
Ah ! res := Copy( res, 1, -1 ) <---- Nasty
Copy() is pretty tolerant, but I doubt this is deliberate
|
I realised that these 2 problems, and found that the copy solution is
not good. In order to keep compatability with the original component I
use a TString component, which works just as wanted (and the original
component)
| Quote: | for I := 1 to NumValues do
if Form1.ItemHSz[I] = hsz1 then
Form1.Memo1.Lines.Add(TimeToStr(now) + ',
'+DataItemNames[I]+'=' + res);
end;
FreeMem(DataStr); // sjj
With a String you don't need to use FreeMem
end;
I think that you would be well advised to look at some of the later
Delphi constructs
- they would simplify your code
- and that would make it more robust
|
As above, a large number of changes have been done after I turned it
into components (rewrote it).
Thaks for the help!
BR
Sonnich
|
|
| Back to top |
|
 |
J French Guest
|
Posted: Fri Mar 05, 2004 8:43 am Post subject: Re: DDE Call back and it's parameters and values |
|
|
On 4 Mar 2004 23:25:50 -0800, [email]sonnich.jensen (AT) elektrobit (DOT) com[/email] (Sonnich
Jensen) wrote:
<snip>
| Quote: |
The problem here is SizeOf(DataStr), which is always 4. This works:
GetMem(DataStr, 256);
DdeGetData(hDdeTemp, DataStr, 256, 0);
|
The SizeOf an ANSIString is always 4
This is because it is really a pointer to the first byte of the
contents of the String, the length of the String and various other
bits of info are stored /before/ the first byte of the contents of the
String.
If the String is empty the pointer is Nil
To find the length of a String use: Length( AString )
Strings are extremely handy as buffers, because they are much more
versatile, and are automatically destroyed.
In effect a String can be thought of as an enhanced PChar
- the 'String' is actually a PChar to a buffer
- it is @S[1] or Addr( S[1] )
Personally I reckon that GetMem and FreeMem are pretty much obsolete,
if one wants a buffer then simply create a String
- it is easy to skip Freeing a manually allocated buffer
One of the problems with Delphi is that it is actually /enhanced/
Pascal, so older more cumbersome constructs exist alongside newer,
slicker ways of doing things
- typical examples are memory allocation and ASCIIZ ('C' style)
Strings
HTH
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|