Hi guys,
I'm starting to use GDI to mess around in Visual C# and I'm drawing a lot of graphics in the Panel container control. What I notice is that as soon as I scroll the panel, the graphics 'scrolled over' are wiped away.
I think I need to 'kill' the paint or 'refresh' method, I'm just not sure how. Any tips or suggestions would be greatly appreciated :)
6 replies to this topic
#1
Posted 04 December 2010 - 07:46 PM
|
|
|
#2
Posted 05 December 2010 - 01:12 AM
Wrong approach. What you have to do is to repaint the graphics each time you receive window messsage WM_PAINT. I haven't been too familiar with C# to know this detail, but perhaps in that Panel there already defined a "Paint" method? If so, usually this "Paint" method called each time the panel receives WM_PAINT message. So you can override it and do the graphics drawing there.
#3
Posted 07 December 2010 - 01:38 PM
This works a little better. I'm working on a project where you pick up pieces of puzzle and place them inside a panel control, but I need to be able to scroll the width and height of panel and keep the pieces drawn at their 'placed' location.
Is this still possible via the paint method while keeping the puzzle pieces at their desired location in the panel?
Is this still possible via the paint method while keeping the puzzle pieces at their desired location in the panel?
#4
Posted 08 December 2010 - 04:02 AM
Of course. My usual approach is to use an off-screen bitmap to store the whole image. When painting, you only draw the area currently shown by the panel.
For example, the whole panel size is 2000x2000pixels while the actual size on screen is 800x400. So you create an 2000x2000 pixels bitmap off-screen and when painting you only paint the area shown by the panel by considering the scrollbar locations. So when painting you have to read the location of the scrollbars. For example, when painting you detect that the horizontal scrollbar is in position 200 and the vertical one is in position 300. Therefore you have to copy area (200, 300) to (1000, 700) from the off-screen bitmap and paint it to your panel.
Note that (1000, 700) is coming from 200 (horizontal scrollbar pos) + 800 (panel's width) and 300 (vertical scrollbar pos) + 400 (panel's height). Actually this is simplified calculation, since in real implementation you also should consider scrollbars dimensions.
For example, the whole panel size is 2000x2000pixels while the actual size on screen is 800x400. So you create an 2000x2000 pixels bitmap off-screen and when painting you only paint the area shown by the panel by considering the scrollbar locations. So when painting you have to read the location of the scrollbars. For example, when painting you detect that the horizontal scrollbar is in position 200 and the vertical one is in position 300. Therefore you have to copy area (200, 300) to (1000, 700) from the off-screen bitmap and paint it to your panel.
Note that (1000, 700) is coming from 200 (horizontal scrollbar pos) + 800 (panel's width) and 300 (vertical scrollbar pos) + 400 (panel's height). Actually this is simplified calculation, since in real implementation you also should consider scrollbars dimensions.
#5
Posted 08 December 2010 - 06:02 AM
from the original question.. to 'kill' the refresh.. I think you mean this.
Assuming you were using your own panel (a class that derived from panel)
eg class MyPanel : Panel ..
you could impose your own redraw behavior..
it's possible to gain much more control over when everything is redrawn.
example: (defined within MyPanel of course)
public const int WM_ERASEBKGND = 0x0014;
protected override void WndProc(ref Message message) {
switch (message.Msg) {
case Win32.WM_ERASEBKGND: //removes flicker
return;
}
base.WndProc(ref message);
}
Assuming you were using your own panel (a class that derived from panel)
eg class MyPanel : Panel ..
you could impose your own redraw behavior..
it's possible to gain much more control over when everything is redrawn.
example: (defined within MyPanel of course)
public const int WM_ERASEBKGND = 0x0014;
protected override void WndProc(ref Message message) {
switch (message.Msg) {
case Win32.WM_ERASEBKGND: //removes flicker
return;
}
base.WndProc(ref message);
}
#6
Posted 08 December 2010 - 08:37 AM
Luth, that was actually very close to one idea that popped into my head after reading your original response, so I'm glad I'm on the right track now!
Thanks :)
Thanks :)
#7
Posted 08 December 2010 - 10:14 AM
Great minds work alike, they say! Just kidding, lol! Btw, I used that technique in some of my software. You can check one, my freeware (Image Captor). There to get the "blacker" background I must use off-screen bitmap. To show the "real" color I used the real image. I have to combine them before painting to screen.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account


Back to top









