Yet another alt tab question

Started by
15 comments, last by James Gregory 20 years, 3 months ago
I''ve been reading all the previous stuff on this forum about alt-tab issues, and as my game is no Half-Life I quite like the sound of simply reszing the desktop to match my desired resolution and then running in windowed mode. However, I don''t know how I would go about doing such a thing. Can anyone help? Thanks.
Advertisement
You will still run into the same problems running in windows mode (alt-tab is no different than clicking off a window then clicking back onto it.) I suggest learning about alt-tab and put the correct code into your software. Its not very hard. You just release all DEFAULT pool objects, then call the Device->Reset() function, the re-create all DEFAULT pool objects. Not much harder than that.

PS. I''d suggest never resizing someones desktop on them... Thats not very user friendly and you might receive death threats if you do so. =)
I''m using DirectDraw, not Direct3D, so I can''t call CheckIfDeviceIsStillFineAndDandy() or whatever the Direct3D function is called.

And WM_Activate isn''t caught in full screen mode, I think because the window isn''t actually your program, it''s just something to keep Window happy. Plus it requires reloading all the bitmaps.




Hmm.. apparently blt and bltfast can return DDERR_SURFACELOST,
so I guess I could check for that.

Trial and error here we come...
Ah, at last,
http://www.codeproject.com/system/enum_display_modes.asp

tells you abotu changing the display settings
I''ve used the IsLost() member function to check if I still have my surface. If I do not then RestoreAllSurfaces() else proceed to render image.
quote:Original post by JoeyBlow2
PS. I''d suggest never resizing someones desktop on them... Thats not very user friendly and you might receive death threats if you do so. =)


Speaking oh which... Does anyone know of some way you can prevent all the windows being resized when any application goes fullscreen? I seem to have that problem a lot. Some things that run in fullscreen don''t do it but most do... Its really annoying...
www.ice-d.com
I'm afraid I can't help you there, but in case someone else searches the forum archives some time with the same problem as me, and doesn't want to waste hours of their life:

If you want to make a pseudo-fullscreen application (i.e. it looks full screen, but is actually in a window), here's how you do it:

1. At the beginning of your program, save the person's current screen settings in a global, and then change the screen settings to what you want them to be. E.g.:

//globalsDEVMODE oldDispSettings;...//at the very beginning of the program    //save the person's old settings    EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &oldDispSettings);    oldDispSettings.dmSize = sizeof(DEVMODE);    oldDispSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;        //set up the new ones    DEVMODE newDispSettings;        newDispSettings.dmSize = sizeof(DEVMODE);    newDispSettings.dmBitsPerPel = screenBPP;    newDispSettings.dmPelsWidth = screenWidth;    newDispSettings.dmPelsHeight = screenHeight;    newDispSettings.dmDisplayFrequency = oldDispSettings.dmDisplayFrequency;    newDispSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;    ChangeDisplaySettings(&newDispSettings, 0);


This should come right at the very beginning, before you even create a window. Your game's main window size should obviously be equal to the size you just set for the monitor size.

2. If the person alt tabs or otherwise deactivates your game, you want to do 2 things:

a) Pause the game so it doesn't eat up all their system resources. You need some sort of global boolean "paused" variable.

b) Minimize your window such that your game's display doesn't interfere with whatever the person is doing.

You could use the global old settings DEVMODE to restore their old settings whenever they alt tab, but I think this invalidates all your surfaces so it would probably require reloading everything in the same way that real full screen games have to.

Anyway, in my Windows call back function I have the following:

case WM_ACTIVATE:{       WORD fActive = LOWORD(wParam);            if (fActive == WA_ACTIVE || fActive == WA_CLICKACTIVE)    {       //if MSWIN it means the window has just been created       if (gsCurrent != MSWIN)            gsCurrent = gsTo;    }    else //must be WA_INACTIVE    {       gsCurrent = DEACTIVATED;              //this minimizes your game's window       WINDOWPLACEMENT tempPlacer;       tempPlacer.length = sizeof(WINDOWPLACEMENT);       tempPlacer.showCmd = SW_MINIMIZE;                   SetWindowPlacement(mainWindowHandle, &tempPlacer);     }}


The "gsCurrent" and "gsTo" stuff is perculiar to my game, you could just have a global boolean called "paused" or whatever, but bear in mind you'll get an activated message when your program first starts.

Then at the beginning of my main game loop I have a switch on the current game state, with a simple:

case DEACTIVATED:       return 1;break;


for the case of being paused. I cut out the whole main game loop when deactivated, if you're making a game that is real time and multiplayer, you'll probably just want to pause out your DrawWorld() part.

3. When the program shuts down, restore the person's old settings again.

ChangeDisplaySettings(&oldDispSettings, 0);  


Note I set the valid fields on the oldDispSettings structure at start up, you could leave it until shutdown, but whatever, you have to do it some time.

www.hcstreet.f2s.com/galaxyhack

[edit: why proofread for typos before posting when you know there's an edit button?]

[edited by - James Gregory on January 17, 2004 2:52:36 AM]
For James, and anyone else who finds this post and thinks it''s a good idea, *please* dont do that in your game. The reason is simple: It''s very anti-social to your user base. If your game crashes with some terminal error and is unable to run your shutdown code, you have left your user with their desktop in a FUBAR state.

I''m not into death threats but as a consumer, I will return any game that uses this technique to the store, and hit you in your wallet.

Go on, put some (realtively simple) work into it and do the job properly... you know it makes sense. :D


Atlay
If it''s so simple, why don''t you explain how it can be done?

I''m utterly fed up with seaching the DirectX documentation/Win32 documentation/MSDN library/google, finding some function call or argument that looks like it might be relevant, compiling, running, quitting, changing it so it''s slightly different, compiling, running, changing it a bit again, searching for more functions a bit more, running again, ad infinitum.

It''s not like it''s a matter of putting a bit of logic or thought or effort into it, or a matter of thinking about what exactly it is you want your program to do, it''s just extremely tedious trial and error.

This topic is closed to new replies.

Advertisement