| Bug # | Delphi versions | Description |
| 373 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE You can't make a static link to a 16 bit DLL that contains the DDEMAN unit under Windows 3.x. If you load the DLL dynamically from another application, the static links works OK. |
| 374 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE There are problems with multiple clients on the same form. Probably caused by subscript bug in TDdeClientConv.ClearItems |
| 375 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE On Windows95, a DDE hot-link will die on the client side, if you enter a menu or "live" drag the form containing the DDE client. |
| 376 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE Don't ever use Application.ProcessMessages in a DDE event handler (not really a bug, but should be documented). The DDE links will die. |
| 377 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE If you use Form.Release on a form containing a server with open links, the form will never be destroyed. |
| 378 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE Closing a link while there are DDE messages in the message queue will cause a GPF (both client and server). With netDDE you can sometimes cause a GPF on two different machines simultaneously by closing one end. |
| 379 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE In some situations you must explicitely remove the link between the conversation component and the item component (both client and server) before the form is destroyed - or else... GPF. |
| 380 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE You get an access violation if you try to remove a TDdeClientConv with a linked TDdeClientItem. |
| 381 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE A DDE hot-link dies on the client side if the client performs a database action using BDE/Paradox and sometimes using BDE/Microsoft ODBC Paradox. |
| 382 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
DDE When a form has both DdeClientConv and DdeServerConv components, problems arise. |
| 22 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TDdeClientConv If TDdeClientConv.ExecuteMacro or TDdeClientConv.ExecuteMacroLines is called with the WaitFlg parameter set to True, the TDdeClientConv.WaitStat property remains True for ever (it should become False when the server completes the processing of the macro) |
| 23 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TDdeClientConv Potential memory overrun in TDdeClientConv |
| 24 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TDdeServerConv DDE ExecuteMacro may fail if debugging VCL *with* range checking turned on. |
| 514 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TMediaPlayer Problem when AutoOpen = True |
Bug #378; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
Bug #381; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
if DdeQueryConvInfo(Conv, QID_SYNC, @ci)=0 then Exit;
Result := 0;
case CallType of
XTYP_CONNECT:
Result := HDdeData(ddeMgr.AllowConnect(hsz2, hsz1));
XTYP_WILDCONNECT:
Result := ddeMgr.AllowWildConnect(hsz2, hsz1);
XTYP_CONNECT_CONFIRM:
ddeMgr.Connect(Conv, hsz1, Boolean(Data2));
if Conv <> 0 then
begin
ci.cb := sizeof(TConvInfo);
if DdeQueryConvInfo(Conv, QID_SYNC, @ci)=0 then Exit;
Result := 0;
case CallType of
XTYP_CONNECT:
Result := HDdeData(ddeMgr.AllowConnect(hsz2, hsz1));
XTYP_WILDCONNECT:
Result := ddeMgr.AllowWildConnect(hsz2, hsz1);
XTYP_CONNECT_CONFIRM:
ddeMgr.Connect(Conv, hsz1, Boolean(Data2));
XTYP_ADVDATA: {added for Win 95 broken link bug}
begin
RLTopic := DDeQueryString(Ddemgr.FddeInstId,
hsz1, @STopic, 256, CP_WINANSI);
RLItem := DDeQueryString(Ddemgr.FddeInstId,
hsz2, @SItem, 256, CP_WINANSI);
if integer(RLTopic)>0
then SSTopic:=StrPas(STopic)
else SSTopic:='';
if integer(RLItem)>0
then SSItem:=StrPas(SItem)
else SSItem:='';
Result:=HDdeData(DDE_FNOTPROCESSED);
for I:=0 to DdeMgr.FClientConvs.Count-1
do
begin
DummyClientConv:=TDDEClientConv(DdeMgr.FClientConvs.Items[I]);
if (DummyClientConv.FConv=Conv) and
(DummyClientConv.FDdeTopic=SSTopic)
then
begin
Result:=HDdeData(DummyClientConv.DataChange(Data, hsz2));
break;
end;
end;
end;
end;
if Conv <> 0 then
begin
ci.cb := sizeof(TConvInfo);
if DdeQueryConvInfo(Conv, QID_SYNC, @ci)=0 then Exit;
Bug #382; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Exists | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
EAccessViolation in TestDDE.EXE at 000075DE.
Access violation at address 004087DE. Read address FFFFFFFF.
ddeMgr.ComponentIndex := Application.ComponentCount -1;
This by-pass may fix one problem but there still at least one problem with the DDE support in Delphi 2.0. With more complex applications which are "cross-linked" via DDE, i.e. the applications are both clients and servers, failures still occur when the form is closed. These failures are slightly intermittent but they happen roughly 80-90% of the time. A typical failure is:
EAccessViolation in DDESamp.EXE at 000018xx. Access violation at address 00402Axx. Read address 007949C6C [or sometimes FFFFFFFF or FFFFFFFC].
PROGRAM caused a general protection fault in module DDEML.DLL at 0002:00004c38. Registers: EAX=00003c26 CS=16e7 EIP=00004c38 EFLGS=00000246 EBX=172f0550 SS=3b7f ESP=00008d64 EBP=00008d78 ECX=0000b01a DS=16df ESI=00000550 FS=3b87 EDX=00000000 ES=3ade EDI=00000510 GS=0000 Bytes at CS:EIP: c4 7f 16 26 8b 35 26 8b 55 02 89 56 f6 66 83 7f Stack dump: 05100550 00000510 00000000 022e0000 00008da6 06358da6 055016e7 3b870157 08b40157 0000b01a 00000000 001fbc01 011b0253 01870028 0000c2bc bff70510
Bug #22; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
Cause:
Delphi sets FWaitStat to True before issuing the
Execute transaction to the DDEML. It uses the TIMEOUT_ASYNC flag in the
Execute, so it expects to get a DDE callback of type XTYP_XACT_COMPLETE
when the server finishes the transaction. The DDE callback routine should
then call TDdeClientConv.XactComplete which sets FWaitStat to false.
The problem is that Delphi is using the DDEML DDESetUserHandle and
DDEQueryConvInfo functions to store the TDdeClientConv pointer in the hUser
member of the CONVINFO structure maintained by the DDEML. In the DDE callback
handler it uses DDEQueryConvInfo to get the TDdeClientConv associated with
the callback, passing it the transaction id for XTYP_XACT_COMPLETE callbacks
and QID_SYNC for all other callbacks. Unfortunately it only calls DDESetUserHandle
with QID_SYNC (when the conversation is opened), and never calls it with
the transaction id for async transactions, so it never finds the TDdeClientConv
for XTYP_XACT_COMPLETE callbacks.
function DdeMgrCallBack(CallType, Fmt: UINT; Conv: HConv; hsz1, hsz2: HSZ;
Data: HDDEData; Data1, Data2: DWORD): HDDEData; stdcall;
var
ci: TConvInfo;
ddeCli: TComponent;
ddeSrv: TDdeSrvrConv;
ddeObj: TComponent;
xID: Integer;
begin
Result := 0;
case CallType of
XTYP_CONNECT: Result := HDdeData(ddeMgr.AllowConnect(hsz2, hsz1));
XTYP_WILDCONNECT: Result := ddeMgr.AllowWildConnect(hsz2, hsz1);
XTYP_CONNECT_CONFIRM: ddeMgr.Connect(Conv, hsz1, Boolean(Data2));
end;
if Conv <> then
begin
ci.cb := sizeof(TConvInfo);
// FIX TO BUG - COMMENT OUT NEXT 3 LINES
// if CallType = XTYP_XACT_COMPLETE then
// xID := Data1
// else xID := QID_SYNC;
Bug #23; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
function TDdeClientConv.RequestData(const Item: string): PChar;
....
begin
...
if pData <> nil then
begin
try
{$IFDEF FixPotentialOverflowBug}
Result := StrAlloc (len + 1);
FillChar(Result^,len+1,0);
StrLCopy(Result, pData, len);
{$ELSE}
Result := StrAlloc (StrLen (PData) + 1);
StrCopy (Result, pData);
{$ENDIF}
finally
DdeUnaccessData(hdata);
end;
end;
Bug #24; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
{$IFDEF FixDDESrvrConv}
function ExecuteMacro(Conv: HConv; hszTopic: HSZ; Data:
HDdeData): LongInt;
{$ELSE}
function ExecuteMacro(Conv: HConv; hszTopic: HSZ; Data:
HDdeData): Integer;
{$ENDIF}
both in the object interface for TDdeSrvrConv as well as in the implementation.
Bug #514; last modified: 20-Dec-98| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Absent | Absent | Absent | Absent | Absent | Exists | Exists | Exists |
OpenParm.lpstrElementName := PChar(FElementName);and
FFlags := FFlags or mci_Open_Element;should be rewritten as:
if FElementName <> '' then
OpenParm.lpstrElementName := PChar(FElementName);
and
if FElementName <> '' then FFlags := FFlags or mci_Open_Element;To test this I copied MPlayer.Pas from \Delphi4\SourceVCL in a separate directory and applied the patch described; then I wrote a small application with a TMediaPlayer created at runtime i.e.:
procedure TForm1.FormShow(Sender: TObject); begin Mp:= TMediaPlayer.Create(Self); Mp.Parent:= Self; Mp.DeviceType:= dtCDAudio; Mp.Open; end;