Log in

View Full Version : Windows desktop icons, screen resolutions, frustration, etc


damocles
03-07-2004, 02:17 AM
I decided last night to add Alt+Enter support to switch between windowed mode/fullscreen mode in my current game. All works great except that every so often when I quit out of the game, the desktop icons are a mess (the old resizing desktop squashes up the icons problem). If it happened everytime I could at least have an idea where to begin looking but it only seems to happen once every X plays.

Now I'll be the first to admint that I suck at windows programming. I tend to avoid it where possible because I loathe the windows API. So I'm probably making some rookie mistake but as a rookie I have no idea how to find that mistake.

I'd be grateful if someone could give a quick once over of my windowed mode code below to see if everything is in order.


The code:

// windowed mode
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = config->oldVideoX;
dmScreenSettings.dmPelsHeight = config->oldVideoY;
dmScreenSettings.dmBitsPerPel = config->oldBPP;
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
//tbd: error handling
return;
}

DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style

dwStyle = WS_BORDER | WS_POPUP | WS_SYSMENU;
dwStyle &= ~WS_MAXIMIZEBOX;
showCursor(true);

RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)config->videoX;
WindowRect.top=(long)0;
WindowRect.bottom=(long)config->videoY;
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
MoveWindow(hWnd, (config->oldVideoX/2)-(config->videoX/2),
(config->oldVideoY/2)-(config->videoY/2), config->videoX, config->videoY, true);
config->bWindowed=true;
showCursor(true);


That's just to switch to windowed mode. Fullscreen mode does much the same except obviously it sets the desktop to the lower resolution and then moves the window to 0,0.

Anyone have any ideas why it occasionally decides to mess up the desktop icons?

Scorpio
03-07-2004, 07:18 AM
Are you using DirectX in your game? If not, you should probably consider using it, at least to deal with changing in-and-out of fullscreen mode.

The problem you could encounter since you are manually changing it yourself is that if your game were to crash while in full-screen mode, the user would be stuck in the resolution your game was running in (for example 640x480).

Also, using Dx for full-screen mode also deals with Alt+Tab, Alt+Esc much more gracefully.

I had an older game/engine that came from Windows 3.x and (obviously :) didn't use DDraw. I was able to add full-screen support without DDraw (similar to how you're doing it) but then found all these oddball cases that were not handled without a lot more work. It took about 30 minutes to add in DDraw support just to do the fullscreen/restore work...which solved everything.

You don't need the latest version of DDraw to do this so it will be installed on everything except Win95.

Glad you're adding Alt+Enter support. :)
-Scorpio

damocles
03-07-2004, 07:55 AM
I'd rather not add in DirectX - at the moment I'm using just OpenGL1.0 and the windows API. Maximum compatability and all that :)

The crashing raises an interesting point. Putting aside the fact that I hope the game never crashes, does windows XP prevent that problem? I'm developing on XP and so only XP has seen any crashes. And after every crash the desktop has returned to normal.

It was only since I added in the window/fullscreen toggling that the problem appeared. Seeing as it's showing up with the toggle and never with the crashing, I think it must be possible to make it work and the crashing should be okay (partly because I'm doing my best so that it never crashes, and partly because a crash so far has not resulted in an error).

Scorpio
03-07-2004, 07:59 AM
Are you currently handling Alt+Tab correctly?
-Scorpio

damocles
03-07-2004, 12:38 PM
I'm guessing that as you felt the need to ask the question that I'm probably not handling it properly. At the moment my Alt-Tabbing checks are just part of my regular keyboard input routines. Is there a system message that corresponds to alt-tabbing then?

Scorpio
03-07-2004, 04:14 PM
It's really a combination of handling minimization either via alt+tab (or some other keyboard input) as well as being minimized by Windows itself (for example, if some other app steals the focus...such as Firewall software telling the user the app is trying to access the net).

I guess if you handle focus loss and restore the video mode, you might be ok. I remember thinking about the user alt+tabbing back to the desktop, and then changing the desktop resolution...and then my app exiting and restoring the old desktop resolution. At that point, I just grabbed the 10 lines of code from our newer tech because I new DDraw would handle all of the oddball cases properly.

However, I'm not saying DDraw is the only answer...it just seems the safest/easist in my opinion.

Also, I've really liked the Windows API since Windows 3.0 so we seem to be opposites...so maybe you should do the non-Windows-ish solution. :)

(although, you did mention maximum compatibility, but you're also using OpenGL ???)

Anyway, for a non-DDraw solution, I think you're on the right track, you'll just need to do a bunch of testing of all the oddball cases. You may need to force the desktop window to repaint or something like that to fix the icons. Actually, when this problem does happen currently, what are you able to do to fix them? If all apps are minimized and you hit F5 to refresh does it help?

Good luck,
-Scorpio

DGuy
03-07-2004, 04:32 PM
From MSDN.com:

"Windows 95/98/Me: If the calling thread has any windows, ChangeDisplaySettings sends them the WM_DISPLAYCHANGE message immediately (for windows in all other threads, the message is sent when the thread can receive nonqueued messages). This may cause the shell to get its message too soon and could squash icons. To avoid this problem, have ChangeDisplaySettings do resolution switching by calling on a thread with no windows, for example, a new thread."

Try this:

On Start up:
-Register Window Class (RegisterClassEx)
-Create Main Window (CreateWindowEx)
NOTE: keep the above two operations separate, not in one routine.

Before changing resolution:
-Close/Destroy Main window (PostMessage(hwnd,WM_CLOSE,0,0) -OR- DestroyWindow(hwnd))
-Change the resolution (ChangeDisplaySettings)
-Re-Create Main Window (CreateWindowEx)

HTH,
David

damocles
03-08-2004, 03:56 AM
I think I have it working - but no doubt I'll have missed one of the "oddball" cases. Something to be tested for sure :)

DGuy - although your suggestion sounds like the solution, it causes some weird funky stuff to happen :) It seemed like windows was destroying the window, changing the resolution, but then after it creates the new window, the new window received the message to resize again! It kept getting caught in infinte destroy/create loops. Was very bizarre. And very difficult to break out of because the resolution was changing non-stop it made it very difficult to see what you were doing :)

Like I said in my first post, the way I had it set-up works most of the time, but not all - it was as Scoripio suggested - just a case of catching the few oddball situations that you hadn't counted for. Although focus doesn't seem to be a problem, when you Alt-F4 it was bypassing the code that resizes the desktop back to normal, so I moved that into the right place and it seems to be fine now. Haven't managed to get it to squash my icons yet :) Of course, I've yet to test it on a Win95 machine :)

And yes Scorpio - I did use the terms OpenGL and maximum compatability in the same sentence - there's more to this world than PCs you know ;) Plus the fact that pretty much every card in the last 6 years has an openGL1.0 driver implementation helps :) (excepting of course those stupid intel/sis on-board chips that pretty much suck across the board).