PostMessage Para o programa em execução
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...
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
Curtidas 0
Respostas
Wdrocha
18/07/2008
esqueci de dizer q...
estou usando um teclado virtual q estou desenvolvendo...
vlw
estou usando um teclado virtual q estou desenvolvendo...
vlw
GOSTEI 0
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
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
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...
//******************************************************************************
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
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
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
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:
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
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
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....
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
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
18/07/2008
Vlw cara....eu vou procurar....
Mt obrigado pela ajuda....
Mt grato a vc....
Vlw....
Abraços,
Williame Rocha
Mt obrigado pela ajuda....
Mt grato a vc....
Vlw....
Abraços,
Williame Rocha
GOSTEI 0
Nildo
18/07/2008
Estamos ai!
GOSTEI 0
Wdrocha
18/07/2008
Como eu faço pra pegar o handle de uma janela através do click do mouse???
GOSTEI 0
Nildo
18/07/2008
Como assim? Você quer clicar em um local da janela e pegar o handle desse local?
GOSTEI 0
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.....
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
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
Um bom comećo seria estudar esta página: http://www.codeproject.com/KB/winsdk/hwndfrommouseclick.aspx
GOSTEI 0
Wdrocha
18/07/2008
esqueci d falar q....
ele só escreve a primeira letra no firefox, por exemplo....e depois não escreve mais.....
ele só escreve a primeira letra no firefox, por exemplo....e depois não escreve mais.....
GOSTEI 0
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...
ele só escreve a primeira letra no firefox, por exemplo....e depois só manda mensagem pro botão...
GOSTEI 0
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
18/07/2008
Blz....tow olhando tbm o q vc me mandou...vai me ajudar bastante....era o q eu queria....
vlw d novo......
vlw d novo......
GOSTEI 0
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
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
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
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
18/07/2008
Legal cara! Meus parabéns!!
Abraços
Abraços
GOSTEI 0
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....
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
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:
Agora você deve alocar memória para seu PChar, pois ele nada mais é que um ponteiro apontando para o nada no momento:
Feito isso, você ja pode fazer a chamada:
Pronto, o nome da classe do componente está na variável p_Class agora.
Qualquer outra dúvida estamos ai
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
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...
Vou tentar e logo postarei a resposta....vlw mais uma vez....
Mt Obrigado...
GOSTEI 0
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.
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
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
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
18/07/2008
Tenta ver se uma dessas APIs funciona para o objeto em foco:
function GetActiveWindow: HWND; stdcall;
function GetFocus: HWND; stdcall;
function GetActiveWindow: HWND; stdcall;
function GetFocus: HWND; stdcall;
GOSTEI 0