编程为控制台和GUI

时间:2009-10-27 07:52:53

标签: delphi user-interface console

是否有可能(如果是这样,我如何)使用Delphi 2007将单个程序作为控制台应用程序和GUI版本工作?

我所追求的是,​​如果程序使用适当的命令行选项运行,它应该用作控制台程序,使用WRITELN将输出打印到控制台,但如果没有给出命令行参数,它应该作为一个普通的Delphi GUI应用程序?

问题在于,作为控制台应用程序运行时,命令行解释程序在允许您输入新命令之前等待应用程序终止,而从命令行启动的GUI应用程序会立即返回到命令行, GUI应用程序在分离的进程中启动。我希望保留这种行为。

我不介意这样的事情:

  

如果GUI那么StartApplicationAsGUI(ParamStr(0))

即。我不介意我必须使用某种形式的EXECUTE调用重新启动应用程序,以便在GUI模式下启动它(如果需要),只要命令行界面在GUI版本启动时返回到命令行输入。 / p>

我更喜欢解决方案/建议:

  

< Parse Comnand Line>
  如果ConsoleMode那么   RunConsole(参数)
  ELSE BEGIN
  在Application.Initialize;
  Application.CreateForm(...)
  Application.Run;
  END

(反之亦然,即在GUI模式下以特殊方式做事)

这样我在构建GUI界面时仍然可以使用Delphi的IDE和VCL ......

5 个答案:

答案 0 :(得分:13)

在Windows上,这有点棘手。实际上,控制台应用程序和GUI之间的区别是PE标头中的单个标志。您可以轻松编写创建窗口的控制台应用程序,但这样您总是可以使用控制台窗口(但您可以隐藏它,但是当人们从cmd运行您的程序时,这不会很好。)

可以使用AllocConsole函数编写一个GUI应用程序,如果需要,可以创建一个控制台:

  

进程只能与一个控制台关联,因此如果调用进程已有控制台,则 AllocConsole 功能将失败。进程可以使用FreeConsole函数将自己从当前控制台分离,然后可以调用 AllocConsole 来创建新控制台,或AttachConsole以附加到另一个控制台。

     

如果调用进程创建子进程,则子进程将继承新控制台。

     

AllocConsole 初始化新控制台的标准输入,标准输出和标准错误句柄。标准输入句柄是控制台输入缓冲区的句柄,标准输出和标准错误句柄是控制台屏幕缓冲区的句柄。要检索这些句柄,请使用GetStdHandle函数。

     

此功能主要由图形用户界面(GUI)应用程序用于创建控制台窗口。无需控制台即可初始化GUI应用程序。控制台应用程序使用控制台初始化,除非它们是作为分离的进程创建的(通过使用DETACHED_PROCESS标志调用CreateProcess函数)。

但是,从cmd运行时,这可能会导致出现另一个控制台窗口,而不是重新使用现有控制台窗口。我不知道那里是否存在一个好的解决方案。

答案 1 :(得分:12)

IMO,这里最好的方法是拥有实际完成程序工作的非可视化类。然后你可以从GUI程序调用它,你也可以从一个单独的命令行程序调用它。这两个程序都只是你的类功能的包装。

这也会强制设计干净 - 您的类必须与应用程序的GUI层分开。

答案 2 :(得分:11)

答案 3 :(得分:4)

Windows在控制台和UI应用程序的可执行文件头中具有不同的值(请参阅更多详细信息here)。因此,似乎不可能使相同的可执行文件在两种模式下都能工作。

作为替代方案,您可以在UI应用程序中打开控制台,但它将是新的控制台,而不是您已启动应用程序的控制台。

答案 4 :(得分: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