Implementação de Tela Cheia com MFC para Aplicações DirectX

Ao integrar DirectX com aplicações MFC, enfrentei desafios na configuração do modo tela cheia durante a criação do dispositivo gráfico. Mesmo ajustando o parâmetro D3DPRESENT_PARAMETERS.Windowed, a chamada para CreateDevice falhava consistentemente. Após análise, desenvolvi uma solução puramente baseada em MFC que manipula as coordenadas da janela para cobrir toda a área da tela.

A classe TelaCheiaMFC calcula dinamicamente as dimensões necessárias considerando a relação entre a jenela principal e a área de visualização:

#pragma once
#include <cassert>

class TelaCheiaMFC {
public:
    TelaCheiaMFC();

    void ConfigurarJanelas(CWnd* janelaQuadro, CWnd* janelaVisualizacao);
    bool EstaConfigurado() const;
    
    void AtivarTelaCheia();
    void RestaurarJanela();
    bool EmModoTelaCheia() const;
    CSize ObterTamanhoTelaCheia() const;

private:
    CRect CalcularRetanguloTelaCheia(const CRect& quadro, 
                                    const CRect& visualizacao, 
                                    const CRect& tela) const;
    CRect CalcularRetanguloTelaCheia(CWnd* janelaQuadro, CWnd* janelaVisualizacao) const;
    void AjustarPosicaoJanelas(const CRect& novaPosicao);

private:
    CRect m_retanguloOriginal;
    CWnd* m_janelaQuadro;
    CWnd* m_janelaVisualizacao;
    bool m_ativoTelaCheia;
};

A implementação manipula as coordenadas de tela através de cálculos precisos de deslocamento:

TelaCheiaMFC::TelaCheiaMFC() 
    : m_retanguloOriginal(0, 0, 0, 0), 
      m_janelaQuadro(nullptr),
      m_janelaVisualizacao(nullptr),
      m_ativoTelaCheia(false) {}

void TelaCheiaMFC::ConfigurarJanelas(CWnd* janelaQuadro, CWnd* janelaVisualizacao) {
    assert(janelaQuadro && janelaVisualizacao);
    m_janelaQuadro = janelaQuadro;
    m_janelaVisualizacao = janelaVisualizacao;
}

bool TelaCheiaMFC::EstaConfigurado() const {
    return m_janelaQuadro && m_janelaVisualizacao;
}

CRect TelaCheiaMFC::CalcularRetanguloTelaCheia(
    const CRect& quadro, 
    const CRect& visualizacao, 
    const CRect& tela) const 
{
    const int deslocX = quadro.left - visualizacao.left;
    const int deslocY = quadro.top - visualizacao.top;
    
    return CRect(
        tela.left + deslocX,
        tela.top + deslocY,
        tela.right + (quadro.right - visualizacao.right),
        tela.bottom + (quadro.bottom - visualizacao.bottom)
    );
}

void TelaCheiaMFC::AtivarTelaCheia() {
    if (!m_ativoTelaCheia) {
        m_ativoTelaCheia = true;
        m_janelaQuadro->GetWindowRect(m_retanguloOriginal);
        AjustarPosicaoJanelas(CalcularRetanguloTelaCheia(m_janelaQuadro, m_janelaVisualizacao));
    }
}

void TelaCheiaMFC::AjustarPosicaoJanelas(const CRect& posicao) {
    m_janelaQuadro->MoveWindow(posicao);
    const bool acimaOutras = m_ativoTelaCheia;
    m_janelaQuadro->SetWindowPos(
        acimaOutras ? &CWnd::wndTopMost : &CWnd::wndNoTopMost,
        posicao.left, posicao.top, 0, 0,
        SWP_NOSIZE | SWP_NOACTIVATE
    );
}

Para integrar em uma aplicação MFC:

  1. Adicione a instância da classe no CMainFrame:
private:
    TelaCheiaMFC m_controleTela;
  1. Inicialize durante a criação da janela:
BOOL CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
    m_controleTela.ConfigurarJanelas(this, &m_wndView);
    return 0;
}
  1. Implemente o tratamento de limites de janela:
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* info) {
    if (m_controleTela.EstaConfigurado()) {
        const CSize tamanho = m_controleTela.ObterTamanhoTelaCheia();
        info->ptMaxSize = tamanho;
        info->ptMaxTrackSize = tamanho;
    } else {
        CFrameWnd::OnGetMinMaxInfo(info);
    }
}
  1. Crie um comando para alternar modos:
void CMainFrame::OnAlternarTelaCheia() {
    if (m_controleTela.EmModoTelaCheia()) {
        m_controleTela.RestaurarJanela();
    } else {
        m_controleTela.AtivarTelaCheia();
    }
}

A solução manipula corretamente as coordenadas de tela mesmo em múltiplos monitores, utilizando GetSystemMetrics para obter dimensões reais da área de trabalho. O mecanismo de posicionamento garante que a janela principal ocupe exatamente a área necessária para cobrir totalmente a tela sem sobreposições indesejadas.

Tags: mfc DirectX C++ JanelasWindows

Publicado em 8-29 17:39