question on maximum width/heights

  • Thread starter Thread starter smith
  • Start date Start date
S

smith

Googles shows that this question has been asked a couple of times but every
"answer" turns out to be a snappy "only an idiot would need that" rather
than a real answer. I'd kinda like a real answer if there is one.

question, in 3 parts:

1) Why is there a 32767 maximum width/height limit on GUI controls?

2) Since there is that limit why aren't those properties defined as Shorts
instead of Ints?

3) Why was the decision made to just force higher values to the
Short.MaxValue value without tossing an exception alerting the dev/user that
such a silent force was going on?

It applies to all controls (buttons, groupboxes, panels, etc) and only
really gets in the way on pictureboxes being filled with very large images -
and that's is where the other "answers" turn into ""you don't need that
ability" rants rather than being very informative.

There is a mention of a 32bit exposed property being internally a 16bit
value at:

http://msdn.microsoft.com/library/d...eference/scrollbarfunctions/getscrollinfo.asp

.... but it seems to be a slightly different issue (or is it?)

If anyone's got an idea, I'd love to hear it just for the knowledge factor.

Thanks.

Robert Smith
Kirkland, WA
www.smithvoice.com
 
smith said:
Googles shows that this question has been asked a couple of times but
every "answer" turns out to be a snappy "only an idiot would need that"
rather than a real answer. I'd kinda like a real answer if there is one.

question, in 3 parts:

1) Why is there a 32767 maximum width/height limit on GUI controls?

This is a limitation imposed by Windows itself. Internally your controls
just call the SetWindowPos API which exhibits this behvaiour. Which version
of Windows are you running? I thought this was resolved in the NT line.
2) Since there is that limit why aren't those properties defined as Shorts
instead of Ints?

Because it's a pain working with shorts. Most methods, classes etc expects
either ints for floats, To have to go and created another set of Size and
Rectangle objects just to handle a special case that nobody really
encounters would be a bit of a waste. So if Longhorn came out supporting int
sizes, we'd all have to change our code that deals with window size &
placement. Finally, ints are more efficient on a 32-bit machine.
3) Why was the decision made to just force higher values to the
Short.MaxValue value without tossing an exception alerting the dev/user
that such a silent force was going on?

No idea. The SetWindowPos function should return a failure code of some
sort, but Control and it's derived classes don't appear to test for it's
failure.
It applies to all controls (buttons, groupboxes, panels, etc) and only
really gets in the way on pictureboxes being filled with very large
images - and that's is where the other "answers" turn into ""you don't
need that ability" rants rather than being very informative.

A 32000 pixel image? That's pretty huge. I'd think that running out of
memory would be your biggest problem here. A quick calculation tells me that
a 32767x32767x32bpp image will take up just shy of 4GB of RAM, leaving about
256KB for the OS.

Have you considered not making the picture box that size, but merely doing
your own "virtual scrolling"? This might also allow you to avoid wiping your
computers memory
There is a mention of a 32bit exposed property being internally a 16bit
value at:

http://msdn.microsoft.com/library/d...eference/scrollbarfunctions/getscrollinfo.asp

... but it seems to be a slightly different issue (or is it?)

It is a different issue.
 
smith said:
Googles shows that this question has been asked a couple of times but every
"answer" turns out to be a snappy "only an idiot would need that" rather
than a real answer. I'd kinda like a real answer if there is one.

question, in 3 parts:

1) Why is there a 32767 maximum width/height limit on GUI controls?

This is a limitation of the Windows OS, not the dotNet Framework. Way back
in the day, the maximum was 16bits. The API was built around this. Then came
Win32, many things were upgraded, but still retained old behaviour for
compatibility. With 32 bit Windows, 32bit Ints are the fastest, so that is
what is used all over the place to return values. Take a look at
GetSystemMetrics, it returns an Int32 for everything, and clearly most
things don't require 32 bits. It was just easier that way to keep things
generic. At its core, the API only supports "windows" (basically every GUI
component is wrapped in a window) whose parameters are based on Signed 16bit
values. Note that Signed is important for the following reason. Littered
throughout the API are methods which return the X/Y parameters packed into
one Int32 (see WM_MOVE message), or only populate 16 bits of the structure,
this in itself would make it a pain to have "windows" support 32bit values
for size and location. Since the underlying value is signed, you can see
that if you just take the 16bit portion at face value, you very well might
have the incorrect value. So they have given you the "GET_X_LPARAM" and
other macros to convert the packed portions of the Int32 into signed Int16s.

So bottom line, it is that way in dotNet, because it is that way in Windows,
because it has been that way since the beginning. To change it would require
an overhaul of the Windows OS itself.
2) Since there is that limit why aren't those properties defined as Shorts
instead of Ints?

Who knows. The underlying Win32API is riddled with inconsistencies like
this. Just compare MoveWindow method with WM_MOVE message. Since MS uses the
habit in the API, it probably just carried over to the dotNet Framework.
Even MS might not have a good explanation.
3) Why was the decision made to just force higher values to the
Short.MaxValue value without tossing an exception alerting the dev/user that
such a silent force was going on?

Again, good question. And the answer is probably similar to above. If you
research the API, you will probably find that they do this in the API, so
they just keep doing it.
It applies to all controls (buttons, groupboxes, panels, etc) and only
really gets in the way on pictureboxes being filled with very large images -
and that's is where the other "answers" turn into ""you don't need that
ability" rants rather than being very informative.

Again, this is because all controls are wrapped by "windows", and this is a
limitation of the OS.
And think about it, there is also a physical address limitation of about
2^32 for Win32.
Given that Windows will currently let you work with values up to about +-
2^15 for X and Y, if you had a picture that extended from max and min values
on each axis ( (2 ^16) ^2), you would basically consume the entire physical
address space for Windows. Just in case you needed another reason as to why
not to do this ;-)
There is a mention of a 32bit exposed property being internally a 16bit
value at:

http://msdn.microsoft.com/library/d...eference/scrollbarfunctions/getscrollinfo.asp

... but it seems to be a slightly different issue (or is it?)

Um, hmm. I could see how you might see them as related, but I don't think
they are. It is however, just another example of inconsistencies in the API
and carryovers from Win16.
If anyone's got an idea, I'd love to hear it just for the knowledge
factor.

heh, don't do it. :-)
You will just need to work around the limit, and clearly there are most
efficient methods of doing this.
 
Thank you gents, you both put the information in a very clear way.

I do realize that using such large values would not give useful results and
it was the mid-level explanation that you gave, rather than a workaround,
that I was looking for.


Just a side-mention of a related minutia: Even the Int16 "adjustment" isn't
good enough to protect against an un-handleable exception when
programmatically resizing any GUI control. If you give it a fast test
sometime you'll be amused or annoyed to see that on a 4:3-native monitor at
32bit color depth the maximum size you can set a control is a square at
16095x16095 while 16096x16096 will crash your app. And, with no obvious
logic, the non-square maximum is 16228x15964 - values set to either
dimension, it doesn't matter -with 16227x15965, 16226x15966, 16225x15997 and
so on crashing your program. If you're using a 4:3-native display at
16bit then you can get a 22762 square result (22763 being the killer) and
the non-square dimension limits are similarly off-kilter.

These values all come from XPPro machines but the tests were done on several
boxes from AMD-M 1Ghz with 16MB shared video ram to 3.2HT P4 with ATI
Radeon 128MBdedicated and the thresholds seem to hold up the same all
around. I also have test numbers on 1440x900 widescreen displays (the
fastest growing niche in laptops) and those results are even more illogical.

I think you get the idea: If these aren't magic numbers then they may as
well be. ;-)

Oh, and it is an "Unhandle-able" Exception. If you try setting a picturebox
or button or listbox or any painted control to sizes greater than those
mentioned above you'll get a
System.ComponentModel.Win32Exception just after setting the properties. You
can use a try-catch to pass the information along to a user, but once they
hit OK on your message and the code returns the app will immediately die an
ungraceful death. There's no way to stop the application from crashing once
the width and height have been specified (and as far as I can tell it's just
plain impossible for .Net to figure out in advance what IS a truly safe
maximum size without using these magic numbers.)

Again, thanks for your taking the time on my Int16/32 trivial quandry... and
if you happen to see some pattern in the numbers above I hope you'll let me
know because while I know it can't be random, it sure seems pretty random to
me. :)

All the best.

Robert Smith
Kirkland, WA
www.smithvoice.com
 
Yeah, I had forgotten about the failures that occur far below the
theoretical maximums of the Int16. Sometime in the last year I think I saw a
discussion on this topic in the microsoft.public.dotnet.framework.drawing
group. Someone posted what seemed to be a reasonable explanation for why it
chokes at those various levels, but I can't seem to locate the posts at the
moment.
IIRC it has something to do with other address limits. Such address pointers
across the whole bitmap with padding can't exceed a certain number. And if
you look at your sample numbers, you are flirting with the 1GB range.

I didn't know it was a fatal error. However, in this case I'm not surprised.
I wouldn't be pleased, but it wouldn't surprise me.

Gerald
 
Back
Top