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;
}
|