In my Win32 VCL application I am using ShellExecute to launch a number of smaller Delphi console applications. Is there a way to control the position of those console windows? I would like to launch them centered on screen.
-
3Can you re-compile the Delphi console applications? you could get the handle of the console window via `GetConsoleWindow` and `SetWindowPos`... – kobik Aug 27 '12 at 09:01
-
1@kobik I can recompile, so in all of my console apps I should use this GetConsoleWindow and SetWindowPos sequence before any code? – Aug 27 '12 at 09:18
-
yes. the only defect I see is that the console window is "jumping" to it's new position. – kobik Aug 27 '12 at 09:39
-
3@kobik, then you can use [`CreateProcess`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx) and specify its [`STARTUPINFO`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx) structure. – TLama Aug 27 '12 at 09:46
-
What about redirecting the console output to your own window instead? – Leonardo Herrera Aug 27 '12 at 12:58
2 Answers
You can use CreateProcess
and specify the window size and position in its STARTUPINFO
structure parameter. In the following example function, you can specify the size of a console window, which is then according to the specified size centered on the current desktop. The function returns process handle, if succeed, 0 otherwise:
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;

- 75,147
- 17
- 214
- 392
If you have control over the console application, You could set the console window position from inside the console application itself:
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.
If you can't recompile the console application, you could use FindWindow('ConsoleWindowClass', '<path to the executable>')
to obtain the console window handle (the Title parameter could vary if it was set via SetConsoleTitle
).
The downside with this approach, is that the console window is seen "jumping" from it's default position to it's new position (tested with Windows XP).

- 21,001
- 4
- 61
- 121