📄 d3dsaver.cpp
字号:
// Desc: This function forwards all window messages to SaverProc, which has
// access to the "this" pointer.
//-----------------------------------------------------------------------------
LRESULT CALLBACK CD3DScreensaver::SaverProcStub( HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
return s_pD3DScreensaver->SaverProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: SaverProc()
// Desc: Handle window messages for main screensaver windows (one per screen).
//-----------------------------------------------------------------------------
LRESULT CD3DScreensaver::SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
case WM_USER:
// All initialization messages have gone through. Allow
// 500ms of idle time, then proceed with initialization.
SetTimer( hWnd, 1, 500, NULL );
break;
case WM_TIMER:
// Initial idle time is done, proceed with initialization.
m_bWaitForInputIdle = FALSE;
KillTimer( hWnd, 1 );
break;
case WM_DESTROY:
ShutdownSaver();
break;
case WM_SETCURSOR:
if ( m_SaverMode == sm_full && !m_bCheckingSaverPassword )
{
// Hide cursor
SetCursor( NULL );
return TRUE;
}
break;
case WM_PAINT:
{
// Show error message, if there is one
PAINTSTRUCT ps;
BeginPaint( hWnd, &ps );
// In preview mode, just fill
// the preview window with black.
if( !m_bErrorMode && m_SaverMode == sm_preview )
{
RECT rc;
GetClientRect(hWnd,&rc);
FillRect(ps.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH) );
}
else
{
DoPaint( hWnd, ps.hdc );
}
EndPaint( hWnd, &ps );
return 0;
}
case WM_ERASEBKGND:
// Erase background if checking password or if window is not
// assigned to a render unit
if( !m_bCheckingSaverPassword )
{
RenderUnit* pRenderUnit;
D3DAdapterInfo* pD3DAdapterInfo;
for( DWORD iRenderUnit = 0; iRenderUnit < m_dwNumRenderUnits; iRenderUnit++ )
{
pRenderUnit = &m_RenderUnits[iRenderUnit];
pD3DAdapterInfo = m_Adapters[pRenderUnit->iAdapter];
if( pD3DAdapterInfo->hWndDevice == hWnd )
return TRUE; // don't erase this window
}
}
break;
case WM_MOUSEMOVE:
if( m_SaverMode != sm_test )
{
static INT xPrev = -1;
static INT yPrev = -1;
INT xCur = GET_X_LPARAM(lParam);
INT yCur = GET_Y_LPARAM(lParam);
if( xCur != xPrev || yCur != yPrev )
{
xPrev = xCur;
yPrev = yCur;
m_dwSaverMouseMoveCount++;
if ( m_dwSaverMouseMoveCount > 5 )
InterruptSaver();
}
}
break;
case WM_KEYDOWN:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
if( m_SaverMode != sm_test )
InterruptSaver();
break;
case WM_ACTIVATEAPP:
if( wParam == FALSE && m_SaverMode != sm_test )
InterruptSaver();
break;
case WM_POWERBROADCAST:
if( wParam == PBT_APMSUSPEND && m_VerifySaverPassword == NULL )
InterruptSaver();
break;
case WM_SYSCOMMAND:
if ( m_SaverMode == sm_full )
{
switch ( wParam )
{
case SC_NEXTWINDOW:
case SC_PREVWINDOW:
case SC_SCREENSAVE:
case SC_CLOSE:
return FALSE;
};
}
break;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: InterruptSaver()
// Desc: A message was received (mouse move, keydown, etc.) that may mean
// the screen saver should show the password dialog and/or shut down.
//-----------------------------------------------------------------------------
VOID CD3DScreensaver::InterruptSaver()
{
HRESULT hr;
DWORD iRenderUnit;
RenderUnit* pRenderUnit;
BOOL bPasswordOkay = FALSE;
if( m_SaverMode == sm_test ||
m_SaverMode == sm_full && !m_bCheckingSaverPassword )
{
if( m_bIs9x && m_SaverMode == sm_full )
{
// If no VerifyPassword function, then no password is set
// or we're not on 9x.
if ( m_VerifySaverPassword != NULL )
{
// Shut down all D3D devices so we can show a Windows dialog
for( iRenderUnit = 0; iRenderUnit < m_dwNumRenderUnits; iRenderUnit++ )
{
pRenderUnit = &m_RenderUnits[iRenderUnit];
SwitchToRenderUnit(iRenderUnit);
if( pRenderUnit->bDeviceObjectsRestored )
{
InvalidateDeviceObjects();
pRenderUnit->bDeviceObjectsRestored = FALSE;
}
if( pRenderUnit->bDeviceObjectsInited )
{
DeleteDeviceObjects();
pRenderUnit->bDeviceObjectsInited = FALSE;
}
SAFE_RELEASE(pRenderUnit->pd3dDevice);
}
// Make sure all adapter windows cover the whole screen,
// even after deleting D3D devices (which may have caused
// mode changes)
D3DAdapterInfo* pD3DAdapterInfo;
for( DWORD iAdapter = 0; iAdapter < m_dwNumAdapters; iAdapter++ )
{
pD3DAdapterInfo = m_Adapters[iAdapter];
ShowWindow( pD3DAdapterInfo->hWndDevice, SW_RESTORE );
ShowWindow( pD3DAdapterInfo->hWndDevice, SW_MAXIMIZE );
}
m_bCheckingSaverPassword = TRUE;
bPasswordOkay = m_VerifySaverPassword( m_hWnd );
m_bCheckingSaverPassword = FALSE;
if ( bPasswordOkay )
{
// D3D devices are all torn down, so it's safe
// to discard all render units now (so we don't
// try to clean them up again later).
m_dwNumRenderUnits = 0;
}
else
{
// Back to screen saving...
SetCursor( NULL );
m_dwSaverMouseMoveCount = 0;
// Recreate all D3D devices
for( iRenderUnit = 0; iRenderUnit < m_dwNumRenderUnits; iRenderUnit++ )
{
pRenderUnit = &m_RenderUnits[iRenderUnit];
hr = m_pD3D->CreateDevice(pRenderUnit->iAdapter,
pRenderUnit->DeviceType, m_hWnd,
pRenderUnit->dwBehavior, &pRenderUnit->d3dpp,
&pRenderUnit->pd3dDevice );
if( FAILED( hr ) )
{
m_bErrorMode = TRUE;
m_hrError = D3DAPPERR_CREATEDEVICEFAILED;
}
else
{
SwitchToRenderUnit(iRenderUnit);
if( FAILED(hr = InitDeviceObjects() ) )
{
m_bErrorMode = TRUE;
m_hrError = D3DAPPERR_INITDEVICEOBJECTSFAILED;
}
else
{
pRenderUnit->bDeviceObjectsInited = TRUE;
if( FAILED(hr = RestoreDeviceObjects() ) )
{
m_bErrorMode = TRUE;
m_hrError = D3DAPPERR_INITDEVICEOBJECTSFAILED;
}
else
{
pRenderUnit->bDeviceObjectsRestored = TRUE;
}
}
}
}
return;
}
}
}
ShutdownSaver();
}
}
//-----------------------------------------------------------------------------
// Name: Initialize3DEnvironment()
// Desc: Set up D3D device(s)
//-----------------------------------------------------------------------------
HRESULT CD3DScreensaver::Initialize3DEnvironment()
{
HRESULT hr;
DWORD iAdapter;
DWORD iMonitor;
D3DAdapterInfo* pD3DAdapterInfo;
MonitorInfo* pMonitorInfo;
DWORD iRenderUnit;
RenderUnit* pRenderUnit;
MONITORINFO monitorInfo;
if ( m_SaverMode == sm_full )
{
// Fullscreen mode. Create a RenderUnit for each monitor (unless
// the user wants it black)
m_bWindowed = FALSE;
if( m_bOneScreenOnly )
{
// Set things up to only create a RenderUnit on the best device
for( iAdapter = 0; iAdapter < m_dwNumAdapters; iAdapter++ )
{
pD3DAdapterInfo = m_Adapters[iAdapter];
pD3DAdapterInfo->bLeaveBlack = TRUE;
}
GetBestAdapter( &iAdapter );
if( iAdapter == NO_ADAPTER )
{
m_bErrorMode = TRUE;
m_hrError = D3DAPPERR_NOCOMPATIBLEDEVICES;
}
else
{
pD3DAdapterInfo = m_Adapters[iAdapter];
pD3DAdapterInfo->bLeaveBlack = FALSE;
}
}
for( iMonitor = 0; iMonitor < m_dwNumMonitors; iMonitor++ )
{
pMonitorInfo = &m_Monitors[iMonitor];
iAdapter = pMonitorInfo->iAdapter;
if( iAdapter == NO_ADAPTER )
continue;
pD3DAdapterInfo = m_Adapters[iAdapter];
if( pD3DAdapterInfo->bDisableHW && !pD3DAdapterInfo->bHasAppCompatSW &&
!m_bAllowRef )
{
pD3DAdapterInfo->bLeaveBlack = TRUE;
}
if( !pD3DAdapterInfo->bLeaveBlack && pD3DAdapterInfo->dwNumDevices > 0 )
{
pD3DAdapterInfo->hWndDevice = pMonitorInfo->hWnd;
pRenderUnit = &m_RenderUnits[m_dwNumRenderUnits++];
ZeroMemory( pRenderUnit, sizeof(RenderUnit) );
pRenderUnit->iAdapter = iAdapter;
if( FAILED( hr = CreateFullscreenRenderUnit( pRenderUnit ) ) )
{
// skip this render unit and leave screen blank
m_dwNumRenderUnits--;
m_bErrorMode = TRUE;
m_hrError = D3DAPPERR_CREATEDEVICEFAILED;
}
}
}
}
else
{
// Windowed mode, for test mode or preview window. Just need one RenderUnit.
m_bWindowed = TRUE;
GetClientRect( m_hWnd, &m_rcRenderTotal );
GetClientRect( m_hWnd, &m_rcRenderCurDevice );
GetBestAdapter( &iAdapter );
if( iAdapter == NO_ADAPTER )
{
m_bErrorMode = TRUE;
m_hrError = D3DAPPERR_CREATEDEVICEFAILED;
}
else
{
pD3DAdapterInfo = m_Adapters[iAdapter];
pD3DAdapterInfo->hWndDevice = m_hWnd;
}
if( !m_bErrorMode )
{
pRenderUnit = &m_RenderUnits[m_dwNumRenderUnits++];
ZeroMemory( pRenderUnit, sizeof(RenderUnit) );
pRenderUnit->iAdapter = iAdapter;
if( FAILED( hr = CreateWindowedRenderUnit( pRenderUnit ) ) )
{
m_dwNumRenderUnits--;
m_bErrorMode = TRUE;
if( m_SaverMode == sm_preview )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -