Delphi MessageDlg显示信息图标而不是确认

Delphi MessageDlg显示信息图标而不是确认,delphi,windows-7,Delphi,Windows 7,在Win 7上,MessageDlg显示信息图标,而不是确认图标(问号)。 代码如下: MessageDlg('Are you sure you want to delete this file?'+ CRLF+ FileName, mtConfirmation, [mbYes, mbNo], 0)= mrYes 我做错了什么?首先,请注意一个简单的解决方法是使用Windows APIMessageBox函数: MessageBox(Handle, 'This is a test.', 'Te

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

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

我做错了什么?

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

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

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

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

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

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

但是,遗憾的是,任务对话框不支持问号图标(作为预定义图标)。这不是
TTaskDialog
包装器的限制,而是Windows任务对话框API的限制。例如,请参见。有
TD\u错误图标
TD\u警告图标
,和
TD\u信息图标
,但没有问号图标

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

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不可用,我将使用旧的
消息框

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


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

如果您需要一些对话框,您可以查看我们的Windows XP、Vista、Seven

它将在Vista和Seven下调用本机任务对话框,并在XP下进行模拟。与标准对话框单元或Windows API相比,您将有更好的交互,并且会像预期的那样显示确认图标

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

下面是由我们模拟的纯Delphi代码创建的相同对话框:

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

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

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

从Delphi 6一直工作到XE。

如果(Win32MajorVersion>=6)和ThemeServices.ThemesEnabled则
使用TTaskDialog.Create(Self)do
尝试
标题:=‘删除’;
标题:='你确定要移除地雷船吗?';
文本:=“如果你删除minecraft,它将永远消失。”;
CommonButtons:=[tcbYes,tcbNo];
CustomMainIcon.ReleaseHandle;
CustomMainIcon.Handle:=LoadIcon(0,IDI_问题);
标志:=[tfUseHiconMain];
执行;
最后
自由的
结束
其他的
MessageBox(手柄,
“如果你删除minecraft,它将永远消失。”,
“你确定要移除地雷船吗?”,
MB_i查询或MB_YESNO);

请参见
主题服务。主题启用的测试让我咯咯笑了起来。您确实意识到我相信您必须这样做,因为Delphi TTaskDialog中有一个愚蠢的错误。任务对话框适用于Win32MajorVersion>=6,它在Windows经典上运行良好。我不知道为什么Embarcadero会这样做。正如您可能想象的那样,由于这些弱点,我使用了自己的任务对话框API包装器。@David:是的,我一直不明白为什么必须启用主题(但我也没有花任何时间研究这个问题)。但是可以肯定的是,
TTaskDialog
有一些问题。最重要的是,它实际上缺乏文档。但是它也有一些bug,例如,嗨,安德烈亚斯。事实上,当我看到MessageDlg不工作时,我立即切换到MessageBox。我只是想知道我做错了什么。谢谢你最完整的解释。已接受。使用标志:=Flags+[tfUseHiconMain];否则,将松开Windows10:)上对话框的关闭按钮+1对于答案当您必须显示更长的字符串时,MessageBox比TTaskDialog好得多,因为TTaskDialog会过早地包装字符串(其宽度往往比MessageBox的宽度小得多)。不过,程序员的界面看起来比VCL
TTaskDialog
@Andreas Yes的界面更易于使用,小页脚图标是使用GDI呈现的:它是从操作系统中检索到的标准对话框图标,拉伸到一半大小。我应该使用GDI+以更好的抗锯齿效果进行渲染。但是对于XP部分,我不想给这个单元增加任何进一步的依赖性。如果您知道如何通过API检索外观更好的半尺寸图标,我就是您的人!是的,我试着让界面比TTaskDialog更简单:它不是一个免费的克隆,它是一个新的实现(我没有看VCL代码,只是想完成工作)。很高兴知道。谢谢你的链接!PS:我认为这个图标看起来并不完美,但可以接受。用户将理解其含义。这与MessageDlg中的图标完全错误的情况不同。@Arnaud:似乎可以这样做,但它仅在TaskDialogIndirect也可用的情况下可用(我想知道为什么?;-)-所以它对