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:
- Adicione a instância da classe no
CMainFrame:
private:
TelaCheiaMFC m_controleTela;
- 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;
}
- 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);
}
}
- 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.