30

如何使用TTaskDialog该类(在 Delphi 2009 及更高版本中)?官方文档没有帮助。事实上,您可以通过使用 CodeInsight 或 VCL 源代码检查该类来了解更多信息。那里没有教学解释,但至少也没有错误(嗯,只有几个)。

就在最近,我想知道您如何响应对话框中的超链接点击。实际上,设置tfEnableHyperlinks标志,您可以在对话框的文本部分中包含 HTML 超链接。(好吧,文档对标志说:“如果设置,内容、页脚和扩展文本可以包含超链接。”自然,链接是使用<AHTML 元素实现的,这是“显而易见的”。)我设法弄清楚我自己认为您使用该OnHyperLinkClick事件来响应对超链接的点击。但是这个事件是一个TNotifyEvent,那么你怎么知道点击了哪个链接呢?好吧,文档对此只字未提,所以我不得不猜测。最终我发现URL对话框的公共属性已设置,所以我可以这样做

procedure TmainFrm.TaskDialogHyperLinkClicked(Sender: TObject);
begin
  if Sender is TTaskDialog then
    with Sender as TTaskDialog do
      ShellExecute(0, 'open', PChar(URL), nil, nil, SW_SHOWNORMAL);
end;

官方文档说,关于这个属性:

URL 包含任务对话框的 URL。

现在,您必须承认,这是一个很好的解释!但比这更糟糕的是:文档不仅缺乏解释,而且还包含错误。例如

ExpandButtonCaption:此按钮的附加信息。

这不是很准确。什么按钮?如果您显示此特定属性的帮助,它会说

ExpandButtonCaption 包含扩展标题时要显示的附加文本。

也不好。什么字幕?一个适当的解释是

ExpandButtonCaption 是显示在按钮旁边的文本,可让用户展开对话框以显示更多信息。例如,此属性可能是“更多详细信息”。

无论如何,目前,我正在尝试创建一个带有两个命令链接按钮的对话框。我知道操作系统可以显示这些带有标题和更长解释的按钮,但我似乎无法使用TTaskButton. 文档不是很好

但是,与其问如何在 SO 上实现这个特定的东西,我会问另一个问题:

TTaskDialog 类是否有任何(非官方)文档?

4

4 回答 4

76

如果找不到文档,请编写

任务对话框的 Hello World

with TTaskDialog.Create(Self) do
  try
    Caption := 'My Application';
    Title := 'Hello World!';
    Text := 'I am a TTaskDialog, that is, a wrapper for the Task Dialog introduced ' +
            'in the Microsoft Windows Vista operating system. Am I not adorable?';
    CommonButtons := [tcbClose];
    Execute;
  finally
    Free;
  end;

Caption是显示在窗口标题栏中的文本,Title是标题,Text是对话框的主体。不用说,Execute显示任务对话框,结果如下图所示。CommonButtons(我们将在一两个部分返回该物业。)

TTaskDialog 示例

做一个行为端正的公民

当然,如果在没有任务对话框 API 的 Windows XP 下运行,任务对话框会导致程序崩溃。如果禁用视觉主题,它也将不起作用。在任何这种情况下,我们都需要坚持老式的MessageBox. 因此,在实际应用中,我们需要做

if (Win32MajorVersion >= 6) and ThemeServices.ThemesEnabled then
  with TTaskDialog.Create(Self) do
    try
      Caption := 'My Application';
      Title := 'Hello World!';
      Text := 'I am a TTaskDialog, that is, a wrapper for the Task Dialog introduced ' +
              'in the Microsoft Windows Vista operating system. Am I not adorable?';
      CommonButtons := [tcbClose];
      Execute;
    finally
      Free;
    end
else
  MessageBox(Handle,
             'I am an ordinary MessageBox conveying the same message in order to support' +
             'older versions of the Microsoft Windows operating system (XP and below).',
             'My Application',
             MB_ICONINFORMATION or MB_OK);

在本文的其余部分,我们将假设支付了向后兼容性的,而是只关注任务对话框。

对话框的类型。模态结果

CommonButtons属性的类型为TTaskDialogCommonButtons,定义为

TTaskDialogCommonButton = (tcbOk, tcbYes, tcbNo, tcbCancel, tcbRetry, tcbClose);
TTaskDialogCommonButtons = set of TTaskDialogCommonButton;

这个属性决定了对话框中显示的按钮(如果没有手动添加按钮,我们稍后会这样做)。如果用户单击这些按钮中的任何一个,相应的TModalResult值将在返回后ModalResult立即存储在属性中Execute。该MainIcon属性决定了对话框中显示的图标,并且应该——当然——反映对话框的性质,按钮集也应该如此。形式上是一个整数,MainIcon可以设置为任何值tdiNonetdiWarningtdiErrortdiInformationtdiShield

with TTaskDialog.Create(Self) do
  try
    Caption := 'My Application';
    Title := 'The Process';
    Text := 'Do you want to continue even though [...]?';
    CommonButtons := [tcbYes, tcbNo];
    MainIcon := tdiNone; // There is no tdiQuestion
    if Execute then
      if ModalResult = mrYes then
        beep;
  finally
    Free;
  end;

TTaskDialog 示例

以下是其余图标类型的示例(分别为屏蔽、警告和错误):

TTaskDialog 示例

TTaskDialog 示例

TTaskDialog 示例

最后,您应该知道您可以使用该DefaultButton属性来设置对话框中的默认按钮。

with TTaskDialog.Create(Self) do
  try
    Caption := 'My Application';
    Title := 'The Process';
    Text := 'Do you want to continue even though [...]?';
    CommonButtons := [tcbYes, tcbNo];
    DefaultButton := tcbNo;
    MainIcon := tdiNone;
    if Execute then
      if ModalResult = mrYes then
        beep;
  finally
    Free;
  end;

TTaskDialog 示例

自定义按钮

您可以将自定义按钮添加到任务对话框。事实上,您可以将CommonButtons属性设置为空集,并完全依赖自定义按钮(以及无限数量的此类按钮)。以下真实示例显示了这样一个对话框:

with TTaskDialog.Create(self) do
  try
    Title := 'Confirm Removal';
    Caption := 'Rejbrand BookBase';
    Text := Format('Are you sure that you want to remove the book file named "%s"?', [FNameOfBook]);
    CommonButtons := [];
    with TTaskDialogButtonItem(Buttons.Add) do
    begin
      Caption := 'Remove';
      ModalResult := mrYes;
    end;
    with TTaskDialogButtonItem(Buttons.Add) do
    begin
      Caption := 'Keep';
      ModalResult := mrNo;
    end;
    MainIcon := tdiNone;
    if Execute then
      if ModalResult = mrYes then
        DoDelete;
  finally
    Free;
  end

TTaskDialog 示例

命令链接

任务对话框按钮可以是命令链接,而不是传统的按钮。这是通过设置tfUseCommandLinks标志 (in Flags) 来实现的。现在您还可以设置CommandLinkHint(每个按钮)属性:

with TTaskDialog.Create(self) do
  try
    Title := 'Confirm Removal';
    Caption := 'Rejbrand BookBase';
    Text := Format('Are you sure that you want to remove the book file named "%s"?', [FNameOfBook]);
    CommonButtons := [];
    with TTaskDialogButtonItem(Buttons.Add) do
    begin
      Caption := 'Remove';
      CommandLinkHint := 'Remove the book from the catalogue.';
      ModalResult := mrYes;
    end;
    with TTaskDialogButtonItem(Buttons.Add) do
    begin
      Caption := 'Keep';
      CommandLinkHint := 'Keep the book in the catalogue.';
      ModalResult := mrNo;
    end;
    Flags := [tfUseCommandLinks];
    MainIcon := tdiNone;
    if Execute then
      if ModalResult = mrYes then
        DoDelete;
  finally
    Free;
  end

TTaskDialog 示例

tfAllowDialogCancellation标志将恢复关闭系统菜单项(和标题栏按钮——事实上,它将恢复整个系统菜单)。

TTaskDialog 示例

不要向最终用户抛出技术细节

您可以使用属性ExpandedTextExpandedButtonCaption添加一段文本(前者),该文本仅在用户单击按钮(在后者属性中的文本左侧)后才会显示以请求它。

with TTaskDialog.Create(self) do
  try
    Title := 'Confirm Removal';
    Caption := 'Rejbrand BookBase';
    Text := Format('Are you sure that you want to remove the book file named "%s"?', [FNameOfBook]);
    CommonButtons := [];
    with TTaskDialogButtonItem(Buttons.Add) do
    begin
      Caption := 'Remove';
      CommandLinkHint := 'Remove the book from the catalogue.';
      ModalResult := mrYes;
    end;
    with TTaskDialogButtonItem(Buttons.Add) do
    begin
      Caption := 'Keep';
      CommandLinkHint := 'Keep the book in the catalogue.';
      ModalResult := mrNo;
    end;
    Flags := [tfUseCommandLinks, tfAllowDialogCancellation];
    ExpandButtonCaption := 'Technical information';
    ExpandedText := 'If you remove the book item from the catalogue, the corresponding *.book file will be removed from the file system.';
    MainIcon := tdiNone;
    if Execute then
      if ModalResult = mrYes then
        DoDelete;
  finally
    Free;
  end

下图显示了用户单击按钮以显示其他详细信息后的对话框。

TTaskDialog 示例

如果添加tfExpandFooterArea标志,则附加文本将显示在页脚中:

TTaskDialog 示例

在任何情况下,您都可以通过添加tfExpandedByDefault标志来打开已展开详细信息的对话框。

自定义图标

您可以在任务对话框中使用任何自定义图标,方法是使用tfUseHiconMain标志并TIcon在属性中指定要使用的CustomMainIcon

with TTaskDialog.Create(self) do
  try
    Caption := 'About Rejbrand BookBase';
    Title := 'Rejbrand BookBase';
    CommonButtons := [tcbClose];
    Text := 'File Version: ' + GetFileVer(Application.ExeName) + #13#10#13#10'Copyright © 2011 Andreas Rejbrand'#13#10#13#10'http://english.rejbrand.se';
    Flags := [tfUseHiconMain, tfAllowDialogCancellation];
    CustomMainIcon := Application.Icon;
    Execute;
  finally
    Free;
  end

TTaskDialog 示例

超链接

如果您只添加标志Text,您甚至可以在对话框中使用类似 HTML 的超链接(在Footer,和中):ExpandedTexttfEnableHyperlinks

with TTaskDialog.Create(self) do
  try
    Caption := 'About Rejbrand BookBase';
    Title := 'Rejbrand BookBase';
    CommonButtons := [tcbClose];
    Text := 'File Version: ' + GetFileVer(Application.ExeName) + #13#10#13#10'Copyright © 2011 Andreas Rejbrand'#13#10#13#10'<a href="http://english.rejbrand.se">http://english.rejbrand.se</a>';
    Flags := [tfUseHiconMain, tfAllowDialogCancellation, tfEnableHyperlinks];
    CustomMainIcon := Application.Icon;
    Execute;
  finally
    Free;
  end

TTaskDialog 示例

但是请注意,单击链接时没有任何反应。链接的动作必须手动实现,这当然是一件好事。为此,请响应OnHyperlinkClicked事件,即TNotifyEvent. 链接的 URL(即 a 元素的 href)存储在 的URLpublic 属性中TTaskDialog

procedure TForm1.TaskDialogHyperLinkClicked(Sender: TObject);
begin
  if Sender is TTaskDialog then
    with Sender as TTaskDialog do
      ShellExecute(0, 'open', PChar(URL), nil, nil, SW_SHOWNORMAL);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  with TTaskDialog.Create(self) do
    try
      Caption := 'About Rejbrand BookBase';
      Title := 'Rejbrand BookBase';
      CommonButtons := [tcbClose];
      Text := 'File Version: ' + GetFileVer(Application.ExeName) + #13#10#13#10'Copyright © 2011 Andreas Rejbrand'#13#10#13#10'<a href="http://english.rejbrand.se">http://english.rejbrand.se</a>';
      Flags := [tfUseHiconMain, tfAllowDialogCancellation, tfEnableHyperlinks];
      OnHyperlinkClicked := TaskDialogHyperlinkClicked;
      CustomMainIcon := Application.Icon;
      Execute;
    finally
      Free;
    end
end;

页脚

您可以使用FooterFooterIcon属性来创建页脚。该icon属性接受与该属性相同的值MainIcon

with TTaskDialog.Create(self) do
  try
    Caption := 'My Application';
    Title := 'A Question';
    Text := 'This is a really tough one...';
    CommonButtons := [tcbYes, tcbNo];
    MainIcon := tdiNone;
    FooterText := 'If you do this, then ...';
    FooterIcon := tdiWarning;
    Execute;
  finally
    Free;
  end

TTaskDialog 示例

使用tfUseHiconFooter标志和CustomFooterIcon属性,您可以在页脚中使用任何自定义图标,就像您可以选择自己的主图标一样。

复选框

使用VerificationText字符串属性,您可以在任务对话框的页脚添加一个复选框。复选框的标题是属性。

with TTaskDialog.Create(self) do
  try
    Caption := 'My Application';
    Title := 'A Question';
    Text := 'This is a really tough one...';
    CommonButtons := [tcbYes, tcbNo];
    MainIcon := tdiNone;
    VerificationText := 'Remember my choice';
    Execute;
  finally
    Free;
  end

TTaskDialog 示例

tfVerificationFlagChecked您可以通过指定标志来使复选框最初被选中。不幸的是,由于 的 VCL 实现中的错误(?),在返回TTaskDialog时包含此标志Execute并不能反映复选框的最终状态。为了跟踪复选框,应用程序因此需要记住初始状态并切换内部标志作为对每个OnVerificationClicked事件的响应,每次在对话框模式期间更改复选框的状态时都会触发该事件。

单选按钮

单选按钮可以以类似于添加自定义按钮(或命令链接按钮)的方式实现:

with TTaskDialog.Create(self) do
  try
    Caption := 'My Application';
    Title := 'A Question';
    Text := 'This is a really tough one...';
    CommonButtons := [tcbOk, tcbCancel];
    MainIcon := tdiNone;
    with RadioButtons.Add do
      Caption := 'This is one option';
    with RadioButtons.Add do
      Caption := 'This is another option';
    with RadioButtons.Add do
      Caption := 'This is a third option';
    if Execute then
      if ModalResult = mrOk then
        ShowMessage(Format('You chose %d.', [RadioButton.Index]));
  finally
    Free;
  end

TTaskDialog 示例

于 2011-02-13T01:29:25.183 回答
7

这是旧东西,但为了完整起见,我在这里添加:

适用于 XP、Vista、7 的开源 SynTaskDialog 单元

TTaskDialog在 XP(使用 VCL)下工作的单元,但在 Vista+ 下使用系统 TaskDialog。

于 2012-01-08T20:51:51.147 回答
5

TMS 有一个很好的包装器,它还模拟了在 XP 上运行时的新行为。这是一个快速插入。虽然它不是免费的,但并没有真正回答您的“如何做”问题。

http://www.tmssoftware.com/site/vtd.asp

他们还有一些讨论对话框的文章,如果您想制作自己的包装器,还有一些源代码可能对您有用。

http://www.tmssoftware.com/site/atbdev5.asp

http://www.tmssoftware.com/site/atbdev7.asp

于 2011-02-12T18:07:40.127 回答
0

这是我的简短文档:

  1. 不要使用它,除非您不希望您的应用程序在 XP 上运行。

  2. 与其他人一样,建议对delphi doc wiki内容进行改进,但请注意短语“注意:任务对话框需要 Vista 或 Windows 7”。那是“不要使用它!”的代码。基本上,有人想到要完全支持新的 Windows Vista 对话框,而这样做的方式是编写只调用对话框 API 的包装器代码。由于没有为您提供后备功能,因此您在 XP 上不走运。

于 2011-02-13T04:04:11.930 回答