Modo de tela cheia no monitor A na configuração de monitor duplo se quebra ao mover as janelas do monitor B para ele

9

Estou criando um aplicativo de desktop Win7 / 8/10 x64 Direct3D11 que permite ao usuário alternar entre o modo de janela e tela cheia (modo de tela inteira dedicada, não apenas uma janela maximizada *). Em uma configuração de monitor duplo, estou encontrando alguns problemas.

O comutador é executado manualmente usando IDXGISwapChain::SetFullscreenState e funciona como esperado: O monitor que abriga a maior parte da área da janela (vamos chamá-lo de monitor A) entra em modo de tela cheia dedicada enquanto deixa o outro (monitor B) como foi, permitindo que o usuário interaja normalmente com janelas em B, bem como o aplicativo de tela cheia em A.

No entanto, se uma janela em B for arrastada ou redimensionada para que ela passe para A, o estado de tela cheia do aplicativo será perturbado: às vezes, ela volta ao modo de janela (deixando a variável de rastreamento interna do aplicativo fora de sincronia), às vezes ele fica em um modo quase tela cheia, onde aparentemente recusa interrupções de modo adicionais, e assim por diante. O mesmo acontece quando uma janela que se sobrepõe a A e B antes de o aplicativo entrar no modo de tela cheia recebe o foco.

Existe alguma maneira de evitar isso?

Eu gostaria que o SO honrasse o modo de tela cheia dedicada do meu aplicativo e o mantivesse em um estado robusto, mesmo se outras janelas fossem arrastadas para esse monitor. Eu quero que o comportamento seja semelhante a ter uma "janela sem borda maximizada sempre em cima", ou seja, ter outras janelas apenas "desaparecendo por trás dela" e não afetar o estado da minha janela de tela cheia. / p>

Eu tentei algumas soluções, como responder a WM_KILLFOCUS e temporariamente mudar meu aplicativo para uma "janela sem borda maximixed" até receber WM_SETFOCUS novamente, mas a mensagem WM_KILLFOCUS tem um atraso durante o qual há tempo para um usuário para arrastar outra janela para a área que ainda está no modo de tela cheia, colocando-me de volta ao quadrado um.

* O motivo pelo qual eu quero esse recurso, em vez de simplesmente usar uma janela sem borda maximizada (que também é um modo suportado, btw), tem a ver com menor latência de movimento do mouse para renderização, controle vsync (ON / OFF) etc. todos eles - em suma - são importantes para a natureza desta aplicação (que não é um jogo).

    
por d7samurai 16.08.2015 в 16:51
fonte

1 resposta

2

Embora não seja ideal ( ideal seria que houvesse uma maneira de ter o próprio SO lidando com isso corretamente), eu encontrei uma solução razoável que eu suponho que eu possa viver por agora. É uma variação do conceito mencionado na pergunta ("..como responder a WM_KILLFOCUS e temporariamente mudar meu aplicativo para uma janela sem borda maximixed"), mas sem o problema de atraso incapacitante:

Sempre que o aplicativo entra no modo dedicado de tela cheia, ele também captura o mouse com uma chamada para SetCapture . Isso não afetará a capacidade do usuário de interagir com outras janelas no monitor B, mas irá garantir que qualquer interação de ativação / desativação - como um clique do mouse em outro aplicativo - envie um WM_LBUTTONDOWN para minha aplicação antes perde o foco. É importante que isso aconteça imediatamente , diferentemente da mensagem WM_KILLFOCUS que possui latência significativa.

Quando uma mensagem WM_LBUTTONDOWN é recebida (em tela cheia), o aplicativo verifica se o clique ocorreu fora da área da tela. Se assim for, significa que está prestes a perder o foco e, assim, se expor a todas as complicações trazidas na questão original. Assim, ele sai temporariamente do modo de tela cheia dedicada e "o substitui" por uma janela maximizada sem borda (visualmente idêntica). Quando o aplicativo recupera o foco, volta para tela inteira dedicada.

Isso funciona bem, já que você não se importa com a capacidade de resposta do aplicativo quando não está interagindo com ele de qualquer maneira. O maior inconveniente aqui é a troca de modo que ocorre nessas transferências de foco, mas dadas as alternativas, acho que é um preço aceitável a pagar pelo que eu quero realizar (mas de qualquer forma - eu seria muito < interessado em uma melhor solução).

Editar 1: Vale a pena notar que, uma vez que existem outras formas de uma aplicação perder a concentração do que através dos cliques do rato, WM_KILLFOCUS é também tratado.

Editar 2: Recentemente, percebi que lidar com a mensagem WM_BUTTONDOWN é redundante. SetCapture sozinho garantirá que a mensagem WM_KILLFOCUS seja recebida com rapidez suficiente.

    
por d7samurai 17.08.2015 / 21:24
fonte