This happens when compiling for Any Cpu as well as compiling to x86. Sections of the GUI doesn't redraw unless it's resized, for instance if the main form is maximized some of the controls don't resize with it, and others have sections that don't redraw and displays the what was previously there.
This works fine on 32-bit machines, both XP and Vista, but on 64-bit Vista (don't have x64 XP to test with) the redrawing just isn't working properly.
Anyone have any ideas on where to start tracking this down?
Edit: This occurs on 2 separate machines, and at least the one I'm currently on has the latest drivers from NVidia.
Edit2: Running a 32-bit XP virtual machine on my 64-bit machine and the application doesn't exhibit the redrawing issue in the VM
Edit3: It may be a driver issue, but we don't know if or when drivers will fix the issue. A co-worker says there's fewer issues with an ATI card at home than with NVidia, but I've been updating my video drivers pretty much monthly for the past few months and it's still not resolved, so we can't just release our product and just tell our customers that some day the driver manufacturers may get around to fixing this.
Does anyone have any insight on what things to try to avoid? We're compiling as x86 and all our components are x86. I can't seem to reproduce this issue with any of the components in test projects, and I haven't heard anyone else report these issues on most of the the component forums, so it is fairly likely that it's something we're doing.
That sounds horribly like this problem.
When resizing windows on Windows you typically get a chain where each window receives a WM_SIZE
message and then calls MoveWindow()
(or similar) on its children which in turn receive a WM_SIZE
and so on. I'm sure that .NET does the same thing under the covers.
On x64, Windows limits the depth of this nesting, and after a certain point (12-15 nested windows) it will just not send the WM_SIZE
messages anymore. This limitation does not appear to exist on x86. This limitation affects both x86 and x64 code running on x64 versions of Windows.
This foxed us for ages, as different x64 installs would show different symptoms. The MSDN blog posting above has some possible workarounds - we ended up using a secondary thread to do the window sizes asynchronously, this solved the problem fairly neatly.
If you're using Windows Forms, it could be to do with nesting limitation issues on Windows 64-bit.
Details here: http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17829
In summary...
From the MS source, in Control.SetBoundsCore:
SafeNativeMethods.SetWindowPos(new HandleRef(window, Handle), NativeMethods.NullHandleRef, x, y, width, height, flags);
// NOTE: SetWindowPos causes a WM_WINDOWPOSCHANGED which is processed
// synchonously so we effectively end up in UpdateBounds immediately following
// SetWindowPos.
//
//UpdateBounds(x, y, width, height);
And from MSDN:
http://social.msdn.microsoft.com/forums/en-US/windowsuidevelopment/thread/25181bd5-394d-4b94-a6ef-06e3e4287527/
"A little investigation showed that Windows stops sending WM_SIZE when it reaches some certain nesting level. In other words, it won't send WM_SIZE to your child windows if you try to resize them when you process WM_SIZE in the parent ones. Depending on the USER stuff/updates/serivice packs the maximum nesting level at which it stops propagating WM_SIZE may vary from 15 to 31 and even much higher (effectively unreachable) under latest XP 32bit/sp2.
But it still too little under XP x64 and still some similar ugly things happen to other messages under some builds of Vista.
So it is certainly a Windows bug."
You have two choices: either reduce the depth of your control hierarchy (the more ideal solution), or else derive "fixed" controls from each of the system ones that you use, as follows:
public class FixedPanel : Panel
{
protected override void SetBoundsCore( int x, int y, int width, int height, BoundsSpecified specified )
{
base.SetBoundsCore( x, y, width, height, specified );
if( specified != BoundsSpecified.None )
{
if( ( specified & BoundsSpecified.X ) == BoundsSpecified.None )
{
x = Left;
}
if( ( specified & BoundsSpecified.Y ) == BoundsSpecified.None )
{
y = Top;
}
if( ( specified & BoundsSpecified.Width ) == BoundsSpecified.None )
{
width = Width;
}
if( ( specified & BoundsSpecified.Height ) == BoundsSpecified.None )
{
height = Height;
}
}
if( x != Left || y != Top || width != Width || height != Height )
{
UpdateBounds( x, y, width, height );
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With