aehimself 396 Posted December 28, 2022 I am in a bit of a dazzle here. However it wouldn't be a surprise in general, but is it possible that the Delphi IDE doesn't (and never did) handle WM_DDE_INITIATE correctly? In a different post, @Attila Kovacs managed to get DDE functioning properly on a modern IDE, but I realized that Delphi 7 for example doesn't reply to any conversation request with service "bds" and topic "system". Service is usually the executable name, this is confirmed by the registry entry: However it says nothing about a topic. I experimented with sending empty strings, nulls, "system" or "DELPHI32" directly to windows and HWND_BROADCAST without success. According to Microsoft: Quote If the low-order word of lParam is NULL, any server application can respond. If the high-order word of lParam is NULL, any topic is valid. Upon receiving a WM_DDE_INITIATE request with the high-order word of the lParam parameter set to NULL, a server must send a WM_DDE_ACK message for each of the topics it supports. Basically, broadcasting 0-0 will end up discovering all available DDE services and topics for use. explorer.exe behaves correctly: Quote PID: 5148, title: "", class: "DDEMLMom" ACK from 4523036: service: PROGMAN, topic: PROGMAN ACK from 4850962: service: Shell, topic: AppProperties ACK from 4130072: service: Folders, topic: AppProperties However Delphi 7 and Delphi 10.4.2 does not reply with anything. Is it possible that the Delphi IDE never handled WM_DDE_INITIATE messages correctly? If yes, what documentation I have to dig up to get DDE details for earlier Delphi IDEs? The code I used is: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; procedure FormCreate(Sender: TObject); private procedure DdeWndProc(var AMsg: TMessage); public { Public declarations } end; var Form1: TForm1; implementation Type TDDEInfo = Record WindowHandle: HWND; ServiceAtom: Word; TopicAtom: Word; End; PDDEInfo = ^TDDEInfo; {$R *.dfm} Function FindDelphiWindow(inHWND: HWND; inParam: LParam): Boolean; StdCall; Var ppid: Cardinal; title, classname: Array[0..255] Of Char; Begin // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms633498(v=vs.85) // Result := True -> Continue evaluation // Result := False -> Do not continue evaluation Result := True; GetWindowThreadProcessID(inHWND, ppid); // if ppid <> 7196 then // Exit; GetWindowText(inHWND, title, 255); GetClassName(inHWND, classname, 255); Form1.Memo1.Lines.Add('PID: ' + ppid.ToString + ', title: "' + title + '", class: "' + classname + '"'); SendMessage(inHWND, WM_DDE_INITIATE, PDDEInfo(inParam)^.WindowHandle, Makelong(PDDEInfo(inParam)^.ServiceAtom, PDDEInfo(inParam)^.TopicAtom)); End; procedure TForm1.DdeWndProc(var AMsg: TMessage); Var service, topic: PChar; begin if Amsg.Msg = WM_DDE_ACK then Begin GetMem(service, 256); GetMem(topic, 256); Try GlobalGetAtomName(AMsg.LParamLo, service, 255); GlobalGetAtomName(AMsg.LParamHi, topic, 255); Memo1.Lines.Add('ACK from ' + AMsg.wParam.ToString + ': service: ' + service + ', topic: ' + topic); Finally FreeMem(service); FreeMem(topic); End; // PostMessage(HWND(AMsg.wParam), WM_DDE_TERMINATE, AMsg., 0); End; end; procedure TForm1.FormCreate(Sender: TObject); Var di: PDDEInfo; Begin New(di); di^.WindowHandle := AllocateHWND(DdeWndProc); Try di^.ServiceAtom := 0; // GlobalAddAtom(PChar('DELPHI32')); di^.TopicAtom := 0; // GlobalAddAtom(PChar('DELPHI32')); Memo1.Lines.BeginUpdate; Try Memo1.Lines.Clear; EnumWindows(@FindDelphiWindow, LParam(di)); Finally Memo1.Lines.EndUpdate; End; // GlobalDeleteAtom(di^.ServiceAtom); // GlobalDeleteAtom(di^.TopicAtom); Finally DeallocateHwnd(di^.WindowHandle); End; end; end. Share this post Link to post
Attila Kovacs 629 Posted December 28, 2022 di^.ServiceAtom := 0; // GlobalAddAtom(PChar('DELPHI32')); di^.TopicAtom := 0; // GlobalAddAtom(PChar('DELPHI32')); it won't answer on 0/0, just on 'system'/'bds' does D7 support DDE anyway? Share this post Link to post
aehimself 396 Posted December 28, 2022 Sometimes it's good to take a break from something. I went to play with my daughter and realized... D7 doesn't understand Unicode! Maybe it receives the message but it will see only it's first character... Will have to test this theory later out though. 1 Share this post Link to post
aehimself 396 Posted December 28, 2022 (edited) 3 hours ago, Attila Kovacs said: it won't answer on 0/0, just on 'system'/'bds' does D7 support DDE anyway? I know, this is one of the questions in this topic. As far as I understand, a DDE server should reply with one WM_DDE_ACK message for each service / topic pair it supports, but Delphi doesn't seem to do that. Neither 7, neither 10.4.2. As for being Unicode it was a good guess but it doesn't work. Running the same code from D7, or changing GlobalAddAtom to GlobalAddAtomA yields no results. I guess there's only one question. As detection doesn't seem to work, in which documentation / source file I can look for supported DDE service / topic strings for Delphi? Edit: Ummm... Edited December 28, 2022 by aehimself 1 Share this post Link to post
aehimself 396 Posted December 28, 2022 My idea seems to be correct after all, I should add my daughter right next to the rubber duck on my desk. I don't know what happened when I tried to run the code under D7 but if I change every call to the WinApi "A" version in D10.4.2 it simply works... And yes, I can confirm... Delphi 7 supports DDE, needs the service "DELPHI32" and the topic "system". It just has to be ANSI, not Unicode. 1 Share this post Link to post