HighTechTalks DotNet Forums  

Question on graphic objects disposing

Dotnet Framework (Drawing) microsoft.public.dotnet.framework.drawing


Discuss Question on graphic objects disposing in the Dotnet Framework (Drawing) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #11  
Old   
pamela fluente
 
Posts: n/a

Default Re: Question on graphic objects disposing - 10-28-2006 , 10:07 AM







Quote:
---snip---
Thanks a lot Joergen,

this is very helpful. It's really kind of you to provide such quality
help.

Actually based on your suggestion of using the drawimage function for
the pages, I am actually thinking to modify my current strategy. I am
thinking to replace the controls (which usually are relatively "heavy",
with directly drawn images). Actualy the images I already have, because
they are just the bitmap I currently load as image in the picture
boxes.

The only complication is that would change the coordinates of the mouse
events (I have a lot of mouse processing, dragging and so on, on the
pages). But I expect the effort could be worth. Drawing directly the
pages on a bitmap which represent the vievable portion of the document
should be much quicker than addin the page controls.

Another complication I can foresee is with scrolling. Imagine I have a
100 pages vertically and some othe 10 horizontally. If I place the
pages as picture boxes in a scrollable panel it's easy to scroll and to
dispose them when go out of scope. I am not sure I will be able to
handle this on a bitmap (representing the document). Hmmm, In this case
the bitmap would remain "still" and what change is just the portion of
document which is projected on to it...

-P



Reply With Quote
  #12  
Old   
Joergen Bech
 
Posts: n/a

Default Re: Question on graphic objects disposing - 10-28-2006 , 12:23 PM







Quote:
Another complication I can foresee is with scrolling. Imagine I have a
100 pages vertically and some othe 10 horizontally. If I place the
pages as picture boxes in a scrollable panel it's easy to scroll and to
dispose them when go out of scope. I am not sure I will be able to
handle this on a bitmap (representing the document). Hmmm, In this case
the bitmap would remain "still" and what change is just the portion of
document which is projected on to it...
Just add a horizontal and vertical scrollbar to the usercontrol.
Recalculate their positions, sizes, max values, and visibility every
time the control is resized. Use current values as offsets when
processing subsequent mouse events. When calculating
whether or not to show either vertical or horizontal scrollbar,
remember that the appearance of one limits the space available
on the other axis, which suddenly might require that the other
is shown as well
....

An easier solution might be to set the size of your user control
to encompass the pages you need, place that single user control
on a scrollable panel, thereby getting the scrollbars for free.
Only paint on the part of the user control which is visible.

In this case you should do any buffering yourself. Do NOT use
SetStyle(...) to let the system handle the buffering, as it will
create a buffer the size of the control.

Try out the code below. Start a new VB.NET project, add
a new UserControl named "HugeControl" with the code
shown below. Set Form1.AutoScroll = True. Add an instance
of HugeControl to Form1 and set its size to 30.000 x 30.000.

Yes, a 30.000 x 30.000 pixel control with double-buffered
rendering without taking up more memory for the buffer than
the size of the screen (make sure you read the comments).

/Joergen Bech

---snip---
Option Explicit On
Option Strict On

Public Class HugeControl
Private buffer As Bitmap

Public Sub New()

' This call is required by the Windows Form Designer.
InitializeComponent()

' ' Add any initialization after the
InitializeComponent() call.

'NO! Do NOT use the system's double buffering. A buffer
matching the
' full size of the control would be created, even if we are
only
' going to show a small portion of it.
' If you enable this code, memory will disappear and the
app might
' even crash.
' SetStyle(ControlStyles.AllPaintingInWmPaint, True)
' SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
' SetStyle(ControlStyles.ResizeRedraw, True)
' SetStyle(ControlStyles.UserPaint, True)

'We are being lazy here by just once and for all creating a
buffer
'the size of the primary screen. In the case that the primary
screen
'is smaller than a secondary screen and we are displaying the
application
'on the secondary screen, this is a really, really bad idea.
buffer = New Bitmap(Screen.PrimaryScreen.Bounds.Width, _
Screen.PrimaryScreen.Bounds.Height, _

System.Drawing.Imaging.PixelFormat.Format32bppPArg b)

End Sub

Private Sub HugeControl_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim count As Integer = 0

Dim offsetX As Integer = -e.ClipRectangle.X
Dim offsetY As Integer = -e.ClipRectangle.Y

Dim gBuffer As Graphics = Graphics.FromImage(buffer)

gBuffer.FillRectangle(New SolidBrush(Me.BackColor), New
Rectangle(0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height))

For x As Integer = 0 To Me.ClientRectangle.Width Step 64
Dim x255 As Integer = CType((x / Me.ClientRectangle.Width)
* 255, Integer)
For y As Integer = 0 To Me.ClientRectangle.Height Step 64
Dim y255 As Integer = CType((y /
Me.ClientRectangle.Height) * 255, Integer)
Dim clr As Color = Color.FromArgb(x255, x255, y255)
Dim destrect As New Rectangle(x, y, 64, 64)
If e.ClipRectangle.IntersectsWith(destrect) Then
Dim bufferrect As New Rectangle(x + offsetX, y +
offsetY, 64, 64)
gBuffer.FillEllipse(New SolidBrush(clr),
bufferrect)
count = count + 1
End If
Next
Next

e.Graphics.DrawImageUnscaled(buffer, e.ClipRectangle)

gBuffer.Dispose()

Debug.WriteLine("Count: " & count.ToString)

End Sub

Protected Overrides Sub OnPaintBackground(ByVal e As
System.Windows.Forms.PaintEventArgs)
'Do nothing here. Do not call the base event handler.
End Sub

End Class
---snip---





Reply With Quote
  #13  
Old   
pamela fluente
 
Posts: n/a

Default Re: Question on graphic objects disposing - 10-28-2006 , 03:38 PM





Joergen Bech ha scritto:

....
Quote:
e.Graphics.DrawImageUnscaled(buffer, e.ClipRectangle)

gBuffer.Dispose()

Debug.WriteLine("Count: " & count.ToString)

End Sub

Protected Overrides Sub OnPaintBackground(ByVal e As
System.Windows.Forms.PaintEventArgs)
'Do nothing here. Do not call the base event handler.
End Sub

End Class

Thanks Joergen. Very very helpful.

I am going to rewrite completely my editor based on you enlighting
suggestions

-P




Quote:
---snip---


Reply With Quote
  #14  
Old   
pamela fluente
 
Posts: n/a

Default Re: Question on graphic objects disposing - 10-30-2006 , 04:05 AM




Joergen Bech ha scritto:


Quote:
'NO! Do NOT use the system's double buffering. A buffer
matching the
' full size of the control would be created, even if we are

Hello Joergen,

I wanted just let you know I have rewritten the code for layout
visualization.
I have removed the controls (pages) layed out on a scrolling panel.

As you suggested, I have used a viewport with a couple of scrollbars
(vertical and horizontal).
Only the pages visible are plotted on the viewport and their origin
(the "starting point" of layout) is shifted using the bars to give the
impression of scrolling. I draw the pages on a bitmap (buffer) which is
loaded into the viewport after finishing drawing.

The final result is much smoother and faster. I have not measured it,
but it's probably more
than 10 times faster.

I still have to refine some details (there is something strange going
on with the horizontal bar)
scrolling but I am quite happy with that . Thanks

-P



Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.