1

我的 Delphi 应用程序的一部分从另一个程序访问信息。因为执行可能需要一些时间,而且有时其他程序可能没有响应,所以我在单独的线程中运行我的那部分代码。

为了让我的用户了解后台线程的进度,我在启动线程后执行了一个 TaskDialog。我将一个指向 TaskDialog 的指针传递给我的线程,以便线程可以与 TaskDialog 同步以在线程进行时更新它。线程完成后,我使用以下方法向 TaskDialog 发送关闭消息PostMessage(CurrentTaskDialog.Handle, WM_CLOSE, 0, 0);

到目前为止一切正常,但是如果用户单击 TaskDialog 上的 Cancel 按钮(它是 TaskDialog 上的唯一按钮),我想取消该过程。我不知道该怎么做。无论用户是否单击按钮,或者 TaskDialog 是否收到关闭消息,ModalResult都始终是mrCancel. 我尝试ModalResult在线程中分配一个不同的值,但它仍然评估为mrCancel.

有没有办法做到这一点?

4

1 回答 1

3

TaskDialogIndirect()根据文档,您所描述的是正常行为:

pnButton

类型:int*

接收以下任一变量的地址:

  • 参数pButtons成员中指定的按钮 ID 之一pTaskConfig

  • 以下值之一:

    • 0:函数调用失败。有关详细信息,请参阅返回值。
    • IDCANCEL:取消按钮被选中,Alt-F4 被按下,Escape 被按下,或者用户点击了关闭窗口按钮。
    • IDNO:未选择任何按钮。
    • IDOK:确定按钮被选中。
    • IDRETRY:重试按钮被选中。
    • IDYES:选择是按钮。

由于您只有一个 Cancel 按钮,并且正在模拟按下关闭按钮,因此TaskDialogIndirect()总是报告IDCANCEL,这就是为什么ModalResult总是mrCancel。没有办法区分实际原因(没有挂钩对话窗口本身)。

无论如何,您实际上根本不需要使用ModalResult来完成您想要的。

当对话框因任何原因关闭时,只需发出信号结束线程,然后等待线程完全退出。如果在对话框关闭之前线程已经结束,则忽略该信号,并立即满足等待。

然后,您可以更进一步。tcbCancel您可以在 TaskDialog 的CommonButtons属性中使用自定义按钮,而不是在 TaskDialog 的属性中使用Buttons,然后使用 TaskDialog 的OnButtonClicked事件来通知线程退出。阻止对话框自动关闭(通过CanClose=False在事件处理程序中设置)并等待线程在完成后关闭对话框。这将允许您在等待线程结束时继续在 TaskDialog 内显示反馈,例如显示“等待”消息。而在另一种方法中,当用户单击标准取消按钮时,TaskDialog 窗口将关闭,因此即使线程可能仍在运行,您也无法再显示反馈。

于 2020-07-18T01:31:36.523 回答