B3D_AppBase.dll - Helps Prevent MAV

Blitz3D Forums/Blitz3D Programming/B3D_AppBase.dll - Helps Prevent MAV

DGuy(Posted 2007) [#1]
It was requested that a DLL I had written to help prevent MAVs under Blitz3D be made available as a compiled DLL. To that end, I have emailed the compiled DLL w/ source code to a few Blitz3D community members who offered to host the files on their sites. When I get some download URLs, I'll post them here. In the mean while, below is the complete source code of the DLL.

This code can be used for whatever purpose.

If there are any question or comments, feel free to ask.

Hope this proves helpful,
David

/*
  B3D_AppBase.cpp
    - Blitz3D Helper DLL

  For help preventing Memory Access Violations in Blitz3D,
  particularly when running in windowed mode.
  Tested under both WinXP and Vista.

  To setup, place both the DLL and the *.decls file into the Blitz3D
  '\userlibs' dir.

  For usage, see comments within the code.

  For 'B3D_AppBase.decls' file:
  .lib "B3D_AppBase.dll"
  app_init%(hwnd%):"_app_init@4"
  app_uninit():"_app_uninit@0"
  app_DDHook%(pDD7%):"_app_DDHook@4"
  app_DDUnHook():"_app_DDUnHook@0"
  app_DDWasLost%():"_app_DDWasLost@0"
  app_possibleLogOut%():"_app_possibleLogOut@0"
  app_clearPossibleLogOut():"_app_clearPossibleLogOut@0"

  See the follow forum threads for more info:
    http://www.blitzbasic.com/Community/posts.php?topic=67837
    http://www.blitzbasic.com/Community/posts.php?topic=67841

  Any questions or comments can be posted to the Blitz3D forums at
  www.BlitzBasic.com.

  - DGuy 05/2007
*/
#include <windows.h>
#define DIRECTDRAW_VERSION 0x0700
#include <ddraw.h>


//========================================================== Constants
#define BBDECL extern "C" _declspec(dllexport)
#define BBCALL _stdcall


//========================================================== Variables
static BOOL                 _is_init;

static LPDIRECTDRAW7        _b3d_pdd;
static LPDIRECTDRAWSURFACE7 _b3d_pddsPrim;

static HWND                 _b3d_hwnd;
static WNDPROC              _b3d_windowProc;

static BOOL                 _ctrlKeyIsDown;
static BOOL                 _menuKeyIsDown;
static BOOL                 _winKeyIsDown;
static BOOL                 _possibleLogOut;


//================================================== Private Functions
/*--------------------------------------------------------------------
 Finds the primary direct draw surface. Called by 'app_DDHook()'
*/
HRESULT WINAPI _surfaceEnumCallback_GetPrimary
  (
  LPDIRECTDRAWSURFACE7 lpDDSurface,
  LPDDSURFACEDESC2 lpDDSurfaceDesc,
  LPVOID /*lpContext*/
  )
  {
  if( lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE )
    {
    _b3d_pddsPrim = lpDDSurface;
    return DDENUMRET_CANCEL;
    }
  lpDDSurface->Release();
  return DDENUMRET_OK;
  }

/*--------------------------------------------------------------------
 Intercepts and examines messages received by Blitz3D app
*/
LRESULT CALLBACK _AppBase_WindowProc
  (
  HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
  )
  {
  switch( uMsg )
    {
    case WM_KEYDOWN:
      {
      switch( wParam )
        {
        case VK_CONTROL: _ctrlKeyIsDown = TRUE; break;
        case VK_MENU: _menuKeyIsDown = TRUE; break;
        case VK_LWIN: case VK_RWIN: _winKeyIsDown = TRUE; break;
        }
      }
      break;

    case WM_KEYUP:
      {
      switch( wParam )
        {
        case VK_CONTROL: _ctrlKeyIsDown = FALSE; break;
        case VK_MENU: _menuKeyIsDown = FALSE; break;
        case VK_LWIN: case VK_RWIN: _winKeyIsDown = FALSE; break;
        }
      }
      break;

    case WM_ACTIVATEAPP:
      {
      if( (wParam == FALSE) && (lParam == 0x0) )
        _possibleLogOut =
          (_winKeyIsDown || (_ctrlKeyIsDown && _menuKeyIsDown));

      _winKeyIsDown = _ctrlKeyIsDown = _menuKeyIsDown = FALSE;
      }
      break;
    }

  return CallWindowProc( _b3d_windowProc, hwnd, uMsg, wParam, lParam );
  }


//=================================================== Public Functions
/*--------------------------------------------------------------------
 Sets-up helper DLL.
 Should be called as soon as possible by Blitz3D App
 Always returnd True.
*/
BBDECL BOOL BBCALL app_init( HWND hwnd )
  {
  if( !_is_init )
    {
    _b3d_hwnd = hwnd;
    _b3d_windowProc =
      (WNDPROC)SetWindowLong
        (
        _b3d_hwnd, GWL_WNDPROC, (LONG)_AppBase_WindowProc
        );
    _is_init = TRUE;
    }
  return TRUE;
  }

/*--------------------------------------------------------------------
 Cleans up DLL.
 Should be called before exiting Blitz3D App
*/
BBDECL void BBCALL app_uninit()
  {
  if( _is_init )
    {
    SetWindowLong( _b3d_hwnd, GWL_WNDPROC, (LONG)_b3d_windowProc );
    _b3d_hwnd = 0;
    _is_init = FALSE;
    }
  }

/*--------------------------------------------------------------------
 Obtains pointer to primary direct draw surface.
 Should be called after graphics mode has been set.
 Returns True on success, False on error
 Usage:
  Graphics3D ...
  If Not app_DDHook() Then ;Error
*/
BBDECL BOOL BBCALL app_DDHook( LPDIRECTDRAW7 pDD )
  {
  if( _is_init )
    {
    if( pDD )
      {
      _b3d_pdd = pDD;
      return (DD_OK == _b3d_pdd->EnumSurfaces(
        DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
        NULL, NULL, _surfaceEnumCallback_GetPrimary
        ));
      }
    }
  return FALSE;
  }

/*--------------------------------------------------------------------
 Releases primary direct draw surfaces and cleans up.
 Should be called before graphics mode is cleared or changed
 Usage:
  app_DDUnHook(): EndGraphics
*/
BBDECL void BBCALL app_DDUnHook()
  {
  if( _is_init )
    {
    if( _b3d_pddsPrim )
      {
      _b3d_pddsPrim->Release();
      _b3d_pddsPrim = NULL;
      _b3d_pdd = NULL;
      }
    }
  }

/*--------------------------------------------------------------------
 Checks if primary direct draw surface has been lost.
 Should be called before UpdateWorld and, probably, any direct (pixel
 level) access of direct draw surfaces (ie. before LockBuffer, if the
 buffer being locked may refer to a direct draw surface)
 Returns True if lost, False if not

 Usage:
   If app_DDWasLost() Then ; reset display & reload graphics
   UpdateWorld
   If app_possibleLogOut() Then
     app_clearPossibleLogOut()
     ; reset display & reload graphics
   Else
     RenderWorld: Flip
   EndIf
*/
BBDECL BOOL BBCALL app_DDWasLost()
  {
  return (_is_init && _b3d_pddsPrim && (_b3d_pddsPrim->IsLost() != DD_OK));
  }

/*--------------------------------------------------------------------
 Checks for possible user log-out.
 Returns True if user has possibly logged-out, False if not.
 Usage:
   See above
*/
BBDECL BOOL BBCALL app_possibleLogOut() { return _possibleLogOut; }

/*--------------------------------------------------------------------
  Clears possible-log-out flag.
  Usage:
    See above
*/
BBDECL void BBCALL app_clearPossibleLogOut()
  {
  _possibleLogOut = FALSE;
  }


//============================================================ DLLMain
BOOL APIENTRY DllMain(
  HANDLE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/
  )
  {
    switch( ul_reason_for_call )
    {
    case DLL_PROCESS_ATTACH: break;
    case DLL_THREAD_ATTACH: break;
    case DLL_THREAD_DETACH: break;
    case DLL_PROCESS_DETACH: break;
    }
  return TRUE;
  }



Kev(Posted 2007) [#2]
DGuy

the compiled .dll is available direct from the clicky below.

http://www.winblitz3d.co.uk/B3D_AppBase.zip

kev


Knotz(Posted 2007) [#3]
Thx, nice stuff.


popcade(Posted 2007) [#4]
Thanks DGuy and Kev, mirrored this in

http://icworx.org/_ext/B3D_AppBase.zip


@rtur(Posted 2007) [#5]
Here is my mirror:
http://www.master-of-defense.com/upload/B3D_AppBase.zip


@rtur(Posted 2007) [#6]
Here is version with test.bb file:
http://www.master-of-defense.com/upload/B3D_AppBase2.rar


John Blackledge(Posted 2007) [#7]
This is for that 'Vista loss of focus problem' is it?


Kev(Posted 2007) [#8]
@John, yes it fixes vista problem and the problem with blitz3d when the screensaver becomes active.

and heres a mirror of @rtur with test.bb file.
http://www.winblitz3d.co.uk/B3D_AppBase2.rar


DGuy(Posted 2007) [#9]
Thanks for making this available for download guys ... :D

Also, thanks to @rtur for writing a simple test program so others can quickly check that it works.

BTW, if anyone comes across a loss-of-focus event that causes a Blitz3D MAV under WinXP or Vista, that is not prevented by this DLL, please let me know and I'll see about developing a work-around.

Thanks,
David