From: Webbiz on
Hello.

An old project of mine draws stock charts on a picturebox called
pctChart.

On this pctChart, a routine called DrawChart is used to draw OHLC or
Candlestick price bars.

After the bars are drawn, the chart tools are drawn over them, such as
lines, boxes, etc. This is done in RedrawTools.

Currently, I can scroll this chart by either double-clicking the
chart, holding down the mouse button on the second click, and dragging
the mouse to a new location. After the mouse is let up, then the draw
is redrawn in the new location.

Or, I can press and hold the Left or Right arrow keys and it will
scroll the chart (slowly) to the right or left.

Problem:

With the arrow keys, in order to show the chart actually scrolling, it
runs the DrawChart and RedrawTools over and over, one day (bar) at a
time. This looks really rickety, and moves so slow. Watching it redraw
each time is a flickering hodge-podge. It would be nice if the chart
would scroll smoothly and quickly.

As for scrolling with the mouse, I'd like it to actually show the bars
scrolling, also smoothly and as quick as the mouse is being moved,
while the mouse is being moved. Right now, I don't do any of the
redraw with the mouse until it has stopped at the new location,
because of the flickering issue. There is just all these redraws.

Because I have purchased programs that seem to do this without any
problem, I believe it should be possible to do the same with my
project. Yet, I'm wondering if this is a VB6 problem, and that I'd
have to program with C to achieve the above.

And yes, I have a decently quick computer and graphics card, so that's
not the problem.

Any suggestions, tips and otherwise?

Thanks.

Webbiz
From: Nobody on
Use the same technique used by games. It's called double buffering. Draw
everything on another PictureBox that has AutoRedraw=True, and
Visible=False. Once you are done, copy from the off screen PictureBox to the
on screen PictureBox. Example copying code:

Set pctChartOnScreen.Picture = pctChartOffScreen.Picture
pctChartOnScreen.Refresh ' Only use if pctChartOnScreen.AutoRedraw=True



From: Mike Williams on
"Webbiz" <nospam(a)forme.thanks.com> wrote in message
news:lfolg51dqo43v288g7k8v7ahd7fv5f2gce(a)4ax.com...

> With the arrow keys, in order to show the chart actually
> scrolling and using it runs the DrawChart and RedrawTools
> over and over, one day (bar) at a time.

If you are using key events then the scroll rate will be limited by the
current keyboard repeat rate, but I imagine you are already aware of that
and are reading the state of the arrow keys in a way that overcomes that
problem?

> This looks really rickety, and moves so slow.

Are you redrawing the entire PictureBox each time, or are you drawing only
the new data and scrolling any unchanged existing data by blitting the
unchanged block a little to the left? (although which will be the faster of
these two methods depends on the complexity of your drawings).

> Watching it redraw each time is a flickering hodge-podge

With many kinds of drawings you need to use double buffering in order to
eliminate the flicker, as has already been mentioned by "Nobody".

By the way, are you using the most appropriate GDI functions for your
drawings? For example, are you using PolyLine and Rectangle etc rather than
individual LineTo calls? Most GDI drawing functions are very much slower in
Vista than they are in XP (because most Vista systems do not use your video
card's GDI accelerated hardware, whereas XP systems almost always do) but
even in Vista using things like Polyline can be up to two or three times
faster than the equivalent bunch of LineTo calls (and of course often very
much faster still on the same system running XP). Also, if you are using a
system that does use the video card's accelerated 2D hardware (Win98 / XP)
you will find that Polyline is very much slower if there is a "clipping
hole" in the window that covers even a single pixel of the complete Polyline
drawing (a Command Button or other Control or something that VB is
displaying on the window whilst its ClipControls property is at its default
value of True), because GDI hardware is not usually used by Polyline under
such conditions.

I think the first thing I would do in your specific case would be to put a
high resolution timer on both the DrawChart and RedrawTools functions, to
see which of those is taking the most time, on the grounds that it's always
best to tackle the biggest bottleneck first before you look at other smaller
things. If your system is using your video cards GDI accelerated hardware
then it might be wise for test purposes to place a function call at the very
end of both of these routines that will cause the routine to wait until the
video card hardware has actually finished the drawing that was triggered by
your code, otherwise you will get misleading timings (changing the Form's
Caption property usually serves to perform the wait).

Other than that, it is really hard to think of anything concrete to suggest
without being able to actually see and run your code.

Mike



From: Larry Serflaten on

"Webbiz" <nospam(a)forme.thanks.com> wrote
<...>
> Currently, I can scroll this chart by either double-clicking the
> chart, holding down the mouse button on the second click, and dragging
> the mouse to a new location. After the mouse is let up, then the draw
> is redrawn in the new location.
<...>
> With the arrow keys, in order to show the chart actually scrolling, it
> runs the DrawChart and RedrawTools over and over, one day (bar) at a
> time. This looks really rickety, and moves so slow. Watching it redraw
> each time is a flickering hodge-podge. It would be nice if the chart
> would scroll smoothly and quickly.
<...>
> Any suggestions, tips and otherwise?


As other have said, using a second buffer is going to help.

Do remember that your whole application is just so many pixels on
a screen. As long as you can draw something that looks like a chart,
people will believe its a chart. If you can draw something that looks
like a button, people will believe its a button, until shown otherwise.

One method to help reduce the flicker would be to draw the whole
chart to an invisible picturebox, and then just show what you need
to fill the form area.

For an example, add a picturebox to a new form and paste in the
code below....

As posted it only handles the mouse drag operation, I've left it up
to you to handle the others.

HTH
LFS


Option Explicit
Private imgLeft As Long
Private MX As Single

Private Sub Form_Load()
Dim X
' Draw chart
Picture1.BorderStyle = vbBSNone
Picture1.Move 0, 0, 30000, 4000
Picture1.AutoRedraw = True
Picture1.BackColor = vbWhite
Picture1.Line (90, 90)-(29780, 3920), vbBlack, B
For X = 105 To 29800 Step 900
Picture1.PSet (X, 90), vbBlack
Picture1.Line -Step(0, 3810), &HCCCCCC
Picture1.PSet (X + 30, 1600), vbWhite
Picture1.Print CStr(X \ 90 - 1)
Next
Me.Move 1000, 1000, 8000, 4600
Picture1.Visible = False
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MX = X
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
imgLeft = imgLeft + (X - MX)
' Test boundries
If imgLeft > 0 Then imgLeft = 0
If imgLeft < (Me.Width - Picture1.Width) Then imgLeft = (Me.Width - Picture1.Width)
MX = X
' Paint chart
PaintPicture Picture1.Image, imgLeft, 0
End If
End Sub

Private Sub Form_Paint()
PaintPicture Picture1.Image, imgLeft, 0
End Sub


From: Webbiz on
On Mon, 23 Nov 2009 21:54:23 -0000, "Mike Williams"
<Mike(a)WhiskyAndCoke.com> wrote:

>"Webbiz" <nospam(a)forme.thanks.com> wrote in message
>news:lfolg51dqo43v288g7k8v7ahd7fv5f2gce(a)4ax.com...
>
>> With the arrow keys, in order to show the chart actually
>> scrolling and using it runs the DrawChart and RedrawTools
>> over and over, one day (bar) at a time.
>
>If you are using key events then the scroll rate will be limited by the
>current keyboard repeat rate, but I imagine you are already aware of that
>and are reading the state of the arrow keys in a way that overcomes that
>problem?

Ah...no. I'm not that sophisticated, remember. :-0

>
>> This looks really rickety, and moves so slow.
>
>Are you redrawing the entire PictureBox each time, or are you drawing only
>the new data and scrolling any unchanged existing data by blitting the
>unchanged block a little to the left? (although which will be the faster of
>these two methods depends on the complexity of your drawings).

Drawing the whole picturebox each time.


>> Watching it redraw each time is a flickering hodge-podge
>
>With many kinds of drawings you need to use double buffering in order to
>eliminate the flicker, as has already been mentioned by "Nobody".

That sounds so easy. (Thanks Nobody!).

So what I am currently drawing directly to the pctChart, instead draw
to a non visible picturebox and THEN copy it over. That's it?


>By the way, are you using the most appropriate GDI functions for your
>drawings? For example, are you using PolyLine and Rectangle etc rather than
>individual LineTo calls? Most GDI drawing functions are very much slower in
>Vista than they are in XP (because most Vista systems do not use your video
>card's GDI accelerated hardware, whereas XP systems almost always do) but
>even in Vista using things like Polyline can be up to two or three times
>faster than the equivalent bunch of LineTo calls (and of course often very
>much faster still on the same system running XP). Also, if you are using a
>system that does use the video card's accelerated 2D hardware (Win98 / XP)
>you will find that Polyline is very much slower if there is a "clipping
>hole" in the window that covers even a single pixel of the complete Polyline
>drawing (a Command Button or other Control or something that VB is
>displaying on the window whilst its ClipControls property is at its default
>value of True), because GDI hardware is not usually used by Polyline under
>such conditions.

Mostly, I use the Picturebox.Line method. Just drawing a line from
here to there, here to there, here to there.

For example, each price bar is simply a vertical line with a small
horizontal line off the left side and one on the right side. The chart
may show anywhere from 100 to 200 of these vertical lines representing
the high/low/open/close of each trading day.

Take a look at this video. It will show you what my chart looks like,
and also show the redraw stuff.

http://www.screencast.com/t/Y2FhMDY2Z

I know that it probably doesn't look that bad. But I've seen smoother,
faster. The video also shows a couple tools being redrawn as part of
RedrawTools.

>I think the first thing I would do in your specific case would be to put a
>high resolution timer on both the DrawChart and RedrawTools functions, to
>see which of those is taking the most time, on the grounds that it's always
>best to tackle the biggest bottleneck first before you look at other smaller
>things. If your system is using your video cards GDI accelerated hardware
>then it might be wise for test purposes to place a function call at the very
>end of both of these routines that will cause the routine to wait until the
>video card hardware has actually finished the drawing that was triggered by
>your code, otherwise you will get misleading timings (changing the Form's
>Caption property usually serves to perform the wait).
>
>Other than that, it is really hard to think of anything concrete to suggest
>without being able to actually see and run your code.



>Mike
>
>


Thanks.

Webbiz
 |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9
Prev: Snapshot of screen
Next: HTTPS File Uploads