Estou usando um formulário para mostrar notificações (ele aparece na parte inferior direita da tela), mas quando mostro esse formulário, ele rouba o foco do formulário principal. Existe uma maneira de mostrar este formulário de "notificação" sem roubar o foco?
140
form1.Enabled = false
para evitar controles internos da enfoque roubarWS_EX_NOACTIVATE
eWS_EX_TOOLWINDOW
são0x08000000
e0x00000080
respectivamente.Stolen de PInvoke.net 's ShowWindow método:
(Alex Lyman respondeu a isso, estou apenas expandindo-o colando diretamente o código. Alguém com direitos de edição pode copiá-lo por lá e excluí-lo para todo o que me importo;))
fonte
Se você estiver disposto a usar o Win32 P / Invoke , poderá usar o método ShowWindow (o primeiro exemplo de código faz exatamente o que você deseja).
fonte
Isto é o que funcionou para mim. Ele fornece o TopMost, mas sem roubar o foco.
Lembre-se de omitir a configuração do TopMost no designer do Visual Studio ou em outro lugar.
Isso é roubado, errado, emprestado, a partir daqui (clique em Soluções alternativas):
https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost
fonte
Fazer isso parece um hack, mas parece funcionar:
Edit: Note, isso apenas gera um formulário já criado sem roubar o foco.
fonte
O código de exemplo do pinvoke.net nas respostas de Alex Lyman / TheSoftwareJedi tornará a janela uma janela "no topo", o que significa que você não pode colocá-lo atrás das janelas normais depois que ele aparecer. Dada a descrição de Matias sobre o que ele quer usar, pode ser o que ele quer. Mas se você deseja que o usuário possa colocar sua janela atrás de outras janelas depois que você a abriu, basta usar HWND_TOP (0) em vez de HWND_TOPMOST (-1) na amostra.
fonte
No WPF, você pode resolvê-lo assim:
Na janela, coloque estes atributos:
O último atributo é o que você precisa ShowActivated = "False".
fonte
Tenho algo parecido e simplesmente mostro o formulário de notificação e depois
para trazer o foco de volta ao formulário principal.
fonte
Crie e inicie o formulário de notificação em um thread separado e redefina o foco novamente para o formulário principal após a abertura do formulário. Peça ao Formulário de notificação que forneça um evento OnFormOpened que seja acionado a partir do
Form.Shown
evento. Algo assim:Você também pode manter um identificador no objeto NotifcationForm, para que ele possa ser fechado programaticamente pelo formulário principal (
frm.Close()
).Alguns detalhes estão faltando, mas espero que isso o leve à direção certa.
fonte
Você pode considerar que tipo de notificação você gostaria de exibir.
Se for absolutamente crítico informar ao usuário sobre algum evento, usar o Messagebox.Show seria a maneira recomendada, devido à sua natureza para bloquear outros eventos na janela principal, até que o usuário o confirme. Esteja ciente da cegueira pop-up, no entanto.
Se for menos que crítico, convém usar uma maneira alternativa de exibir notificações, como uma barra de ferramentas na parte inferior da janela. Você escreveu que exibe notificações no canto inferior direito da tela - a maneira padrão de fazer isso seria usar uma dica de balão com a combinação de um ícone na bandeja do sistema .
fonte
Isso funciona bem.
Consulte: OpenIcon - MSDN e SetForegroundWindow - MSDN
fonte
Você também pode lidar com isso apenas pela lógica, embora eu deva admitir que as sugestões acima, onde você acaba com um método BringToFront sem realmente roubar o foco, são as mais elegantes.
De qualquer forma, eu me deparei com isso e o resolvi usando uma propriedade DateTime para não permitir mais chamadas BringToFront se as chamadas já tivessem sido feitas recentemente.
Suponha uma classe principal, 'Core', que lida com, por exemplo, três formulários, 'Form1, 2 e 3'. Cada formulário precisa de uma propriedade DateTime e de um evento Activate que chame o Core para trazer janelas para a frente:
E, em seguida, crie o trabalho na Classe Principal:
Em uma nota lateral, se você deseja restaurar uma janela minimizada para seu estado original (não maximizado), use:
Novamente, eu sei que essa é apenas uma solução de patch na falta de um BringToFrontWithoutFocus. É uma sugestão para evitar o arquivo DLL.
fonte
Não sei se isso é considerado como necro-postagem, mas foi o que fiz porque não consegui fazê-lo funcionar com os métodos "ShowWindow" e "SetWindowPos" do user32. E não, substituir "ShowWithoutActivation" não funciona nesse caso, pois a nova janela deve estar sempre em cima. Enfim, criei um método auxiliar que assume um formulário como parâmetro; quando chamado, mostra o formulário, o traz para a frente e o torna TopMost sem roubar o foco da janela atual (aparentemente, mas o usuário não notará).
fonte
Eu sei que pode parecer estúpido, mas isso funcionou:
fonte
Eu precisava fazer isso com minha janela TopMost. Eu implementei o método PInvoke acima, mas descobri que meu evento Load não estava sendo chamado como Talha acima. Eu finalmente consegui. Talvez isso ajude alguém. Aqui está a minha solução:
fonte
Quando você cria um novo formulário usando
rouba o foco porque seu código não pode continuar em execução no formulário principal até que este seja fechado.
A exceção é usar o threading para criar um novo formulário e, em seguida, Form.Show (). Porém, verifique se o thread está visível globalmente, porque se você o declarar em uma função, assim que sua função terminar, seu thread terminará e o formulário desaparecerá.
fonte
Descobri-lo:
window.WindowState = WindowState.Minimized;
.fonte