Home All Groups Group Topic Archive Search About

How do I avoid performance-robbing operations while resizing a form?

Author
8 May 2007 3:39 AM
Peter Duniho
The basic idea: I've got a form in which I draw a bitmap, scaled to fit 
the form.  For obvious reasons, I want to cache the scaled version of the 
bitmap so that repainting the form is faster.  I need to update the cache 
any time the form size is changed.  But I don't want to generate the 
scaled bitmap every time I get the Resize event, because doing so makes 
the resizing itself way too slow, even on a fast computer.

Ideally, I'm looking for an event that basically says "the form size has 
changed and the user is done dragging".  Alternatively would be some 
convenient way to detect when the user starts and stops dragging the form.

The only solutions I've come up with so far are getting into the nuts and 
bolts of the form's window, with the WndProc and the window messages 
(probably have to be non-client, since I don't see anything obvious in the 
basic WM messages that would work), or taking a completely different 
approach to maintaining performance of the Resize event.

I'd prefer to avoid messing around with the WndProc, especially if there's 
a better .NET Framework-approved way of dealing with the issue.  In the 
latter idea, all I can come up with is doing the bitmap caching in the 
background on a different thread.  That would work, and probably pretty 
well too, but it seems overly complicated.

It seems like this would come up fairly often...what techniques are other 
people using to deal with the problem?

Thanks!
Pete

Author
8 May 2007 4:19 AM
Peter Duniho
On Mon, 07 May 2007 20:39:02 -0700, Peter Duniho 
<NpOeStPe***@nnowslpianmk.com> wrote:

> [...]
> In the latter idea, all I can come up with is doing the bitmap caching 
> in the background on a different thread.  That would work, and probably 
> pretty well too, but it seems overly complicated.

For the record, I tried this mechanism, and it didn't improve 
responsiveness at all anyway.  So, obviously my guess of "pretty well" was 
way off.  :)

I admit, even without rebuilding the cached bitmap, performance for 
resizing the form isn't great.  But the best responsiveness still comes 
when I don't do anything except redraw (no creating new bitmaps).  I'd 
sure love to hear if anyone has ideas for how to either improve the 
overall responsiveness, or know when the user is dragging the window (so I 
can avoid bothering to rebuild the cached version when that's happening).

Thanks,
Pete
Author
8 May 2007 5:10 AM
Lloyd Dupont
why not used vector graphic instead of a bitmap?
i.e. instead of generating a bitmap, why not draw directly on the form?

--
Regards,
Lloyd Dupont
NovaMind Software
Mind Mapping at its best
www.nova-mind.com
Show quote
"Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote in message
news:op.trzofclw8jd0ej@petes-computer.local...
> The basic idea: I've got a form in which I draw a bitmap, scaled to fit
> the form.  For obvious reasons, I want to cache the scaled version of the
> bitmap so that repainting the form is faster.  I need to update the cache
> any time the form size is changed.  But I don't want to generate the
> scaled bitmap every time I get the Resize event, because doing so makes
> the resizing itself way too slow, even on a fast computer.
>
> Ideally, I'm looking for an event that basically says "the form size has
> changed and the user is done dragging".  Alternatively would be some
> convenient way to detect when the user starts and stops dragging the form.
>
> The only solutions I've come up with so far are getting into the nuts and
> bolts of the form's window, with the WndProc and the window messages
> (probably have to be non-client, since I don't see anything obvious in the
> basic WM messages that would work), or taking a completely different
> approach to maintaining performance of the Resize event.
>
> I'd prefer to avoid messing around with the WndProc, especially if there's
> a better .NET Framework-approved way of dealing with the issue.  In the
> latter idea, all I can come up with is doing the bitmap caching in the
> background on a different thread.  That would work, and probably pretty
> well too, but it seems overly complicated.
>
> It seems like this would come up fairly often...what techniques are other
> people using to deal with the problem?
>
> Thanks!
> Pete
Author
8 May 2007 4:28 PM
Peter Duniho
On Mon, 07 May 2007 22:10:48 -0700, Lloyd Dupont <net.galador@ld> wrote:

> why not used vector graphic instead of a bitmap?
> i.e. instead of generating a bitmap, why not draw directly on the form?

Because the image that I'm drawing is itself a bitmap.  I agree it would 
be a waste to cache non-bitmap data to a bitmap, but since I'm starting 
with a bitmap in the first place, it's not an option to just render using 
vector-based commands.

Pete
Author
8 May 2007 2:59 PM
Brian Schwartz
Are you using .NET 2.0? Forms have ResizeBegin and ResizeEnd events.

--
Brian Schwartz
FishNet Components
http://www.fishnetcomponents.com
Fish Grid .NET Light: Powerful Layouts for Small Datasets


Show quote
"Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote in message
news:op.trzofclw8jd0ej@petes-computer.local...
> The basic idea: I've got a form in which I draw a bitmap, scaled to fit
> the form.  For obvious reasons, I want to cache the scaled version of the
> bitmap so that repainting the form is faster.  I need to update the cache
> any time the form size is changed.  But I don't want to generate the
> scaled bitmap every time I get the Resize event, because doing so makes
> the resizing itself way too slow, even on a fast computer.
>
> Ideally, I'm looking for an event that basically says "the form size has
> changed and the user is done dragging".  Alternatively would be some
> convenient way to detect when the user starts and stops dragging the form.
>
> The only solutions I've come up with so far are getting into the nuts and
> bolts of the form's window, with the WndProc and the window messages
> (probably have to be non-client, since I don't see anything obvious in the
> basic WM messages that would work), or taking a completely different
> approach to maintaining performance of the Resize event.
>
> I'd prefer to avoid messing around with the WndProc, especially if there's
> a better .NET Framework-approved way of dealing with the issue.  In the
> latter idea, all I can come up with is doing the bitmap caching in the
> background on a different thread.  That would work, and probably pretty
> well too, but it seems overly complicated.
>
> It seems like this would come up fairly often...what techniques are other
> people using to deal with the problem?
>
> Thanks!
> Pete
Author
8 May 2007 4:29 PM
Peter Duniho
On Tue, 08 May 2007 07:59:33 -0700, Brian Schwartz 
<ow***@fishnetcomponentswos.com> wrote:

> Are you using .NET 2.0? Forms have ResizeBegin and ResizeEnd events.

Yes.  I missed those.  Probably because I was looking only at the events 
in my custom control, rather than in the form containing that control.  
Thanks!

Pete
Author
8 May 2007 11:23 PM
Peter Duniho
On Tue, 08 May 2007 09:29:51 -0700, Peter Duniho 
<NpOeStPe***@nnowslpianmk.com> wrote:

> On Tue, 08 May 2007 07:59:33 -0700, Brian Schwartz 
> <ow***@fishnetcomponentswos.com> wrote:
>
>> Are you using .NET 2.0? Forms have ResizeBegin and ResizeEnd events.
>
> Yes.  I missed those.  Probably because I was looking only at the events 
> in my custom control, rather than in the form containing that control.  
> Thanks!

Just to follow up...

These events do just what I want.  By setting a flag in ResizeBegin, I can 
conditionally do the extra work either in the OnClientSizeChanged method 
(if the flag is clear) or in the ResizeEnd event handler.  This way I only 
do the expensive work of caching a new bitmap the right size for the 
control when the user is done messing with the window.

One little gotcha: you only get these events in a Form, but I'm using them 
in a custom Control.  So my Control-derived class has to subscribe to the 
ParentChanged event, walk up the tree to find the actual Form that owns 
the control, and then subscribe to that form's ResizeBegin and ResizeEnd 
events.

Seems a little clunky to me, but it works.  :)  Thanks for the tip Brian.

Pete

AddThis Social Bookmark Button