Как получить дескриптор консольного окна
Модератор: Модераторы
-
Stargazer44
- новенький
- Сообщения: 10
- Зарегистрирован: 24.12.2013 23:49:31
Как получить дескриптор консольного окна
Как получить дескриптор (HWND) консольного окна средствами Free Pascal ?
Нашёл несколько примеров на C++ :
http://www.cyberguru.ru/cpp-sources/ui-windows/kak-poluchit-deskriptor-konsolnogo-okna-hwnd.html
http://www.rsdn.ru/article/qna/ui/conhandl.xml
Помогите, пожалуйста, с "переводом".
Нашёл несколько примеров на C++ :
http://www.cyberguru.ru/cpp-sources/ui-windows/kak-poluchit-deskriptor-konsolnogo-okna-hwnd.html
http://www.rsdn.ru/article/qna/ui/conhandl.xml
Помогите, пожалуйста, с "переводом".
Текущего, в котором работает сама программа?
-
Stargazer44
- новенький
- Сообщения: 10
- Зарегистрирован: 24.12.2013 23:49:31
Vadim писал(а):Текущего, в котором работает сама программа?
Да.
Из второй статьи (там код короче
)
Код: Выделить всё
Uses windows;
Function EnumWndProc(h:HWND; l:LPARAM): BOOL; stdcall;
begin
if GetWindowThreadProcessId(h, NIL) = GetCurrentThreadId() Then
Begin
//Здесь надо что-то сделать с h (которое в параметре l), т.к. это оно
...
//Прекращаем выполнение
EnumWndProc:=FALSE;
End
Else
EnumWndProc:=TRUE;
end;
var
h: HWND;
Begin
EnumWindows(@EnumWndProc, LPARAM(h));
// h содержит дескриптор.
End.Чтобы h после вызова содержало дескриптор найденного окна, его надо присвоить внутри EnumWndProc. Поскольку это функция обратного вызова, самым простым будет передать во втором параметре адрес h, а внутри выполнить присваивание найденного HWND, используя параметр как указатель на HWND.
-
Stargazer44
- новенький
- Сообщения: 10
- Зарегистрирован: 24.12.2013 23:49:31
Уважаемый Vadim, слепил я из Вашего кода вот такую функцию:
Она не компилируется, компилятор пишет ошибку:
Error: Incompatible type for arg no. 1: Got "<address of function(LongWord,LongInt):LongBool is nested;StdCall>", expected "<procedure variable type of function(LongWord,LongInt):LongBool;StdCall>"
Мой уровень знаний WinApi находится на уровне чайника
Не могли бы Вы более конкретно "ткнуть меня носом"?
Код: Выделить всё
function GetConsoleHwnd:HWND;
var h: HWND;
function EnumWndProc(h:HWND; l:LPARAM): BOOL; stdcall;
begin
if GetWindowThreadProcessId(h, NIL) = GetCurrentThreadId() then
EnumWndProc:=FALSE;
else
EnumWndProc:=TRUE;
end;
begin
EnumWindows(@EnumWndProc, LPARAM(h));
end;Она не компилируется, компилятор пишет ошибку:
Error: Incompatible type for arg no. 1: Got "<address of function(LongWord,LongInt):LongBool is nested;StdCall>", expected "<procedure variable type of function(LongWord,LongInt):LongBool;StdCall>"
bormant писал(а):Чтобы h после вызова содержало дескриптор найденного окна, его надо присвоить внутри EnumWndProc. Поскольку это функция обратного вызова, самым простым будет передать во втором параметре адрес h, а внутри выполнить присваивание найденного HWND, используя параметр как указатель на HWND.
Мой уровень знаний WinApi находится на уровне чайника
Не могли бы Вы более конкретно "ткнуть меня носом"?
А зачем Вы матрёшку сделали?
У Вас в строке Uses что написано?
У Вас в строке Uses что написано?
-
Stargazer44
- новенький
- Сообщения: 10
- Зарегистрирован: 24.12.2013 23:49:31
uses windows;
Как скажете.Stargazer44 писал(а):Не могли бы Вы более конкретно "ткнуть меня носом"?
Код: Выделить всё
{$apptype console}
uses Windows, SysUtils;
type
pHWND=^HWND;
function enumGetHwnd(h: HWND; l: LPARAM): bool; stdcall;
begin
enumGetHwnd:=true;
if GetWindowThreadProcessId(h, NIL) = GetCurrentThreadId() then begin
pHWND(l)^:=h; enumGetHwnd:=false;
end;
end;
var
h: HWND;
begin
EnumWindows(@enumGetHwnd, LPARAM(@h));
WriteLn('$'+IntToHex(h, 8));
ReadLn;
end.
Имейте в виду, если программа запущена из другой консольной программы, скажем из cmd или Far Manager, показанный метод окошко не найдёт.
Добавлено спустя 15 минут 22 секунды:
Microsoft рекомендует другой способ, по уникальному временному заголовку окна, http://support.microsoft.com/kb/124103, лишенный предыдущего недостатка:
Код: Выделить всё
{$apptype console}
uses Windows, SysUtils;
var
h: HWND;
ct, nt: WideString;
begin
nt:=IntToStr(GetTickCount)+'/'+IntToStr(GetCurrentProcessId);
SetLength(ct,1024);
GetConsoleTitleW(PWideChar(ct),1024);
SetConsoleTitleW(PWideChar(nt));
Sleep(40);
h:=FindWindowW(nil,PWideChar(nt));
SetConsoleTitleW(PWideChar(ct));
WriteLn('$'+IntToHex(h, 8));
ReadLn;
end.
