gpt4 book ai didi

delphi - 如何判断 Delphi 应用程序 "owns"是否是其控制台?

转载 作者:行者123 更新时间:2023-12-03 14:49:54 27 4
gpt4 key购买 nike

Delphi 控制台应用程序可以从现有控制台窗口的命令行运行,并且可以通过双击其图标来运行。在后一种情况下,它将创建自己的控制台窗口,并在应用程序终止后将其关闭。

如何判断我的控制台应用程序是否已创建自己的窗口?

我想检测到这一点,以便我可以显示一条消息,例如“按 Enter 关闭窗口”,让用户在窗口关闭之前阅读显示的内容。显然,如果应用程序是从命令行运行的,那么这样做是不合适的。

我正在使用 Delphi 2010,以防万一这很重要。

最佳答案

您基本上有两件事需要测试:

  1. 应用程序控制台是否在进程之间共享?如果您使用cmd.exe要运行控制台应用程序,它默认会共享控制台,因此您不需要显示“按 Enter 关闭窗口”消息。

  2. 输出是否重定向到文件?如果是这样,也没有必要显示该消息。

对于第一个,有一个简单的解决方案,形式为 GetConsoleProcessList() Windows API 函数。不幸的是,它仅适用于 Windows XP 及更高版本,但也许这对您来说已经足够了。它不在 Delphi 2009 Windows 中单位,因此您必须自己导入它:

function GetConsoleProcessList(lpdwProcessList: PDWORD;
dwProcessCount: DWORD): DWORD; stdcall; external 'kernel32.dll';

当然,如果您的软件能够在早期的 Windows 版本上运行,您应该使用 LoadLibrary()GetProcAddress()相反。

由于您只对进程句柄的数量是否大于 1 感兴趣,因此您可以使用非常小的句柄缓冲区来调用它,例如如下所示:

var
HandleCount: DWORD;
ProcessHandle: DWORD;
begin
HandleCount := GetConsoleProcessList(@ProcessHandle, 1);
// ...
end;

如果您的句柄计数大于 1,则表示您有其他进程保持控制台打开,因此您可以跳过显示该消息。

您可以使用 GetFileInformationByHandle() 用于检查控制台输出句柄是否引用真实文件的 Windows API 函数:

var
StdOutHandle: THandle;
IsNotRedirected: boolean;
FileInfo: TByHandleFileInformation;
begin
StdOutHandle := GetStdHandle(STD_OUTPUT_HANDLE);
IsNotRedirected := not GetFileInformationByHandle(StdOutHandle, FileInfo)
and (GetLastError = ERROR_INVALID_HANDLE);
// ...
end;

此代码仅供您入门,我确信存在一些未正确处理的极端情况。

关于delphi - 如何判断 Delphi 应用程序 "owns"是否是其控制台?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1482604/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com