Discussion:
DDE / DdeQueryNextServer
(too old to reply)
m***@web.de
2007-07-13 06:59:48 UTC
Permalink
Hello,

I have to make a DDE-Connection from dot.net (as a Client).
The DDE-Implementation from Brian Gideon (http://www.ozemail.com.au/
~markhurd/vbnetdde.zip)
works, but I still need a function to list all avaiable DDE-
applications.

I found this example in C:
http://msdn2.microsoft.com/en-us/library/ms997517.aspx
Sourcecode:
www.microsoft.com/downloads/details.aspx?familyid=F89F86DF-04D7-4464-AB21-9EB1679F41BD&displaylang=en

Who can help me to migrate the "list of DDE-Applications" to C#
(see DdeConnectList and DdeQueryNextServer)

Manfred Kiener
Brian Gideon
2007-07-26 00:14:40 UTC
Permalink
Post by m***@web.de
Hello,
I have to make aDDE-Connection from dot.net (as a Client).
TheDDE-Implementation from Brian Gideon (http://www.ozemail.com.au/
~markhurd/vbnetdde.zip)
works,
Actually, that one is not mine. I moved mine from the gotdotnet site
to http://www.codeplex.com/ndde recently.
Post by m***@web.de
but I still need a function to list all avaiableDDE-
applications.
Mine doesn't either really. It does have an API that raises an event
when a new server registers using the DDEML, but that's it. Well,
then there's the DdeMonitor class which monitors all activity on a
system, but honestly, I can't remember what all it can monitor. DDE
is nearly dead so I don't really support the library anymore. In
fact, it's been almost 2 years since I did anything with it.
Post by m***@web.de
I found this example in C:http://msdn2.microsoft.com/en-us/library/ms997517.aspx
Sourcecode:www.microsoft.com/downloads/details.aspx?familyid=F89F86DF-04D7-4464-...
Who can help me to migrate the "list ofDDE-Applications" to C#
(see DdeConnectList and DdeQueryNextServer)
I have a lot of experience using DDE in C# so I could help if you have
specific questions, but I really recommend moving away from the
technology altogether.
jose romero
2012-04-28 03:01:23 UTC
Permalink
I need your help brian could u help me with nDDe
Post by m***@web.de
Hello,
I have to make a DDE-Connection from dot.net (as a Client).
The DDE-Implementation from Brian Gideon (http://www.ozemail.com.au/
~markhurd/vbnetdde.zip)
works, but I still need a function to list all avaiable DDE-
applications.
http://msdn2.microsoft.com/en-us/library/ms997517.aspx
www.microsoft.com/downloads/details.aspx?familyid=F89F86DF-04D7-4464-AB21-9EB1679F41BD&displaylang=en
Who can help me to migrate the "list of DDE-Applications" to C#
(see DdeConnectList and DdeQueryNextServer)
Manfred Kiener
Post by Brian Gideon
Actually, that one is not mine. I moved mine from the gotdotnet site
to http://www.codeplex.com/ndde recently.
Mine doesn't either really. It does have an API that raises an event
when a new server registers using the DDEML, but that's it. Well,
then there's the DdeMonitor class which monitors all activity on a
system, but honestly, I can't remember what all it can monitor. DDE
is nearly dead so I don't really support the library anymore. In
fact, it's been almost 2 years since I did anything with it.
I have a lot of experience using DDE in C# so I could help if you have
specific questions, but I really recommend moving away from the
technology altogether.
Post by Mark Hurd
A C# DDEML solution would be better for you, but my sample above already
enumerates all available DDE applications because if follows the basic
DDE protocol when initiating a connection: It broadcasts to all windows
a request to respond to DDE. You could accumulate the responses and not
(necessarily) start a connection.
Regards,
Mark Hurd, B.Sc.(Ma.)(Hons.)
Post by m***@web.de
Thank you for your answers.
I know that DDE is a dead tecnology, but in my case I have no chance
to change the technology.
What exact is DDEML?
Is DDEML to use e.g.
[DllImport("user32.dll", EntryPoint="DdeInitialize",
CharSet=CharSet.Ansi)]
public static extern int DdeInitialize(ref int pidInst,
DdeCallback pfnCallback, int afCmd, int ulRes);
Marks sample is very complex and uses "DdeInitialize" too, is there an
easier way to be an DDE-Client?
I adapted the sample to be a DDE-Client for a barcode tool from will-
software
(www.will-software.com) and it works very fine (to be a DDE-Client for
this barcode-Software is ONLY A SAMPLE,
I need DDE to simulate a 15 years old technoligie which can control
DDE-Servers in many cases).
I tried to debug your sample, but I didn't find what you mean.
Could you give me more hints (e.g. a methode-name where the broadcast
is realized?)
Yes, I have a specific question.
But the sample is difficult to isolate to print the sourcecode here.
I call DdeConnectList (from user32.dll) and get a integer-Handle for a
list of DDE-Application (I belive!).
With DdeQueryNextServer I get exact the same number of int-handles (in
my case I got 4 int-handles), as the c++ - Tool.
(Folders, PROGMAN, Shell, Winword)
But I can not resolve the int-handles e.g. to the application-Name
(DdeQueryString), may be there ist only a little mistake with the call
and interop.
Maybe if you could spent 10 minutes of your time you will find the
error.
In this case I would send you the complete Sample-solution (just a few
KB)
Thank you and regards,
Manfred Kiener
Post by Brian Gideon
Dynamic Data Exchange Management Library. It encapsulates a lot of
the complexities of passing messages back and forth between
applications.
Yes, DdeInitialize is part of the DDEML.
I didn't see the call in his example, but then again I didn't look
very closely. He's probably mixing the DDEML with the raw DDE message
protocol which, as I understand, should be perfectly acceptable.
As far as creating a DDE client easily...have you looked at the
library I provide? To request data from a server the code would look
like the following.
DdeClient client = new DdeClient("myserver", "mytopic");
client.Connect();
string data = client.Request("myitem", 60000);
It can't get much easier than that.
You talk about controlling a server...that's usually done by doing a
DDE execute. The library I provide supports that easily as well with
the DdeClient.Execute method.
DdeConnectList and DdeQueryNextServer are a little complicated to
use. I'm still unclear as to why you want to use them. Can you
clarify?
Post by m***@web.de
Hello,
Brian: yes, you are right. At my first message I talked about your
NDDE but
write the linkt to Marc's sample. Sorry
I realized that yesterday.
This solution to get "a list of DDE-Servers" works
(in context with the NDDE-library)
public static extern IntPtr DdeConnectList(int idInst, IntPtr
hszService, IntPtr hszTopic, IntPtr hConvList, ref
NDde.Foundation.Ddeml.CONVCONTEXT pCC/*IntPtr pCC*/);
public static extern int DdeQueryConvInfo(IntPtr hConv, int
idTransaction, ref CONVINFO pConvInfo/*IntPtr pConvInfo*/);
I added this in DDEMLClient.cs
public string[] GetListOfDdeServer()
{
ArrayList DdeServers = new ArrayList();
IntPtr hszSystem =
Ddeml.DdeCreateStringHandle(_InstanceId,"System",Ddeml.CP_WINANSI);
NDde.Foundation.Ddeml.CONVCONTEXT pCC = new
NDde.Foundation.Ddeml.CONVCONTEXT();
pCC.cb = (ushort)Marshal.SizeOf(pCC);
IntPtr hConvList =
Ddeml.DdeConnectList(_InstanceId,IntPtr.Zero,hszSystem,
IntPtr.Zero, // new list
ref pCC); // default context
Ddeml.DdeFreeStringHandle(_InstanceId,hszSystem);
//
// Walk the list adding the server names to our listbox
//
IntPtr hConv = IntPtr.Zero;
Ddeml.CONVINFO pConvInfo = new Ddeml.CONVINFO();
pConvInfo.cb = (ushort)Marshal.SizeOf(pConvInfo);
while((hConv = Ddeml.DdeQueryNextServer(hConvList,hConv)) !
= IntPtr.Zero)
{
int ui =
Ddeml.DdeQueryConvInfo(hConv,Ddeml.QID_SYNC,ref pConvInfo);
StringBuilder psz = new StringBuilder(255);
Ddeml.DdeQueryString(_InstanceId,
(IntPtr)pConvInfo.hszSvcPartner,psz,psz.Capacity,Ddeml.CP_WINANSI);
DdeServers.Add(psz.ToString());
Debug.WriteLine(psz.ToString());
}
//
// Free the list handle
//
Ddeml.DdeDisconnectList(hConvList);
return (string[])DdeServers.ToArray(typeof(string));
}
It was i little "try and error" (e.g. Thread-Handling), but now it
works "good enought"
thank you for your help.
regards
Manfred Kiener
Thanks Manfred. If DDE were not already nearly defunct and if I
actually had the motivation to keep supporting NDde I'd probably add
that method and publish a new release :)
Post by g***@gmail.com
Hi, Manfred,
I am sorry to bother you, but I found the following thread online, and
http://groups.google.com/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/d6c9031c0aafa0d5/aa9f445e0718167f#aa9f445e0718167f
, and I see that you have added a very useful function (to the great
NDDE library) that is supposed to list all the available DDE server
names.
1) How do you properly call this function? (examples?)
2) How can you connect to two different DDE servers which provide the
same DDE server name? I basically start two apps that both provide the
same DDE Server names, and I can't distinguish between them with the
regular DDEClient, but I want to connect to both of them. :(
Thank you!
Post by m***@web.de
Hello,
1) It is a litte bit tricky because of multithreading. Please email me
you still need help
2) I am not shure if it is possible to connect to two applications
with the same name.
Manfred Kiener
I need to create and use a DDE from within my WPF app, because I need to get and send data to an older simulator (a VisSim simulation). VisSim supports creating a bi-directional DDE connection
What is the best way to do this?
Thanks!
Peter
Mark Hurd
2007-07-27 23:54:27 UTC
Permalink
Post by m***@web.de
Hello,
I have to make a DDE-Connection from dot.net (as a Client).
The DDE-Implementation from Brian Gideon (http://www.ozemail.com.au/
~markhurd/vbnetdde.zip)
works, but I still need a function to list all avaiable DDE-
applications.
A C# DDEML solution would be better for you, but my sample above already
enumerates all available DDE applications because if follows the basic
DDE protocol when initiating a connection: It broadcasts to all windows
a request to respond to DDE. You could accumulate the responses and not
(necessarily) start a connection.

Regards,
Mark Hurd, B.Sc.(Ma.)(Hons.)
m***@web.de
2007-07-31 21:33:41 UTC
Permalink
Thank you for your answers.

I know that DDE is a dead tecnology, but in my case I have no chance
to change the technology.

I googled a lot about DDE and I am a little bit confused:
What exact is DDEML?

Is DDEML to use e.g.

[DllImport("user32.dll", EntryPoint="DdeInitialize",
CharSet=CharSet.Ansi)]
public static extern int DdeInitialize(ref int pidInst,
DdeCallback pfnCallback, int afCmd, int ulRes);
A C# DDEML solution would be better for you...
Marks sample is very complex and uses "DdeInitialize" too, is there an
easier way to be an DDE-Client?
but my sample above already
enumerates all available DDE applications because if follows the basic
DDE protocol when initiating a connection: It broadcasts to all windows
a request to respond to DDE. You could accumulate the responses and not
(necessarily) start a connection.
I adapted the sample to be a DDE-Client for a barcode tool from will-
software
(www.will-software.com) and it works very fine (to be a DDE-Client for
this barcode-Software is ONLY A SAMPLE,
I need DDE to simulate a 15 years old technoligie which can control
DDE-Servers in many cases).
I tried to debug your sample, but I didn't find what you mean.
Could you give me more hints (e.g. a methode-name where the broadcast
is realized?)
I have a lot of experience using DDE in C# so I could help if you have
specific questions, but I really recommend moving away from the
technology altogether.
Yes, I have a specific question.
But the sample is difficult to isolate to print the sourcecode here.

I call DdeConnectList (from user32.dll) and get a integer-Handle for a
list of DDE-Application (I belive!).
With DdeQueryNextServer I get exact the same number of int-handles (in
my case I got 4 int-handles), as the c++ - Tool.
(Folders, PROGMAN, Shell, Winword)
But I can not resolve the int-handles e.g. to the application-Name
(DdeQueryString), may be there ist only a little mistake with the call
and interop.

Maybe if you could spent 10 minutes of your time you will find the
error.
In this case I would send you the complete Sample-solution (just a few
KB)

Thank you and regards,

Manfred Kiener
Brian Gideon
2007-08-03 20:44:56 UTC
Permalink
Post by m***@web.de
Thank you for your answers.
I know that DDE is a dead tecnology, but in my case I have no chance
to change the technology.
What exact is DDEML?
Dynamic Data Exchange Management Library. It encapsulates a lot of
the complexities of passing messages back and forth between
applications.
Post by m***@web.de
Is DDEML to use e.g.
[DllImport("user32.dll", EntryPoint="DdeInitialize",
CharSet=CharSet.Ansi)]
public static extern int DdeInitialize(ref int pidInst,
DdeCallback pfnCallback, int afCmd, int ulRes);
Yes, DdeInitialize is part of the DDEML.
Post by m***@web.de
A C# DDEML solution would be better for you...
Marks sample is very complex and uses "DdeInitialize" too, is there an
easier way to be an DDE-Client?
I didn't see the call in his example, but then again I didn't look
very closely. He's probably mixing the DDEML with the raw DDE message
protocol which, as I understand, should be perfectly acceptable.

As far as creating a DDE client easily...have you looked at the
library I provide? To request data from a server the code would look
like the following.

DdeClient client = new DdeClient("myserver", "mytopic");
client.Connect();
string data = client.Request("myitem", 60000);

It can't get much easier than that.
Post by m***@web.de
but my sample above already
enumerates all available DDE applications because if follows the basic
DDE protocol when initiating a connection: It broadcasts to all windows
a request to respond to DDE. You could accumulate the responses and not
(necessarily) start a connection.
I adapted the sample to be a DDE-Client for a barcode tool from will-
software
(www.will-software.com) and it works very fine (to be a DDE-Client for
this barcode-Software is ONLY A SAMPLE,
I need DDE to simulate a 15 years old technoligie which can control
DDE-Servers in many cases).
I tried to debug your sample, but I didn't find what you mean.
Could you give me more hints (e.g. a methode-name where the broadcast
is realized?)
You talk about controlling a server...that's usually done by doing a
DDE execute. The library I provide supports that easily as well with
the DdeClient.Execute method.
Post by m***@web.de
@Brian:>I have a lot of experience using DDE in C# so I could help if you have
specific questions, but I really recommend moving away from the
technology altogether.
Yes, I have a specific question.
But the sample is difficult to isolate to print the sourcecode here.
I call DdeConnectList (from user32.dll) and get a integer-Handle for a
list of DDE-Application (I belive!).
With DdeQueryNextServer I get exact the same number of int-handles (in
my case I got 4 int-handles), as the c++ - Tool.
(Folders, PROGMAN, Shell, Winword)
But I can not resolve the int-handles e.g. to the application-Name
(DdeQueryString), may be there ist only a little mistake with the call
and interop.
Maybe if you could spent 10 minutes of your time you will find the
error.
In this case I would send you the complete Sample-solution (just a few
KB)
DdeConnectList and DdeQueryNextServer are a little complicated to
use. I'm still unclear as to why you want to use them. Can you
clarify?
Post by m***@web.de
Thank you and regards,
Manfred Kiener
m***@web.de
2007-08-05 09:18:35 UTC
Permalink
Hello,
Post by Brian Gideon
I didn't see the call in his example, but then again I didn't look
very closely. He's probably mixing the DDEML with the raw DDE message
protocol which, as I understand, should be perfectly acceptable.
Brian: yes, you are right. At my first message I talked about your
NDDE but
write the linkt to Marc's sample. Sorry
I realized that yesterday.

This solution to get "a list of DDE-Servers" works
(in context with the NDDE-library)


I Changed this definitions in DDEML.CS:

public static extern IntPtr DdeConnectList(int idInst, IntPtr
hszService, IntPtr hszTopic, IntPtr hConvList, ref
NDde.Foundation.Ddeml.CONVCONTEXT pCC/*IntPtr pCC*/);
public static extern int DdeQueryConvInfo(IntPtr hConv, int
idTransaction, ref CONVINFO pConvInfo/*IntPtr pConvInfo*/);


I added this in DDEMLClient.cs
public string[] GetListOfDdeServer()
{
ArrayList DdeServers = new ArrayList();
IntPtr hszSystem =
Ddeml.DdeCreateStringHandle(_InstanceId,"System",Ddeml.CP_WINANSI);

NDde.Foundation.Ddeml.CONVCONTEXT pCC = new
NDde.Foundation.Ddeml.CONVCONTEXT();
pCC.cb = (ushort)Marshal.SizeOf(pCC);
IntPtr hConvList =
Ddeml.DdeConnectList(_InstanceId,IntPtr.Zero,hszSystem,
IntPtr.Zero, // new list
ref pCC); // default context
Ddeml.DdeFreeStringHandle(_InstanceId,hszSystem);
//
// Walk the list adding the server names to our listbox
//
IntPtr hConv = IntPtr.Zero;

Ddeml.CONVINFO pConvInfo = new Ddeml.CONVINFO();
pConvInfo.cb = (ushort)Marshal.SizeOf(pConvInfo);

while((hConv = Ddeml.DdeQueryNextServer(hConvList,hConv)) !
= IntPtr.Zero)
{
int ui =
Ddeml.DdeQueryConvInfo(hConv,Ddeml.QID_SYNC,ref pConvInfo);

StringBuilder psz = new StringBuilder(255);
Ddeml.DdeQueryString(_InstanceId,
(IntPtr)pConvInfo.hszSvcPartner,psz,psz.Capacity,Ddeml.CP_WINANSI);

DdeServers.Add(psz.ToString());
Debug.WriteLine(psz.ToString());
}
//
// Free the list handle
//
Ddeml.DdeDisconnectList(hConvList);

return (string[])DdeServers.ToArray(typeof(string));
}

It was i little "try and error" (e.g. Thread-Handling), but now it
works "good enought"

@Brian, @Marc:
thank you for your help.

regards
Manfred Kiener
Brian Gideon
2007-08-06 19:15:20 UTC
Permalink
Post by m***@web.de
Hello,
Post by Brian Gideon
I didn't see the call in his example, but then again I didn't look
very closely. He's probably mixing the DDEML with the raw DDE message
protocol which, as I understand, should be perfectly acceptable.
Brian: yes, you are right. At my first message I talked about your
NDDE but
write the linkt to Marc's sample. Sorry
I realized that yesterday.
This solution to get "a list of DDE-Servers" works
(in context with the NDDE-library)
public static extern IntPtr DdeConnectList(int idInst, IntPtr
hszService, IntPtr hszTopic, IntPtr hConvList, ref
NDde.Foundation.Ddeml.CONVCONTEXT pCC/*IntPtr pCC*/);
public static extern int DdeQueryConvInfo(IntPtr hConv, int
idTransaction, ref CONVINFO pConvInfo/*IntPtr pConvInfo*/);
I added this in DDEMLClient.cs
public string[] GetListOfDdeServer()
{
ArrayList DdeServers = new ArrayList();
IntPtr hszSystem =
Ddeml.DdeCreateStringHandle(_InstanceId,"System",Ddeml.CP_WINANSI);
NDde.Foundation.Ddeml.CONVCONTEXT pCC = new
NDde.Foundation.Ddeml.CONVCONTEXT();
pCC.cb = (ushort)Marshal.SizeOf(pCC);
IntPtr hConvList =
Ddeml.DdeConnectList(_InstanceId,IntPtr.Zero,hszSystem,
IntPtr.Zero, // new list
ref pCC); // default context
Ddeml.DdeFreeStringHandle(_InstanceId,hszSystem);
//
// Walk the list adding the server names to our listbox
//
IntPtr hConv = IntPtr.Zero;
Ddeml.CONVINFO pConvInfo = new Ddeml.CONVINFO();
pConvInfo.cb = (ushort)Marshal.SizeOf(pConvInfo);
while((hConv = Ddeml.DdeQueryNextServer(hConvList,hConv)) !
= IntPtr.Zero)
{
int ui =
Ddeml.DdeQueryConvInfo(hConv,Ddeml.QID_SYNC,ref pConvInfo);
StringBuilder psz = new StringBuilder(255);
Ddeml.DdeQueryString(_InstanceId,
(IntPtr)pConvInfo.hszSvcPartner,psz,psz.Capacity,Ddeml.CP_WINANSI);
DdeServers.Add(psz.ToString());
Debug.WriteLine(psz.ToString());
}
//
// Free the list handle
//
Ddeml.DdeDisconnectList(hConvList);
return (string[])DdeServers.ToArray(typeof(string));
}
It was i little "try and error" (e.g. Thread-Handling), but now it
works "good enought"
thank you for your help.
regards
Manfred Kiener
Thanks Manfred. If DDE weren't already nearly defunct and if I
actually had the motivation to keep supporting NDde I'd probably add
that method and publish a new release :)
g***@gmail.com
2007-09-13 16:21:50 UTC
Permalink
Post by m***@web.de
Hello,
Post by Brian Gideon
I didn't see the call in his example, but then again I didn't look
very closely. He's probably mixing the DDEML with the raw DDE message
protocol which, as I understand, should be perfectly acceptable.
Brian: yes, you are right. At my first message I talked about your
NDDE but
write the linkt to Marc's sample. Sorry
I realized that yesterday.
This solution to get "a list of DDE-Servers" works
(in context with the NDDE-library)
public static extern IntPtr DdeConnectList(int idInst, IntPtr
hszService, IntPtr hszTopic, IntPtr hConvList, ref
NDde.Foundation.Ddeml.CONVCONTEXT pCC/*IntPtr pCC*/);
public static extern int DdeQueryConvInfo(IntPtr hConv, int
idTransaction, ref CONVINFO pConvInfo/*IntPtr pConvInfo*/);
I added this in DDEMLClient.cs
public string[] GetListOfDdeServer()
{
ArrayList DdeServers = new ArrayList();
IntPtr hszSystem =
Ddeml.DdeCreateStringHandle(_InstanceId,"System",Ddeml.CP_WINANSI);
NDde.Foundation.Ddeml.CONVCONTEXT pCC = new
NDde.Foundation.Ddeml.CONVCONTEXT();
pCC.cb = (ushort)Marshal.SizeOf(pCC);
IntPtr hConvList =
Ddeml.DdeConnectList(_InstanceId,IntPtr.Zero,hszSystem,
IntPtr.Zero, // new list
ref pCC); // default context
Ddeml.DdeFreeStringHandle(_InstanceId,hszSystem);
//
// Walk the list adding the server names to our listbox
//
IntPtr hConv = IntPtr.Zero;
Ddeml.CONVINFO pConvInfo = new Ddeml.CONVINFO();
pConvInfo.cb = (ushort)Marshal.SizeOf(pConvInfo);
while((hConv = Ddeml.DdeQueryNextServer(hConvList,hConv)) !
= IntPtr.Zero)
{
int ui =
Ddeml.DdeQueryConvInfo(hConv,Ddeml.QID_SYNC,ref pConvInfo);
StringBuilder psz = new StringBuilder(255);
Ddeml.DdeQueryString(_InstanceId,
(IntPtr)pConvInfo.hszSvcPartner,psz,psz.Capacity,Ddeml.CP_WINANSI);
DdeServers.Add(psz.ToString());
Debug.WriteLine(psz.ToString());
}
//
// Free the list handle
//
Ddeml.DdeDisconnectList(hConvList);
return (string[])DdeServers.ToArray(typeof(string));
}
It was i little "try and error" (e.g. Thread-Handling), but now it
works "good enought"
thank you for your help.
regards
Manfred Kiener
Hi, Manfred,

I am sorry to bother you, but I found the following thread online, and
I am having issues similar to yours:

http://groups.google.com/group/microsoft.public.dotnet.framework.interop/browse_thread/thread/d6c9031c0aafa0d5/aa9f445e0718167f#aa9f445e0718167f

, and I see that you have added a very useful function (to the great
NDDE library) that is supposed to list all the available DDE server
names.

I have 2 questions, if you don't mind:

1) How do you properly call this function? (examples?)
2) How can you connect to two different DDE servers which provide the
same DDE server name? I basically start two apps that both provide the
same DDE Server names, and I can't distinguish between them with the
regular DDEClient, but I want to connect to both of them. :(

Thank you!
m***@web.de
2007-09-25 19:42:39 UTC
Permalink
Hello,

1) It is a litte bit tricky because of multithreading. Please email me
you still need help
2) I am not shure if it is possible to connect to two applications
with the same name.

Manfred Kiener
Loading...