Entwickler-Ecke

Windows API - ICQ - Nachricht auslesen


hibbert - So 13.02.05 21:50
Titel: ICQ - Nachricht auslesen
Hi,
ich möchte gerne ein Programm schreiben, dass einzelne Wörte zählt, und zwar die ich per ICQ zugeschickt bekomme.

Das bedeutet, dass ich erstmal das ICQ - Fenster finden muss, das ist ja kein Problem. Doch wie lese ich nun den Text aus? Da bin ich leider nicht fündig geworden bzw. ich weiß nicht genau wie ich den Text aus ICQ herausfiltern kann.

Wenn ich dann nämlich den Text habe, kann ich in diesem nach bestimmten Wörtern suchen und sie zählen.

thx hibbert


Moderiert von user profile iconTino: Topic aus Sonstiges verschoben am Di 08.03.2005 um 14:30


davidbaumann - So 13.02.05 22:01

schonmal überlegt die einfach zwischen ICQ und das Internet zu klemmen?
Ich denke mal, dass das einfacher wäre..
oder du wertest einfach die logs von ICQ aus

Baumi


hibbert - So 13.02.05 22:07

baumi hat folgendes geschrieben:
schonmal überlegt die einfach zwischen ICQ und das Internet zu klemmen?

Mhh wenn mir einer sagt, wie das gehen soll.

baumi hat folgendes geschrieben:
oder du wertest einfach die logs von ICQ aus

mhh wäre auch ne möglichkeit, ich möchte das aber gerne anders machen....

hibbert


retnyg - So 13.02.05 22:39

probiere mal mit enumchildwindows die dem icq handle untergeordneten fenster zu durchsuchen. eines von denen enthält dann den gewünshcten text.

du könntest dir mal dieses programm anschauen was etwas ähnlichen macht:
OpenPass: exe http://delphisoftware.narod.ru/OpenPass.rar
source http://delphisoftware.narod.ru/OpenPassSrc.rar


hibbert - So 13.02.05 22:46

mhh ist ja ganz nett, aber da bekomme ich immer nur die "Caption" des Fensters, aber nicht die Message (jedenfalls bei ICQ5)


retnyg - So 13.02.05 23:05

hmm weiss ich nicht so genau, frag mal die API-freaks. Luckie z.b. kann dir da sicher weiterhelfen.


hibbert - Di 15.02.05 16:05

mhh hat jemand evtl. noch eine idee ??

thx hibbert


Karlson - Di 15.02.05 16:11

mach das nochmal mit X-Spy oder win-spy

Da kannste dir sogar den findwindow code, direkt für die Memo-Klasse erzeugen lassen.
das funktioniert im übrigen auch nur solange das Fenster nicht minimiert ist.


hibbert - Di 15.02.05 16:26

mhh naja, die beiden tools helfen mir auch nicht weiter :oops:

ich benötige doch eigentlich nur den Namen des Feldes, in dem der gesamte Text erscheint und den muss ich doch irgendwie auslesen könne, oder ??

das heißt ich brauche erstmal den namen, doch den habe ich noch net gefunden :cry:

hibbert


F34r0fTh3D4rk - Di 15.02.05 16:50

wie wäre es mit sendmessage und WM_GETTEXT ??? :wink:

ich dachte an sowas in etwa:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var
  l : Integer;
  Handle : HWND;
  s: string;
begin
  Handle:=FindWindow('Name - Nachrichtensitzung',nil);
  if Handle <> 0 then
  begin
    l:= SendMessage(Handle, WM_GETTEXTLENGTH, 00);
    SetLength(s, l);
    Handle:=FindWindowEx(Handle,0,'Edit',nil);
    if Handle <> 0 then
      SendMessage(Handle, WM_GETTEXT, l + 1, lParam(@s[1]));
    showmessage(s);
  end;
end;

bei mir geht es nicht, ich glaub da muss noch etwas dran rumgeschnippelt werden :oops:


hibbert - Di 15.02.05 17:31

ja an soetwas habe ich ja auch gedacht, doch dazu benötige ich doch den namen des feldes, wo der gesamte text angezeigt wird und der efhlt mir...


hibbert


F34r0fTh3D4rk - Di 15.02.05 17:48

der braucht keinen namen, der ist vom typ edit und childwindow des chatfensters


hibbert - Di 15.02.05 18:10

mhh dann habe ich jetzt folgendes beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Button1Click(Sender: TObject);
var
  l : Integer;
  Handle : HWND;
  s: string;
begin
  Handle:=FindWindow(nil,'Name - Message Session');
  if Handle <> 0 then
  begin
    l:= SendMessage(Handle, WM_GETTEXTLENGTH, 00);
    SetLength(s, l);
    Handle:=FindWindowEx(handle,0,'childwindow',nil);
    if Handle <> 0 then
      begin
      SendMessage(Handle, WM_GETTEXT, l + 1, lParam(@s[1]));
      end;
    showmessage(s);
  end;
end;

so wenn das ICQ Fenster geschlossen ist passiert nichts - ist ja auch richtig so.
doch ist es geöffnet und ein Text steht drin, dann erhalte ich nur eine leere nachricht :oops:

hibbert


F34r0fTh3D4rk - Di 15.02.05 19:19

hibbert hat folgendes geschrieben:
mhh dann habe ich jetzt folgendes beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
<div class="syntaxContainer">    <div class="syntaxTitle genmed">        <b>Delphi-Quelltext</b>    </div>    <div class="syntax">        <table cellspacing="0" cellpadding="0">            <tr>                <td valign="top" style="text-align: right; padding-right: 3px; border: #DBE4EB solid; border-width: 0px 1px 0px 0px;">                    <pre>1:
2:
3:
4:
</pre>                </td>                <td valign="top" style="width: 100%; padding-left: 3px;">                    <pre class="sourcecode">    <span class="codekey">if</span> Handle <> <span class="codenumber">0</span> <span class="codekey">then</span>
      <span class="codekey">begin</span>
      SendMessage(Handle, WM_GETTEXT, l + <span class="codenumber">1</span>, lParam(@s[<span class="codenumber">1</span>]));
      <span class="codekey">end</span>;                    </pre>                </td>            </tr>        </table>    </div></div>



das macht keinen sinn, du brauchst kein begin und end dafür:


Delphi-Quelltext
1:
2:
if Handle <> 0 then
  SendMessage(Handle, WM_GETTEXT, l + 1, lParam(@s[1]));

das ist das gleiche ^^


hibbert - Di 15.02.05 19:46

schön das es das gleiche ist, aber trotzdem wird das auch nichts an meinem problem ändern, dass es noch immer net funzt :cry:

hibbert


F34r0fTh3D4rk - Di 15.02.05 19:54

ja warte bis einer von den experten hier aufkreuzt und dir den code perfektioniert (wenns am code liegt) :)

und was soll das childwindow ?

der text ist in einem fenster vom typ edit :wink:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);  
var
  l : Integer;
  Handle : HWND;
  s: string;
begin
  Handle:=FindWindowEx(FindWindow('Name - Nachrichtensitzung',nil),0,'Edit',nil);
  if Handle <> 0 then
    begin
      l:= SendMessage(Handle, WM_GETTEXTLENGTH, 00);
      SetLength(s, l);
      SendMessage(Handle, WM_GETTEXT, l + 1, lParam(@s[1]));
      showmessage(s);
    end;
end;

so, der code ist zwar vereinfacht, funzt aber imme noch net :(


F34r0fTh3D4rk - Di 15.02.05 20:10

funktionierender Code(made by luckie):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure TForm1.Button1Click(Sender: TObject);
var
  hMemo, hHandleDesFensters : HWND;
  Text : pchar;
  len: Integer;
begin
  SetLastError(0);
  hHandleDesFensters := FindWindow('notepad'nil);
  if hHandleDesfensters <> 0 then
  begin
    hMemo:= FindWindowEx(hHandleDesFensters, 0'EDIT'nil);
    if hMemo <> 0 then
    begin
      len := SendMessage(hMemo, WM_GETTEXTLENGTH, 00);
      GetMem(Text, len+1);
      try
        try
          SendMessage(hMemo, WM_GETTEXT, len+1, Integer(@Text[0]));
          ShowMessage(String(Text));
        except
          on E: EOutOfMemory do Messagebox(Handle, PChar(E.Message), 'Fehler', MB_ICONSTOP);
        end;  
      finally
        FreeMem(Text, len+1);  
      end;
    end
    else
      Messagebox(Handle, PChar(SysErrorMessage(GetLastError)), 'Fehler', MB_ICONSTOP);
  end
  else
    Messagebox(Handle, PChar(SysErrorMessage(GetLastError)), 'Fehler', MB_ICONSTOP);
end;


hibbert - Di 15.02.05 23:11

cool für notepad funzt es jetzt, doch wie setzte ich das für ICQ um ?

dazu benötige ich sicherlich das ICQ - Handle, oder ?
wenn ja, welches ist das ?

hibbert


Delete - Di 15.02.05 23:19

Stimmt, für Notepad funktioniert das, bei einem Mirandafenstertitel schon nicht mehr. Wo ist Luckie :wink:


patrick - Mi 16.02.05 10:29

zur umsetzung:
1. du must den namen des fensters umändern, nach welchem gesucht werdens soll
2. dann must du den vermutlich namen des objektes ändern, nach dem in dem fenster gesucht werden soll. evntl hast du ja glück und du bekommst ergebnisse wenn du den wert "edit" behälst :D


hier sidn ei paar befehle die man sich unbedingt agucken sollte, wenn man mit sowas arbeitet:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/window_89windowclasse.asp

damit man auch weiß was man da programmiert :wink:


F34r0fTh3D4rk - Mi 16.02.05 18:25

ich glaube, wenn du den code so abänderst könnte es klappen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure TForm1.Button1Click(Sender: TObject);  
var  
  hMemo, hHandleDesFensters : HWND;  
  Text : pchar;  
  len: Integer;  
begin  
  SetLastError(0);  
  hHandleDesFensters := FindWindow(nil'Name - Nachrichtensitzung');  
  if hHandleDesfensters <> 0 then  
  begin  
    hMemo:= FindWindowEx(hHandleDesFensters, 0'EDIT'nil);  
    if hMemo <> 0 then  
    begin  
      len := SendMessage(hMemo, WM_GETTEXTLENGTH, 00);  
      GetMem(Text, len+1);  
      try  
        try  
          SendMessage(hMemo, WM_GETTEXT, len+1, Integer(@Text[0]));  
          ShowMessage(String(Text));  
        except  
          on E: EOutOfMemory do Messagebox(Handle, PChar(E.Message), 'Fehler', MB_ICONSTOP);  
        end;    
      finally  
        FreeMem(Text, len+1);    
      end;  
    end  
    else  
      Messagebox(Handle, PChar(SysErrorMessage(GetLastError)), 'Fehler', MB_ICONSTOP);  
  end  
  else  
    Messagebox(Handle, PChar(SysErrorMessage(GetLastError)), 'Fehler', MB_ICONSTOP);  
end;

Das Problem ist, dass das Fenster keinen fenstertitel hat, und auch keine eigene exe, aber du solltest es mal probieren (hans nicht getestet) :)


Delete - Di 08.03.05 11:45

ist das Thema jetzt abgeschlossen? Bei mir funktionierts nicht, bei euch?


toms - Di 08.03.05 12:30

Hallo,
anstatt


Delphi-Quelltext
1:
 hMemo:= FindWindowEx(hHandleDesFensters, 0'EDIT'nil);                    

schreibe


Delphi-Quelltext
1:
 hMemo:= FindWindowEx(hHandleDesFensters, 0'RichEdit20A'nil);                    


hans-maulwurf - Mi 20.04.05 18:14
Titel: oberes Feld
Das funktioniert bei mir schon ganz toll.
Aber wie kann ich das OBERE Icq-Fenster auslesen oder zB die AddressLeiste des Internet Explorers?
:?:
nächste Frage wäre: wie kann man in diese Felder schreiben??
:?: :!:


F34r0fTh3D4rk - Do 05.05.05 12:55

das wirst du alles hier im forum finden 8)


retnyg - Do 05.05.05 13:14
Titel: Re: oberes Feld
user profile iconhans-maulwurf hat folgendes geschrieben:
Das funktioniert bei mir schon ganz toll.
Aber wie kann ich das OBERE Icq-Fenster auslesen oder zB die AddressLeiste des Internet Explorers?
:?:
nächste Frage wäre: wie kann man in diese Felder schreiben??
:?: :!:

für solche aufgaben empfiehlt es sich entweder den spy++ von ms (ist bei visual studio und c++ dabei) oder den x-spy von motzi zu verwenden.
der listet dir alle aktiven fenster auf, und du kannst die klassennamen der einzelnen unterfenster auslesen.