【问题标题】:ShowMessage in Delphi XE3 DllMainDelphi XE3 DllMain 中的 ShowMessage
【发布时间】:2013-05-08 07:26:12
【问题描述】:

下面的DLL是用XE3编译的。

library MyDLL;

uses System.SysUtils, System.Classes, Vcl.Dialogs;

{$R *.res}

var
  II: Integer;

function Test: Integer;
begin
  Result := II;
end;

exports Test;

begin
  II := 5;
  ShowMessage('DLL prolog');
end.

当我从 Delphi XE3 或 Delphi 2007 程序调用函数 Test() 时,我在这两种情况下都得到了正确的结果 (5)。但是只有 Delphi 2007 程序会显示“DLL prolog”消息,而不是 Delphi XE3 程序。为什么?

编辑

当我使用 Delphi 2007 主机 ShowMessage() 从 XE3 IDE “运行” dll 时也不起作用。

【问题讨论】:

  • 您是否尝试改用标准窗口MessageBox
  • 是的MessageBox 工作正常!?
  • 您知道您可以从 DllMain 执行的操作受到严格限制吗?
  • 我不知道,但我现在在msdn 上找到了。谢谢!

标签: delphi windows-7 delphi-2007 delphi-xe3


【解决方案1】:

关键在这个函数里:

function MessageDlgPosHelp(const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
  const HelpFileName: string): Integer;
begin
  if TOSVersion.Check(6) and UseLatestCommonDialogs and
     StyleServices.Enabled and StyleServices.IsSystemStyle then
    Result := DoTaskMessageDlgPosHelp('', Msg, DlgType, Buttons,
      HelpCtx, X, Y, HelpFileName)
  else
    Result := DoMessageDlgPosHelp(CreateMessageDialog(Msg, DlgType, Buttons),
      HelpCtx, X, Y, HelpFileName);
end;

在某些情况下,根据主机应用程序是否具有 comctl32 v6 清单,会选择 if 语句的不同分支。

如果选择了DoTaskMessageDlgPosHelp 分支,则随后对TaskDialogIndirect 的调用将失败,并显示HRESULT 代码$80070057。这是一个 Win32 错误代码,ERROR_INVALID_PARAMETER

如果选择了DoMessageDlgPosHelp 分支,则会显示对话框。

我不确定为什么从库初始化块调用 TaskDialogIndirect 时会失败,但我并不完全感到惊讶。你在DllMain 可以做的事情受到严格限制,你不应该尝试从那里显示对话框。

【讨论】:

  • 是的,这是说明的 DllMain 限制
  • ComCtl32.TaskDialogIndirect 调用 ComCtl32.CTaskDialog.Show,后者调用 DUser.InitGadgets,后者调用 DUser.ResourceManager.InitContextNL。后一种显式检查是否从 DllMain 内部调用,DUser.WinNT.IsInsideLoaderLock 返回 TRUE,因此调用者返回硬编码 0x80070057,弹出到 TaskDialogIndirect 的 retvalue。
  • 在从 DllMain 调用 ShowMessage 之前尝试类似 UseLatestCommonDialogs := False。如果您想编写通用包装器 - 尝试使用 NtDll.RtlIsThreadWithinLoaderCallout。
  • @Alex 不要显示来自 DllMain 的对话框。另外,请不要使用QC。现在是 QualityPortal。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多