What can cause redrawing problems in a 64-bit perspective, but not in a 32-bit version of .NET WInForms?

This happens when compiling for any Cpu, as well as compiling on x86. Sections of the graphical interface are not redrawn if they are not changed, for example, if the main form is maximized, some controls do not change with it, while others have sections that do not redraw and display what was there before.

This works fine on 32-bit machines, both on XP and Vista, but on a 64-bit version of Vista (x64 XP is not required for verification) redrawing just doesn’t work properly.

Anyone have any ideas on where to start tracking this?

Edit: this happens on two separate machines, and at least the one I find now has the latest drivers from NVidia.

Edit2: running a 32-bit XP virtual machine on my 64-bit machine, and the application does not detect a redraw problem in the VM

Edit3: Perhaps this is a problem with the driver, but we do not know whether or when drivers can fix this problem. An employee says that there are fewer problems with an ATI card at home than with NVidia, but in recent months I have been updating my video drivers quite a lot every month, and this is still not allowed, so we can’t just release our product and just tell our customers that someday, driver manufacturers will get around this.

Does anyone have an idea of ​​what to try to avoid? We compile as x86, and all our components are x86. I cannot reproduce this problem using any of the components of the test projects, and I have not heard anyone else report these problems on most component forums, so it is likely that this is what we are doing.

+7
64bit windows-vista winforms redraw
source share
8 answers

That sounds awful like this problem .

When resizing windows in Windows, you usually get a chain in which each window receives a WM_SIZE message, and then calls MoveWindow() (or the like) on its children, which in turn receive WM_SIZE and so on. I'm sure .NET does the same under covers.

On x64, Windows limits the depth of this attachment, and after a certain point (12-15 nested windows) it will no longer send WM_SIZE messages. This limitation does not exist on x86. This limitation affects both x86 and x64 code running on 64-bit versions of Windows.

This took us forever, as different x64 installations showed different symptoms. There are some possible workarounds in the MSDN blog published above - we ended up using the secondary stream to asynchronously create window sizes, this solved the problem fairly neatly.

+13
source share

If you use Windows Forms, this may be due to problems with nesting restrictions in the 64-bit version of Windows.

Details here: http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17829

In short ...

From MS source to 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 research showed that Windows stops sending WM_SIZE when it reaches some specific nesting level. In other words, it will not send WM_SIZE to your child windows if you try to resize them when processing WM_SIZE in the parent. Depending on the material USER / update / seriality packs the maximum nesting level at which WM_SIZE stops spreading, can vary from 15 to 31 and even much higher (virtually unattainable) for the latest XP 32bit / sp2.

But it is still too small under XP x64 and yet some similar ugly things happen to other messages with some Vista builds.

So this, of course, is a Windows error.

You have two options: either reduce the depth of the control hierarchy (a more ideal solution), or derive "fixed" controls from each of the system controls 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 ); } } } 
+3
source share

I think the most likely cause of this problem is the redraw problem in your application. It is possible that in the 64-bit language there is a subtle difference in the settings of Windows messages, which exposes this problem in your code.

You can experiment with this by doing the following.

  • Add a timer to the application.
  • In case of calling the handler flakyControl.Update ()

I would set the timer for something as long as 5 seconds. Then run the application on Win64 and check if this fixes the problem. If so, then the most likely reason is that one of your controls incorrectly signals its invalidity.

I would start with any custom controls in the application. Systematically add an Update call for each override method and event handler in the code. In the end, you will find one that fixes the problem, and then you will find out where the error is actually.

+1
source share

If you use the BeginInvoke () solution described in the MSDN blog , be sure to disable the docking of the child controls, overrides OnSizeChanged (). I had Dock = DockStyle.Fill and I had to switch to DockStyle.None to fix it.

+1
source share

Sounds like a problem with the driver for the screen ...

Try updating the latest drivers and see if this fixes the problem? The 64/32 bit difference is probably red-herring ...

0
source share

I would agree with Gordon. I saw problems when new 64-bit machines had problems displaying programs that looked great under 32-bit ones but would show odd problems on 64-bit machines. Updating to the latest / recommended drivers almost always fixed the problem.

0
source share

The fact that you can run the program on a virtual OS without problems suggests that this is a problem with the driver, because (at least in VirtualPC) the graphics card is emulated. This means that some of the things that the graphics card normally processes are now performed by the processor and thus do not interact with the graphics driver. Keep in mind that I'm not a virtualization specialist, and I believe that the level of virtualization can affect the problem in other ways.

0
source share

I believe this is due to the number of nested HWNDs in the tree. I don’t know the specific details, but some restrictions were imposed on nested HWNDs with 64-bit. The time that I saw is happening, I'm working on it, casting a full perspective from the main theme (or iro) into the Windows classic. At this point, the problems go away.

Try switching to classic, and if that fixes it, see if you can reduce the number of nested HWNDs.

0
source share

All Articles