【问题标题】:MessageDlg shows information icon instead of confirmationMessageDlg 显示信息图标而不是确认
【发布时间】:2011-09-14 17:17:54
【问题描述】:

在 Win 7 上,MessageDlg 显示信息图标而不是确认图标(问号)。 代码如下:

MessageDlg('Are you sure you want to delete this file?'+ CRLF+ FileName, mtConfirmation, [mbYes, mbNo], 0)= mrYes

我做错了什么?

【问题讨论】:

标签: delphi windows-7


【解决方案1】:
if (Win32MajorVersion >= 6) and ThemeServices.ThemesEnabled then
    with TTaskDialog.Create(Self) do
      try
        Caption := 'Delete';
        Title := 'Are you sure to remove the minecraft?';
        Text := 'if you delete minecraft it well be gone forever.';
        CommonButtons := [tcbYes, tcbNo];
        CustomMainIcon.ReleaseHandle;
        CustomMainIcon.Handle := LoadIcon(0, IDI_QUESTION);
        Flags := [tfUseHiconMain];
        Execute;
      finally
        Free;
      end
  else
    MessageBox(Handle,
               'if you delete minecraft it well be gone forever.',
               'Are you sure to remove the minecraft?',
               MB_ICONQUESTION or MB_YESNO);

【讨论】:

  • 欢迎您!如果您写了几句话,用文字描述您正在尝试做什么以及您的代码在您编写时没有做什么,那么我估计您可以使这个问题变得更好。
【解决方案2】:

首先,请注意一个简单的解决方法是改用 Windows API MessageBox 函数:

MessageBox(Handle, 'This is a test.', 'Test', MB_ICONQUESTION or MB_YESNO)

但是为什么MessageDlg 不起作用?好吧,MessageDlg 做了两种可能的事情之一。如果可能,它使用 Windows Vista+ 任务对话框,即操作系统是 Windows Vista 或更高版本and 启用主题and UseLatestCommonDialogs 全局变量为true(默认值)。如果没有,VCL 实际上会创建一个自定义 TForm 并手动添加所有按钮、标签和图标(如果你问我,这有点奇怪——为什么不简单地使用 MessageBox?)。

最后一种方法支持问号图标。确实,试试

UseLatestCommonDialogs := false;
MessageDlg('This is a test', mtConfirmation, [mbYes, mbNo], 0);

但这看起来太丑了!请不要这样做!创建自定义消息对话框而不是使用本机操作系统对话框是愚蠢

不幸的是,任务对话框不支持问号图标(作为预定义图标)。这不是 TTaskDialog 包装器的限制,而是 Windows 任务对话框 API 的限制。例如,参见official documentation。有TD_ERROR_ICONTD_WARNING_ICONTD_INFORMATION_ICON,但没有问号图标。

当然,任务对话框可以使用任何图标。例如,你可以这样做

if (Win32MajorVersion >= 6) and ThemeServices.ThemesEnabled then
    with TTaskDialog.Create(Self) do
      try
        Caption := 'Test';
        Title := 'Test';
        Text := 'This is a test.';
        CommonButtons := [tcbYes, tcbNo];
        CustomMainIcon.ReleaseHandle;
        CustomMainIcon.Handle := LoadIcon(0, IDI_QUESTION);
        Flags := [tfUseHiconMain];
        Execute;
      finally
        Free;
      end
  else
    MessageBox(Handle,
               'This is a test.',
               'Test',
               MB_ICONQUESTION or MB_YESNO);

请注意,如果任务对话框 API 不可用,我将使用旧的 MessageBox

原则上,MessageDlg 函数可以使用额外的逻辑来分别处理问号情况,其方式不同于信息、警告和错误情况。这将使mtConfirmation 即使使用任务对话框也能给出正确的图标,但代价是 VCL 代码稍微复杂一些,也不那么优雅。然而,Embarcadero 显然选择了更简单的替代方案,即简单地假装您要求提供信息图标。

不过,我想知道为什么 Microsoft 选择不在 API 中包含 TD_QUESTION_ICON 常量。也许他们最新的 UI 指南不鼓励使用此图标?

【讨论】:

  • ThemeServices.ThemesEnabled 测试让我发笑。你确实意识到我相信你必须这样做是因为 Delphi TTaskDialog 中的一个愚蠢的错误。任务对话框适用于 Win32MajorVersion >= 6,它在 Windows Classic 上完美运行。我不知道为什么 Embarcadero 会像他们那样做。正如你可能想象的那样,由于这些弱点,我使用我自己的任务对话框 API 包装器。
  • @David:是的,我一直不明白为什么必须启用主题(但我也没有花时间研究这个问题)。但可以肯定的是,TTaskDialog 有一些问题。最重要的是,它几乎没有文档。但它也有一些错误,例如this one
  • 你好安德烈亚斯。实际上,当我看到 MessageDlg 不起作用时,我立即切换到 MessageBox。我只是想我做错了什么。感谢您最完整的解释。接受。
  • 使用标志 := 标志 + [tfUseHiconMain];否则你会松开 Windows10 上对话框的关闭按钮 :) 。为答案+1
  • 当你必须显示较长的字符串时,MessageBox 比 TTaskDialog 好得多,因为 TTaskDialog 会过早地包装你的字符串(它的宽度往往比 MessageBox 的宽度小得多)。
【解决方案3】:

如果您需要一些对话框,可以查看我们的Open Source SynTaskDialog unit for Windows XP、Vista、Seven。

它将在Vista和Seven下调用Native Task Dialog,并在XP下模拟它。与标准 Dialogs 单元或 Windows API 相比,您将获得更好的交互,并且将有您的确认图标,正如预期的那样。

这是在 Windows 7 64 位计算机下的结果:

这是从我们模拟的纯 Delphi 代码创建的同一个对话框:

这是一个选择任务对话框,带有“命令链接”按钮,在本机七中:

这是使用 VCL 仿真代码创建的窗口:

请注意,有确认图标。 ;)

从 Delphi 6 到 XE。

【讨论】:

  • 不过,程序员的界面看起来比VCL的界面好用TTaskDialog
  • @Andreas 是的,小页脚图标是使用 GDI 呈现的:它是从操作系统检索到的标准对话框图标,拉伸到一半大小。我应该使用 GDI+ 以更好的抗锯齿来渲染它。但是对于 XP 部分,我不想为该单元添加任何进一步的依赖项。如果你知道如何通过 API 检索更好看的半尺寸图标,我就是你的人!是的,我试图让界面比 TTaskDialog 更简单:它不是免费的克隆,它是一个新的实现(我没有看 VCL 代码,只是希望完成工作)。
  • 很高兴知道。感谢您的链接!
  • PS:我认为图标看起来并不完美,但可以接受。用户将理解其含义。这不像 MessageDlg 的图标完全错误。
  • @Arnaud: LoadIconWithScaleDown 似乎可以这样做,但它仅在 TaskDialogIndirect 也可用的情况下可用(我想知道为什么?;-)) - 所以它对你的仿真没有多大用处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 2017-07-20
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2020-04-25
相关资源
最近更新 更多