2017-05-15 96 views
2

的Application.Run過程調用一個無限循環,處理Windows消息:德爾福應用程序運行

repeat 
    try 
     HandleMessage; 
    except 
     HandleException(Self); 
    end; 
    until Terminated; 

Terminated屬性只能通過Application.Terminate程序,它發送PostQuitMesage設置爲true。 我想更改消息處理循環,這樣我可以使用它的全局變量直接停止(不使用消息隊列):

var MyTerminated:Boolean 
.... 
    repeat 
    try 
     HandleMessage; 
    except 
     HandleException(Self); 
    end; 
    until Terminated or MyTerminated; 

的問題是,是否有可能使程序使用自己的版本Application.Run?

+0

我試過這一次,不會推薦它。它需要製作一個'Vcl.Forms'的完整副本,最重要的是,確保所有的東西都引用它,而不是主引用。 –

+0

(「試圖**這**」作爲替代默認的一個實現我自己的消息隊列。) –

+2

對我的生活中,我無法想象,你爲什麼會想這樣做。我的猜測是,無論是激發問題,是真正問題的錯誤解決方案 –

回答

5

「Terminated」屬性爲只讀屬性。但它是FTerminated字段的直接獲取者,因此Application.Terminated直接從布爾字段中讀取。

PBoolean(@Application.Terminated)^ := True; 

您也可以考慮使用Halt,這將傳過來的消息循環完全,對於更爲陡峭的,但少:雖然語言不允許設置Application.Terminated,您可以使用指針在該地址設定的布爾值hacky解決方案。

+0

哇,什麼是黑客。我以前從未見過這個。這是否適用於任何只讀文字屬性? –

+0

@Jerry - 是的,如果是「literal」,你的意思是一個引用一個字段的道具。我想我們在這裏已經討論過了,它是關於改變Application.MainForm。 –

+0

是的,這裏:http://stackoverflow.com/questions/25666626/delphi-change-main-form-while-application-is-running –

0

是的,你可以讓你的應用程序中使用的應用程序運行的自己的版本,但這種做法不提倡,因爲它改變了正常的程序流程,由德爾福的建築師設計。

直接停止Application.Run表示需要稍後重新啓動Application.Run,​​例如,在想要從主線程執行某個操作之後。這使得程序感到困惑,同行程序員更難理解,整體上更容易出錯。

程序設計應該簡單明瞭。如果應用程序是很大的,例如代碼兩個百萬行,執行流程的整體設計要簡單反正:

  • 如果你需要做一些較長的行動,從工作線程做他們;
  • 如果你需要做的瞬間動作,從你的主要形式或其他形式做他們。

因此,一個Delphi應用程序主循環只應退出到整個應用程序出口,由PostQuitMessage完成。我們不必避免這個消息。

想要避免PostQuitMessage的原因可能是瞬間退出。這不是VCL應用程序應該運行的方式。如果不需要表單(例如Windows服務應用程序),只是不要使用TApplication類而不運行表單,只需根據MsgWaitForMultipleObjects製作自己的消息循環即可。

+1

「WM_CLOSE」處理程序調用「Close」,它在主窗體上調用「Application.Terminate」,然後調用「PostQuitMessage」。 –

+0

@SertacAkyuz - 哎呀,抱歉,謝謝你指出 - 我已經更新了回覆。 –