SendMessage() WINAPI 在用于连接到 DDE 服务器时挂起

Posted

技术标签:

【中文标题】SendMessage() WINAPI 在用于连接到 DDE 服务器时挂起【英文标题】:SendMessage() WINAPI gets hang when used to connect to a DDE server 【发布时间】:2011-08-18 17:44:21 【问题描述】:

我有一个 DDE 客户端应用程序,它使用 SendMessage() WINAPI 连接到 DDE 服务器应用程序。在请求连接到 DDE 服务器时挂起的 SendMessage() 调用之后。 DDE 客户端应用程序和服务器应用程序都在 VC++ 中。

SendMessage((HWND) -1,WM_DDE_INITIATE,(WPARAM) m_hWnd,MAKELPARAM(hService,hTopic));

现在SendMessage() 正在做什么让它被绞死?基本上它是向系统中的所有窗口广播WM_DDE_INITIATE 窗口消息。它所针对的窗口(DDE 服务器)应处理该消息并应以确认回复。收到确认后,SendMessage() 调用完成并连接客户端。

在我们的例子中,它挂起并且永远不会返回,因此我们的 DDE 客户端应用程序挂起。

我在网上搜索发现使用SendMessage()进行广播通常不推荐,因为它会挂很多次。

我有 DDE 客户端应用程序和 DDE 服务器应用程序的代码。

让我知道有什么方法可以检索 DDE 服务器窗口句柄,或者有什么方法可以为 DDE 服务器窗口分配一个唯一的名称。

通过这样做,我相信在客户端我可以从唯一名称检索 DDE 服务器的窗口句柄(使用 FindWindow()winapi),而不是使用 SendMessage() 广播,我可以使用直接将消息发送到 DDE 服务器窗口句柄。

如果您觉得上述获取DDE服务器窗口句柄的方法不可行或不推荐,那么请告诉我其他使用SendMessage()winapi连接DDE服务器的方法。

【问题讨论】:

使用 EnumWindows 而不是 FindWindow,这样您就有更好的机会识别正确的窗口。使用 Spy++ 查看窗口属性,类名往往有利于过滤。获取类名()。顺便说一句,DDE 太可怕了。 【参考方案1】:

如果另一个进程,任何进程,正在他们的 UI 线程中休眠并且不处理消息,broadcast messages will hang。 stop using DDE 的另一个原因;这是 16 位 Windows when broadcast messages were perfectly safe 时代的遗留物。

不幸的是,这在某种程度上是 DDE 中的一个基本问题。推荐的解决方法是干脆不使用 DDE;使用更现代的方法,例如named pipes、DCOM,甚至 TCP 套接字。

【讨论】:

感谢您的回复。我知道你在说什么,但还有其他方法可以使用 SendMessage winapi 连接到 DDE 服务器 如果您知道目标窗口的 HWND,您可能可以直接向该特定窗口发送消息。不过,我不推荐这种方法;问题仍然是您需要以某种方式找到 HWND,而诸如命名管道或 DCOM 等现代技术往往会更好地工作。 DDE 仅适用于 20 世纪的古老遗留代码。你为什么要针对它编写新代码? 亲爱的大卫,我有一个遗留的 DDE 代码,我需要修复它。 所以通过切换到不同的通信方式来解决它?【参考方案2】:

使用 SendMessageTimeout 而不是 SendMessage,这样挂起的应用程序就不会挂起您。

【讨论】:

以上是关于SendMessage() WINAPI 在用于连接到 DDE 服务器时挂起的主要内容,如果未能解决你的问题,请参考以下文章

WinAPI 鼠标点击无法正常工作

delphi中使用 SendMessage(HWND_BROADCAST,WM_WININICHANGE,0,0);软件卡死,怎么解决?

我用C# 编写的winform 最小化到托盘了

是不是UI线程的线程可以操作UI元素?

如何将强化学习应用于连续动作空间?

如何使 MS SQL Server 可用于连接?