Array
(
)

Pegar conteúdo do label de outra janela ou um loop nos comps

Adriano Santos
   - 22 fev 2006

Galera,

To precisando pegar o conteúdo de um label na janela do iTunes, alguém tem idéia? Tinha que ser algo assim:

#Código


var
wnd2 : HWND;
i : Integer;
s : string;
begin
wnd := FindWindow(nil,´iTunes´);
{o Wnd está retornando correto, ou seja, ele encontra a janela do iTunes}
for I := 0 to ...ComponentCount-1 do
if ...Components[I] is TLable then
ShowMessage(...Components[I].Caption));
end;


Tentei algo como:

#Código

var
wnd2 : HWND;
i : Integer;
s : string;
begin
wnd := FindWindow(nil,´iTunes´);
{o Wnd está retornando correto, ou seja, ele encontra a janela do iTunes}
for I := 0 to TApplication(wnd).ComponentCount-1 do
if (TApplication(wnd).ComponentCount) is TLable then
ShowMessage((TApplication(wnd).ComponentCount).Caption));
end;


Mas não funciona pq da Access Violation na linha do FOR
#Código

for I := 0 to TApplication(wnd).ComponentCount-1 do


Não deve ser assim que eu dou um loop nos componentes de outra janela.

Num sei se expliquei direto.
As Apis que conheço não me ajudam em nada.


Massuda
   - 22 fev 2006

Você está assumindo que o iTunes é feito em Delphi (o que não é certeza) e que o handle retornado para a janela do iTunes corresponde a um TApplication (o que é errado).

No caso do handle retornado por FindWindow, ele é um ´ponteiro´ (na verdade não é) interno do Windows para a janela (no sentido Windows) do iTunes.

Para saber quais são as janelas filha (ou seja, as janelas contidas) da janela do iTunes, use EnumChildWindows da API do Windows; com isso você pode construir a lista das janelas filha.

Já obter o texto que você deseja depende do programa estar usando uma janela filha para mostrar o texto (algo como usar um TEdit) ou estar escrevendo direto na janela do programa (algo como usar um TLabel). Se for o segundo caso, não tem como pegar o texto dessa forma.

Um problema parecido é importar o resultado da calculadora do Windows para um programa.


Adriano Santos
   - 22 fev 2006


Citação:
Você está assumindo que o iTunes é feito em Delphi (o que não é certeza) e que o handle retornado para a janela do iTunes corresponde a um TApplication (o que é errado).

No caso do handle retornado por FindWindow, ele é um ´ponteiro´ (na verdade não é) interno do Windows para a janela (no sentido Windows) do iTunes.

Para saber quais são as janelas filha (ou seja, as janelas contidas) da janela do iTunes, use EnumChildWindows da API do Windows; com isso você pode construir a lista das janelas filha.

Já obter o texto que você deseja depende do programa estar usando uma janela filha para mostrar o texto (algo como usar um TEdit) ou estar escrevendo direto na janela do programa (algo como usar um TLabel). Se for o segundo caso, não tem como pegar o texto dessa forma.

Um problema parecido é importar o resultado da calculadora do Windows para um programa.


Aff, quanta coisa errada...rsrs....
Então Massuda, a idéia é esta: dar um loop na janela até achar o componente que eu quero e pegar o valor. O exemplo de pegar o conteúdo da calculadora eu tenho aqui, estou fuçando em cima dele pra ver se descubro algo. Cheguei a passar pela função Api mencionada (EnumChildWindows), mas tô em fase de estudo pra ver se consigo aprender a usar.

vlw;


Martins
   - 22 fev 2006

Adriano pode ser que o código abaixo lhe seja útil, segundo o nobre Massuda os problemas são parecidos, então, segue o código para pegar o valor do display da calculadora do windows.

#Código


implementation

{$R *.DFM}

Type
//Dados para a procura
PDadoProcura = ^TDadoProcura;
TDadoProcura = record
Win : THandle;
YPos : Integer;
end;

Agora você precisa criar a function que procura a calculadora

//Procura pelo TStatic visível com a menor coordenada Y

function ListaFilhos(Win: THandle; lp: LPARAM): Boolean; stdcall;
var
P: PDadoProcura;
R: TRect;
ClassName: array[0..255] of char;
begin
P:=PDadoProcura(lp);
GetClassName(Win, ClassName, sizeof(ClassName));
//Verifica se é um campo estático
If StrPas(ClassName) = ´Static´ Then
begin
//Verifica se está visível
If IsWindowVisible(Win) Then
begin
//Pega a posição e o tamanho da janela
GetWindowRect(Win, R);
//Verifica se a coordenada Y é menor
If R.Top < P^.YPos then
begin
//É, assume que é esta
P^.YPos := R.Top;
P^.Win := Win;
end;
end;
end;
//Continua chamando a enumeração
Result:=True;
end;
//Retorna o valor do campo Label da Calculadora cuja coordena Y é menor
//e estiver visível

Agora pegue o valor da calculadora

function ResultadoDaCalculadora : String;
var
CalcWin: THandle;
P : TDadoProcura;
Buffer: array[0..80] of char;
begin
Result:=´´;
//Pega o handle da calculadora, se estiver aberta
CalcWin:= FindWindow(´SciCalc´,nil);
If CalcWin <> 0 Then
begin
//Assume nenhuma janela em coordenada Y absurda
P.Win:=0;
P.YPos:=Maxint;
//Lista todas as janelas filhas
EnumChildWindows(CalcWin,@ListaFilhos,LPARAM(@P));
//Verifica se realmente achou
If P.Win <> 0 then
begin
//Recupera o texto da janela
GetWindowText(P.Win, Buffer, sizeof(Buffer));
Result:=Buffer;
end
Else
//Opa, a calculadora não é conhecida
Raise Exception.Create(´Esta calculadora não é familiar.´);
end
Else
//A calculadora não está aberta
Raise Exception.Create(´A calculadora não está aberta.´);

end;

Use o programa assim

procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=ResultadoDaCalculadora;
end;



Michael
   - 22 fev 2006

Existem outros problemas: o Label na janela do iTunes pode ser uma imagem, ou mesmo outro componente, e fica difícil de se saber como extrair o conteúdo dele.

Complementando o que o Massuda disse, cada elemento de uma janela é tratado pelo Windows como sendo tbm uma janela, com posições na tela, estado, etc. Desta forma, vc pode usar API´s como a já mencionada EnumChildWindows e GetWindowText. Estas duas são, a propósito, as usadas para se pegar o valor da calculadora do Windows. Se quiser ver um exemplo completo de como fazer isso, e quem sabe adaptar para o seu problema, [url=http://www.ramosdainformatica.com.br/art_recentes01.php?CDA=67]este link[/url] pode ser útil.

[]´s


Adriano Santos
   - 22 fev 2006

Então galera, o que eu quero, pra vcs entenderem melhor, é o seguinte:
Eu ouço uma rádio inglesa que toca muito trance (música eletrônica) e é pelo iTunes. Quando a música tah rolando aparece um ´label´ (nem sei se é label) com o nome da música e o dj. Então pensei em criar um programinha bem fulero pra pegar isso e gravar num txt, pois a noite eu baixo o som em casa.

Tentei dar uma de loko e ver se conseguia percorrer a tela do iTunes no intuito de pegar o conteúdo do suposto Label, mas acho que não é possível pelas razões que o Massuda mencionou. Nem sabemos se o programa é feito em Delphi, talvez seja Java então as classes devem ser totalmente diferentes das nossas.

Bom, descobri que no site da rádio existe um label mostrando a música que tah rolando. Daí foi fácil, só usar uma dica que saiu em uma revista ClubeDelphi a uns meses atrás e pimba, consegui. Agora é só colocar um timerzinho e boas.

Tô em casa então não tenho o exemplo aqui. De manhã eu posto como ficou o esquema.


vlw, abraços.


Adriano Santos
   - 23 fev 2006

Tah ai pessoal.

#Código


procedure TfPsy.Verify;
var
strFull: string;
Start: Integer;
I: Integer;
Words: Integer;
CompleteWord: string;
begin
try
Screen.Cursor := crHourGlass;
strFull := idhttpWebsite.Get(´http://www.di.fm/goapsy/´);
Start := Pos(´text_trackname´, strFull) + 16;
CompleteWord := Copy(strFull, Start, 100);
Words := 0;
for I := 0 to Length(CompleteWord) do
begin
if Copy(CompleteWord, I, 2) = ´</´ then
Break
else
Inc(Words);
end;
lblAtualMusic.Caption := Copy(strFull, Start, Words - 1);
if lblAtualMusic.Caption <> memMusics.Lines[memMusics.Lines.Count-1] then
begin
memMusics.Lines.Add(lblAtualMusic.Caption);
memMusics.Lines.SaveToFile(ExtractFilePath(Application.ExeName)+´musics.txt´);
end;
finally
Screen.Cursor := crDefault;
end;
Update;
end;



Martins
   - 23 fev 2006


Citação:
Tah ai pessoal.

#Código


procedure TfPsy.Verify;
var
strFull: string;
Start: Integer;
I: Integer;
Words: Integer;
CompleteWord: string;
begin
try
Screen.Cursor := crHourGlass;
strFull := idhttpWebsite.Get(´http://www.di.fm/goapsy/´);
Start := Pos(´text_trackname´, strFull) + 16;
CompleteWord := Copy(strFull, Start, 100);
Words := 0;
for I := 0 to Length(CompleteWord) do
begin
if Copy(CompleteWord, I, 2) = ´</´ then
Break
else
Inc(Words);
end;
lblAtualMusic.Caption := Copy(strFull, Start, Words - 1);
if lblAtualMusic.Caption <> memMusics.Lines[memMusics.Lines.Count-1] then
begin
memMusics.Lines.Add(lblAtualMusic.Caption);
memMusics.Lines.SaveToFile(ExtractFilePath(Application.ExeName)+´musics.txt´);
end;
finally
Screen.Cursor := crDefault;
end;
Update;
end;


Boa Adriano, problema resolvido então? Nem vou mais tentar escrever nada.

valeu por postar a resolução do problema.

Valew!!!!