jcornwall's picture

"Full-screen" GLControl

I am following up this thread on simulating fullscreen behaviour with a borderless form, to avoid context destruction/recreation.

My implementation is roughly this:

_MinimalWindow = new Form();
_MinimalWindow.FormBorderStyle = FormBorderStyle.None;
_MinimalWindow.TopMost = true;
 
...
 
Hide();
 
// Use a native SetWindowPos call because the Form.Bounds property
// does not move windows across monitors when the form is hidden.
Platform.SetFormBounds(_MinimalWindow, new Rectangle(screenOffset, 0, dDev.Width, dDev.Height));
_GLControl.Parent = _MinimalWindow;
_GLControl.Bounds = new Rectangle(0, 0, dDev.Width, dDev.Height);
 
_MinimalWindow.Show();

(Best to ignore the native SetWindowPos call; Forms.Bounds would not move the form correctly if it was in the hidden state. I'm chasing this up on the MSDN forums. It doesn't change the problem I'm about to describe.)

This almost works great. If I make the GLControl width (dDev.Width - 1) then the behaviour is correct. However with (dDev.Width) the OpenGL full-screen effect spills from the first screen onto the second, causing the display to go black. I suspected an off-by-one error but (dDev.Width - 1) does leave a single column of the form's pixels unrendered.

Can you think of any reason this might be? I could make the form black so that the column of pixels is not visible, but it's a bit ugly!


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Why don't you try this?

_MinimalWindow = new Form();
_MinimalWindow.FormBorderStyle = FormBorderStyle.None;
_MinimalWindow.WindowState = FormWindowState.Maximized;
_MinimalWindow.TopMost = true;
 
_GLControl.Parent = _MinimalWindow;
_GLControl.Dock = DockStyle.Fill;
 
_MinimalWindow.Show();

The maximized line will ensure that the size is always correct (even if screen resolution changes).

jcornwall's picture

Maximising was the first solution I tried, but I couldn't find a way to choose which monitor to maximise on. (I want the minimal form to maximise on the screen that the main form was double-clicked on.)

The Form.Location / Form.Bounds property would not move the form to the second screen without first making it visible, which causes a flicker. In any case, I gave this a try on the first monitor and it still blanks the second monitor when the control fills the form.

I'll have a look in the OpenTK code, later. Any suggestions for relevant source files are welcome.

the Fiddler's picture

It might be possible to move the form when it's invisible, if you call CreateControl first:

_MinimalWindow = new Form();
_MinimalWindow.CreateControl();
_MinimalWindow.Location = new Point(...);
_MinimalWindow.Show();

By default, position is set on control creation - and controls are not created until they become visible. Using this should allow you to set the Location property (and thus control which screen the control is maximized on).

Regarding the second monitor becoming blank, there's a chance this is driver related. For example, I've tried this on an Intel IGP (965 mobile, to be exact) and the secondary monitor is not blanked, while on an Ati X1950 it is.

Does the secondary monitor still turn off if you remove the _MinimalWindow.TopMost = true; line?

jcornwall's picture

Aha. Your first suggestion didn't quite work and why is made clearer in the MSDN documentation:

"CreateControl does not create a control handle if the control's Visible property is false. You can either call the CreateHandle method or access the Handle property to create the control's handle regardless of the control's visibility, but in this case, no window handles are created for the control's children."

Constructing a subclass of Form (to access the protected CreateHandle method) and calling CreateHandle does work! The form can be correctly positioned before being displayed.

The other good news is that your suggestion of leaving the TopMost property as false fixes the OpenGL spill onto the second monitor. I'm not a fan of "forced" full-screen windows, anyway, so having it off is probably a good thing.

Thanks for your help, spot on as always. :)