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
Actually, that one is not mine. I moved mine from the gotdotnet site
to http://www.codeplex.com/ndde recently.
> 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.
> 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.
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.)
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);
This was my understanding from DDEML, but Mark says:
>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?
@Mark:
>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?)
@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)
Thank you and regards,
Manfred Kiener
Dynamic Data Exchange Management Library. It encapsulates a lot of
the complexities of passing messages back and forth between
applications.
>
> 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.
> This was my understanding from DDEML, but Mark says:
>
> >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.
> @Mark:
>
> >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.
>
> @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?
> 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
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 :)
Hi, Manfred,
I am sorry to bother you, but I found the following thread online, and
I am having issues similar to yours:
, 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!
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
What is the best way to do this?
Thanks!
Peter