Just to be complete ...
Under WinXP, another action which can cause a MAV, which was touched upon in this thread
http://www.blitzbasic.com/Community/posts.php?topic=67841 , is the pressing of WinKey+L (Log-Off). Pressing this key combination causes a MAV within RenderWorld when the application regains focus.
Interestingly, this is not caught by a check for lost DirectDraw surfaces. A complete dump of all surface information just before the call to RenderWorld shows no lost surfaces. It seems the log-off is causing some other part of B3D to generate a MAV.
The work around I came up with was to detect when WinKey+L had been pressed and reset B3D (just like when a lost directdraw surface is detected). The problem was detecting when WinKey+L had been pressed, as there is no specific windows message generated and it appears to the application that it is simply losing focus.
What I noticed after viewing the messages received (Winspector is great!), was if just WinKey was pressed (which brings up the Start Menu) a WM_KEYDOWN/WM_KEYUP pair for WinKey was being generated before the app received WM_ACTIVEATEAPP indicating focus had been lost and the lParam != 0x0 (lParam indicates the handle of the window receiving focus). But, if WinKey+L was pressed, the app received ONLY a WM_KEYDOWN message for WinKey before it received the WM_ACTIVATEAPP message: No WM_KEYUP message for WinKey was being generated, and, in addition lParam == 0x0.
So, I simply check for WinKey WM_KEYDOWN/KEYUP messages an set/clear a flag, then whenever my app is about to lose focus, the flag is checked. If the flag is set, it is very likely the user is logging out in which case another flag is set indicating a possible log-out. Then just before calls to RenderWorld, the possible-log-out-flag is checked and B3D reset if needed.
Below is the relevant code (it can be added to the DirectDraw surface check code above):
; Blitz3D =======================================================
app_init%(hwnd%):"_app_init@4"
app_uninit():"_app_uninit@0"
app_possibleLogOut%():"_app_possibleLogOut@0"
app_clearPossibleLogOut():"_app_clearPossibleLogOut@0"
// C++ =======================================================
//------------------------------------------------------------
static BOOL _winKeyIsDown;
static BOOL _possibleLogOut;
//------------------------------------------------------------
// Intercepts & examines window messages recevied by Blitz3D
LRESULT CALLBACK _AppBase_WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_KEYDOWN: _winKeyIsDown = ((wParam == VK_LWIN) || (wParam == VK_RWIN)); break;
case WM_KEYUP : _winKeyIsDown = !((wParam == VK_LWIN) || (wParam == VK_RWIN)); break;
case WM_ACTIVATEAPP:
{
if( (wParam == FALSE) && (lParam == 0x0) ) _possibleLogOut = _winKeyIsDown;
_winKeyIsDown = FALSE;
}
break;
}
return CallWindowProc( _b3d_windowProc, hwnd, uMsg, wParam, lParam );
}
//------------------------------------------------------------
// Should be called as soon as possible within B3D app.
// Usage: if app_init( SystemProperty( "AppHWND" ) ) then ...
BBDECL BOOL BBCALL app_init( HWND hwnd )
{
_b3d_hwnd = hwnd;
_b3d_windowProc = (WNDPROC)SetWindowLong( _b3d_hwnd, GWL_WNDPROC, (LONG)_AppBase_WindowProc );
return TRUE;
}
//------------------------------------------------------------
// Should be called just before B3D app ends.
// Usage: app_uninit()
BBDECL void BBCALL app_uninit()
{
SetWindowLong( _b3d_hwnd, GWL_WNDPROC, (LONG)_b3d_windowProc );
_b3d_hwnd = 0;
}
//-----------------------------------------------------------
// Should be called just before calls to RenderWorld().
// Usage:
// if app_possibleLogOut() then
// app_clearPossibleLogOut()
// /* reset B3D */
// else
// RenderWorld: Flip
// EndIf
BBDECL BOOL BBCALL app_possibleLogOut() { return _possibleLogOut; }
//-----------------------------------------------------------
// Should be called after app_possibleLogOut() has returned TRUE
// Usage: see above
BBDECL void BBCALL app_clearPossibleLogOut() { _possibleLogOut = FALSE; }
The above code dropped MAVs on log-out from 100% to almost 0%: Yes, there is still the *VERY* rare MAV on log-out. I'm thinking it's due to the log-out occuring after the log-out check but before RenderWorld has completed.
NOTE: Under Vista, the WinKey+L combination is caught by the check for lost DirectDraw surfaces.
HTH,
David