By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,967 Members | 2,211 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,967 IT Pros & Developers. It's quick & easy.

graphics help

P: n/a
I need some help. I have an app that talks to a sonar board via the
serial port. In my sp_DataReceived I gather all the data and put it
into arrays. Then I want to draw the data in a pictureBox. I wrote a
function called Draw_sonar2 that does all the drawing. It usually
works but sometimes crashes saying the graphics object is already in
use. After digging I saw that I should be doing the Drawing in the
PB.paint, not a seperate function. My problem is how to move the code
from Draw_sonar2 to pb.paint.

Here are my current functions
private void DrawSonar2()
{
Graphics objGraphics;
objGraphics = Graphics.FromImage(m_objDrawingSurface);
objGraphics.Clear(SystemColors.Control);
int startX, startY, endX, endY;
int angle;
startX = m_objDrawingSurface.Width / 2;
startY = m_objDrawingSurface.Height - robotDiameter/2;

for (int x = 0; x <= 9; x++)
{
int Angle = SA.sensorAngle[x];
int BeamWidth = SA.sensorBeamWidth[x];
int Range = SA.Range[x]*int.Parse(textBox_scale.Text);
if (Range int.Parse(textBox_maxRange.Text) *
int.Parse(textBox_scale.Text))
Range = int.Parse(textBox_maxRange.Text) *
int.Parse(textBox_scale.Text);
for (angle = (Angle - (BeamWidth / 2)); angle < (Angle
+ (BeamWidth / 2)); angle += 2)
{
endX = startX + (int)(Range * Math.Cos(angle *
6.28 / 360));
endY = startY + (int)(Range * Math.Sin(angle *
6.28 / 360));
objGraphics.DrawLine(Pens.Green, startX, startY,
endX, endY);

}
}

objGraphics.Dispose();
PB.Invalidate();
}
private void PB_Paint(object sender, PaintEventArgs e)
{

/////////////////////////////////
Graphics objGraphics;
objGraphics = e.Graphics;
objGraphics.Clear(SystemColors.Control);

objGraphics.DrawImage(m_objDrawingSurface, 0, 0,
m_objDrawingSurface.Width, m_objDrawingSurface.Height);
// objGraphics.Dispose();
}
if I change the line in sp_DataReceived from
DrawSonar2();
to
PB.Invalidate();

And then move the code into PB_paint like this

private void PB_Paint(object sender, PaintEventArgs e)
{
Graphics objGraphics;
objGraphics = Graphics.FromImage(m_objDrawingSurface);
objGraphics.Clear(SystemColors.Control);
// Rectangle rectBounds;
int startX, startY, endX, endY;
int angle;
startX = m_objDrawingSurface.Width / 2;
startY = m_objDrawingSurface.Height - robotDiameter / 2;

objGraphics = Graphics.FromImage(m_objDrawingSurface);
for (int x = 0; x <= 9; x++)
{
int Angle = SA.sensorAngle[x];
int BeamWidth = SA.sensorBeamWidth[x];
int Range = SA.Range[x] *
int.Parse(textBox_scale.Text);
if (Range int.Parse(textBox_maxRange.Text) *
int.Parse(textBox_scale.Text))
Range = int.Parse(textBox_maxRange.Text) *
int.Parse(textBox_scale.Text);
for (angle = (Angle - (BeamWidth / 2)); angle < (Angle
+ (BeamWidth / 2)); angle += 2)
{
endX = startX + (int)(Range * Math.Cos(angle *
6.28 / 360));
endY = startY + (int)(Range * Math.Sin(angle *
6.28 / 360));
objGraphics.DrawLine(Pens.Green, startX, startY,
endX, endY);

}
}

objGraphics.Dispose();
}

Then nothing ever draws. What am I missing.

Is this the correct way to do it, or was I closer the first time with
Draw_sonar2?

Thanks
Ringo

Oct 1 '07 #1
Share this Question
Share on Google+
1 Reply


P: n/a
Ringo wrote:
[...]
Then nothing ever draws. What am I missing.

Is this the correct way to do it, or was I closer the first time with
Draw_sonar2?
Well, what is "m_objDrawingSurface"?

Based on the "before" code, it seems to be some sort of Image object
(Bitmap, Metafile, whatever). It seems to me that the original code was
not actually all that bad. The one obvious thing I see is that you
should not need to erase the background in the Paint handler. The
control will get a separate event to do that. (But you do need to erase
the background in your image object, of course).

But other than that, the original code is actually more efficient,
because you draw once into some cached image object, and use that to
update the control whenever it actually needs updating. This way you
only update the image object when the data changes, and otherwise if the
control needs redrawing for some reason other than that (overlapping
windows being moved, for example) all you have to do is copy the image
that's already been drawn.

However, if you really want to fix the "after" code, you're going to
need to draw to the Graphics object in the event rather than the
"m_objDrawingSurface" object. If you do it that way, you should just
get rid of the "m_objDrawingSurface" altogether. There's no need to
have it if you are going to redraw everything every time the control
needs updating. (Getting rid of that object will also eliminate the bug
you have where you get a Graphics object from the "m_objDrawingSurface"
twice :) ).

Pete
Oct 1 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.