Как получить дескриптор консольного окна

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Как получить дескриптор консольного окна

Сообщение Stargazer44 » 31.12.2013 16:49:58

Как получить дескриптор (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
Помогите, пожалуйста, с "переводом".
Stargazer44
новенький
 
Сообщения: 10
Зарегистрирован: 24.12.2013 23:49:31

Re: Как получить дескриптор консольного окна

Сообщение Vadim » 02.01.2014 08:08:43

Текущего, в котором работает сама программа?
Vadim
долгожитель
 
Сообщения: 3843
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как получить дескриптор консольного окна

Сообщение Stargazer44 » 02.01.2014 10:33:03

Vadim писал(а):Текущего, в котором работает сама программа?

Да.
Stargazer44
новенький
 
Сообщения: 10
Зарегистрирован: 24.12.2013 23:49:31

Re: Как получить дескриптор консольного окна

Сообщение Vadim » 03.01.2014 06:32:18

Из второй статьи (там код короче :) )

Код: Выделить всё
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.
Vadim
долгожитель
 
Сообщения: 3843
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как получить дескриптор консольного окна

Сообщение bormant » 03.01.2014 11:20:59

Чтобы h после вызова содержало дескриптор найденного окна, его надо присвоить внутри EnumWndProc. Поскольку это функция обратного вызова, самым простым будет передать во втором параметре адрес h, а внутри выполнить присваивание найденного HWND, используя параметр как указатель на HWND.
Аватара пользователя
bormant
постоялец
 
Сообщения: 389
Зарегистрирован: 21.03.2012 11:26:01

Re: Как получить дескриптор консольного окна

Сообщение Stargazer44 » 10.01.2014 22:04:29

Уважаемый Vadim, слепил я из Вашего кода вот такую функцию:
Код: Выделить всё
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 находится на уровне чайника :?
Не могли бы Вы более конкретно "ткнуть меня носом"?
Stargazer44
новенький
 
Сообщения: 10
Зарегистрирован: 24.12.2013 23:49:31

Re: Как получить дескриптор консольного окна

Сообщение Vadim » 11.01.2014 05:51:20

А зачем Вы матрёшку сделали?
У Вас в строке Uses что написано?
Vadim
долгожитель
 
Сообщения: 3843
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как получить дескриптор консольного окна

Сообщение Stargazer44 » 11.01.2014 08:37:44

uses windows;
Stargazer44
новенький
 
Сообщения: 10
Зарегистрирован: 24.12.2013 23:49:31

Re: Как получить дескриптор консольного окна

Сообщение bormant » 12.01.2014 18:58:52

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.
Аватара пользователя
bormant
постоялец
 
Сообщения: 389
Зарегистрирован: 21.03.2012 11:26:01


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru