2009-04-20 159 views
1

我有一個算法。我想暫停它,然後一旦用戶按下按鈕繼續。我怎麼做?我瀏覽過文檔,並搜索了互聯網,但沒有運氣。如何暫停程序執行,直到按下按鈕?

這裏有一個相關的代碼剪斷:

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

      sleep(pauza); 

      br:=br+1; 
      end; 

現在,我使用的睡眠(pauza僅僅是一個常量,意味着塞爾維亞暫停)。理想情況下,我想用一段時間睡眠的程序替換該行,或者等待基於配置設置的按鈕按下。編輯1:啊,是的,如果它不是明顯的 - 這是一個圖形應用程序,而不是控制檯,所以掌握一個「readln」不會工作(可悲)。

回答

0

我不會推薦它作爲優秀的應用程序設計,但如果其他建議都不適合您,您可能更喜歡這樣。

將'Paused:Boolean'字段添加到您的班級/表格和一個'繼續'按鈕。

當您開始操作時,將暫停設置爲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; 

正如我以前說過,不漂亮,但它應該得到的任務完成。

-1

只要使用ReadLn;

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

這不是你如何做事件驅動的編程。您應該執行到暫停點的處理並結束您的功能。在按鈕按下事件處理程序之後,您可以執行剩餘的處理 - 這隻會在用戶按下按鈕時發生。您可以從OnTimer事件中調用相同的代碼,以在給定的peruiod之後繼續處理。

+0

是的,但這只是for循環的內部部分 - 如果這會更有幫助,我可以發佈整個函數。 – VPeric 2009-04-20 17:00:15

+2

聽起來像您可能需要重新考慮您的設計 - 事件驅動(即GUI)代碼中的大循環是一個壞主意,除非它們在單獨的線程中。 – 2009-04-20 17:08:05

+0

嗯,我不想讓主要問題出軌,但我正在製作一個程序來說明各種排序算法是如何工作的(通過對各種彩色圖形進行洗牌 - 請參閱QuickSort上的Wikipedia頁面以獲取靈感),因此循環是需要。這個想法是讓用戶逐步完成整理過程,以便他們能夠按自己的步調理解它。 – VPeric 2009-04-20 17:36:11

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; 

這可能只是暫停當前線程不過,如果你有一個以上的線程,你可能想嘗試更多的參與。

1

將i存儲在一個靜態變量中。在循環內添加一個檢查暫停標誌(由您的暫停按鈕設置)。如果標誌爲真,退出該功能。再次單擊暫停按鈕時再次調用該功能。檢查我的價值,如果它已經> 0,只需進入你離開的循環。

當循環成功完成時,將i重置爲0;

2

使用線程和TThread類的內置掛起/恢復功能。 Jens Borrisholt在about.com here上寫了一篇很好的小示例文章來做這種事情。

如果您在應用程序中引入了多個ProcessMessage位置,那麼當表單關閉時,您可能會遇到其他事件仍在運行的代碼執行問題。例如,如果表單在ProcessMessage「睡眠」模式下關閉,沒有好方法展開堆棧。

如果您使用DirectX/OpenGL,MessageDialog可能無法正常工作,因爲您不會打開正常的顯示。調用MessageDialog可能會將視圖從DirectX視圖切換到普通桌面視圖(醜陋但可行),或者它可能會在正常桌面視圖上顯示消息,而不會改變DirectX的顯示模式(使用戶無法看到提示)。自從我與Dx合作已經很長時間了,但我記得有關未能改變視圖模式是一種痛苦的問題。

編輯:正如亞歷山大指出的那樣,您不應該在線程中的任何地方掛起線程(即線程A可以掛起線程A而不掛入線程B)。如果您希望GUI線程掛起排序線程,請向排序線程發送消息並處理排序線程內的掛起。他的鏈接包含了一個很好的討論,爲什麼這是如此。

0

雖然我同意線程方法,但我認爲使用暫停/恢復是一個非常糟糕的主意。這是爲什麼:http://blogs.msdn.com/oldnewthing/archive/2003/12/09/55988.aspx

創建一個線程並使用事件來暫停/恢復線程。簡單。順便說一句,你也可以使用像AsyncCalls這樣的東西來簡化線程創建(你不需要TThread類)。

創建一個單獨的線程是有好處的另一個原因:你可以在後臺進行大量計算,所以它們不會干擾UI。你的應用會有順暢的反應。