CSharp Resize flicker and flashing

I

Ian Stiles

If you have "Show window contents while dragging" turned on
(Right-click desktop, Appearance, Effects) then you get horrible
flashing
and flickering on a CSharp form when the form hosts a
TreeView or WebBrowser control and then you resize the form.

Here is what I've tried so far:
1. Turning off CS_VREDRAW and CS_HREDRAW in both the parent form and a
subclass of the control via the "override CreateParams" property
(these values were already off).

2. Setting various styles and handling the OnPaintBackground to do
nothing while also filtering WM_ERASEBKGND during the OnNotifyMessage
event. This was done by the following in the form and control
sub-class constructor:
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);

// Allows for catching the WM_ERASEBKGND message
SetStyle(ControlStyles.EnableNotifyMessage, true);

3. Setting WS_CLIPCHILDREN in the form's CreateParams (was already
set).

4. Using LockWindowUpdate on the Resize event with a timer that clears
it after 300ms of no additional resizes. This fixes the flashing of
the form, but causes desktop icons to refresh which is equally
annoying.

Just for fun I tried Delphi and made a form with both controls and the
resize has no flicker whatsoever so I know a fix is possible.

Thanks in advance for any help.
 
J

Julie

Ian said:
If you have "Show window contents while dragging" turned on
(Right-click desktop, Appearance, Effects) then you get horrible
flashing
and flickering on a CSharp form when the form hosts a
TreeView or WebBrowser control and then you resize the form.

Here is what I've tried so far:
1. Turning off CS_VREDRAW and CS_HREDRAW in both the parent form and a
subclass of the control via the "override CreateParams" property
(these values were already off).

2. Setting various styles and handling the OnPaintBackground to do
nothing while also filtering WM_ERASEBKGND during the OnNotifyMessage
event. This was done by the following in the form and control
sub-class constructor:
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);

// Allows for catching the WM_ERASEBKGND message
SetStyle(ControlStyles.EnableNotifyMessage, true);

3. Setting WS_CLIPCHILDREN in the form's CreateParams (was already
set).

4. Using LockWindowUpdate on the Resize event with a timer that clears
it after 300ms of no additional resizes. This fixes the flashing of
the form, but causes desktop icons to refresh which is equally
annoying.

Just for fun I tried Delphi and made a form with both controls and the
resize has no flicker whatsoever so I know a fix is possible.

Thanks in advance for any help.

C# is an interpreted language, so it will be slower than native machine code.
I don't know if Delphi is interpreted or not.

Don't erase/paint/do anything in response to WM_ERASEBKGND.

Make sure that you paint *ONLY* within the invalid/paint region in response to
the repaint.
 
B

Bob Grommes

Julie said:
C# is an interpreted language, so it will be slower than native machine code.
I don't know if Delphi is interpreted or not.

C# is JIT compiled to native code, so a given line of code is interpreted
only the first time it executes. Even then, what's interpreted is highly
optimized pcode. So it is not really accurate to say that C# is
interpreted -- at least not without qualification.

Since the original poster's problem is confined to the TreeView and
WebBrowser controls, the root cause is probably inefficiencies in those
controls. The steps he's already taken are probably beyond the capabilities
of most WinForm developers, and he still hasn't solved it. So my suggestion
is a low-tech one ... live with it, or consider 3rd party replacements for
the offending controls.

After all, as a user I would not be very concerned about such artifacts if
they were confined to when I was dragging the form. I don't really need to
see it then anyway, at least any more than is needed to position it where I
want it.

--Bob
 
C

C# Learner

Julie said:
[...]
C# is an interpreted language, so it will be slower than native machine code.
I don't know if Delphi is interpreted or not.

Delphi's natively compiled.

Regards
 
J

Jon Skeet [C# MVP]

Julie said:
C# is an interpreted language

No it's not. It's JIT-compiled, which is entirely different from being
interpreted.

Consider a very large loop. In an interpreted language, the interpreter
looks at the bytecodes (or whatever) of the language for each iteration
of the loop, and performs whatever operations those bytecodes describe.
This is very slow.

A JIT-compiler, however, takes the method and compiles it into native
code. The whole loop then runs in native code, and nothing needs to
examine the bytecode within the loop. This is usually about the same
speed as "statically compiled" languages.
 
M

Michael A. Covington

C# Learner said:
Julie said:
[...]
C# is an interpreted language, so it will be slower than native machine code.
I don't know if Delphi is interpreted or not.

Delphi's natively compiled.

C# is JIT-compiled. That is, it is compiled into native code too, but this
normally happens as needed during loading and execution. Once compiled,
it's as native as anything else. That is the .NET path toward inter-CPU
portability.
 
C

C# Learner

Michael said:
C# is JIT-compiled. That is, it is compiled into native code too, but this
normally happens as needed during loading and execution. Once compiled,
it's as native as anything else. That is the .NET path toward inter-CPU
portability.

Yeah, I guess "natively-compiled" is rather ambiguous. Instead, I
should have said "fully compiled prior to program execution".

Thanks
 
J

Julie

Jon Skeet said:
No it's not. It's JIT-compiled, which is entirely different from being
interpreted.

Consider a very large loop. In an interpreted language, the interpreter
looks at the bytecodes (or whatever) of the language for each iteration
of the loop, and performs whatever operations those bytecodes describe.
This is very slow.

A JIT-compiler, however, takes the method and compiles it into native
code. The whole loop then runs in native code, and nothing needs to
examine the bytecode within the loop. This is usually about the same
speed as "statically compiled" languages.

Yeah, I got the terminology wrong.

Regardless it is curently slower than native. Last I heard is that it averages
about 80% as fast as native code.
 
J

Jon Skeet [C# MVP]

Julie said:
Yeah, I got the terminology wrong.

Regardless it is curently slower than native. Last I heard is that it
averages about 80% as fast as native code.

It entirely depends on what you're doing. For many things it'll be very
very close to native code - to the extent that whether or not it beats
a native compiler will depend on the compiler. As I say though, it
depends on what you're doing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top