PDA

View Full Version : Windowed -> Full-screen -> Windowed problem



Sly
21-07-2005, 01:40 PM
I'm having a very strange problem switching from full-screen mode back to windowed mode. At the time the Direct3D9 device is reset, the window is 20 pixels shorter than it should be. Here is some debug output showing the problem (WSize is the window size, CSize is the window client size):

Debug Output: Starting in windowed mode
Debug Output: WSize:806x632 CSize:800x600
Debug Output: Going to fullscreen mode
Debug Output: WSize:800x600 CSize:800x600
Debug Output: Going to windowed mode
Debug Output: WSize:806x612 CSize:800x580
Here is the code that changes the window properties.
procedure TfrmMain.DeviceReset(Sender: TObject);
begin
gSystem.Fonts.InvalidateDeviceObjects;

if gSystem.Device.Windowed then
begin
DKLog('Going to windowed mode');
{ Going to a windowed mode }
{ Restore the previous border style and position }
BorderStyle := FWindowedBorderStyle;
Left := FWindowedLeft;
Top := FWindowedTop;
end
else
begin
DKLog('Going to fullscreen mode');
{ Going from windowed to full-screen }
{ Save the border style and position of the window }
FWindowedBorderStyle := BorderStyle;
FWindowedLeft := Left;
FWindowedTop := Top;

{ Borderless window at 0,0 }
BorderStyle := bsNone;
Left := 0;
Top := 0;
end;
ClientWidth := gSystem.Device.Width;
ClientHeight := gSystem.Device.Height;

gSystem.Device.WindowHandle := Handle;
end;
I call that code, fill the D3DPRESENTPARAMETERS structure and call Reset on the Direct3D device. The debug output above is logged just before the call to Reset.

Why would the window be 20 pixels shorter than it was before?

Edit: Why don't the pascal tags understand the original Pascal style comments?

Sly
21-07-2005, 01:50 PM
Just changed the code to use the BoundsRect property instead and it shows me that
DKLog(Format('BRect1:%dx%d', [FWindowedBounds.Right - FWindowedBounds.Left, FWindowedBounds.Bottom - FWindowedBounds.Top]));
BoundsRect := FWindowedBounds;
DKLog(Format('BRect2:%dx%d', [BoundsRect.Right - BoundsRect.Left, BoundsRect.Bottom - BoundsRect.Top]));
outputs

Debug Output: BRect1:806x632 Process Testbed.exe (4040)
Debug Output: BRect2:806x612 Process Testbed.exe (4040)
So setting BoundsRect and then reading it is returning the height minus 20 pixels.

I'm lost now. I don't understand.

Clootie
21-07-2005, 07:34 PM
1) Are you sure you're not handling WM_SIZE somewhere.
2) Just looked as SDK samples and they are using GetWindowPlacement / SetWindowPlacement. And this is a better ways as it IIRC restores "is window maximized" status, normal AND maximized sizes. Just try it - may be something will change.

Crisp_N_Dry
21-07-2005, 08:12 PM
Edit3 - Looking at your post again I finally get the point. Very odd that the FWindowedBounds and BoundsRect give different values when they should be exactly the same. Although it seems as if the screen border is playing a part in this somewhere because at certain settings (bsToolWindow) the border is exactly 20 pixels high.

Clootie
21-07-2005, 08:37 PM
Crisp_N_Dry:
BorderStyle := bsNone;Means no borders - not the toolstyle ones.

Sly:
Crisp_N_Dry is right that you are changing Window size in wrong place: you should change window size AFTER resetting to windowed mode (maybe even hiding fullscreen window before reset).
In your current state - (a) you change window style to normal; (b) try to restore window client size - but desktop at this stage is too small to contain your window, so Windows forces window size to max desktop size; (c) you call "d3d.Reset" restoring desktop size - and got wrong (reduced) window size.

Sly
22-07-2005, 03:27 AM
I guess I'll have to use the Windows API directly then, because using the BorderStyle property to change from bsNone to bsSingle recreates the window, thus returning a different window handle. Since you have to pass the window handle to Reset() in the D3DPRESENTPARAMETERS structure, changing the window handle (by changing the BorderStyle) will cause errors. Using the Windows API to change the window style would be the answer here.

Thanks all.

Sly
22-07-2005, 09:58 AM
Woohoo! That works fine. Thanks for the tips, guys. Set the window style _after_ resetting the 3D device.

Edit: Using Get/SetWindowPlacement, it was sizing the window the correct height, but 6 pixels too narrow.

Edit2: I took a look at DXUT for reference. My goodness! Their code for changing from full-screen to windowed and back is many pages long. Sure, it covers all the possible cases, but damn.