0

I have a WinForms application. It has a MainWindowForm (creatively) named Form1, and within that, a maximised child Form named fymmapdraw. The child form is created with the following VB.NET snippet:

fformmapdraw = New fymmapdraw With {
    .MdiParent = Form1,
    .WindowState = FormWindowState.Maximized
}
fformmapdraw.Show()

My issue is that with Form1 maximised and fymmapdraw maximised within it, the fymmapdraw.Width reports a value greater than the screen width in some cases. This is an issue with the drawing code within fymmapdraw, where some snapping functionality incorrectly snaps beyond the window border.

It appears this is linked to Aero-style desktops - the width was correct on Windows XP, and correct on Windows 7 if an Aero-style desktop theme was not used, but incorrect on Windows 7 or 10 with such a theme enabled.

My screen resolution is 1920x1080. The mouse X coordinates reported by fymmapdraw's MouseMove event e.X property, which reports relative to the form itself, range from 0 to 1915. These values are reasonable - a couple of pixels are lost at either side to the window frame.

However, the form's Me.Width property returns 1932 pixels, in excess of the screen width. Me.Left returns -8 and Me.Right returns 1924.

The application is fairly old, originally dating back to the Windows XP era (2006-7). It is currently using .Net Framework 4.0. fymmapdraw has its FormBorderStyle set to Sizeable, and its AutoScaleMode to Font (although it contains no text controls or similar - all drawing is handled by custom code).

Is there a way to have Form.Width return the "correct" value - i.e. the true number of pixels visible - perhaps by changing some property of the Form or Application? If not, there another property of the Form where I can get the true width?

The image below illustrates the output. At top left, the "Raw" coordinates are those reported by the MouseMove event, with the mouse just inside the right hand boundary. The "Form Dimensions" reported are fymmapdraw.Width and fymmapdraw.Height. The small control bar is the one which is snapping incorrectly - it is placed with it's right hand edge equal to fymmapdraw.Width, but is partially off screen (a full blue border should be visible).

Image of form

  • 1
    When a Window is maximized, its borders (visible or invisible, as in Windows 10) are moved outside the bounds of the Screen. So the Window's Size is always 16 pixels (8*2 or (7+1)*2) wider than the ClientSize. Maybe you want to use the ClientRectangle as the reference size when the Window is maximized. Try `var windowRect = this.RectangleToScreen(this.ClientRectangle)`. DpiAwareness plays a role when the Screen is not scaled 100%. Also the current Screen layout. See the notes here: [Using SetWindowPos with multiple monitors](https://stackoverflow.com/a/53026765/7444103) – Jimi Dec 31 '20 at 12:35
  • @Jimi - thanks, this looks to have done the trick. One minor difference is that I've used `ClientSize`, as `ClientRectangle` looks like it's only defined on Controls, not Forms, but it seems that they behave similarly. – Danny252 Jan 30 '21 at 12:24
  • Form also has Control as ancestor, the property is of course available. – Jimi Jan 30 '21 at 12:40
  • I had thought that was the case, but Visual Studio didn't show it as a possible auto-complete. On trying again, it turns out that Visual Studio still refuses to show it as a possible autocompletion at all, but on manually typing it, it happily autocapitalises it, shows the docstring, builds the program, etc.. A weird quirk of my install, I'm sure. – Danny252 Jan 31 '21 at 13:20

2 Answers2

0

If the aim of the game is to determine the visible size of the form, then when it's maximized, you'd surely be interested in the bounds of the screen the form is on instead of the form size?

Dim screenRect = Screen.FromControl(yourForm1).Bounds

This gives you a Rectangle for the screen..

And if it's not maximized, then some jiggling of the position of the form, and it's width/height, and the screen's width/height, to work out how much of the form is within the visible bounds of the screen...

.. though then you have multi monitor setups that may be offset from each other, so there's another curve ball there in working out the portion of the form showing on the second (and third..) screen(s)...

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • The game is still played within the normal Windows border/window frame - i.e. it's not borderless. When maximised, it's a maximised WinForms window, with the game inside. It's not the most graphically advanced game; it derives from a project started in 2008. – Danny252 Jan 30 '21 at 12:20
0

if the above answer is not giving you the desired results, try checking the colors of the pixels along the x axis and find the points where the color of your program breaks off onto the background, then find the the difference.

drpepper1324
  • 113
  • 9