【发布时间】: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
我做错了什么?
【问题讨论】:
在 Win 7 上,MessageDlg 显示信息图标而不是确认图标(问号)。 代码如下:
MessageDlg('Are you sure you want to delete this file?'+ CRLF+ FileName, mtConfirmation, [mbYes, mbNo], 0)= mrYes
我做错了什么?
【问题讨论】:
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);
【讨论】:
首先,请注意一个简单的解决方法是改用 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_ICON、TD_WARNING_ICON和TD_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 包装器。
TTaskDialog 有一些问题。最重要的是,它几乎没有文档。但它也有一些错误,例如this one。
如果您需要一些对话框,可以查看我们的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。
【讨论】:
TTaskDialog。