Text von fremden Programmen auslesen/senden
-
Mein Problem ist es, das ich es nicht schaffe mit GetItemDlgText Text aus einem definiertem Feld auszulesen.
hwnd ist ein handle vom normalen Windows Notepad.
0xF ist díe ID vom Textfeld des Editors (stimmt, da ich es da drüber auch hide / unhiden kann).
Was mache ich falsch?char text[8000]; GetDlgItemText(hwnd, 0xF, text, sizeof(text))); Memo2->Lines->Add(text);Das andere Problem ist, das ich nicht genau weiß, wie ich die ID ansonsten von bestimmten Objekten fremder Programme bekomme. Zur Zeit mache ich das mit einem kleinen Tool, WindowMan, womit man sich sämtliche IDs anzeigen lassen kann (anderes Problem ist das bei manchen Fenstern verschiedene Objekte die gleiche ID haben, jedoch anderes Handles. Wie kann ich dann darauf zugreifen?)
Letztes Problem welches ich noch habe ist unter anderem auch das senden. Im FAQ steht zwar vieles da drüber wie man Text zu fremd Programmen schickt, jedoch wird nirgendwo beschrieben wie man das Objekt welches den Text erhalten soll definieren kann.
void TextSend(AnsiString wintext, AnsiString text) { HWND hwndPrev = GetForegroundWindow(); HWND hwnd = FindWindow(0, wintext.c_str()); DWORD idAttach = GetCurrentThreadId(); DWORD idAttachTo = GetWindowThreadProcessId(hwnd, NULL); SetForegroundWindow(hwnd); if( AttachThreadInput(idAttach, idAttachTo, TRUE) == FALSE ) ShowMessage("ERROR: AttachThreadInput\(\)"); HWND hwndFocus = GetFocus(); if(hwndFocus) { int length = (int)SendMessage(hwndFocus, WM_GETTEXTLENGTH, 0, 0); length++; char* prevText = new char[length + text.Length()]; SendMessage(hwndFocus, WM_GETTEXT, (WPARAM)(length), (LPARAM)prevText); strcat(prevText, text.c_str()); if( SendMessage(hwndFocus, WM_SETTEXT, 0, (LPARAM)prevText) == FALSE ) ShowMessage("ERROR: WM_SETTEXT"); delete[] prevText; } if( AttachThreadInput(idAttach, idAttachTo, FALSE) == FALSE ) ShowMessage("ERROR: AttachThreadInput\(\)"); SetForegroundWindow(hwndPrev); }Das funktioniert soweit wunderbar.
Ändere ich die SendMessage zu SendDlgItemMessage und benutze die Richtige ID klappt es nicht mehr
Das ganze soll übrigens bei einem ICQ Chatfenster funktionieren, zur Info. Man könnte das ganze auch über viele Tabstopps und kopieren über die Zwischenablage realisieren. Doch ist das viel zu Fehleranfällig und einfach Quick & Dirty.
Ich hoffe mir kann jemand hier zu helfen
Vielen dank schon mal
-
Dieser Thread wurde von Moderator/in Jansen aus dem Forum Borland C++ Builder (VCL/CLX) in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Was meint denn GetLastError?!
-
Hallo
GetLastError sagt soweit gar nichts.
Es rührt sich dann einfach nichts.
Um noch mal mein anliegen zuverdeutlichen. Mir geht es hautpsächlich um das Senden an bestimmte Objekte von fremd Programmen, sowie den Umgang deren Handles/IDs (wie ich diese bestimmen kann).
-
Um an die Handles zu kommen, gibt es vielfältige Möglichkeiten:
FindWindow(Ex), Enum(Child)Windows, WindowFromPoint, GetDlgItem (waren das jetzt alle bzw. die wichtigsten?!)
-
Ich denke wohl die wichtigsten
Mit FindWindow bekomme ich ja nur das Handle von einem jeweiligen geöffneten Fenster (was ich ja eh brauche).
Mit GetDlgItem bekomme ich das Handle von einem Objekt wen das Fensterhandle sowie die ID vorgegeben ist (doch wie bestimme ich diese normalerweise?).
Mit WindowFromPoint benutzt man ja eigentlich um das Handle zu bekommen wo gerade der Mauszeiger ist. Kann man das evtl. missbrauchen um an ein bestimmtes zu bekommen?
Mit Enum(Child)Windows habe ich noch nichts gemacht. Wie wende ich das an und was kann es alles?
-
Über FindWindowEx kannst du dir theoretisch für jedes beliebige Fenster das Handle besorgen (indem du es mehrmals hintereinander aufrufst)
Mit Enum(Child)Windows wird eine von dir angegebene Callback-Funktion für jedes (Child-)Fenster aufgerufen, dort kannst du dann machen, was du eben machen willst

-
Vielen Danke schon mal
Ich habe gerade ein wenig im Forum herum gesucht noch.
Dabei ist mir folgende Idee gekommen. In einem ICQ Fenster ist die Klasse wo Text Ein und Ausgegeben wird "RichEdit20A". Es gibt doch auch die Möglichkeit die Handles über die Klassen dann zu bekommen. Wie würde das dann in c++ Code aussehen? Das Handle für das Fenster jeweils habe ich.
Wäre super nett
-
Schau dir doch bitte mal die Parameter von FindWindowEx an - btw: deine "Objekte" sind auch nichts anderes als Fenster

-
Ich glaub ich tu mich wirklich etwas schwer damit

HWND hwnd = FindWindow(0, ICQFensterNm[0].c_str()); SetForegroundWindow(hwnd); HWND richedit = FindWindowEx(hwnd,NULL,"RichEdit20A",NULL); EnableWindow(richedit,FALSE);Wieso klappt das mit dem Handle nicht?
Also das Richedit würd nicht ausgeblendet (was bei anderen objekten sonst funktioniert.
@flenders: kannst du mir vielleicht ein Codebsp. geben. Sonst werd ich daran noch verrückt
-
Könnte es sein, dass das RichEdit20A-Control gar kein direktes Child des Hauptfensters ist?!
Die genaue Verschachtelung kannst du am besten mit Spy++ bzw. WinSpector ermitteln
-
Also das habe ich natürlich schon gemacht.
Spuckt folgendes aus:Properties for window 0x005B0862 Item Value Class Name RichEdit20A Text Rectangle 447, 539, 914, 647 Size 467, 108 Client Rectangle 0, 0, 461, 102 Client Size 461, 102 Styles WS_CHILD WS_VISIBLE WS_BORDER WS_TABSTOP 0x00004420 StylesEx WS_EX_CLIENTEDGE WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR ID 101 Properties OleDropTargetInterface 0x00199B18 (1678104) OleDropTargetMarshalHwnd 0x00010250 (66128) Class specific none Owner EXE C:\Programme\ICQ\Icq.exeWenn ich es mit der ID 101 bzw. 0x65 versuche über GetDlgItem klappt es auch nicht so wirklich

Aktueller Quelltext der mit dem ICQ RichEdit20A nicht funktioniert, aber zB. mit dem Notepad (über GetDlgItem)
HWND hwndPrev = GetForegroundWindow(); HWND hwnd = FindWindow(0, ICQFensterNm[0].c_str()); SetForegroundWindow(hwnd); //HWND richedit = FindWindowEx(hwnd,NULL,"RichEdit20A",NULL); //EnableWindow(richedit,FALSE); HWND richedit = GetDlgItem(hwnd, 0xF); SendMessage(richedit,EM_SETSEL,0,-1); //start selecting SendMessage(richedit,WM_COPY,0,0); SendMessage(richedit,EM_SETSEL,-1,0); //end selecting
-
Ich denke, du hast mich falsch verstanden: ich meinte, dass du wohl bei FindWindowEx ein falsches Parent verwendet hast

-
Wieso meinst du das?
Ich benutze als Parent, ein Handle des ganzen ICQ Message Fensters. Daraus will ich dann als Child das RichEdit20A handlen. Habe ich denn da irgendwie was falsch verstanden?
Könntest du mir vielleicht einen konkreten Hinweis geben wie ich es machen soll. Ich glaube so drehen wir uns im Kreis sind.
Trotzdem vielen dank schon mal für deine bemühungen
-
BlackSunrise schrieb:
Wieso meinst du das?
Ich benutze als Parent, ein Handle des ganzen ICQ Message Fensters. Daraus will ich dann als Child das RichEdit20A handlen. Habe ich denn da irgendwie was falsch verstanden?
Könntest du mir vielleicht einen konkreten Hinweis geben wie ich es machen soll. Ich glaube so drehen wir uns im Kreis.
Trotzdem vielen dank schon mal für deine bemühungen
-
Ist denn das Edit ein direktes Child des Haupt-Fensters - hab gerade hier kein ICQ installiert...
-
Ich bin ein wenig weiter gekommen. Das RichEdit20A ist kein direktes Child vom Hauptfenster sondern erst kommt noch AfxOleControl42.
Also habe ich nun folgedes probiert:
HWND hwnd = FindWindow(0, "User (Invisible) - Message Session"); SetForegroundWindow(hwnd); Sleep(50); HWND OleControl = FindWindowEx(hwnd,NULL,"AfxOleControl42",NULL); HWND richedit = FindWindowEx(OleControl,NULL,"RichEdit20A",NULL); EnableWindow(richedit,FALSE);Mache ich einen Zugriff zB. beim Wordpad wo auch ein RichEdit benutzt wird was direkt dem Hauptfenster zugeordnet ist klappt meine Methode. Also sollte es doch eigentlich auch der richtige weg sein?
Anderes Problem ist, wie kann ich nachher Unterscheiden welches RichEdit ich bekomme? Es gibt leider 2 RichEdit20A die jeweils in einem AfxOleControl42 sind.
-
Wenn du nicht über die ID gehen willst / kannst, dann eben anhand der Reihenfolge (also das wievielte Child es ist) - dazu gibt es den Parameter hwndChildAfter bei FindWindowEx

-
So als ich habs nun endlich geschafft

Meine Probleme war letztlich immer noch bei der Verschachtelung (RichEdit20A war zT. das 3. Child).
Mit ChildAfter habe ich das nun auch endlich verstanden
Also vielen dank soweit.
Wenn einer fragen zuhat und Code sehen will soll er mich fragen