我的Delphi应用程序的一部分从另一个程序访问信息。因为执行它可能需要一些时间,有时其他程序可能没有响应,所以我在单独的线程中运行了那部分代码。
为了使我的用户了解后台线程的进度,我在启动线程后执行TaskDialog。我将指向TaskDialog的指针传递给我的线程,以便线程可以与TaskDialog同步以随着线程的进展对其进行更新。线程完成后,我使用PostMessage(CurrentTaskDialog.Handle, WM_CLOSE, 0, 0);
将关闭消息发送到TaskDialog
到目前为止,一切正常,但是如果用户单击TaskDialog上的Cancel按钮(这是TaskDialog上的唯一按钮),我想取消该过程。我不知道该怎么做。无论用户单击按钮还是TaskDialog收到关闭消息,ModalResult
始终为mrCancel
。我尝试在线程中分配不同的ModalResult
,但它的计算结果仍为mrCancel
。
有什么办法可以做到这一点?
最佳答案
根据 TaskDialogIndirect()
documentation,您描述的是正常行为:
pnButton
Type:
int*
Address of a variable that receives either:
one of the button IDs specified in the
pButtons
member of thepTaskConfig
parameterone of the following values:
- 0: Function call failed. Refer to return value for more information.
- IDCANCEL: Cancel button was selected, Alt-F4 was pressed, Escape was pressed, or the user clicked on the close window button.
- IDNO: No button was selected.
- IDOK: OK button was selected.
- IDRETRY: Retry button was selected.
- IDYES: Yes button was selected.
由于您只有一个“取消”按钮,并且正在模拟关闭按钮的按下操作,因此
TaskDialogIndirect()
始终报告IDCANCEL
,这就是为什么ModalResult
始终为mrCancel
的原因。没有办法区分实际原因(缺少对话框对话框本身)。无论如何,您实际上根本不需要使用
ModalResult
即可完成所需的工作。当对话框由于某种原因而关闭时,只需发出信号以结束线程,然后等待线程完全退出即可。如果线程在关闭对话框之前已经结束,则该信号将被忽略,并且等待将立即得到满足。
然后,您可以进一步进行此操作。您可以在TaskDialog的
tcbCancel
属性中使用自定义按钮,而不是在TaskDialog的CommonButtons
属性中使用Buttons
,然后使用TaskDialog的OnButtonClicked
事件来通知线程退出。阻止对话框自动关闭(通过在事件处理程序中设置CanClose=False
),并在完成后等待线程关闭对话框。这将允许您在等待线程结束时继续在TaskDialog中显示反馈,例如显示“等待”消息。而使用另一种方法,当用户单击标准的“取消”按钮时,“任务对话框”窗口将关闭,因此即使线程可能仍在运行,您也无法再显示反馈。
关于multithreading - 确定为什么在Delphi中关闭了一个任务对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62963407/