如何暂停程序执行直到按下按钮?

时间:2009-04-20 16:52:45

标签: delphi

我有一个算法。我想在某个时候暂停它,然后在用户按下按钮后继续。我怎么做?我浏览了文档,搜索了互联网,但还没有运气。

以下是相关的代码片段:

      if A[i]>A[i+1]
        then
          begin
            Zameni(i,i+1);
            done:=true;

            sleep(pauza);

            br:=br+1;
          end;

现在,我使用睡眠(pauza只是一个常数,意味着在塞尔维亚暂停)。理想情况下,我想用一个可以间隔睡眠的程序替换该行,或者根据配置设置等待按下按钮。

EDIT1:啊,是的,如果不是很明显 - 它是一个图形应用程序,而不是控制台,所以拍打“readln”将无法工作(遗憾)。

7 个答案:

答案 0 :(得分:5)

这不是你如何做事件驱动的编程。您应该处理暂停点并在此时结束您的功能。在按钮按下事件处理程序中,然后执行剩余的处理 - 这只会在用户按下按钮时发生。您可以从OnTimer事件中调用相同的代码,以在给定的peruiod之后继续处理。

答案 1 :(得分:2)

使用线程和TThread类的内置暂停/恢复功能。 Jens Borrisholt写了一篇关于about.com here做一个很好的小例子文章。

如果在应用程序中引入多个ProcessMessage位置,则表单关闭时,其他事件的代码执行可能会出现问题。例如,如果在ProcessMessage“sleep”模式下关闭了表单,则没有好的方法来展开堆栈。

如果您使用的是DirectX / OpenGL,MessageDialog可能无法正常工作,因为您无法打开正常显示。调用MessageDialog可能会将视图从DirectX视图切换到普通桌面视图(丑陋但可行)或者它可以在普通桌面视图上显示消息而不更改DirectX的显示模式(使用户无法看到提示)。我和Dx合作已经有很长一段时间了,但我记得有关未能改变视图模式的问题很痛苦。

编辑:正如亚历山大指出的那样,你不应该从线程中的任何地方暂停线程(即,线程A可以挂起线程A而不是线程B)。如果您希望GUI线程暂停排序线程,请向排序线程发送消息并在排序线程内处理挂起。他的链接很好地讨论了为什么会这样。

答案 2 :(得分:1)

将i存储在静态变量中。在循环内部添加一个Pause标志的检查(由暂停按钮设置)。如果该标志为true,则退出该函数。再次单击暂停按钮时再次调用该功能。检查i的值,如果已经> 0只需进入你离开的循环。

当循环成功完成时,将i重置为0;

答案 3 :(得分:0)

您可以启动一个我们所做的对话框,一个简单的消息框就可以了,即


  procedure TForm1.Pause1Click(Sender: TObject);
  begin
    // A dialog box will halt thread execution
    Windows.MessageBox(0, 'Paused ...' + sLineBreak + 'Press Enter to Continue',
      '', MB_OK);
  end;

这可能只会暂停当前线程,如果你有多个线程,你可能想尝试更多参与。

答案 4 :(得分:0)

我不推荐它作为良好的应用程序设计,但如果没有其他建议适合您,您可能更喜欢这个。

在您的班级/表单中添加“已暂停:布尔”字段,并添加“继续”按钮。

开始操作时,将Paused设置为False,然后设置Continue.Enabled:= False;

当您的代码到达您要暂停的部分时:

Paused := True;
Continue.Enabled := True;
while Paused do
begin
  sleep(100);
  Application.ProcessMessages;
end;

在“继续”按钮事件处理程序中:

procedure Form1.ContinueClick(Sender: TObject);
begin
  Paused := False;
  Continue.Enabled := False;
end;

正如我之前所说,不是很漂亮,但它应该完成工作。

答案 5 :(得分:0)

虽然我同意线程方法,但我认为使用暂停/恢复是一个非常糟糕的主意。原因如下:http://blogs.msdn.com/oldnewthing/archive/2003/12/09/55988.aspx

创建一个线程并使用事件来暂停/恢复线程。简单。顺便说一下,你也可以使用像AsyncCalls这样的东西来简化线程创建(你不需要TThread类)。

创建一个单独的线程有另一个原因:你可以在后台进行繁重的计算,因此它们不会干扰UI。你的应用程序会有平稳的反应。

答案 6 :(得分:-1)

只需使用ReadLn;

 ShowConsole("Enter to continue.");
 ReadLn;