Prev: Snapshot of screen
Next: HTTPS File Uploads
From: Mike Williams on 27 Nov 2009 00:30 "Webbiz" <nospam(a)forme.thanks.com> wrote in message news:2rhtg5t0qaq95h56u3f4t1p1ke331g7163(a)4ax.com... > When you discussed the thinkness of the line being more > than 1 pixel, I suppose you are referring to when my app > sets the DrawWidth > 1, right? Yes. DrawWidth sets the thickness of the line in pixels, regardless of the VB ScaleMode you might be using. > Let's take one of these line draws as an example. > 'Draw the main vertical bar > frmChart.pctChart.Line ((i - (gFirstBarRecNum)) * gHSpace, > dblLowPoint)-((i - (gFirstBarRecNum)) * gHSpace, dblHighPoint), > lngColor > Break it down to... > X1 = (i - (gFirstBarRecNum)) * gHSpace > Y1 = dblLowPoint > X2 = ((i - (gFirstBarRecNum)) * gHSpace) - Int(gHSpace / 2) > Y2 = dblHighPoint > frmChart.pctChartLine (X1, Y1) - (X2, Y2) It looks as though you have broken that down wrongly (which is probably just a typo) because the former appears to draw a vertical line (your main bar) whereas the latter appears to draw a small horizontal line (either your opening or closing price marker), so they are not equivalent, but I think I can see what you mean . . . > . . . frmChart.pctChartLine (X1, Y1) - (X2, Y2) > If I were to replace the above line with the FillRect > API code, what would be the approach? This ... > Dim r as RECT, retval as Long, brush as Long > ' Set the coordinates of the bar/rectangle > retval = SetRect(r, X1, Y1, X2, Y2) > brush = CreateSolidBrush(lngColor) > retval = FillRect(frmChart.pctChart.hDC, r, brush) Not quite, because the Line coordinates represent the two ends of a line whereas the FillRect coordinates represent the coordinates of the top left corner and the bottom right corner of a rectangle. As far as the FillRect coordinates are concerned (as they relate to the coordinates you would use for the Line method) it depends on the thickness of the line and on its orientation (vertical or horizontal). It also depends on the pctChart.ScaleMode you are using, because the VB Line method uses ScaleMode units for the X1, Y1, etc coordinates whereas the FillRect function (as with all other GDI drawing functions) defaults to using Pixels. So, if you're not using pixels as your ScaleMode then you would need to perform the appropriate conversion (or alternatively you can force the GDI functions to use something other than pixels, but that's another story and is best avoided for now). On the assumption that your pctChart.ScaleMode is vbPixels (if not then there will be a little more math) then, using your own VB Line method example, here are the equivalent FillRect methods ("wide" is a Long variable containing the desired line thickness in pixels) . . . frmChart.pctChartLine.DrawWidth = wide frmChart.pctChartLine (X1, Y1) - (X2, Y2) .. . . the equivalent for a vertical line would be SetRect r, X1 - wide \ 2, Y1, X2 + wide - wide \ 2, Y2 + 1 FillRect frmChart.pctChart.hdc, r, brush1 .. . . and for a horizontal line it would be: SetRect r, X1, Y1 - wide \ 2, X2 + 1, Y2 + wide - wide \ 2 FillRect frmChart.pctChart.hdc, r, brush1 You also need to remember that the VB Line method draws rounded ends on lines thicker than one pixel (or at least it attempts to do so, with the degree of success depending on the thickness of the line). These rounded ends are generally added to each end of what would otherwise be a flat edged line, thereby making it slightly longer than your coordinates when you are drawing fairly thick lines. The FillRect function will of course not do that, and will produce a perfectly squared off line of exactly the size and thickness you require. Personally I think that for your own purposes you are better off without those rounded ends anyway, but that's a personal choice of course. > I would assume that the 'brush' is set once if all the bars will > have the same color. Then for every .Line code, replace it > with two lines, the SetRect and FillRect lines. Yes. You need create only one brush and you can use it to draw as many "lines" (FillRects) as you wish. When you have finally finished with the brush (and certainly before your program ends) you must delete it (using the DeleteObject function), otherwise you will have a memory and resource leak. Since you will be using the brush over and over again for as long as your program is running I would suggest that you declare it as Private in your frmChart declarations section (Private BrushBlack as Long, for example) and create it (CreateSolidBrush) in your frmChart Load event and delete it (DeleteObject) in your frmChart Unload event. In that way you will be able to use it in all blocks of code in that Form. You can of course create as many different colour brushes as you wish, in exactly the same way, so for example you could have BrushBlack, BrushRed, BrushGreen, BrushBlue etc, all declared as Private in the declarations section of frmChart and all created in the Load event and deleted in the Unload event. There were a number of points raised in your post and I'm not sure whether I have covered them all here, and of course I may have forgotten to mention some things that I had intended to mention, but I think that about covers it. Mike
From: Mike Williams on 27 Nov 2009 02:00 "Larry Serflaten" <serflaten(a)usinternet.com> wrote in message news:OcGvpPvbKHA.5976(a)TK2MSFTNGP05.phx.gbl... > I would raise an objection there. The difference between drawing > the chart once (to an off screen buffer) and painting in place > compared to drawing the chart in every Resize event . . . > . . . If you're only talking about drawing the visible portion of the > chart on each Resize (or Scroll) event, then I would agree, there > is no gain in using a second buffer if VB already does it for you. > [Autoredraw] But I would suggest that drawing the chart once > and painting to the form as needed will be more responsive to > user input.... Yes it would. I agree, and in fact that is the way I would prefer to do it myself, perhaps using code very similar to the code you posted yourself which uses a large pre-drawn offscreen bitmap and which moves the required portion of it into view in response to user scrolling. That method (and other similar methods) is very quick as far as scrolling is concerned. In fact Webbiz took your own code on board and thanked you for it . . . .. . . But Webbiz has said that he has an extremely large chart, apparently about the height of the screen but as wide as at least 25 screens and possibly many more, which if you drew it in its entirety into a buffer using the code you posted yourself could be more than 40,000 pixels wide and which would need a bitmap of about 160 MB on my own machine, or about 120 MB if you used a DIB and accepted the slightly slower copying to the display that a DIB would give you. And Webbiz has said that is the minimum size he is talking about. It could be much more than that from what he has said. That is still "doable" of course using youur own suggested method (as long as Webbiz does not want very much larger charts than he has suggested as his minimum), and you might even be able to modify it so that it draws just half a dozen screenfulls as a buffer and kind of "plans ahead" replacing parts of it with other sections on the fly that it thinks might be needed next (similar to a typical picture viewer), although that might cause you to lose much of the responsiveness that the basic method you have already outlined would otherwise give you. I do like the idea of a full and complete chart already pre-drawn into a backbuffer as you have suggested, but personally in view of the very large size of Webbiz's chart and in view of other of his requirements I think my own current suggestion of drawing only the currently visible part of the graph in response to user input is the way I would advise Webbiz to go about it in this specific case. The more input and alternative suggestions that Webbiz has from yourself and from others can only be for the good of course, and I welcome all your comments about my own suggested method, both negative and positive, but at the moment considering Webbiz's requirements I am still leaning towards my own suggestion of drawing only the currently required portion of the chart, and drawing the other required portions on the fly as the user scrolls. In this specific case there is also the problem of the requirement to respond to the user's request to magnify portions of the chart, which as I vaguely recall (although I could be wrong on that point) from some very much earlier postings by Webbiz (in different threads quite some time ago) required not just a simple magnification of an existing ready drawn portion of the chart but needed to draw various elements so that they gained in visible data resolution when they were magnified, a bit like a metafile drawing would . . . .. . . now there's a thought :-) Mike
From: Mike Williams on 27 Nov 2009 03:51 "Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote in message news:%23k9GN9ybKHA.4024(a)TK2MSFTNGP06.phx.gbl... > ... so that they gained in visible data resolution when > they were magnified, a bit like a metafile drawing > would . . . . . now there's a thought :-) .. . . by the way, just in case the smiley didn't give it away, the remark about the metafile /was/ a joke :-) Mike
From: Larry Serflaten on 27 Nov 2009 11:52 "Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote > . . . But Webbiz has said that he has an extremely large chart, apparently > about the height of the screen but as wide as at least 25 screens and > possibly many more, While I saw that 120 / 3000 post, it simply did not register as being so massive. I don't know about you, but I think I'd get dizzy looking at 25 screens worth of vertical lines scrolling by.... Might there may be a user interface issue there? Perhaps they should be categorized, or a favorites list, or something to bring that down to a more manageable size. Similar to what is somethimes done when a list has thousands of items, etc... We'll see.... LFS
From: Mike Williams on 27 Nov 2009 14:53
"Larry Serflaten" <serflaten(a)usinternet.com> wrote in message news:et2cOI4bKHA.1596(a)TK2MSFTNGP06.phx.gbl... > > "Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote > >> . . . But Webbiz has said that he has an extremely large chart, >> apparently about the height of the screen but as wide as at least >> 25 screens and possibly many more, > > While I saw that 120 / 3000 post, it simply did not register > as being so massive. I thought you might have missed it Larry, or perhaps it just hadn't registered properly in amongst all the other stuff. That extremely large chart is why my own suggestion has so far been that he draws only the part of it that is currently visible, redrawing the newly selected part each time the user scrolls. Normally, for charts which are not as large as Webbiz's, I would agree with your own previously suggested method of predrawing the lot, before you realised the amount of data he was working with. But drawing a new frame each time the user scrolls would seem to be quite suitable for the OP, although not as fast as scrolling a pre-drawm memory bitmap of course. Looking at the demo at the link posted by Webbiz I can't see anything there that should take more than about 5 or 6 milliseconds to draw on a fairly modest machine. > I don't know about you, but I think I'd get dizzy looking at > 25 screens worth of vertical lines scrolling by.... I certainly would! It's not so bad with other drawings, expanded views of sound waveforms or whatever, but closely spaced fairly thin vetical lines are just about the worst! But is should be okay if the line and background colours are chosen wisely. > Might there may be a user interface issue there? Perhaps they > should be categorized, or a favorites list, or something to bring > that down to a more manageable size. Yes, that's another option. But I have an idea that Webbiz might want to stick to his scrolling viewport with each screen of data drawn on the fly. It is after all the way lots of things with large data sets are arranged, such as waveform editors and the like. The main problem as far as reducing perceived flicker is concerned is the display of the large bunch of very similar and closely spaced vertical lines, so it remains to be seen how it all works in practice with that sort of arrangement. Mike |