Game Development Community

Game crashes while using ALT TAB keys in game window..

by Raja John · in Technical Issues · 01/21/2009 (5:41 am) · 4 replies

Alt+Tab'ing back to the game will cause the game to crash with an Access Violation message.


1. Launch the game (Vista).
2. Once in-game, Alt+Tab away from the game.
3. Alt+Tab back to the game.
4. Notice that the game crashes with an Access Violation error message.

My coding :
moveMap.bind("keyboard", "alt tab", "pausescreen");

#1
01/21/2009 (6:45 am)
Which game/engine are you referring to?

This was a fix proposed by Alex Stone. I never could replicate the problem on any of my machines, but many people who have experienced the problem, especially for portal distribution, have used his fix successfully.

#2
01/21/2009 (10:17 pm)
The link is not working, it navigate as to our home page, could you please refer someother link
#3
01/22/2009 (6:15 am)
The link is working fine, unfortunately you have to be a TGE owner to see it.

From Alex Stone:
Quote:Yeah, so I totally fixed this. The problem turned out to be a fundamental flaw in the way torque processes WM_ACTIVATEAPP messages. Torque destroys and recreates the window when processing this message, while still in the message loop, which could easily cause the Win32 API to freak out. The solution is to move the actual work of reactivating the game into the next trip through Platform::process, outside the messaging loop.

Part 1: Setting up some extra Video tracking state

In platformVideo.h, after


static bool smCritical;


insert

static bool smActive;
   static bool smActivating;
   static bool smReactivating;
   static bool smInactive;
after

static void setVideo(const char * gapi, const char * vendor, const char * renderer, const char * platform, const char * os, const char * arch);

insert

static bool isActive() { return smActive; }
   static bool isActivating() { return smActivating; }
   static bool isReactivating() { return smReactivating; }
   static bool isInactive() { return smInactive; }

In platformVideo.cc, after

bool					Video::smCritical = false;
bool					Video::smNeedResurrect = false;

insert

bool                    Video::smActive = false;
bool                    Video::smActivating = false;
bool                    Video::smReactivating = false;
bool                    Video::smInactive = false;

In Video::setDevice, after

Con::printf( "Activating the %s display device...", renderName );
      smCurrentDevice = smDeviceList[deviceIndex];

      smCritical = true;

insert

smActivating = true;

and after

bool result = smCurrentDevice->activate( width, height, bpp, fullScreen );

insert

smActivating = false;
	  smActive = true;
	  smInactive = false;

In Video::deactivate, after

Platform::minimizeWindow();
      smCritical = false;
   }

insert

smInactive = true;
   smActive = false;
[code]

in Video::reactivate, after 

[code]
	   Resolution res = DisplayDevice::getResolution();

      smCritical = true;

insert

smReactivating = true;

and after

smCurrentDevice->activate(res.w,res.h,res.bpp,DisplayDevice::isFullScreen());

insert

smReactivating = false;
	  smInactive = false;
	  smActive = true;

Ok, now for Part Deux, rearranging the reactivation code in winWindow.cc:

After:

static bool gWindowCreated = false;

static bool windowNotActive = false;

Insert:

static bool gDoReactivate = false;

In Platform::process, after:

void Platform::process()
{

Insert:

if(gDoReactivate)
   {
            Video::reactivate();
            ShowCursor(false);
            if ( Video::isFullScreen() )
               hideTheTaskbar();

            // HACK:  Windows 98 (after switching from fullscreen to windowed mode)
            SetForegroundWindow( winState.appWindow );

            // If our keyboard state is dirty, clear it
            if( sgKeyboardStateDirty == true )
            {
               sgKeyboardStateDirty = false;
               InitInput();
            }

			gDoReactivate = false;
   }

In WindowProc, after

case WM_ACTIVATEAPP:
         if ((bool) wParam)
         {

REPLACE THE CODE UP TO THE CLOSURE OF THE IF STATEMENT WITH:

if(Video::isInactive() && !Video::isReactivating())
			 {
				gDoReactivate = true;
			 }
So it should look like...

case WM_ACTIVATEAPP:
         if ((bool) wParam)
         {
			 //>NEW CODE
			 if(Video::isInactive() && !Video::isReactivating())
			 {
				gDoReactivate = true;
			 }
			 //<NEW CODE
         }
NOTE: THIS IS A TENTATIVE FIX, it has not been tested on any other platforms except my own machine, but it no longer crashes when you alt-tab back into the game while it is in fullscreen. I'm actually a little suprised that GG didn't catch this in their QA process, as it seems to be a hardware independant bug in the windows platform code.
#4
01/22/2009 (6:22 am)
Nelson A. K. Gonsalves then added this:
Quote:
And here is a little change I made to make it minimize the game window when you alt-tab out of full screen mode(or else all you will see is the task bar as the game window will stay on top of everything else):

After
case WM_ACTIVATEAPP:
   if ((bool) wParam)
   {
      if(Video::isInactive() && !Video::isReactivating())
      {
         gDoReactivate = true;
      }
   }
which was added by the changes above, add
else if(Video::isFullScreen())
      Platform::minimizeWindow();
so that the case block looks like:
case WM_ACTIVATEAPP:
   if ((bool) wParam)
   {
      if(Video::isInactive() && !Video::isReactivating())
      {
         gDoReactivate = true;
      }
   }
   else if(Video::isFullScreen())
      Platform::minimizeWindow();
   break;

Louis Dufresne added how to disable Alt-Tab:
Quote:
Well I figured out a way to just simply disable Alt-Tab altogether.

inside WindowProc
right above the switch ( message ) call just add:
#define MY_HOTKEYID 100
bool isMyKeyComboTrapped = RegisterHotKey(hWnd, MY_HOTKEYID, MOD_ALT, VK_TAB);

That should help those with TGB Pro/Torque 2D.