How to Get the Handle of a Console Application's Window

How do I get the handle of a console application's window

Not sure it works, but you can try that :

IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;

How to get handle of a console window launched from my GUI application?

The following code simply creates the process (console application), attaches your process to the newly created console by AttachConsole function and from that attached console takes the window handle using the GetConsoleWindow function.

The biggest weakness of the following code is that CreateProcess function returns immediately at the time, when the console is not yet fully initialized and when you try to attach the console immediately after, you will fail. Unfortunately, there's no WaitForInputIdle function for console applications so as one possible workaround I would choose the attempt to attach the console in some limited loop count and once it succeed, get the handle and detach the console.

In code that might look like follows. The RunApp function there should return the handle of the console window (assuming you'll run only console applications from it), and should wait approx. 1 second for the console application you've started to be attachable. You can modify this value either by changing initial value of the Attempt variable and/or by changing Sleep interval.

function GetConsoleWindow: HWND; stdcall;
external kernel32 name 'GetConsoleWindow';
function AttachConsole(dwProcessId: DWORD): BOOL; stdcall;
external kernel32 name 'AttachConsole';

function RunApp(const ACmdLine: string): HWND;
var
CmdLine: string;
Attempt: Integer;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
Result := 0;
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWNORMAL;
CmdLine := ACmdLine;
UniqueString(CmdLine);
if CreateProcess(nil, PChar(CmdLine), nil, nil, False,
CREATE_NEW_CONSOLE, nil, nil, StartupInfo, ProcessInfo) then
begin
Attempt := 100;
while (Attempt > 0) do
begin
if AttachConsole(ProcessInfo.dwProcessId) then
begin
Result := GetConsoleWindow;
FreeConsole;
Break;
end;
Sleep(10);
Dec(Attempt);
end;
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
end;

Then you can e.g. change the title of a console window of your lauched application this way:

procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
ConsoleHandle: HWND;
begin
ConsoleHandle := RunApp('cmd.exe');
if ConsoleHandle <> 0 then
begin
S := 'Hello! I''m your console, how can I serve ?';
SendTextMessage(ConsoleHandle, WM_SETTEXT, 0, S);
end;
end;

How to get the window state of a C++ console application

For Windows use GetConsoleWindow to get a handle to the window, then e.g. GetWindowPlacement.

But what on Earth are you planning to use this information for?

Console window gets bugged if I get the window handle too early..?

Here is working example for Windows 8. But you need to refresh window region each time console is moved/resized/restored.

#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <dwmapi.h>

//#pragma comment(lib, "uxtheme.lib")
#pragma comment(lib, "dwmapi.lib")

int _tmain(int argc, _TCHAR* argv[])
{
HWND hWnd = GetConsoleWindow();
DWMNCRENDERINGPOLICY policy = DWMNCRP_DISABLED;
DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof(DWMNCRENDERINGPOLICY));
//SetThemeAppProperties(0);
//SetWindowThemeNonClientAttributes(hWnd, STAP_VALIDBITS, 0);
//SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
//RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
RECT rClnt, rWnd;
GetClientRect(hWnd, &rClnt);
GetWindowRect(hWnd, &rWnd);
POINT pt = {0,0};
MapWindowPoints(hWnd, NULL, &pt, 1);
OffsetRect(&rClnt, pt.x-rWnd.left, pt.y-rWnd.top);
HRGN rgnClnt = CreateRectRgnIndirect(&rClnt);
SetWindowRgn(hWnd, rgnClnt, 1);

_getch();
return 0;
}


Related Topics



Leave a reply



Submit