【发布时间】:2015-12-15 12:04:03
【问题描述】:
我们有一个 delphi 7 dde 客户端应用程序,它与另一家公司的 dde 服务器通信(ISIS Papyrus 打印系统) 两者都是 32 位,在 windows 7 32 位上运行良好。
现在我们公司正在切换到windows 7 64位,客户端和服务器之间的通信不再正常了。 我们使用带有 DdeInitialize 的回调函数
我们使用它是因为我们想知道服务器完成的过程何时真正完成并生成文档。
在 windows 7 64bits 上,我们得到了 PTMonMsgStruct(pData)^.wMsg 的粗糙数据
有谁知道怎么回事?
代码:
DdeInitialize(FDdeInstId, SVDdeCallBack, MF_POSTMSGS + MF_SENDMSGS, 0);
和 SVDdeCallBack
function SVDdeCallBack(
CallType, Fmt : UINT; //transaction type ; format atom of the data sent from the server
Conv: HConv; //a handle the conversation
hsz1, hsz2: HSZ; // hsz1: topic name ; hsz2: item name
Data: HDDEData; //a handle to the data associated with the topic and item name pair
Data1, Data2: ULONG) //
: HDDEData; stdcall;
var
pData: Pointer;
Len: Integer;
type
PTMonMsgStruct = ^TMonMsgStruct;
begin
Result := 0;
// Check if the calltype is the monitoring DDE call
if CallType = XTYP_MONITOR then
begin
// Get the DDE data
pData := DdeAccessData( Data, @Len);
// If data
if pData <> nil then
begin
// If data is a posted message
if Data2 = MF_POSTMSGS then
begin
try
// Check if the message was an acknowledge message
//myMonitorStruct := PTMonMsgStruct(pData^);
if PTMonMsgStruct(pData)^.wMsg = WM_DDE_ACK then
begin
WriteLogFile('prcDDE.DDECallBack: TMonMsgStruct(pData^).wMsg = WM_DDE_ACK');
WriteLogFile('prcDDE.DDECallBack: Acknowledge message');
// Detect only the acknowledge messages with no busy flag
if ((PTMonMsgStruct(pData)^.dmhd.uilo and DDE_FACK) = DDE_FACK) and
((PTMonMsgStruct(pData)^.dmhd.uilo and DDE_FBUSY) = 0) then
begin
// The DDE command has terminated
WriteLogFile('prcDDE.DDECallback: ((TMonMsgStruct(pData^).dmhd.uilo and DDE_FACK) = DDE_FACK) and ((TMonMsgStruct(pData^).dmhd.uilo and DDE_FBUSY) = 0)');
WriteLogFile('prcDDE.DDECallback: Acknowledge with BUSY Flag = 0');
ApplData.WaitStat := False;
WriteLogFile('prcDDE.DDECallback: ApplData.WaitStat := False');
end
else
begin
WriteLogFile('prcDDE.DDECallback: Acknowledge with BUSY Flag <> 0')
end;
end;
if PTMonMsgStruct(pData)^.wMsg = WM_DDE_TERMINATE then
begin
// Check if in close
WriteLogFile('prcDDE.DDECallBack:TMonMsgStruct(pData^).wMsg = WM_DDE_TERMINATE');
WriteLogFile('prcDDE.DDECallBack: DDE_terminate message');
if not scrFrontOffice.FInClose then
begin
// Check if there is a second file
if ((Length(ApplData.DataFile2) > 0) and (ApplData.DataFile <> ApplData.DataFile2)) then
begin
// Activate the timer
// 2 following commands removed by VDP -> added in PrcFrontOffice
if bInternWaitForView then
begin
scrFrontOffice.FTimerProcess := True;
scrFrontOffice.tmrClose.Enabled := True;
end;
end
else
begin
// The DDE connection is inactive
scrFrontOffice.FDDEConnectionActive := False;
// Close the program
scrFrontOffice.Close;
end;
end;
end;
finally
// Free the accessed data
DdeUnaccessData(Data);
end;
end
else
begin
//WriteLogFile('Data is no posted message');
end;
end
else
begin
//WriteLogFile('No data received with DdeAccessData');
end;
end;
end;
【问题讨论】:
-
我们能否假设您检查了
DDEInitialize的返回值并验证了它是DMLERR_NO_ERROR?否则,可能的 DDE 问题通常是 win7 安装不是最新的(过去一些坏 KB 已经破坏了 DDE)、防病毒应用程序阻止 DDE 消息、坏硬件驱动程序、UAC 问题...... DDE 非常脆弱 - 它已经快 30 年了老了,已经死了将近 20 年。不幸的是,这里没有足够的信息来提供帮助。 -
DDE 大约在 20 年前被 COM 取代。也许该软件具有更现代的 COM 自动化接口。我快速浏览了一下,here 据说它有一个 'MQ/SOAP/HTML/REST' 接口无论如何,我找不到任何有效的开发人员文档。
-
2 周前在 Embarcadero 论坛上提出了完全相同的问题:DDECallback with Delphi 7 on win7 64 bits machine。
-
是的,我知道。现在公司要求我修复它:-(