Existem soluções para impedir que os aplicativos roubem o foco da janela ativa?
Isso é especialmente irritante quando estou iniciando um aplicativo, mude para fazer outra coisa e o novo aplicativo começa a receber meia frase do texto.
windows
window-focus
svandragt
fonte
fonte
This is especially annoying when I'm starting an application, switch to do something else and the new application starts receiving half a sentence of text.
É ainda mais irritante quando uma caixa de diálogo é exibida e você acidentalmente a dispensa sem nem mesmo ver a mensagem porque pressionouSpace
ouEnter
digitou uma frase.Respostas:
Isso não é possível sem a manipulação extensiva de componentes internos do Windows e você precisa superá-lo.
Há momentos no uso diário do computador em que é realmente importante que você execute uma ação antes que o sistema operacional permita outra. Para fazer isso, ele precisa bloquear seu foco em determinadas janelas. No Windows, o controle sobre esse comportamento é amplamente deixado para os desenvolvedores dos programas individuais que você usa.
Nem todo desenvolvedor toma as decisões corretas quando se trata deste tópico.
Sei que isso é muito frustrante e irritante, mas você não pode comer o seu bolo e também comê-lo. Provavelmente, existem muitos casos ao longo da sua vida diária em que você está perfeitamente bem com o foco sendo movido para um determinado elemento da interface do usuário ou um aplicativo solicitando que o foco permaneça bloqueado. Mas a maioria das aplicações é um pouco igual quando se trata de decidir quem é o líder agora e o sistema nunca pode ser perfeito.
Há algum tempo, fiz uma extensa pesquisa sobre a solução desse problema de uma vez por todas (e falhei). O resultado da minha pesquisa pode ser encontrado na página do projeto de aborrecimento .
O projeto também inclui um aplicativo que tenta recuperar o foco repetidamente chamando:
Como podemos ver neste trecho, minha pesquisa também foi focada em outros aspectos do comportamento da interface do usuário que eu não gosto.
A maneira como tentei resolver isso foi carregar uma DLL em cada novo processo e ligar as chamadas da API que fazem com que outras janelas sejam ativadas.
A última parte é a mais fácil, graças às incríveis bibliotecas de conexão de API existentes. Eu usei a grande biblioteca mhook :
Dos meus testes naquela época, isso funcionou muito bem. Exceto pela parte de carregar a DLL em cada novo processo. Como se pode imaginar, isso não é nada demais. Eu usei a abordagem AppInit_DLLs naquela época (o que simplesmente não é suficiente).
Basicamente, isso funciona muito bem. Mas nunca encontrei tempo para escrever algo que injete corretamente minha DLL em novos processos. E o tempo investido nisso obscurece amplamente o aborrecimento que o foco roubado me causa.
Além do problema de injeção de DLL, também há um método de roubo de foco que não cobri na implementação no Google Code. Um colega de trabalho realmente fez algumas pesquisas adicionais e cobriu esse método. O problema foi discutido no SO: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus
fonte
jne
?No Windows 7, a
ForegroundLockTimeout
entrada do registro não está mais marcada, você pode verificar isso com o Process Monitor. De fato, no Windows 7, eles não permitem que você altere a janela do primeiro plano. Vá e leia sobre seus detalhes , ele existe desde o Windows 2000.No entanto, a documentação é péssima e eles se perseguem e encontram maneiras de contornar isso .
Portanto, há algo de buggy acontecendo
SetForegroundWindow
ou funções similares da API ...A única maneira de realmente fazer isso corretamente é criar um pequeno aplicativo que periodicamente chama
LockSetForegroundWindow
, praticamente desativando todas as chamadas para nossa função de API de buggy.Se isso não for suficiente (outra chamada de API de buggy?), Você pode ir ainda mais longe e fazer algum monitoramento da API para ver o que está acontecendo. Depois, basta conectar as chamadas da API em todos os processos e depois eliminar as chamadas que atrapalharem. primeiro plano. No entanto, ironicamente, isso é desencorajado pela Microsoft ...
fonte
Há uma opção no TweakUI que faz isso. Isso evita a maioria dos truques usuais que desenvolvedores de software duvidosos empregam para forçar o foco em seu aplicativo.
É uma guerra de armas em andamento, portanto, não sei se funciona para tudo.
Atualização : De acordo com EndangeredMassa , o TweakUI não funciona no Windows 7.
fonte
Acredito que possa haver alguma confusão, pois existem duas maneiras de "roubar o foco": (1) uma janela chegando ao primeiro plano e (2) a janela recebendo teclas.
O problema mencionado aqui é provavelmente o segundo, em que uma janela reivindica o foco, trazendo-se para o primeiro plano - sem a solicitação ou permissão do usuário.
A discussão deve ser dividida aqui entre XP e 7.
Windows XP
No XP, existe um hack do registro que faz o XP funcionar da mesma maneira que o Windows 7, impedindo que os aplicativos roubem o foco:
HKEY_CURRENT_USER\Control Panel\Desktop
.ForegroundLockTimeout
e defina seu valor em hexadecimal para30d40
.Windows 7
(A discussão abaixo se aplica principalmente ao XP também.)
Por favor, entenda que não há como o Windows impedir totalmente os aplicativos de roubar o foco e permanecer funcional. Por exemplo, se durante uma cópia de arquivo seu antivírus detectou uma possível ameaça e gostaria de abrir uma janela solicitando a ação a ser tomada, se essa janela estiver bloqueada, você nunca entenderá por que a cópia nunca termina.
No Windows 7, existe apenas uma modificação possível para o comportamento do Windows, que é usar os hacks de registro do MS-Windows focus-segue-mouse , nos quais o foco e / ou a ativação vão sempre para as janelas sob o cursor. Um atraso pode ser adicionado para evitar que aplicativos apareçam em toda a área de trabalho.
Consulte este artigo: Windows 7 - Passar o mouse ativa a janela - Ativar .
Caso contrário, é preciso detectar e neutralizar o programa culpado: se esse é sempre o mesmo aplicativo que está recebendo o foco, esse aplicativo é programado para ter o foco e impedir que isso possa ser feito, desativando a inicialização do computador ou use alguma configuração fornecida por esse aplicativo para evitar esse comportamento.
Você pode usar o script VBS incluído no Código VB, que identifica quem está roubando o foco , que o autor usou para identificar o culpado como um atualizador de "call home" para um software de impressora.
Uma medida desesperada quando tudo mais falha, e se você identificou esse aplicativo mal programado, é minimizá-lo e torcer para que ele não se destaque. Uma forma mais forte de minimização é a bandeja, usando um dos produtos gratuitos listados no Melhor Minimizador de Aplicativo Gratuito .
A última idéia na ordem do desespero é fraturar sua área de trabalho virtualmente usando um produto como Desktops ou Dexpot e fazer seu trabalho em outra área de trabalho que não o padrão.
[EDITAR]
Como a Microsoft retirou a Galeria de Arquivos, eis o código VB acima reproduzido:
fonte
Alt-Tab
funciona; forçando apenas o diálogo para a frente.Alt+Tab
lista e, na minha experiência, uma janela que tem uma caixa de diálogo modal aberta nem sempre (nunca?) mostra a caixa de diálogo modal comAlt+Tab
, especialmente se a caixa de diálogo nunca teve uma alteração para obter foco.:-|
Ghacks tem uma solução possível:
fonte
Inspirado pela resposta de Der Hochstapler , decidi escrever um injetor de DLL, que funciona com processos de 64 e 32 bits e evita o roubo de foco no Windows 7 ou mais recente: https://blade.sk/stay-focused/
A maneira como funciona é que ele observa as janelas criadas recentemente (usando
SetWinEventHook
) e injeta DLL muito semelhante à do Der Hochstapler no processo da janela, se ainda não estiver presente. Ele descarrega as DLLs e restaura a funcionalidade original na saída.Dos meus testes, ele funciona muito bem até agora. No entanto, o problema parece ser mais profundo do que apenas aplicativos chamando
SetForegroundWindow
. Por exemplo, quando uma nova janela é criada, ela é automaticamente colocada em primeiro plano, o que também interfere com o usuário digitando em outra janela.Para lidar com outros métodos de roubo de foco, são necessários mais testes e eu gostaria de receber qualquer feedback sobre os cenários em que isso está acontecendo.
fonte
Eu descobri como parar a Barra de Tarefas de exibir uma janela de destino recém-ativada depois que você programaticamente ativa, maximiza e concentra a janela principal desse processo em outro processo. Primeiro de tudo, há muitas restrições sobre se essa operação será permitida.
Portanto, se o processo de controle estiver em primeiro plano, ele poderá permitir temporariamente que outro processo roube totalmente o primeiro plano, chamando AllowSetForegroundWindow com o ID do processo de destino. Depois disso, o processo de destino pode chamar o próprio SetForegroundWindow , usando seu próprio identificador de janela, e funcionará.
Obviamente, isso requer alguma coordenação entre os dois processos, mas funciona, e se você estiver fazendo isso para implementar um aplicativo de instância única que redirecione todas as ativações do Explorer-click para a instância existente do aplicativo, você já tenha um (por exemplo) pipe nomeado para coordenar as coisas de qualquer maneira.
fonte