В моем приложении Win32 VCL я использую ShellExecute для запуска нескольких небольших консольных приложений Delphi. Есть ли способ контролировать положение этих окон консоли? Я хотел бы запустить их в центре экрана.
Как я могу указать положение окна внешней консоли?
Ответ 1
Если у вас есть контроль над консольным приложением, вы можете установить положение окна консоли из самого консольного приложения:
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>')
для получения дескриптора окна консоли (параметр Title может меняться, если он был установлен через SetConsoleTitle
).
Недостатком такого подхода является то, что консольное окно видно "прыгает" с него по умолчанию на новую позицию (протестировано в Windows XP).
Ответ 2
Вы можете использовать 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;