DXGI利用Hook窗口消息处理过程,监听ALT+ENTER按键,来实现自动的在窗口模式和全屏模式切换。这一切在基于SDK的Windows程序看不出什么问题。但是对于MFC的基于对话框的程序就会出现问题。
首先窗口会一闪,进入全屏模式,然后一秒钟左右又重新返回到窗口模式,通过反复实验对话框的各个消息的处理方法,都不能解决这个问题。后来发现问题出在程序的消息循环上。一般SDK的窗口消息循环这样写:
while ( WM_QUIT != msg.message )
{
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
而MFC的消息循环是这样的:
for ( ; ; )
{
//
// ...
//
do
{
//
// ...
//
// pump message, but quit on WM_QUIT
if ( !AfxPumpMessage() )
{
AfxPostQuitMessage( 0 );
return -1;
}
//
// ...
//
} while ( ::PeekMessage( pMsg, NULL, NULL, NULL, PM_NOREMOVE ) );
}
而AfxInternalPumpMessage的定义如下
BOOL AFXAPI AfxInternalPumpMessage()
{
//
// ...
// ...
if ( !::GetMessage( & ( pState->m_msgCur ), NULL, NULL, NULL ) )
{
// ...
return FALSE;
}
// process this message
if ( pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage( &( pState->m_msgCur ) ) )
{
::TranslateMessage( & ( pState->m_msgCur ) );
::DispatchMessage( & ( pState->m_msgCur ) );
}
return TRUE;
}
因此,猜想问题的原因出在DXGI在PeekMessage监听到ALT+ENTER消息后进行了一次窗口和全屏模式的转换,然后到了GetMessage又监听到了ALT+ENTER消息,又进行了一次模式转换,这样就进行了两次转换,最后模式和原先的一样!!!