Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 848

/ вопрос открыт /

Приветствую, уважаемые эксперты!
Подскажите как получить handle активного окна в системе, окна, с которым работает пользователь в данный момент?
Я пишу так:
procedure TForm1.Timer1Timer(Sender: TObject);
var h:hwnd;
begin
h:=GetActiveWindow;
end;
Почему так я получаю h не равно нулю только когда акнивно мое приложение?

volonter Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: volonter (статус: Посетитель)
Вопрос отправлен: 10 августа 2007, 18:57
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Градов Ю.М.

Здравствуйте, volonter!
Посмотрите информацию по этой сноске:
http://narod.yandex.ru/cgi-bin/yandmarkup?cluster=14&prog=0x2757571A&HndlQuery=1335669872&PageNum=0&g=7&d=0&q0=1323451840&p=
А еще лучше - скачайте http://delphiworld.narod.ru/download/dw6.exe и обновитесь. В поиске наберите "чужие окна".

Ответ отправил: Градов Ю.М. (статус: 8-ой класс)
Время отправки: 10 августа 2007, 20:04
Оценка за ответ: 4

Комментарий к оценке: Спасибо за ссылку

Ответ #2. Отвечает эксперт: Aleksey P. Kharitonov

Здравствуйте, volonter!
Приведу пример действующего кода. Метка и заголовок формы отображают название активного окна, даже когда ваше приложение будет неактивно...

Приложение:
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. var
  3. Caption: PChar;
  4. Wnd: HWnd;
  5. begin
  6. Caption:= AllocMem(SizeOf(Byte));
  7. Wnd:= GetForegroundWindow;
  8. GetWindowText(Wnd, Caption, 255);
  9. Form1.Caption:= StrPas(Caption);
  10.  
  11. end;
  12.  
  13. ...........
  14. FreeMem(Caption);


Ответ отправил: Aleksey P. Kharitonov (статус: 3-ий класс)
Время отправки: 10 августа 2007, 20:13
Оценка за ответ: 4

Комментарий к оценке: Что-то этот код у меня не пошел. Прога вылетает с ошибкой. Я его чуть изменил и все заработало. Как оказалось, GetWindowText не желательно использовать, так как в чужих приложениях он способен прочитать текст не всегда. Вот что я нашел в хелпе:

However, GetWindowText cannot retrieve the text of a control in another application.
...
If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string. This behavior is by design. It allows applications to call GetWindowText without becoming unresponsive if the process that owns the target window is not responding. However, if the target window is not responding and it belongs to the calling application, GetWindowText will cause the calling application to become unresponsive.

To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.

Воспользовался WM_GETTEXT и все заработало!!!
Ниже привожу рабочий код, если кому интересно

procedure TForm1.Timer1Timer(Sender: TObject);
var
  buffer: Pchar;
  Wnd, Len: Cardinal;
begin
  Wnd := GetForegroundWindow;
  if Wnd <> 0 then
  begin
    Len := SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0) + 1;
    GetMem(Captions, Len);
    try
      if SendMessage(Wnd, WM_GETTEXT, Len, Integer(Captions)) <> 0 then
        Form1.Caption := captions;
    finally
      FreeMem(Captions)
    end
  end
end;

Мини-форум вопроса

Всего сообщений: 1; последнее сообщение — 10 августа 2007, 22:14; участников в обсуждении: 1.
volonter

volonter (статус: Посетитель), 10 августа 2007, 22:14 [#1]:

Прошу извинения, выложил код с ошибкой. В разделе переменных надо вместо buffer поставить captions

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:49
Выполнено за 0.02 сек.