tags:

views:

1829

answers:

7

I'm working on a C#.Net application which has a somewhat annoying bug in it. The main window has a number of tabs, each of which has a grid on it. When switching from one tab to another, or selecting a different row in a grid, it does some background processing, and during this the menu flickers as it's redrawn (File, Help, etc menu items as well as window icon and title).

I tried disabling the redraw on the window while switching tabs/rows (WM_SETREDRAW message) at first. In one case, it works perfectly. In the other, it solves the immediate bug (title/menu flicker), but between disabling the redraw and enabling it again, the window is "transparent" to mouse clicks - there's a small window (<1 sec) in which I can click and it will, say, highlight an icon on my desktop, as if the app wasn't there at all. If I have something else running in the background (Firefox, say) it will actually get focus when clicked (and draw part of the browser, say the address bar.)

Here's code I added.

m = new Message();
m.HWnd = System.Windows.Forms.Application.OpenForms[0].Handle; //top level
m.WParam = (IntPtr)0; //disable redraw
m.LParam = (IntPtr)0; //unused
m.Msg = 11; //wm_setredraw
WndProc(ref m);

<snip> - Application ignores clicks while in this section (in one case)

m = new Message();
m.HWnd = System.Windows.Forms.Application.OpenForms[0].Handle; //top level
m.WParam = (IntPtr)1; //enable
m.LParam = (IntPtr)0; //unused
m.Msg = 11; //wm_setredraw
WndProc(ref m);

System.Windows.Forms.Application.OpenForms[0].Refresh();

Does anyone know if a) there's a way to fix the transparent-application problem here, or b) if I'm doing it wrong in the first place and this should be fixed some other way?

A: 

There are calls on classes derived from Control for this purpose. They are SuspendLayout and PerformLayout. As they are on Control and Form is derived from Control, your Form has them too.

These calls suffice for most updates but in other circumstances, just hiding the control using Visible = false can be enough. To stop the flicker during this of hiding then reshowing the control, I usually draw the control to a bitmap which I show in a PictureBox during the update. This is useful when updating trees, tab controls, or lists (as can turning off sorting during the update in that last example).

Jeff Yates
A: 

I tried the Layout functions to begin with, but the problem persists. I did notice that after disabling the redraw, the form's CanFocus property becomes false; that might explain the mouse behaviour.

A: 

The behavior you're describing is not normal for a .NET winforms application. The fact that you're using WndProc and sending messages in your example suggests that there is a lot of other unusual stuff going on with this form (I'm guessing there's more than one thread involved). Another possibility that is common in tabbed interfaces is that your form is simply overloaded with controls; sometimes this can cause strange behavior.

I have never witnessed or heard of anything remotely like what you describe.

MusiGenesis
A: 

You can try override the Paint method on your control that you do not want rendered and control it by some global boolean (=ignore all painting while some bool is true.) If your control is a 3rd party, subclass it and override it there.

Then when you are satisified, set the bool to false and let the control be painted again (might have to force a paint when you turn it on again with .Refresh?)

Wolf5
A: 

Thanks for the replies all. Paint override didn't help. I think this one will get sent to the bottom of the pile.

A: 
  0132 » Do your desktop icons redraw frequently? 14-Apr-97


  If your desktop icons redraw frequently, try editing:
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer
  Add Value of Max Cached Icons with type REG_SZ. Set it to 4000.
  Note: There is a space after Max and after Cached.
A: 

If this is a custom control, you can try some of the control style flags: I think DoubleBuffered or AllPaintingInWmPaint might help. You can change the style bits using Control.SetStyle (which is protected, which is why you need to do it in your own custom Control class).

Avish