Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Drawing / April 2005

Tip: Looking for answers? Try searching our database.

How to give parameters to the paint event handler

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
György - 27 Apr 2005 22:47 GMT
I would like to place a character to different points ( X and Y coord) on a
graphics screen. I use the paint event handler to draw my graphics but can
not update the screen with new co-ordinates where I want to place a new
character. Does anybody knows how to submit the parameters to a paint event
handler?

Thanks,
György
Morten Wennevik - 27 Apr 2005 23:26 GMT
Hi György,

I think you need to rethink your strategy.  You call the paint event (by calling Invalidate), then the code inside the event checks to see where to draw the character.

You can't pass parameters directly to the Paint event, but you can do painting outside the event using CreateGraphics.  However, you should try to avoid calling CreateGraphics and do all your drawing inside Paint.

> I would like to place a character to different points ( X and Y coord) on a
> graphics screen. I use the paint event handler to draw my graphics but can
[quoted text clipped - 4 lines]
> Thanks,
> György

Signature

Happy coding!
Morten Wennevik [C# MVP]

Bob Powell [MVP] - 27 Apr 2005 23:30 GMT
You cannot hand new parameters to the Paint event handler. You must create a
variable in your class that maintains the new coordinate.

Signature

Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

> I would like to place a character to different points ( X and Y coord) on
> a
[quoted text clipped - 6 lines]
> Thanks,
> György
György - 28 Apr 2005 15:36 GMT
Dear Bob and Morten,

I went through the web site of Bob and learned a lot. Thanks for bringing it
to life.

But I still confused what is the right solution. According to my
understanding I could do the following:
•    Creating a new blank image in a new Thread
•    Generate a Graphics object with the use of Graphics..Fromimage
•    Stop my thread with an AutoReset EventWait to wait on X,Y coordinates
•    Receiving the coordinates I create my graphics drawing ( place a “dot”
character)
•    Set an other AutoResetEvent informing my X,Y supply thread to go ehead

Is it a possible way?

Many thanks,
György

> You cannot hand new parameters to the Paint event handler. You must create a
> variable in your class that maintains the new coordinate.
[quoted text clipped - 9 lines]
> > Thanks,
> > György
Bob Powell [MVP] - 28 Apr 2005 16:13 GMT
What I don't understand here is exactly what you're trying to do and why you
think you need a multi-threading solution.

Just explain the goal that you want to achieve.

Signature

Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

> Dear Bob and Morten,
>
[quoted text clipped - 32 lines]
>> > Thanks,
>> > György
György - 28 Apr 2005 16:28 GMT
I work on a data acquisition system. I measure something and basically I need
to place a dot to the screen to indicate the measured value.  Than comes a
new measurement and the previous point should be cleared and the new dot
should appear on the screen.  Basically that is the case.
So I need to modify the screen content continuously and because of handling
the measurement device I anyway have multi threads.

György

> What I don't understand here is exactly what you're trying to do and why you
> think you need a multi-threading solution.
[quoted text clipped - 37 lines]
> >> > Thanks,
> >> > György
Bob Powell [MVP] - 28 Apr 2005 17:33 GMT
Just store a point and paint it whenever the screen is invalidated...

Point blob=new Point(-50,-50);

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs
e)

{

e.Graphics.FillEllipse(Brushes.Red,blob.X-10,blob.Y-10,20,20);

}

private void Form1_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)

{

blob=new Point(e.X,e.Y);

}

Signature

Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

>I work on a data acquisition system. I measure something and basically I
>need
[quoted text clipped - 56 lines]
>> >> > Thanks,
>> >> > György
György - 28 Apr 2005 17:54 GMT
Do you mean that I should call the Invalidate method from one of my thread
and that will generate a Form1_Paint event which will refresh the screen? If
so, than when I get a new paint event can I save the content of the screen
and only change what I intend to chane?

György

> Just store a point and paint it whenever the screen is invalidated...
>
[quoted text clipped - 78 lines]
> >> >> > Thanks,
> >> >> > György
Bob Powell [MVP] - 28 Apr 2005 18:36 GMT
From one of your threads you can invalidate the main form but ONLY using the
Invoke or BeginInvoke methods.

You will need to repaint all elements of the screen that are in the invalid
rectangle. If you just call invalidate() then that means all of it.

Don't try to save the content of the screen. The screen should know how to
refresh itself at all times so if the only place you're keeping records is
in the actual pixels of the display you're guaranteed to be causing yourself
problems later.

Signature

Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

> Do you mean that I should call the Invalidate method from one of my thread
> and that will generate a Form1_Paint event which will refresh the screen?
[quoted text clipped - 93 lines]
>> >> >> > Thanks,
>> >> >> > György
György - 28 Apr 2005 19:16 GMT
There is not any other option just to simply edit the content of the screen.
I just want to write out a black coloured charcter to my old position to
clear the old content and write a new character in white color into the new
position.  Is not it possible to do it with CreateGraphics?

György

> From one of your threads you can invalidate the main form but ONLY using the
> Invoke or BeginInvoke methods.
[quoted text clipped - 104 lines]
> >> >> >> > Thanks,
> >> >> >> > György
James Westgate - 28 Apr 2005 21:17 GMT
Dude,

Listen to Bob. He knows what he's doing. We've been there a million times,
trust me on this one.

The GDI+ graphics system is stateless and event driven, this means you need
to repaint everything that is required in the correct order *everytime* the
screen or control or control portion is repainted. Access the control across
the thread using an invoke and set a property eg your point. The control
will know when to paint itself and will then paint the dot.

Dont use CreateGraphics for the reasons outlined in this forum in recent
posts and on Bob's site.

This is a really simple 5 minute job, you dont need to make it complicated
;)

James

> There is not any other option just to simply edit the content of the
> screen.
[quoted text clipped - 129 lines]
>> >> >> >> > Thanks,
>> >> >> >> > György
György - 29 Apr 2005 15:00 GMT
Finally I found a solution. Propably could be interesting for your FAQ site.

•    First I created a blank bitmap. In one of my thread
•    Than I edited my screen into the bitmap. Also in the thread
•    In the paint event handler I just placed a DrawImage command from the bitmap
•    When I wanted to refresh my screen I called the Invalidate method to
generate a paint event.
•    I again did some minor changes on my bitmap and called the invalidate()…..

It works fine. The only pending issue at the moment that I have to find a
solution to invalidate only a pie or rectangle of the bitmap to lower the
flickers of the screen.
If you may have a better idea please let me known!

György

> Dude,
>
[quoted text clipped - 148 lines]
> >> >> >> >> > Thanks,
> >> >> >> >> > György
György - 29 Apr 2005 14:58 GMT
Finally I found a solution. Propably could be interesting for your FAQ site.

•    First I created a blank bitmap. In one of my thread
•    Than I edited my screen into the bitmap. Also in the thread
•    In the paint event handler I just placed a DrawImage command from the bitmap
•    When I wanted to refresh my screen I called the Invalidate method to
generate a paint event.
•    I again did some minor changes on my bitmap and called the invalidate()…..

It works fine. The only pending issue at the moment that I have to find a
solution to invalidate only a pie or rectangle of the bitmap to lower the
flickers of the screen.
If you may have a better idea please let me known!

György

> From one of your threads you can invalidate the main form but ONLY using the
> Invoke or BeginInvoke methods.
[quoted text clipped - 104 lines]
> >> >> >> > Thanks,
> >> >> >> > György
Frank Hileman - 29 Apr 2005 20:04 GMT
This has the potential to fail if you do not lock the Bitmap. In general the
GDI+ methods in .NET are no more thread-safe than Windows Forms methods. The
safest solution is to do all drawing in the main thread, started by
BeginInvoke on a Control or Form.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

> Finally I found a solution. Propably could be interesting for your FAQ
> site.
[quoted text clipped - 14 lines]
>
> György
György - 29 Apr 2005 20:40 GMT
Dear Frank,

Thanks for the advice. I will look after it.

By the way can you see other option to change a graphics screen with
parameters coming from an other thread?

Sincerely,
György

> This has the potential to fail if you do not lock the Bitmap. In general the
> GDI+ methods in .NET are no more thread-safe than Windows Forms methods. The
[quoted text clipped - 26 lines]
> >
> > György
Frank Hileman - 29 Apr 2005 22:10 GMT
Typically people use BeginInvoke, passing in data which is then rendered in
the main UI thread. You will need an efficient rendering engine to be sure
it can keep up without bogging down the UI. You can pass parameters in
BeginInvoke to maintain separation between threads without locking, or you
can simply use it to notify the main thread, and use locks around data
structures to prevent conflicts between the threads.

For example, if you do not want to use locks, your data acquisition thread
allocates and fill a buffer (collection or array), then when it has acquired
enough (or enough time has passed), call BeginInvoke, passing in the buffer
as a parameter. Then the data acquisition thread no longer touches that
buffer but immediately allocates the new one. The garbage collector will
clean up. This is a nice simple way to do it.

If you don't like to allocate so many objects, you could keep two buffers,
and two locks, one associated with each buffer. The data acquisition thread
locks buffer1. When buffer1 is "full" or enough time has passed, BeginInvoke
is called and the lock is released. Immediately the data acquisition thread
then tries to lock buffer2.

The main UI thread then locks the incoming buffer (which buffer might be
specified with an int) and processes it. When done it releases the buffer
lock.

Using the locking solution there is a chance that the next buffer is not
ready for the DA thread when it needs it. In this case you have to decide if
you need every bit of data, and if you do, you need to just keep adding to
the free buffer until the other one is released, by periodically checking
with Monitor.TryEnter.

Using either solution the UI thread must be able to keep up, or you must
abandon data, or decide to skip the rendering. In your rendering code you
could periodically check a flag indicating it is necessary to abandon
rendering. The non-UI thread would set this flag (noticing a backlog of
data), and the UI thread would clear the flag whenever rendering is
abandoned or finished. It is a little more complicated than that to prevent
a race, but I think you get the idea.

By the way, the VG.net run-time engine will automatically redraw a minimum
number of pixels when you modify a graphical object. That engine is free for
run-time only use.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

> Dear Frank,
>
[quoted text clipped - 40 lines]
>> >
>> > György
György - 30 Apr 2005 20:26 GMT
Dear Frank,

Thank you for your time to write down these valuable ideas! I will
definitelly read the relewant documentation and try to implement them.  
Regarding the VG.net may I take it as an option to download from your site?

I have an other pending issue and would appreciate your idea about layering.
I will need one or two layers with fix content that I do not want to change
and will need a third one where I want to do my picture changes that we
discussed before.

Many thanks,
Sincerely,
György

> Typically people use BeginInvoke, passing in data which is then rendered in
> the main UI thread. You will need an efficient rendering engine to be sure
[quoted text clipped - 89 lines]
> >> >
> >> > György
Frank Hileman - 30 Apr 2005 22:15 GMT
Hello György,

Regarding VG.net: the Lite version has a run-time engine in
Prodige.Drawing.dll you can use. If you do not have Visual Studio 2003 send
me a note through the web site, and I can get you an SDK.

Layering: you will need graphical objects that know how to draw themselves,
called a retained mode graphics system. VG.net objects automatically redraw
areas invalidated by animation, or you can look at Bob Powell's site for
more ideas on building a system yourself. If you do it without VG.net you
have to keep track of which objects overlay each other, or redraw the whole
screen.

Regards,
Frank

> Dear Frank,
>
[quoted text clipped - 77 lines]
>> Animated vector graphics system
>> Integrated Visual Studio .NET graphics editor
György - 28 Apr 2005 16:28 GMT
I work on a data acquisition system. I measure something and basically I need
to place a dot to the screen to indicate the measured value.  Than comes a
new measurement and the previous point should be cleared and the new dot
should appear on the screen.  Basically that is the case.
So I need to modify the screen content continuously and because of handling
the measurement device I anyway have multi threads.

György

> What I don't understand here is exactly what you're trying to do and why you
> think you need a multi-threading solution.
[quoted text clipped - 37 lines]
> >> > Thanks,
> >> > György

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.