2009-04-20 14 views
1

私はアルゴリズムを持っています。私はある時点でそれを一時停止し、ユーザがボタンを押すと続行したいと思います。それ、どうやったら出来るの?私はドキュメンテーションを閲覧し、インターネットを検索しましたが、まだ運はありません。 (pauzaは、単に一定でセルビアに一時停止を意味します)私は睡眠を使用し、今ボタンを押すまでプログラムの実行を一時停止する方法は?

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

      sleep(pauza); 

      br:=br+1; 
      end; 

は、ここで関連するコードスニップです。理想的には、その行をその時間間隔の間スリープする手順に置き換えるか、構成設定に基づいてボタンを押すのを待っています。

EDIT1:ああ、それは明白ではない - それはグラフィックアプリケーションであり、コンソールではないので、 "readln"を打つことは(悲しいことに)うまくいきません。

答えて

0

良いアプリケーションデザインとしてはお勧めできませんが、他の提案があなたには適していない場合は、この方法をお勧めします。

クラス/フォームに 'Paused:Boolean'フィールドを追加し、[続行]ボタンをクリックします。

操作を開始するときは、[一時停止]を[偽]に設定し、[続行]を有効にします。あなたのボタンのイベントハンドラを続けて

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; 

はないが、それは取得する必要がありますあなたのコードは、あなたが一時停止するセクションに達する

仕事が終わった。

+2

Sleep()を呼び出すと、ユーザはボタンを押すことができませんので、無限ループを作成しました。少なくともApplication.ProcessMessages()呼び出しを追加してください。それでも、それはひどい解決策になるでしょう。 – mghie

+0

私はApplication.ProcessMessagesを含むように返信を更新しました。 –

+0

私はmghieに同意しなければならないのではないかと心配しています。この解決策の問題は、このループ中にアプリケーションがあなたのCPUサイクルのほぼ100%を使い切ってしまうことです。 –

-1

ReadLnを使用するだけです。

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

これはイベント駆動型プログラミングの仕組みではありません。ポーズポイントまで処理し、その時点で機能を終了する必要があります。ボタンプレスイベントハンドラでは、残りの処理を行います。これは、ユーザがボタンを押したときにのみ発生します。 OnTimerイベントから同じコードを呼び出して、特定の周期後に処理を続けることができます。

+0

ええ、それはちょうどforループの内側の部分です - それがもっと役立つなら、私は関数全体を投稿できます。 – VPeric

+2

あなたのデザインを再考する必要があるかもしれないと思うかもしれません - イベントドリブン(すなわちGUI)コードの大きなループは別々のスレッドに入れないと悪い考えです。 –

+0

まあ、私は主な質問を脱線させたくありませんでしたが、さまざまなソートアルゴリズムがどのように機能するかを説明するプログラムを作っています(さまざまな色のグラフを入れ替えてみましょう - 私のインスピレーションのためにQuickSortのWikipediaのページを見てください)。必要です。アイデアは、ユーザがソート手順を踏んで、自分のペースで理解できるようにすることです。 – VPeric

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; 

これはおそらく唯一のあなたがかもしれない、しかし、現在のスレッドを停止し、シンプルなメッセージボックスがOKになり、私たちは何をすべきかですダイアログを起動できより関わりのあるものを試してみたい

+0

これは1つのスレッドです。そして、ええ、ShowMessageは私が必要とすることを行います - 問題はそれがビューをあいまいにし、それは醜く見えるということです。他のすべてがうまくいかない場合、私はそれを実行します(どこに表示されるかを判断する方法があると思いますが)が、ユーザの立場から見て分かりやすいものではありません。もし彼がちょうど "普通の"ボタンを押すことができるなら、私は好むだろう。 – VPeric

1

iを静的変数に格納します。ループ内で、一時停止ボタン(一時停止ボタンで設定)のチェックを追加します。フラグが真の場合、関数を終了します。一時停止ボタンを再度クリックすると、再度機能を呼び出します。すでに値が0であれば、値を確認してください。

ループが正常に完了したら、iを0にリセットします。

+0

あなたはここで最善の提案をしていると思います。 –

2

スレッドとTThreadクラスの組み込みサスペンド/レジューム関数を使用します。 Jens Borrisholtはabout.com hereのちょっとしたサンプル記事を書いてこの種のことをしています。

アプリケーションに複数のProcessMessageの場所を導入すると、フォームの終了時に実行中の他のイベントからのコード実行に問題が発生する可能性があります。たとえば、ProcessMessageの "スリープ"モードでフォームが閉じられた場合、スタックを巻き戻す良い方法はありません。

通常のディスプレイを開いていないため、DirectX/OpenGLを使用している場合、MessageDialogが機能しないことがあります。 MessageDialogを呼び出すと、DirectXビューから通常のデスクトップビュー(醜いながらも実行可能)にビューを切り替えることができます。また、DirectXから表示モードを変更せずにメッセージを通常のデスクトップビューに表示することもできます。私がDxで作業して以来、長いことがありましたが、ビューモードを変更することができないという問題は苦労しています。

編集:アレクサンダーが指摘しているように、スレッド内のどこからでもスレッドを停止しないでください(つまり、スレッドAはスレッドAを一時停止できますが、スレッドBは一時停止できません)。 GUIスレッドでソートスレッドを中断させたい場合は、ソートスレッドにメッセージを送り、ソートスレッド内でサスペンドを処理します。彼のリンクには、これがなぜそうであるかに関する良い議論が含まれています。

+0

これは彼が達成しようとしているものについてはあまりにも複雑すぎないのですか? –

+0

サスペンドとレジュームは、デバッガ以外には何もありませんでした。 –

0

私はスレッドアプローチに同意しますが、私はsuspend/resumeを使用することは非常に悪い考えです。理由は次のとおりです。http://blogs.msdn.com/oldnewthing/archive/2003/12/09/55988.aspx

スレッドを作成し、イベントを使用してスレッドを一時停止/再開します。シンプル。ところで、AsyncCallsのようなものを使ってスレッドの作成を簡単にすることもできます(TThreadクラスは必要ありません)。

別のスレッドを作成することは、バックグラウンドで重い計算を行うことができるため、UIを妨げないためです。あなたのアプリはスムーズに反応します。

+1

その記事では何の言い方もされていないので、あなたがそれを逃したことは分かりますが、最初のコメントと5番目のコメントには記載されています。スレッドが自分自身を中断することは完全に安全です。これはスレッドの他のアクティビティを中断させる可能性がないためです。スレッドはソートの1つのステップを実行して、それ自体を中断します。 –

+0

このリンクは実際には前の回答の例に対する応答でした;) – Alex

関連する問題