PostMessage Para o programa em execução

Delphi

18/07/2008

Bom dia pessoal...


estou aq d novo com mais uma dúvida...


Eu estou tentando enviar um caracter para um programa em execução usando o PostMessage...

Por exemplo, estou testando com o Word 2003, Windows Vista e D7...

mas ele não envia o caracter q eu mando....

estou usando o seguinte código..

//******************************************************************************
Procedure TForm1.BtCedilhaClick(Sender: TObject);

Var MyHandle : THandle;

Begin

MyHandle:= FindWindow(´Opusapp´, Pchar(´Documento1 - Microsoft Word´));

If MyHandle <> 0 then
Begin
PostMessage( myHandle, WM_SETFOCUS, 0, 0);
PostMessage( myHandle, WM_KEYDOWN, 65, 0);
End;
End;
//******************************************************************************

Ele até envia o setFocus...mas não escreve o caracter 65 q é o A...

O q eu pretendo depois q conseguir enviar para o Word, seria pegar qual janela está com o focus na tela e enviar para aquela q estiver com o focus. Enviar caracter para o browser por exemplo, independente de ser o Firefox(q na minha opnião é o melhor) ou o IE.

Alguém tem uma idéia???


Vlw...


Wdrocha

Wdrocha

Curtidas 0

Respostas

Wdrocha

Wdrocha

18/07/2008

esqueci de dizer q...


estou usando um teclado virtual q estou desenvolvendo...


vlw


GOSTEI 0
Nildo

Nildo

18/07/2008

Olá.

Após colocar foco na janela, tente usar a função

keybd_event( [codigo da tecla], 0, 0, 0 );

Faz um tempinho que não programo com Delphi então estou um pouco enferrujado


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Nildo....fiz como vc mandou e o código ficou assim...

//******************************************************************************
Procedure TForm1.BtCedilhaClick(Sender: TObject);

Var MyHandle : THandle;

Begin

MyHandle := FindWindow(´OpusApp´, nil);

//MyHandle := Getwindow(MyHandle,GW_CHILD);

If (MyHandle <> 0) then
Begin
PostMessage( myHandle, WM_SETFOCUS, 0, 0);

keybd_event( 65, 0, 0, 0 );

SendMessage(MyHandle, WM_SETTEXT, 0, Integer(PChar(´Williame Rocha´)));

End;
End;
//******************************************************************************

Se eu deixar a segunda linha comentada....ele muda o título do documento....Se eu descomentar a segunda linha....ele não faz nada...


o q eu sei q tenho q fazer e não sei como, é pegar o handle da janela filha....ou a última janela q esteve com o focus pra assim poder enviar os caracteres....Ele está enviando para a janela mãe...

Eu pus o código q vc indicou mas...ele escreve a letra no próprio delphi...


Vc tem mais alguma idéia??



Vlw...


GOSTEI 0
Nildo

Nildo

18/07/2008

Bom, é o seguinte... O WM_SETTEXT altera o Caption da janela. O keybd_event simula o pressionamento de uma tecla. Logo, você deve antes de enviar o keybd_event, dar um SetForegroundWindow da janela que você quer enviar a tecla.

Dessa maneira a tecla será enviada para a janela que estará ativa. Então brinque com essas APIs: SetForegroundWindow, FindWindow e Keybd_event


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Eu fiz o q vc falow...mas...


Acontece o seguinte....

Ele só escreve se estiver no modo debug....qdo eu clico no botão para enviar o SenMessage e aperto rapidamente na tecla F9 ele escreve no Word

mas só escreve uma vez.....nas outras vezes ele escreve no form...

Eu fiz um teste e a partir da segunda vez usando o SETTEXT, foi pra saber em qual janela estava o focus ele muda o caption do form.... O código ficou assim Nildo...
//***********************************************************
Procedure TForm1.Button1Click(Sender: TObject);

Var Handle : THandle;

Begin

If Handle <> 0 Then

Begin

SendMessage (Handle, WM_SETFOCUS, 0, 0);

SetForegroundWindow(Handle);

KeyBd_Event (67, 0,0,0);

SendMessage(Handle, WM_SETTEXT, 0, Integer(Pchar(´Williame Rocha´)));

End;

End;
//***********************************************************

Falta pouco.....rsrsr

Vlw....alguma luz?? javascript:emoticon(´:lol:´)
:lol:


GOSTEI 0
Nildo

Nildo

18/07/2008

Tá quase la. Mas assim, você declarou a variavel la como THandle, mas você não atribuiu nada a ela!


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Pow cara consegui....

Vlw mesmo...

O código ficou assim....

//******************************************************************************
Procedure TForm1.Button1Click(Sender: TObject);

Begin

Handle := FindWindow(´OpusApp´, Nil);//Variavel Global pra não perder o focus da janela

Ax := Handle;//Variavel Global, guarda o handle da janela mâe

Handle := GetWindow (Handle, GW_CHILD);//Pega o handle da janela filha

If Handle <> 0 Then

Begin

SendMessage (Handle, WM_SETFOCUS, 0, 0);

SetForegroundWindow(Handle);

KeyBd_Event (70, 0,0,0);

End;

SendMessage(ax, WM_SETFOCUS, 0, 0);//Devolve o focus a janela mãe

End;
//******************************************************************************



Agora tem outras coisas que eu preciso fazer...

Certas horas o SO fica maluco....qdo eu clico na tecla da letra q eu quero enviar, por exemplo, ele chama a janela de pesquisa do Windows....outra hora ele abre o Windows Explorer....rsrsrs...

Aew eu tenho q reiniciar a maq....


ma isso é o d menos.....


O q me interessa agora...

é como saber qual janela está com o focus.....independente de ser o Word, Firefox e etc....e enviar o caracter para a janela q estiver com o focus


Tem como ??



Vlw....


Mt Obrigado por está me ajudando....

qdo o teclado estiver pronto eu vou disponibilizar aq pra quem quiser....


GOSTEI 0
Nildo

Nildo

18/07/2008

De alguma maneira o botãozinho do windows do teclado ta apertado. Não fisicamente mas o SO ta interpretando como tal. Olhe na SDK do windows os parâmetros da keybd_event. Se eu não me engano depois que vc da o sinal que você apertou uma tecla, tem que mandar o sinal de que você soltou a tecla. E isso você indica nos parâmetros.


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Vlw cara....eu vou procurar....


Mt obrigado pela ajuda....


Mt grato a vc....


Vlw....



Abraços,



Williame Rocha


GOSTEI 0
Nildo

Nildo

18/07/2008

Estamos ai!


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Como eu faço pra pegar o handle de uma janela através do click do mouse???


GOSTEI 0
Nildo

Nildo

18/07/2008

Como assim? Você quer clicar em um local da janela e pegar o handle desse local?


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Sim...olha o q tah acontecendo Nildo....


Eu alterei o código para q ele envie mensagem para qualquer lugar q aceite texto...


mas ele tah pegando o handle do botão q eu tow clicando....e tah enviando a mensagem pro botão....


o firefox tah rolando atrás dele por exemplo....é pra ele q deveria ser a letra enviada e não pro botão q eu cliquei.....


GOSTEI 0
Nildo

Nildo

18/07/2008

É. Ele envia a mensagem para o que for que esteja em foco. Por isso voce tem que se certificar que você está enviando para o controle que está em foco.

Um bom comećo seria estudar esta página: http://www.codeproject.com/KB/winsdk/hwndfrommouseclick.aspx


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

esqueci d falar q....


ele só escreve a primeira letra no firefox, por exemplo....e depois não escreve mais.....


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

esqueci d falar q....


ele só escreve a primeira letra no firefox, por exemplo....e depois só manda mensagem pro botão...


GOSTEI 0
Nildo

Nildo

18/07/2008

Ele só coloca a primeira letra porque você está fazendo algo de errado (rsrs). Mas então, Para apertar uma tecla você deve apertar e soltar. Você deve fazer a mesma coisa com o keybd_event. Dá uma olhada no help da SDK do windows sobre esta funcão


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Blz....tow olhando tbm o q vc me mandou...vai me ajudar bastante....era o q eu queria....


vlw d novo......


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Falta pouco....hauhuha....

qdo eu consegui eu vou postar o código....



Ele só envia a tecla se eu debugar...mesmo usando o SetForeground....


Tow quase chegando na solução...rsrsrs


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Consegui cara.....rsrsrs...


até q enfim....O código ficou assim...


//***********************************************************
Procedure TFrmTecladoReduzido.BtAClick(Sender: TObject);

Begin

Application.HandleMessage;

MyHandle := FindWindow(´TFrmTecladoReduzido´, Nil);

If (GetActiveWindow = MyHandle) Then

HandleMaeFocus := GetNextWindow(MyHandle, GW_HWNDNEXT);

Sendmessage (HandleFilhaFocus, WM_SETFOCUS, 0, 0);

SetActiveWindow (HandleFilhaFocus);

keybd_event(37, 0, 0, 0);//Caso esteja digitando no browser

keybd_event(65, 0, 0, 0);//Código ascii da letra A

End;
//***********************************************************


Vlw cara.....mt obrigado mesmo...


Fico t devendo essa...

pod testar....até no icq ele escreve.....



Vlw


GOSTEI 0
Nildo

Nildo

18/07/2008

Legal cara! Meus parabéns!!
Abraços


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Ei cara...desculpa t incomodar d novo....

mas sabe como eu faço pra saber qual tipo d componente tah com o focus...


Por exemplo...


Qdo eu digito no browser....tenho q simular KeyBd_Event(37, 0 , 0, 0), pra ele dar uma seta pro lado e escrever a letra, caso contrário ele subscreve o q tah na barra de endereços do browser....tudo pq é um combo....


mas....se eu fizer isso...no controle do excel, ele vai pra célula ao lado e escreve uma letra....sempre dessa forma.....


Tow procurando no SDK mas não tow achando uma função q me retorne o tipo de componente q tah com o focus....


alguma luz??


Vlw....


GOSTEI 0
Nildo

Nildo

18/07/2008

Bom dia (ou Tarde pra vcs aí)

Bom, existe uma API no windows entitulada [b:ea8cdd469e]GetClassName[/b:ea8cdd469e]. Nela você passa o Handle da janela, e uma variável para recever o nome da classe dela.

Então você deve declarar uma variável do tipo PChar, vamos dizer:

var
   p_Class: PChar;


Agora você deve alocar memória para seu PChar, pois ele nada mais é que um ponteiro apontando para o nada no momento:

p_Class := AllocMem( 50 );


Feito isso, você ja pode fazer a chamada:

GetClassName( [Coloque aqui a variavel com o Handle], p_Class, 50 );


Pronto, o nome da classe do componente está na variável p_Class agora.

Qualquer outra dúvida estamos ai


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Aqui ainda é bom dia....e pra vcs aew boa tarde...



Vou tentar e logo postarei a resposta....vlw mais uma vez....


Mt Obrigado...


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Nildo, fiz como vc ensinou, mas....acontece o seguinte...


Ele só pega a classe da janela mãe e não a classe da janela filha...por exemplo...e tbm o mesmo nome d classe q ele retorna pra janela mãe ele retorna pra janela filha q tah como focus...

O código ficou assim...

Obs : As variáveis são globais

//************************************************************
Begin
ClassComponent := AllocMem(50);//Reserva espaço na memória para a variável que guardará o nome do componente com focus

Application.HandleMessage;

MyHandle := FindWindow(´TFrmTecladoReduzido´, Nil);

If (GetActiveWindow = MyHandle) Then

HandleMaeFocus := GetNextWindow(MyHandle, GW_HWNDNEXT);

Sendmessage (HandleFilhaFocus, WM_SETFOCUS, 0, 0);

SetActiveWindow (HandleFilhaFocus);

GetClassName(HandleMaeFocus, ClassComponent, 50);//se eu mudar pra HANDLEFILHAFOCUS, que é a janela filha q tah com o focus, ele vem vazio.

ShowMessage(ClassComponent);

KeyBd_Event(39, 0, 0, 0);//Caso esteja digitando no browser

KeyBd_Event(CodLetra, 0, 0, 0);//Código ascii da letra q vem por parãmetro

End;
//***********************************************************


Alguma luz??



Vlw, mais uma vez, obrigado.


GOSTEI 0
Wdrocha

Wdrocha

18/07/2008

Esqueci d dizer q....

com esse código q tem o ShowMessage, foi só pra fazer teste para q eu soubesse o nome da classe ainda tah sem tratamento..



vlw


GOSTEI 0
Nildo

Nildo

18/07/2008

Tenta ver se uma dessas APIs funciona para o objeto em foco:

function GetActiveWindow: HWND; stdcall;
function GetFocus: HWND; stdcall;


GOSTEI 0
POSTAR