2009-10-27 102 views
24

是否有可能(如果是這樣,我如何)使一個程序既可以作爲控制檯應用程序又可以作爲使用Delphi 2007的GUI版本?作爲控制檯和圖形用戶界面編程

我後來的是,如果程序運行時使用適當的命令行選項,它應該作爲控制檯程序,使用WRITELN將輸出打印到控制檯,但如果沒有給出命令行參數,它應該運行作爲一個普通的Delphi GUI應用程序?

問題在於,當作爲控制檯應用程序運行時,命令行解釋程序在允許您輸入新命令之前等待應用程序終止,而從命令行啓動的GUI應用程序會立即將您返回到命令行並且GUI應用程序在分離的進程中啓動。我希望保留這種行爲。

我不介意這樣的事情:

IF然後GUI StartApplicationAsGUI(ParamStr這(0))

即。如果需要,只要命令行界面在GUI版本啓動時返回命令行輸入,我不介意必須使用某種形式的EXECUTE調用重新啓動應用程序,以便在GUI模式下啓動它(如果需要)。

我寧願的溶液/建議,是沿着線:

<解析Comnand >線
IF THEN ConsoleMode
      RunConsole(參數)
ELSE BEGIN
      Application.Initialize;
      Application.CreateForm(...)
      Application.Run;
END

(或反之亦然,即做事一種特殊的方式,如果GUI模式)

,這樣使得GUI界面時,我仍然可以使用Delphi的IDE和VCL ...

回答

4

Windows在控制檯和UI應用程序的可執行文件頭中有不同的值(請參閱更多詳細信息here)。所以看起來不可能讓同一個可執行文件在兩種模式下工作。

作爲一種替代方法,您可以在UI應用程序中打開一個控制檯,但它將成爲新的控制檯,而不是您從中啓動應用程序的控制檯。

12

在Windows上,這有點棘手。實際上,控制檯應用程序和GUI之間的區別是PE標題中的單個標誌。您可以輕鬆編寫用於創建窗口的控制檯應用程序,但這種方式總是有控制檯窗口(可以隱藏它,但是,當人們從cmd運行程序時,這並不會很好)。

可以然而編寫創建一個控制檯,如果它需要一個GUI應用程序,使用AllocConsole功能:

一個進程可以與只有一個控制檯相關聯,所以AllocConsole功能如果調用進程已經有控制檯,則會失敗。一個進程可以使用FreeConsole函數從其當前控制檯分離,然後它可以調用AllocConsole創建一個新控制檯或AttachConsole以連接到另一個控制檯。

如果調用進程創建子進程,則子進程將繼承新的控制檯。

AllocConsole初始化新控制檯的標準輸入,標準輸出和標準錯誤句柄。標準輸入句柄是控制檯輸入緩衝區的句柄,標準輸出和標準錯誤句柄是控制檯屏幕緩衝區的句柄。要檢索這些手柄,請使用GetStdHandle函數。

此功能主要由圖形用戶界面(GUI)應用程序用於創建控制檯窗口。 GUI應用程序無需控制檯即可初始化。控制檯應用程序使用控制檯進行初始化,除非它們創建爲分離進程(通過使用DETACHED_PROCESS標誌調用CreateProcess函數)。

然而,從cmd運行時,這可能會導致另一個控制檯窗口中出現,而不是重複使用現有的一個。我不知道在那裏是否有好的解決方案。

12

IMO,這裏最好的辦法是讓非可視類,其實做節目的工作。然後你可以從一個GUI程序調用它,你也可以從一個單獨的命令行程序調用它。這兩個程序只是圍繞你的類的功能的包裝。

這會強制設計變得乾淨 - 您的類必須與應用程序的GUI層分離。

+2

這是正確的答案。 – Tim 2009-10-27 15:08:01

+0

這種方法的問題在於,如果正確完成,它需要分配三個文件:1)命令行可執行文件,2)GUI可執行文件和3)包含程序相關核心的庫文件。我更喜歡單個可執行文件,最好的選擇似乎是在頭部有一個帶有控制檯位的GUI程序,然後如果需要以GUI的形式運行,可以使用分離的控制檯重新啓動它自己。就像提供的各種鏈接中的ildasm一樣。 – HeartWare 2009-10-27 16:51:14

+0

嗯,我會說只有兩個可執行文件是可行的。如果您構建包含BPL的EXE,則無需分發任何「核心」文件 - 每個應用程序只需一個exe。但顯然你是知道你的部署需求的人;我很高興ildasm的回答很有幫助。 – JosephStyons 2009-10-28 03:37:32

3

AttachConsole()可用於獲取家長控制檯。 例如如果應用程序是從CMDLINE shell啓動,AllocConsole()可避免:

if not AttachConsole(ATTACH_PARENT_PROCESS) 
then AllocConsole; 

此處瞭解詳情: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681952(v=vs.85).aspx

+0

Chee Wee的代碼示例如下:http://chuacw.ath.cx/blogs/chuacw/archive/2015/12/02/delphi-app-with-console-and-gui.aspx – dummzeuch 2016-01-04 08:33:03