Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 24.06.2009, 12:54
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию Запись чата ICQ

У меня на ПК стоит ICQ. Ну так вот мне нужно записывать весь мой чат в txt файл. Пробовал так, но не вышло.
Код:
var
  H, PageHandle, TabHandle, REHandle: THandle;
  lpBuffer: PChar;
begin
  H := FindWindow(nil, PChar('ICQ'));
  if H <> 0 then
  begin
    PageHandle := FindWindowEx(H, 0, 'SysTabControl32', nil);
    if PageHandle <> 0 then
    begin
     TabHandle := FindWindowEx(PageHandle, 0, '#000605CC',nil);
     if TabHandle <> 0 then
     begin
        REHandle := FindWindowEx(TabHandle, 0, 'RichEdit20A', nil);
        if REHandle <> 0 then
        begin
          lpBuffer := GetMemory(1024);
          try
            SendMessage(REHandle, WM_GETTEXT, 1024, Integer(lpBuffer));
            RichEdit1.Text := lpBuffer;
          finally
            FreeMemory(lpBuffer);
          end;
Для определения иерархии, использую WinSpy++
Ответить с цитированием
  #2  
Старый 24.06.2009, 15:14
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Так аська-же ведет журнал сообщений. Зачем дублировать?
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 24.06.2009, 17:02
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Тогда, как получить доступ к журналу сообщений. Но желательно осуществить, то, что я хотел в первом посте. Исправьте мой код. А то он не ловит сообщения((
Ответить с цитированием
  #4  
Старый 25.06.2009, 18:25
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Неужели мне не помогут на этом форуме?
Переписку нужно получать непосредственно с окна ICQ.

Последний раз редактировалось Muxa, 25.06.2009 в 19:35.
Ответить с цитированием
  #5  
Старый 25.06.2009, 23:41
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Проверила на окнах класса 'RichEdit20W' и 'Edit' (что было под рукой) — нормально считывается текст. Вы уверены, что получаете верный дескриптор (или что вообще получаете)? Проверьте трассировкой, что процедура вообще доходит до строки с SendMessage. А если всё же доходит до этой строки, то проверьте, что дескриптор принадлежит именно тому окну класса 'RichEdit20A', в котором находится текст.
Ответить с цитированием
  #6  
Старый 26.06.2009, 08:49
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Код:
var
  H, PageHandle, TabHandle, REHandle: THandle;
  lpBuffer: PChar;
begin
  H := FindWindow(nil, PChar('Tanya'));
  if H <> 0 then
  begin
    PageHandle := FindWindowEx(H, 0, '__oxFrame.class__', nil);
    if PageHandle <> 0 then
    begin
     TabHandle := FindWindowEx(PageHandle, 0, '#000205C2',nil);
     if TabHandle <> 0 then
     begin
        REHandle := FindWindowEx(TabHandle, 0, 'Internet Explorer_Server', nil);
        if REHandle <> 0 then
        begin
          lpBuffer := GetMemory(1024);
          try
            SendMessage(REHandle, WM_GETTEXT, 1024, Integer(lpBuffer));
            RichEdit1.Text := lpBuffer;
          finally
            FreeMemory(lpBuffer);
          end;
Я получаю и класс, и хендл окна. Скорее всего я ошибся там. Не могли бы вы использую WinSpy++, указать мне на ошибку?

Последний раз редактировалось Muxa, 26.06.2009 в 09:08.
Ответить с цитированием
  #7  
Старый 26.06.2009, 10:13
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Вы бы лучше попробовали для начала взять дескриптор окна непосредственно, а не с помощью цепочки последовательных FindWindowEx. Например, наводите курсор мыши на желаемое окно с чатом и, например, с помощью какого-нибудь сочетания клавиш вызываете в своей программе функцию WindowFromPoint с параметром Mouse.CursorPos. Функция возвращает вам идентификатор окна. Так вы хотя бы будете уверены, что нужный дескриптор вами получен. А потом уже пробуйте отсылать окну с этим дескриптором сообщение WM_GETTEXT. Если результат будет положительный, вот тогда уже можно будет задумываться об автоматическом получении handle путем FindWindowEx.
Вообще, не понятно: сначала вы привели код с окном класса 'RichEdit20A', а теперь — 'Internet Explorer_Server'. Какое правильно-то? (Я ICQ не пользуюсь, поэтому проверить не могу). Вероятнее всего, окна класса 'Internet Explorer_Server' (в отличие от 'RichEdit') не будут нужным вам образом обрабатывать сообщение WM_GETTEXT.
Ответить с цитированием
  #8  
Старый 26.06.2009, 11:54
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
Печаль

ок, будем пробовать.
P.S. в старых версиях ICQ окно чата было "RichEdit20A", а в новых не знаю.
Ответить с цитированием
  #9  
Старый 26.06.2009, 12:55
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Тот handle, что я получаю при помощи WinSpy++ и с помощью WindowFromPoint сходятся.
Код:
var
handle:THandle;
begin
if (ssCtrl in Shift) and (chr(Key) in [chr(114)]) then begin
handle:=WindowFromPoint(Mouse.CursorPos);
Label1.Caption:=IntTohex(handle,8); 
Ответить с цитированием
  #10  
Старый 26.06.2009, 14:33
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Видимо, не всё так просто. Вот цитата из справки по сообщению WM_GETTEXT:
Цитата:
In a rich edit control, if the text to be copied exceeds 64K, use either the message EM_STREAMOUT or EM_GETSELTEXT.

Я-то пробовала работать с маленькими блоками текста, в этом случае всё замечательно. Когда текста много, то, действительно, сообщение WM_GETTEXT бесполезно. Работать же с сообщением EM_STREAMOUT посложнее будет.

P.S. Кстати, для этого еще нужно будет подцепить к проекту модуль RichEdit.pas.
Ответить с цитированием
  #11  
Старый 26.06.2009, 14:55
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Ну я не думаю, что чат ICQ может быть слишком большим. Хотя... У вас есть мысли на счет того, как это считать правильно? В Spy++ который идет в поставке со студией окна отображает по-своему (он удобнее), а WinSpy++ как-то непонятно. Это мое ИМХО. Моя проблема заключается в том, что я не уверен в правильности моего определения класса окна с чатом ICQ.

Последний раз редактировалось Muxa, 26.06.2009 в 15:00.
Ответить с цитированием
  #12  
Старый 26.06.2009, 15:09
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Цитата:
Сообщение от Muxa
Ну я не думаю, что чат ICQ может быть слишком большим.
Если текст больше 254 символов (примерно) уже не будут передаваться с использованием сообщения WM_GETTEXT.

Цитата:
Сообщение от Muxa
Моя проблема заключается в том, что я не уверен в правильности моего определения класса окна с чатом ICQ.
Вам зачем знание класса? Вы получили дескриптор — этого достаточно, чтобы высылать окну сообщения, в частности, этого достаточно, чтобы вытащить текст. Сразу не скажу, как именно работать с сообщением EM_STREAMOUT, но примеров предостаточно (откройте хотя бы модуль ComCtrls.pas).


P.S. Ээээ... Беру свои слова о 254 символах обратно. Это я в спешке написала. Ошиблась, конечно!! Просто необходимо, чтобы размер буфера был достаточным, чтобы уместить все содержимое окна...

Последний раз редактировалось Nyctos Kasignete, 26.06.2009 в 15:24.
Ответить с цитированием
  #13  
Старый 26.06.2009, 15:33
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Пробовал снова... В общем не получается у меня выудить текст((

Последний раз редактировалось Muxa, 26.06.2009 в 15:35.
Ответить с цитированием
  #14  
Старый 26.06.2009, 15:43
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Ну почему сразу не получается! >_<
У меня же получается. Я использую процедуру следующего вида:
Код:
procedure GetTxt(RichEditHandle: HWND);
var
  WndTxt: PChar;
begin
  GetMem(WndTxt, 4096);
  try
    SendMessage(RichEditHandle, WM_GETTEXT, 4096, Integer(WndTxt));
    Form1.RichEdit1.Text := StrPas(WndTxt);  { содержимое пишем в свой RichEdit на форме }
  finally
    FreeMem(WndTxt, 4096);
  end;
end;

Если я передаю корректный дескриптор окна чужого RichEdit'а, то всё прекрасно работает. Нужно только следить, чтобы память выделялась в достаточном количестве, чтобы вместить содержимое окна RichEdit'а.
Ответить с цитированием
  #15  
Старый 26.06.2009, 21:24
Muxa Muxa вне форума
Новичок
 
Регистрация: 01.06.2009
Сообщения: 80
Репутация: 10
По умолчанию

Nyctos Kasignete, пробовал, но он выдает мне какую-то билеберду(( или я такой криворукий. Во вложении проект. Могли бы вы исправить ошибки? И сделать так, что каждый раз искалось окно ICQ и брался хендл окна чата.
Вложения
Тип файла: 7z prog.7z (3.5 Кбайт, 3 просмотров)
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:20.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter