1. Needing some Windows programming help

Hi,

I am having a lot of programming fun with updates to L and D (the report
version) and have arrived at a place I need some help with.

Background: I am drawing in two child windows.  The top one contains the
colored blocks of L and D, and the bottom one is a continuous graph that
reports on two features of the plants and animals.  When the drawings are
erased by minimizing, or by having other windows come up in front of the drawn
areas, the drawings are erased.  This isn't a problem with the colored blocks
as they are redrawn constantly, but the graph *was* a problem.

So, I created a sequence to "draw" into such that I could periodically do my
own refresh of the graph window.  After much head-scratching, I got that to
work.  The fake-refresh is slow, so I do it after each 100 data-writes to
the graph window.  So far, so good, but of course, it is a hack.  I also have
the option to save bitmaps of the graphs for later inspection.

Some of the coding relating to this:
if curX=cw67Coord[5] or not remainder(frame,100) then --update
	SetShadowImage(CWindow67,shadowImage,Black)--draw the shadow image
end if
curX+=1
if curX>cw67Coord[5] then
	curX=cw67Coord[1]
if isChecked(CheckBox73) then
	a1=copyToTrueColorBitmapFile( CWindow67, GetBMPName(), cw67Coord[1],
cw67Coord[2], cw67Coord[5], cw67Coord[6] )
end if
end if


Questions: how can I get Windows to refresh the graph window?  And, because
a minimized window couldn't save the bitmap, how can I save as a bitmap the
sequence that I use to refresh the child window?  It only contains the
pixel-colors of the graph.

Thanks for any help here,

--Quark

new topic     » topic index » view message » categorize

2. Re: Needing some Windows programming help

DB James wrote:
> 
> Hi,
> 
> I am having a lot of programming fun with updates to L and D (the report
> version) and have arrived at a place I need some help with.
> 
> Background: I am drawing in two child windows.  The top one contains the
> colored blocks of L and D, and the bottom one is a continuous graph that
> reports on two features of the plants and animals.  When the drawings are
> erased by minimizing, or by having other windows come up in front of the drawn
> areas, the drawings are erased.  This isn't a problem with the colored blocks
> as they are redrawn constantly, but the graph *was* a problem.
> 
> So, I created a sequence to "draw" into such that I could periodically do my
> own refresh of the graph window.  After much head-scratching, I got that to
> work.  The fake-refresh is slow, so I do it after each 100 data-writes to
> the graph window.  So far, so good, but of course, it is a hack.  I also have
> the option to save bitmaps of the graphs for later inspection.
> 
> Some of the coding relating to this:
> }}}
<eucode>
> if curX=cw67Coord[5] or not remainder(frame,100) then --update
> 	SetShadowImage(CWindow67,shadowImage,Black)--draw the shadow image
> end if
> curX+=1
> if curX>cw67Coord[5] then
> 	curX=cw67Coord[1]
> if isChecked(CheckBox73) then
> 	a1=copyToTrueColorBitmapFile( CWindow67, GetBMPName(), cw67Coord[1],
> cw67Coord[2], cw67Coord[5], cw67Coord[6] )
> end if
> end if
> </eucode>
{{{

> 
> Questions: how can I get Windows to refresh the graph window?  And, because
> a minimized window couldn't save the bitmap, how can I save as a bitmap the
> sequence that I use to refresh the child window?  It only contains the
> pixel-colors of the graph.
> 
> Thanks for any help here,
> 
> --Quark

I'd take this problem the other way round:
1/ draw your graph on a memory bitmap (Pixmap in win32lib)
2/ handle the w32HPaint event fr your graph window and bitBlt() the relevant
section of the
graph.
3/ To improve smoothness, your bitmap should be wider than the window
it will update, and, from time to time, just bitBlt() the "later" part onto
the "earlier" part.

This is scrolling on a double buffered window.

CChris

new topic     » goto parent     » topic index » view message » categorize

3. Re: Needing some Windows programming help

CChris wrote:
> 
> DB James wrote:
> > 

<SNIP>

> I'd take this problem the other way round:
> 1/ draw your graph on a memory bitmap (Pixmap in win32lib)
> 2/ handle the w32HPaint event fr your graph window and bitBlt() the relevant
> section of the
> graph.
> 3/ To improve smoothness, your bitmap should be wider than the window
> it will update, and, from time to time, just bitBlt() the "later" part onto
> the "earlier" part.
> 
> This is scrolling on a double buffered window.
> 
> CChris

Hi CChris,

Thanks for the ideas on how to handle this.  You gave me a lot to think
about.  I don't know yet how to "draw to a memory bitmap", but am not sure
that is the best way to go.  If I could do that, I wonder if I couldn't go
one better and write directly to the bitmap on the screen such that no
flicker would occur and there would be the sort of automatic refreshing we
expect in, for example, MS Paint.  There we could draw a square, fill it with
color, and it would be refreshed no matter what obscuring happened to the
window it was in.  (Being cautious, I just tried it and of course it worked.)

Unless someone else has a solution to suggest, I guess I'll read Petzold and
poke around with Euphorians' contributions related to bitmaps/pixmaps...

--Quark

new topic     » goto parent     » topic index » view message » categorize

4. Re: Needing some Windows programming help

DB James wrote:
> 
> CChris wrote:
> > 
> > DB James wrote:
> > > 
> 
> <SNIP>
> 
> > I'd take this problem the other way round:
> > 1/ draw your graph on a memory bitmap (Pixmap in win32lib)
> > 2/ handle the w32HPaint event fr your graph window and bitBlt() the relevant
> > section of the
> > graph.
> > 3/ To improve smoothness, your bitmap should be wider than the window
> > it will update, and, from time to time, just bitBlt() the "later" part onto
> > the "earlier" part.
> > 
> > This is scrolling on a double buffered window.
> > 
> > CChris
> 
> Hi CChris,
> 
> Thanks for the ideas on how to handle this.  You gave me a lot to think
> about.  I don't know yet how to "draw to a memory bitmap", but am not sure
> that is the best way to go.  If I could do that, I wonder if I couldn't go
> one better and write directly to the bitmap on the screen such that no
> flicker would occur and there would be the sort of automatic refreshing we
> expect in, for example, MS Paint.  There we could draw a square, fill it with
> color, and it would be refreshed no matter what obscuring happened to the
> window it was in.  (Being cautious, I just tried it and of course it worked.)
> 
> Unless someone else has a solution to suggest, I guess I'll read Petzold and
> poke around with Euphorians' contributions related to bitmaps/pixmaps...
> 
> --Quark

DB,

I think the idea behind CChris' suggestion is that any write from Euphoria 
directly to the screen will take a longer time to complete than the time
it takes to bitBlt() the (finished) pixmap to the screen; therefore, while
you're writing the data to the pixmap, although it takes some time, the
screen stays the same, ergo, no flicker.  When your program is finished
writing to the pixmap, then the subsequent bitBlt() happens sufficiently 
quickly that *that action* shows no flicker.

Of course, I could be wrong :)

Dan Moyer

new topic     » goto parent     » topic index » view message » categorize

5. Re: Needing some Windows programming help

Dan Moyer wrote:
> I think the idea behind CChris' suggestion is that any write from Euphoria 
> directly to the screen will take a longer time to complete than the time
> it takes to bitBlt() the (finished) pixmap to the screen; therefore, while
> you're writing the data to the pixmap, although it takes some time, the
> screen stays the same, ergo, no flicker.  When your program is finished
> writing to the pixmap, then the subsequent bitBlt() happens sufficiently 
> quickly that *that action* shows no flicker.
> 
> Of course, I could be wrong :)
> 
Hmmm, just to dot the i's and cross the t's:
It depends. For example, to draw a bevelled border, the usual trick involves
drawing a black block, then a white block at +1, then a grey at +2, then fill
with whatever. While just as fast, it looks awful direct-to-screen, hence the
buffer idea. My first point is that it has *nothing* to do with Euphoria and the
same trick is used in (eg) C++. My second point is that it is perfectly possible
to avoid flicker when using direct-to-screen, and will (in some but not all
cases) be fractionally faster, but in general far harder to code. If you look at
a typical button, it can be drawn in 4 or 5 bitBlts buffer-style (hence faster),
but would need 9 or 10 direct-flicker-free. Conversely raw text is 100% faster
drawn direct, done in 1 not 2.
KISS principle says use a buffer.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

6. Re: Needing some Windows programming help

Dan Moyer wrote:
> 
> DB James wrote:
> > 
> > CChris wrote:
> > > 
> > > DB James wrote:
> > > > 
> > 
> > <SNIP>
> > 
> > > I'd take this problem the other way round:
> > > 1/ draw your graph on a memory bitmap (Pixmap in win32lib)
> > > 2/ handle the w32HPaint event fr your graph window and bitBlt() the
> > > relevant
> > > section of the
> > > graph.
> > > 3/ To improve smoothness, your bitmap should be wider than the window
> > > it will update, and, from time to time, just bitBlt() the "later" part
> > > onto
> > > the "earlier" part.
> > > 
> > > This is scrolling on a double buffered window.
> > > 
> > > CChris
> > 
> > Hi CChris,
> > 
> > Thanks for the ideas on how to handle this.  You gave me a lot to think
> > about.  I don't know yet how to "draw to a memory bitmap", but am not sure
> > that is the best way to go.  If I could do that, I wonder if I couldn't go
> > one better and write directly to the bitmap on the screen such that no
> > flicker would occur and there would be the sort of automatic refreshing we
> > expect in, for example, MS Paint.  There we could draw a square, fill it
> > with
> > color, and it would be refreshed no matter what obscuring happened to the
> > window it was in.  (Being cautious, I just tried it and of course it
> > worked.)
> > 
> > Unless someone else has a solution to suggest, I guess I'll read Petzold and
> > poke around with Euphorians' contributions related to bitmaps/pixmaps...
> > 
> > --Quark
> 
> DB,
> 
> I think the idea behind CChris' suggestion is that any write from Euphoria 
> directly to the screen will take a longer time to complete than the time
> it takes to bitBlt() the (finished) pixmap to the screen; therefore, while
> you're writing the data to the pixmap, although it takes some time, the
> screen stays the same, ergo, no flicker.  When your program is finished
> writing to the pixmap, then the subsequent bitBlt() happens sufficiently 
> quickly that *that action* shows no flicker.
> 
> Of course, I could be wrong :)
> 
> Dan Moyer

You are completely right. 

Flickering occurs when you paint repeatedly the same area. This is why a 
common technique to avoid flickering is to use a memory bitmap as a
scratchpad, and painting is a mere copy of that scratchpad onto the screen.
Plus, as indeed writing to screen is slower (you have to deal with monitor
frequency, retrace issues and all - it's a piece of hardware) than a plain
memory write, double buffering is good when you have many small patches to
update.
bitBlt() is very fast because, on modern machines, it takes advantage of
bulk memory transfers between the CPU cache and the video RAM. The drawing
GDI primitives are now comparatibely slow (this was not true at the time of
Petzold's book).

Another antiflicker is to prevent the window from erasing its background
(default behaviour) before any painting. repaintFG() in win32lib takes care
of this.

CChris

new topic     » goto parent     » topic index » view message » categorize

7. Re: Needing some Windows programming help

CChris wrote:
> 
> Dan Moyer wrote:
> > 
> > DB James wrote:
> > > 
> > > CChris wrote:
> > > > 
> > > > DB James wrote:
> > > > > 
> > > 
> > > <SNIP>
> > > 
> > > > I'd take this problem the other way round:
> > > > 1/ draw your graph on a memory bitmap (Pixmap in win32lib)
> > > > 2/ handle the w32HPaint event fr your graph window and bitBlt() the
> > > > relevant
> > > > section of the
> > > > graph.
> > > > 3/ To improve smoothness, your bitmap should be wider than the window
> > > > it will update, and, from time to time, just bitBlt() the "later" part
> > > > onto
> > > > the "earlier" part.
> > > > 
> > > > This is scrolling on a double buffered window.
> > > > 
> > > > CChris
> > > 
> > > Hi CChris,
> > > 
> > > Thanks for the ideas on how to handle this.  You gave me a lot to think
> > > about.  I don't know yet how to "draw to a memory bitmap", but am not sure
> > > that is the best way to go.  If I could do that, I wonder if I couldn't go
> > > one better and write directly to the bitmap on the screen such that no
> > > flicker would occur and there would be the sort of automatic refreshing we
> > > expect in, for example, MS Paint.  There we could draw a square, fill it
> > > with
> > > color, and it would be refreshed no matter what obscuring happened to the
> > > window it was in.  (Being cautious, I just tried it and of course it
> > > worked.)
> > > 
> > > Unless someone else has a solution to suggest, I guess I'll read Petzold
> > > and
> > > poke around with Euphorians' contributions related to bitmaps/pixmaps...
> > > 
> > > --Quark
> > 
> > DB,
> > 
> > I think the idea behind CChris' suggestion is that any write from Euphoria 
> > directly to the screen will take a longer time to complete than the time
> > it takes to bitBlt() the (finished) pixmap to the screen; therefore, while
> > you're writing the data to the pixmap, although it takes some time, the
> > screen stays the same, ergo, no flicker.  When your program is finished
> > writing to the pixmap, then the subsequent bitBlt() happens sufficiently 
> > quickly that *that action* shows no flicker.
> > 
> > Of course, I could be wrong :)
> > 
> > Dan Moyer
> 
> You are completely right. 
> 
> Flickering occurs when you paint repeatedly the same area. This is why a 
> common technique to avoid flickering is to use a memory bitmap as a
> scratchpad, and painting is a mere copy of that scratchpad onto the screen.
> Plus, as indeed writing to screen is slower (you have to deal with monitor
> frequency, retrace issues and all - it's a piece of hardware) than a plain
> memory write, double buffering is good when you have many small patches to
> update.
> bitBlt() is very fast because, on modern machines, it takes advantage of
> bulk memory transfers between the CPU cache and the video RAM. The drawing
> GDI primitives are now comparatibely slow (this was not true at the time of
> Petzold's book).
> 
> Another antiflicker is to prevent the window from erasing its background
> (default behaviour) before any painting. repaintFG() in win32lib takes care
> of this.
> 
> CChris

Thanks to CChris and Dan and Pete for the helpful comment.

I have done some experimenting and find that CChris' original comments were
right on -- I just hadn't any idea how to do it yet!

But I wrote a little test program that worked like magic.  Using a Bitmap,
an Icon, and a PushButton, I was able to generate pixmaps for all three and,
by putting an update function call in the onPaint event programming area of
each object (using Judith's IDE), the pixmap data is refreshed neatly when
need be.  Now to transfer the knowledge to L and D...

CChris' idea of having a wider Pixmap, I doubt will be necessary, but it does
raise interesting notions of little GIF-like "movies" dancing around on
objects smile


--Quark

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu