Pergunta

Eu estou tentando usar o seguinte código ao pressionar um botão no meu outro aplicativo:

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
   ButtonHandle = FindWindowEx(wnd, 0, "SaveButton", "&Save");
   SendMessage(wnd, WM_COMMAND, MAKEWORD(GetDlgCtrlID(ButtonHandle), BN_CLICKED ), (LPARAM)ButtonHandle);

}

Ele não funciona. Eu tentei passar diferentes alças para MAKEWORD e para alterar o WPARM e LPARAM, mas nada.

Algumas ideias sobre como clicar em um botão na janela de outro aplicativo?

Código é apreciado. Obrigado.

EDIT: A razão pela qual não parece permissões de trabalho. Enviei uma PostMessage () eo resultado foi um erro com GetLastError () = 5 (ou acesso negado). Alguma idéia?

EDIT2 Eu não quero ser rude, mas por favor, por favor, por favor, eu já procurou toda a API de incluindo obter e definir as regiões para o botão e, em seguida, enviar um botão para baixo e botão para cima, ficando a identificação do controle, ficando o ID de classe e uma mais zilhão. A razão pela qual eu fiz a pergunta aqui, em primeiro lugar é porque eu já esgotou a minha pesquisa na internet. Se você sabe a resposta Por favor, poste CÓDIGO , não sugerem uma API e é isso, mostre-me como é que isso resolve API do problema. Não é díficil. obrigado.

EDIT 3: A resposta da questão ter sido seleccionado automaticamente quando a recompensa terminou. A questão ainda permanece sem resposta.

Foi útil?

Solução

  1. Você tem certeza que "SaveButton" nome da classe é válido? Você começa o botão alça?
  2. Tente enviar mensagens para a janela ButtonHandle (diretamente para o botão).

Update: Eu acredito que isso deve funcionar,

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

Outras dicas

SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);

Você tem que enviar um clique de botão duas vezes. Não sei por que (talvez o primeiro clique só ativa a janela do botão), mas eu estou usando este código por um longo tempo e ele sempre trabalhou para mim.

Veja a seguinte solução, você também pode usar

SendMessage(ButtonHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(ButtonHandle, WM_LBUTTONUP, 0, 0);

ou

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

HWND buttonHandle = 0;

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
 char label[100];
 int size = GetWindowTextA(handle,label,sizeof(label));
 if(strcmp(label,"&Save") == 0)
 {
  buttonHandle = handle;
  return false;
 }
 return true;
}
void main()
{
 HWND windowHandle = FindWindowA(NULL,"Do you want to Save?");
 if(windowHandle != 0)
 {
  BOOL ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

  if(buttonHandle != 0)
  {
   LRESULT res = SendMessage(buttonHandle,BM_CLICK,0,0);
   //SendMessage(buttonHandle,WM_LBUTTONDOWN,0,0); 
   //SendMessage(buttonHandle,WM_LBUTTONUP,0,0);
  }

 }



}

Nota: Obtendo certeza do texto da janela, o texto do botão (verificar se há espaço no final do título da janela)

Erros de acesso negado no SendMessage ou PostMessage não fazem sentido, a menos que o processo de enviar a mensagem está sendo executado em um nível de integridade mais baixo do que o processo de destino.

Este não deve estar acontecendo a menos que o processo que possui a janela de destino está sendo executado "asAdministrator" ou é um serviço. E sua maldita duro para serviços para criar janelas na área de trabalho interativa com Windows 6 e para cima.

Você pode fazer algumas leituras sobre Níveis Integridade Aqui se aplicam-se mesmo remotamente a esta situação. Internet Explorer é sobre a única outra aplicação que 'opta em' para o modelo de segurança da integridade de redução propositadamente o nível de integridade de si mesmo, a fim de sandbox-se de forma mais eficaz.

Se você pode levantar a janela que contém o botão você pode enviar evento raw mouse para uma posição dentro dos limites do botão.

Existem duas funções para o evento simular rato SendInput e mouse_event . Eu recomendo usar a função mouse_event. Para elevar uma janela que você pode usar ShowWindow . Eu não sei como obter o identificador de um botão, mas se você tiver seu hWnd é fácil encontrar a sua posição absoluta usando função GetWindowRect . Tente usar estes, se você tiver quaisquer problemas eu vou ser feliz para ajudar.

Ou definir um WM personalizado dentro de sua aplicação janela para lidar com save pedido. WM_CUSTOM ou WM_USER (não consigo lembrar qual) marca o início de mensagens de janela definidos pelo usuário.

Quando eu tenho que fazer este tipo de coisas que eu uso SendKeys. É VB-ish e C # fornece uma interface agradável de usar, mas para C / C ++ você terá que fazê-lo << a href = "http://www.codeproject.com/KB/cpp/sendkeys_cpp_Article.aspx" rel = "noreferrer nofollow"> desta forma >. O que é bom com ele é que você pode escrever scripts e executá-los em vez de codificar-lo em seu código.

A Microsoft está empurrando agora Active Accessibility (MSAA) para UI Automation, (Ele foi renomeado várias vezes ao longo dos anos) veja

Desculpe eu não tenho qualquer código simples para você começar. Como “SendMessage ()” não parece estar a trabalhar para você, eu não sei de outra opção além de “UI Automation”

Eu estou supondo que você tenha verificar com Spy ++ (instalado com MsDev) que você mensagem estão sendo envie o botão correto etc - e que o botão é um padrão de botões das janelas. Meu primeiro instante diria uso “SendMessage () 'ou' PostMessage ()” mas dado o número de respostas sobre ‘SendMessage ()’ e o fato de ele não está funcionando para você. Espero que alguém está acontecendo ...

Você pode usar sendkeys (como tr3 disse) para enviar cliques do mouse, que é diferente do que usar SendMessage. Também é menos direta e mais corte-ish, mas é útil para automação (em VBS).

Além disso, apenas um palpite, mas o problema pode ser que seu manuseio mensagem é quebrado em algum lugar não chamando o membro da classe base. Exemplo:

void CMyClass::OnMessageY(CWnd *cwnd)
{
    CBaseClass::OnMessageY(cwnd);
    //... my code
}

Se você certeza ButtonHandle são manipulador válido você pode usar par WM_LBUTTONDOWN e WM_LBUTTONUP mensagem em vez de BN_CLICKED

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
    SendMessage(ButtonHandle, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    SendMessage(ButtonHandle, WM_LBUTTONUP, MK_LBUTTON, 0);
}

A abordagem não-C: Use Java ea classe java.awt.Robot para mover o mouse ao redor executar cliques reais (Eu acho que há algo no mundo Windows para isso, também). Problema: Você tem que saber onde o botão é: D

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top