【问题标题】:How can I specify the window position of an external console program?如何指定外部控制台程序的窗口位置?
【发布时间】:2012-08-21 18:07:51
【问题描述】:

在我的 Win32 VCL 应用程序中,我使用 ShellExecute 来启动一些较小的 Delphi 控制台应用程序。有没有办法控制这些控制台窗口的位置?我想以屏幕为中心启动它们。

【问题讨论】:

  • 你能重新编译Delphi控制台应用程序吗?您可以通过GetConsoleWindowSetWindowPos 获得控制台窗口的句柄...
  • @kobik 我可以重新编译,所以在我的所有控制台应用程序中,我应该在任何代码之前使用这个 GetConsoleWindow 和 SetWindowPos 序列?
  • 是的。我看到的唯一缺陷是控制台窗口正在“跳”到它的新位置。
  • @kobik,那么你可以使用CreateProcess并指定它的STARTUPINFO结构。
  • 如何将控制台输出重定向到您自己的窗口?

标签: delphi console-application


【解决方案1】:

您可以使用CreateProcess 并在其STARTUPINFO 结构参数中指定窗口大小和位置。在下面的示例函数中,您可以指定控制台窗口的大小,然后根据指定的大小以当前桌面为中心。函数成功返回进程句柄,否则返回0:

function RunConsoleApplication(const ACommandLine: string; AWidth,
  AHeight: Integer): THandle;
var
  CommandLine: string;
  StartupInfo: TStartupInfo;
  ProcessInformation: TProcessInformation;
begin
  Result := 0;
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  FillChar(ProcessInformation, SizeOf(TProcessInformation), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USEPOSITION or 
    STARTF_USESIZE;
  StartupInfo.wShowWindow := SW_SHOWNORMAL;
  StartupInfo.dwXSize := AWidth;
  StartupInfo.dwYSize := AHeight;
  StartupInfo.dwX := (Screen.DesktopWidth - StartupInfo.dwXSize) div 2;
  StartupInfo.dwY := (Screen.DesktopHeight - StartupInfo.dwYSize) div 2;
  CommandLine := ACommandLine;
  UniqueString(CommandLine);
  if CreateProcess(nil, PChar(CommandLine), nil, nil, False,
    NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInformation)
  then
    Result := ProcessInformation.hProcess;
end;

【讨论】:

    【解决方案2】:

    如果您可以控制控制台应用程序,您可以从控制台应用程序本身内部设置控制台窗口位置:

    program Project1;
    {$APPTYPE CONSOLE}
    uses
      Windows,
      MultiMon;
    
    function GetConsoleWindow: HWND; stdcall; external kernel32 name 'GetConsoleWindow';
    
    procedure SetConsoleWindowPosition;
    var
      ConsoleHwnd: HWND;
      R: TRect;
    begin
      ConsoleHwnd := GetConsoleWindow;
      // Center the console window
      GetWindowRect(ConsoleHwnd, R);
      SetWindowPos(ConsoleHwnd, 0,
        (GetSystemMetrics(SM_CXVIRTUALSCREEN) - (R.Right - R.Left)) div 2,
        (GetSystemMetrics(SM_CYVIRTUALSCREEN) - (R.Bottom - R.Top)) div 2,
        0, 0, SWP_NOSIZE);
    end;
    
    begin
      SetConsoleWindowPosition;  
      // Other code...
      Readln;
    end.
    

    如果您无法重新编译控制台应用程序,您可以使用FindWindow('ConsoleWindowClass', '<path to the executable>') 来获取控制台窗口句柄(如果通过SetConsoleTitle 设置,Title 参数可能会有所不同)。 这种方法的缺点是控制台窗口会从它的默认位置“跳”到它的新位置(用 Windows XP 测试)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多