Zwariowane pytanie - jak dobrać się do cudzego Edita :

0

Cześć :)
Mam zwariowane pytanie ;)
Przykładowo mam programik który posiada pole edycyjne do wpisywania czegoś tam :) No i autor na tyle był skąpy że ograniczył
opcję wklejania tekstu do tego pola edycji.
(brak popupmenu myszy oraz wyłączył funkcje klawiszy "Shift+Insert")
Więc zmuszony jestem wypisywać z klawiatury długie teksty, które
czasami muszę powtarzać.

Pytanie co trzeba zrobić by z poziomu mojego programu można było
wklejać przygotowany tekst w okienko edycyjne innego programu ?

  1. Myślę ze dobrze byłoby odblokować funkcje funkcje klawiszy
    "Shift+Insert" - ale jak to zrobić ?

  2. Dobrze by było przechwycić pole edycyjne tego programu

  • ale jak to zrobić ?

Studiowałem zawzięcie procesy, komunikaty itd .. ale ani w ząb mi nie wychodzi.

Proszę więc panów o jakieś wskazówki podparte kawałkiem kodu.
Jesteście ostatnią deską ratunku eh...

0

Jakiś czas temu robiłem program logujący do gry Tibia (kto grał, ten wie po co taki program - jeśli się nie ma opłaconego konta, trzeba się logować x razy czekając na wolne miejsce, a za każdym razem gra zmusza do wpisywania loginu i hasła), której twórcy tak wszystko zabezpieczyli, że pola edycyjne to nie kontrolki windows tylko ich własne, bez uchwytów. A więc zrobiłem to tak, że program przenosił kursor nad pierwsze pole, symulował kliknięcie, następnie po kolei "wpisywał" znaki, przenosił się na następne pole, wpisywał tam co trzeba i "naciskał" przycisk OK. Wszystko przez SendMessage. I działa. Wystarczy trochę poczytać Windows SDK, żeby znać komunikaty.

0

re :)
Dzięki za podpowiedź.
Trochę bawiłem się w przechwytywanie komunikatów wysyłanych przez
ten program. Qrde nagrzebałem się w necie i znalazłem nawet programik podający nazwę klasy (jest to <ort>objekt </ort>TEdit) oraz uchwyt do niego.
Ale nie mogę pojąć jak wysłać jakieś dane do tego objektu. :-/
Jakiej instrukcji użyć ?
Prawdę mówiąc noga jestem akurat w tym zakresie.
Na tej witrynce i na innych jest FAQ o przechwytywaniu komunikatów,
ale akurat jak wysłać tekst do jakiegoś komponentu zawartego w innym uruchomionym progsie - zero :-/
Szukałem tu i znalazłem pewien programik który demonstrował wysyłanie tekstu do standardowego notanika (notepad) Ale akurat jak
na złość nie działa prawidłowo - uruchamia tylko notepada i pusto :-/
Więc nic nie skorzystam z tego kodu eh..

Żebym chociaż potrafił odblokować działanie klawiszy "Shift+Insert"
(ten program to blokuje) to już bym się obył bez przesyłania tekstu
po prostu bym go wklejał.

No ale dałeś nadzieje że to możliwe więc nie spocznę :) dzięki.

0

Hmm... Czy mi się wydaje, czy jeśli masz uchwyt (coś wspomniałeś o programiku, który ci dawał uchwyt), to dalej już wystarczy zajrzeć do FAQ albo Artykułów?? Wybacz, że nie powiem więcej, ale nigdy nie korzystałem dużo z uchwytów, nie lubiłem grzebać po aplikacjach, których sam nie napisałem. Jak już coś kiedyś na uchwytach robiłem, to poszperałem gdzieś na 4p i coś znalazłem, wykorzystałem i zapomniałem absolutnie jak to szło... Ale wydaje mi się, że jak już dorwałeś sam uchwyt, to dalej wklejenie tekstu nie powinno być trudne (szczerze mówiąc odblokowanie kombinacji Shift-Ins może być trudniejsze, jeśli nie wiesz DOKŁADNIE, jak to zostało zrobione)... No cóż, może do czegoś dojdziesz... Powodzenia.

0

Nie wiem czy dobrze zrozumiałem ale jeśli tak to możesz zrobić tak.
Skoro znasz uchwyt okna spróbuj sprawdzić ten kod.

var
  H : HWND;
  Text : string;
begin
  H := WindowFromPoint(Mouse.CursorPos);  //Uchwyt okna
  Text := 'Text';  //Tekst który ma być wpisany do danego okna

  SendMessage(H,WM_SetText,0,LongInt(Text));  
  //Wpisz tekst wysyłając do okna stosowny komunikat
end;

Powinno działać o ile niczego nie pomyliłem ani nie zapomniałem.

0

Dzięki śliczne <browar><browar><browar> :)
Działa na medal !

Dla przetestowania umieściłem ten kodzik w procedurze timera,
no i po wskazaniu pola edycji innego programu wkleił się text :)

Przepraszam że naciągam Twoją dobrą wolę ale zapytam jeszcze:
Po najechaniu myszką na jakiś element - mogę pobierać nazwy klasy i uchwyty przykład dla notepad.exe

nazwa klasy: TMemo
uchwyt: 00000A2Ch

Znasz jakąś prostą procedurę by te dane podstawiać i uzyskać taki efekt
jak w Twoim kodzie ?
(wtedy nie bede musiał myszką wskazywać elementu)

Przepraszam Ciebie i wszystkich - wiem że znalazłbym to w serwisie
Qrde ale znowu stracę dzionek by coś się dogrzebać :-/

A ogólnie jeszcze raz dzięki :)

0

A widzisz mój podpis?

Ale jak już tu jestem to podpowiedz:

Musisz skorzystać z funkcji

//najpierw
FindWindow() //Pobierasz uchwyt okna rodzica
FindWindowEX();  //A następnie uchwyt okien Child aż dojdziesz do właściwego okna do którego wysyłasz już znany ci komunikat. 

To chyba wszystko, ale na drugi raz sam się dobrze zastanów i pytaj dopiero jak już na prawde nie będziesz mógł dojść do odpowiedzi.

0

Dzięki Log <dużo browarków> :)
No teraz już jestem na właściwej drodze.

0

a czy jest mozliwosć, aby taki kawałek kodu

var
   H : HWND;
   Text : string;
begin
   H := WindowFromPoint(Mouse.CursorPos);   //Uchwyt okna
   Text := '[email protected]';   //Tekst który ma być wpisany do danego okna

   SendMessage(H,WM_SetText,0,LongInt(Text));

można byłoby zmodyfikować i zastosować do np. uruchomionej strony www w przeglądarce ?? Chodzi mi o np. pola tekstow a nie tytuł z przeglądarki

[angel] pozdro

0

Cześć :)

Pewnie masz na myśli (przykład) pole edycyjne jakiegoś czata.
Hmmm.. Ciężka sprawa - zazwyczaj jest to aplet który sam tworzy pola edycyjne i ciężko będzie żeby wychwycić uchwyt takiego komponentu, tak jak to można zrobić dla zwykłego execa.
Ciekawy temat... kiedyś sam z ciekawości podglądałem jak to jest ;) . No i jedynie wszystko odnosiło się do przeglądarki oraz do apletu jako całości (uchwyt z klasą stworzoną przez webmastera - a nic standardowego)
Ciekaw jestem jak to jest -? może ktoś wtajemniczony uszczknie
trochwe wiedzu na ten temat :)

0

var
H : HWND;
Text : string;
begin
H := WindowFromPoint(Mouse.CursorPos); //Uchwyt okna
Text := 'Text'; //Tekst który ma być wpisany do danego okna

SendMessage(H,WM_SetText,0,LongInt(Text));
//Wpisz tekst wysyłając do okna stosowny komunikat
end;

Niby wszystko Ok, ale powyższy kod ustawia tekst w polu, nad którym znajduje się kursor. Ale jak zrobić, aby tylko dodać do tego pola jakiś tekst literka po literce razem z klawiszem ENTER? [niewinnosc]

0

Hej ;)

Wygeneruj procedurę śledzącą naciśnięcie klawisza dla swojej formy:

var
 text :String; //zmienna globalna

Procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var
   H :HWND;
Begin
 H:= WindowFromPoint(Mouse.CursorPos);
 if key > ''  then
 begin
   text:= text + key;
   SendMessage( H,WM_SetText,0,LongInt(text) );
 end;
End;

Musiałbyś trochę usprawnić tą procedurę by można było w pełni edytować napis (wstawianie literki(insert) usuwanie, cofanie itp.) bo w tym przykładzie tylko możesz dopisywać do łańcucha.

0

:-) hmm Inter nie chodzi mi o czaty, ale ogólnie elementy typu np. pole tekstowe, przycisk, listy.

Najpierw znalazłem kod i go przemieniłem:

function SetText(WindowHandle: hwnd):string;
var
   txtLength : integer;
   buffer: string;
   text : string;
   begin
TxtLength := SendMessage(WindowFromPoint(Mouse.CursorPos), WM_GETTEXTLENGTH, 0, 0);
txtlength := txtlength + 1;
setlength(buffer, txtlength);
text := 'heroman';
sendmessage (WindowHandle,wm_gettext, txtlength, longint(@buffer[1]));
SendMessage(WindowFromPoint(Mouse.CursorPos),WM_SetText,0,LongInt(text));
result := buffer;
end;

function setURL:string;
var
   ie,toolbar,combo,
   comboboxex,edit,
   worker,toolbarwindow:hwnd;
begin
   ie := FindWindow(pchar('IEFrame'),nil);
   worker := FindWindowEx(ie,0,'WorkerA',nil);
   toolbar := FindWindowEx(worker,0,'rebarwindow32',nil);
   comboboxex := FindWindowEx(toolbar, 0, 'comboboxex32', nil);
   combo := FindWindowEx(comboboxex,0,'ComboBox',nil);
   edit := FindWindowEx(combo,0,'Edit',nil);
   toolbarwindow := FindWindowEx(comboboxex, 0, 'toolbarwindow32', nil);
   result := setText(WindowFromPoint(Mouse.CursorPos));
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(setURL);
end; 

Okazuje się, że odczytuje daną tresć i zmienia go na słowo "heroman", np,. zmienia w przeglądarce pasek narzędzi, stanu, adres, wszystko lecz nie strone.

Może trzeba zmienić ten kod:

  • dla kodu potrzebny jest komponent IHTMLElement --> Project --> Import Type Libray --> Microsoft HTML Object Libray --> Install
 function GetItem(Form,Element :string) :IHTMLElement;
 var WebDoc : IHTMLDocument2;
       pDispatch : IDISPATCH;
       FormCollection : IHTMLElementCollection;
       FormElement : IHTMLFormElement;
       FormItem : IHTMLElement;
 begin
   //   Get the document contained in the WebBrowser
   OleCheck(Form1.wb.Document.QueryInterface(IID_IHTMLDocument2,WebDoc));
   //   Get all the forms in the document as there can be more than one
   FormCollection := WebDoc.Get_forms;
   //   Get a pointer to the first form in the collection of forms
   pDispatch := FormCollection.item(Form, 0);
   //   Make sure it supports the correct interface
   OleCheck(pDispatch.QueryInterface(IID_IHTMLFormElement, FormElement));
   //   Get a pointer the desired element of the form
   //   In this case it is as text box called 'address1'
   pDispatch := FormElement.item(Element, 0);
   //   Make sure it supports the required interface
   OleCheck(pDispatch.QueryInterface(IID_IHTMLElement, FormItem));
   //
   Result:=FormItem;
 end;

 procedure SetCombo(Form,Element :string; Val :Integer);
 var SelectElement :IHTMLSelectElement;
 begin
   //   Make sure its a input element, and it supports the required
   if GetItem(Form,Element).QueryInterface(IID_IHTMLSelectElement, SelectElement) = 0 then
      begin
       //   Final check to make sure its a text box and then set the valueof it
       SelectElement.selectedIndex:=Val;
      end;
 end;

 procedure FillForm(Form,Element,Val :string);
 var InputElement : IHTMLInputElement;
 begin
   //   Make sure its a input element, and it supports the required
   if GetItem(Form,Element).QueryInterface(IID_IHTMLInputElement, InputElement) = 0 then
      begin
       //   Final check to make sure its a text box and then set the valueof it
       InputElement.Set_value(Val);
      end;
 end;

 procedure Submit(Form,Element :string);
 var WebDoc : IHTMLDocument2;
       pDispatch : IDISPATCH;
       FormCollection : IHTMLElementCollection;
       FormElement : IHTMLFormElement;
       FormItem : IHTMLElement;
       InputElement : IHTMLInputElement;
 begin
   //   Get the document contained in the WebBrowser
   OleCheck(Form1.wb.Document.QueryInterface(IID_IHTMLDocument2,WebDoc));
   //   Get all the forms in the document as there can be more than one
   FormCollection := WebDoc.Get_forms;
   //   Get a pointer to the first form in the collection of forms
   pDispatch := FormCollection.item(Form, 0);
   //   Make sure it supports the correct interface
   OleCheck(pDispatch.QueryInterface(IID_IHTMLFormElement, FormElement));
   //   In this case it is as text box called 'address1'
   pDispatch := FormElement.item(Element, 0);
   //   Make sure it supports the required interface
   OleCheck(pDispatch.QueryInterface(IID_IHTMLElement, FormItem));
   //
   FormItem.click;
 end;

 procedure WaitFor;
 begin
   while Form1.wb.Busy do
    begin
      Sleep(10);
      Application.ProcessMessages;
    end;
 end;

Ma ktoś jakiś pomysł [???]

1 użytkowników online, w tym zalogowanych: 0, gości: 1