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

22/02/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:

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&93; is TLable then
      ShowMessage(...Components&91;I&93;.Caption));
end;


Tentei algo como:

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
  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.


Adriano Santos

Respostas

22/02/2006

Massuda

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.


Responder Citar

22/02/2006

Adriano Santos

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;


Responder Citar

22/02/2006

Martins

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

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&93; 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&93; 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;



Responder Citar

22/02/2006

Michael

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 [b:626b9a5653]Massuda [/b:626b9a5653]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 [b:626b9a5653]EnumChildWindows [/b:626b9a5653]e [b:626b9a5653]GetWindowText[/b:626b9a5653]. 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


Responder Citar

22/02/2006

Adriano Santos

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 [b:eed2e0cf99]Massuda[/b:eed2e0cf99] 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.


Responder Citar

23/02/2006

Adriano Santos

Tah ai pessoal.

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&93; then
    begin
      memMusics.Lines.Add(lblAtualMusic.Caption);
      memMusics.Lines.SaveToFile(ExtractFilePath(Application.ExeName)+´musics.txt´);
    end;
  finally
    Screen.Cursor := crDefault;
  end;
  Update;
end;



Responder Citar

23/02/2006

Martins

[quote:efd9be3566=´Adriano Santos´]Tah ai pessoal.

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&93; then
    begin
      memMusics.Lines.Add(lblAtualMusic.Caption);
      memMusics.Lines.SaveToFile(ExtractFilePath(Application.ExeName)+´musics.txt´);
    end;
  finally
    Screen.Cursor := crDefault;
  end;
  Update;
end;
[/quote:efd9be3566]

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

valeu por postar a resolução do problema.

Valew!!!!


Responder Citar