Как использовать TTaskDialog? - PullRequest
24 голосов
/ 12 февраля 2011

Как использовать класс 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 ]

54 голосов
/ 13 февраля 2011

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

Диалог Hello World of Task

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 в разделе или двух.)

Sample of a TTaskDialog

Being a Well-Behaved Citizen

Of course, the task dialog will crash the program if running under Windows XP, where there is not task dialog API. It will also not work if visual themes are disabled. In any such case, we need to stick to the old-fashioned MessageBox. Hence, in a real application, we would need to do

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);

In the rest of this article, we will assume that the налог обратной совместимости уплачивается, и вместо этого сконцентрируемся только на диалоге задачи.

Типы диалогов.Модальные результаты

Свойство 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;

Sample of a TTaskDialog

Below are samples of the remaining icon types (shield, warning, and error, respectively):

Sample of a TTaskDialog

Sample of a TTaskDialog

Sample of a TTaskDialog

Finally, you should know that you can use the DefaultButton property to set the default button in the dialog box.

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;

Sample of a TTaskDialog

Custom Buttons

You can add custom buttons to a task dialog. In fact, you can set the CommonButtons property to the empty set, and rely entirely on custom buttons (and un unlimited number of such buttons, too). The following real-world example shows such a dialog box:

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

Sample of a TTaskDialog

Command Links

Instead of classical pushbuttons, the task dialog buttons can be command links. This is achieved by setting the tfUseCommandLinks flag (in Flags). Now you can also set the CommandLinkHint (per-button) property:

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

Sample of a TTaskDialog

The tfAllowDialogCancellation flag will restore the close system menu item (and titlebar button -- in fact, it will restore the entire system menu).

Sample of a TTaskDialog

Don't Throw Technical Details at the End User

You can use the properties ExpandedText and ExpandedButtonCaption to add a piece of text (the former) that is only displayed after the user clicks a button (to the left of the text in the latter property) to request it.

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

The image below shows the dialog after the user has clicked the button to reveal the additional details.

Sample of a TTaskDialog

If you add the tfExpandFooterArea flag, the additional text will instead be shown in the footer:

Sample of a TTaskDialog

In any case, you can let the dialog open with the details already expanded by adding the tfExpandedByDefault flag.

Custom Icons

You can use any custom icon in a task dialog, by using the tfUseHiconMain flag and specifying the TIcon to use in the CustomMainIcon property.

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

Sample of a TTaskDialog

Hyperlinks

You can even use HTML-like hyperlinks in the dialog (in Text, Footer, and ExpandedText), if you only add the tfEnableHyperlinks flag:

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, tfEnableHyperlinks];CustomMainIcon: = Application.Icon;Выполнить;наконец, свободным;end 

Sample of a TTaskDialog

Notice, however, that nothing happens when you click the link. The action of the link must be implemented manually, which -- of course -- is a good thing. To do this, respond to the OnHyperlinkClicked event, which is a TNotifyEvent. The URL of the link (the href of the a element, that is) is stored in the URL public property of the 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'http://english.rejbrand.se'; Флаги: = [tfUseHiconMain, tfAllowDialogCancellation, tfEnableHyperlinks];OnHyperlinkClicked: = TaskDialogHyperlinkClicked;CustomMainIcon: = Application.Icon;Выполнить;наконец, свободным;конец конец;

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

Вы можете использовать свойства 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

Используя флаг tfUseHiconFooter и свойство CustomFooterIcon, вы можете использовать любой пользовательский значок в нижнем колонтитуле, так же, как вы можете выбрать свой собственный главный значок.

Флажок

Используя строковое свойство VerificationText, вы можете добавить флажок в нижний колонтитул диалогового окна задачи.Заголовок флажка является свойством.

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

Вы можете изначально установить флажок, указав флаг 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

6 голосов
/ 09 января 2012

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

Открытый источник SynTaskDialog для XP, Vista, Seven

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

4 голосов
/ 12 февраля 2011

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

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

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

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

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

1 голос
/ 13 февраля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...