Как использовать TTaskDialog?

Как использовать TTaskDialog класс (в Delphi 2009 и позже)? Официальная документация не помогла. Фактически, вы узнаете намного больше, изучая класс с помощью CodeInsight или исходного кода VCL. Там нет педагогических объяснений, но, по крайней мере, ошибок тоже нет (ну, только несколько).

А совсем недавно мне стало интересно, как можно реагировать на клики по гиперссылкам в диалоговом окне. Действительно, установив tfEnableHyperlinks флаг, вы можете включить гиперссылки HTML в текстовые части диалога. (Что ж, в документе сказано о флаге: "Если установлен, контент, нижний колонтитул и расширенный текст могут включать гиперссылки." Естественно, "очевидно", что ссылки реализуются с использованием <A HTML-элемент.) И мне удалось самому понять, что вы используете 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 ответа

Решение

Если вы не можете найти документацию, напишите:

Привет Мир Задачи Диалог

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

Быть хорошо воспитанным гражданином

Конечно, диалоговое окно задач приведет к сбою программы, если она работает под Windows XP, где нет API диалога задач. Это также не будет работать, если визуальные темы отключены. В любом таком случае нам нужно придерживаться старомодного 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 может быть установлено любое из значений tdiNone, tdiWarning, tdiError, tdiInformation, а также tdiShield,

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 флаг (в 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

Не бросайте технические детали конечному пользователю

Вы можете использовать свойства ExpandedText а также ExpandedButtonCaption добавить фрагмент текста (первый), который отображается только после того, как пользователь нажимает кнопку (слева от текста в последнем свойстве), чтобы запросить его.

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

Гиперссылки

Вы даже можете использовать HTML-подобные гиперссылки в диалоге (в Text, Footer, а также ExpandedText), если вы только добавите tfEnableHyperlinks флаг:

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) хранится в URL государственная собственность 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;

Нижний колонтитул

Вы можете использовать Footer а также FooterIcon свойства для создания нижнего колонтитула. 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 Строковое свойство, вы можете добавить флажок в нижний колонтитул диалогового окна задачи. Подпись флажка является собственностью.

с TTaskDialog.Create(self) попробуйте Caption:= 'My Application'; Название: = 'Вопрос'; Текст: = 'Это действительно сложный вопрос...'; CommonButtons:= [tcbYes, tcbNo]; MainIcon:= tdiNone; VerificationText:= 'Запомнить мой выбор'; Выполнить; наконец, свободным; конец

Образец 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

Это старые вещи, но я добавляю это здесь для полноты:

Блок с открытым исходным кодом SynTaskDialog для XP, Vista, Seven

TTaskDialog Устройство, которое работает под XP (с VCL), но использует систему TaskDialog под Vista+.

TMS имеет приятную оболочку, и он также эмулирует новое поведение при запуске на XP. Это очень просто. Это не бесплатно, и на самом деле не отвечает на ваш вопрос "как".

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

У них также есть несколько статей, в которых они обсуждают диалог, и есть некоторый исходный код, который может быть полезен вам, если вы хотите сделать свою собственную обертку.

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

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

Вот моя короткая документация:

  1. Не используйте его, если только вы не хотите, чтобы ваше приложение работало на XP.

  2. Предложите улучшения вики- контента delphi doc, как это сделали другие, но обратите внимание на фразу "Примечание: для диалоговых окон задач требуется Vista или Windows 7". это код для "Не используйте его!" По сути, кому-то пришла в голову идея полностью поддерживать новые диалоги Windows Vista, и способ, которым это было сделано, заключался в написании кода-обертки, который вызывает только диалоговые API-интерфейсы. Поскольку вам не предоставляется резервная функциональность, вам не повезло в XP.

Другие вопросы по тегам