News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Another little toy (barber pole)

Started by NoCforMe, January 01, 2023, 06:08:25 PM

Previous topic - Next topic

NoCforMe

Here's a cute/stupid little project. Run it, you'll see what it is.

I'm thinking of making this into a retro-looking progress indicator, but a lot smaller.

Made the bitmaps with CorelDraw, massaged with Paint Shop Pro.

I used TransparentBlt() to draw the outline with transparency; saved a lot of hassle messing around with bitmap masks and other crap. Two problems: it's not in the MASM library, even though it's been around since Windows 2000 (solved with LoadLibrary() and GetProcAddress() ), and I discovered that contrary to what the documentation says, it won't work at all if the source and destination DCs (in other words, the source bitmap and the destination DC) aren't exactly the same size. (The Microsoft docs say that the source bitmap will be stretched to fit the destination rectangle, but apparently that's a lie.)
Assembly language programming should be fun. That's why I do it.

zedd151

I was going to make a wisecrack about its potential practical usefulness  :mrgreen: , but the program is actually useful  :biggrin: . It demonstrates how to use TransparentBlt.  :thumbsup:
There is an occasional white flicker in the barber pole interior, but otherwise the animation is smooth.

NoCforMe

Yeah, I was bothered by that flicker too. If I make a nice little BarberPoleProgressBar, it'll probably be small enough not to flicker. Not gonna obsess over it and work on double-buffering or whatever.
Assembly language programming should be fun. That's why I do it.

jj2007


NoCforMe

OK, while you guys were cracking wise**, I had my nose to the grindstone (bloody grindstone!), and now the barber pole is a bona fide Windows control. Meaning you could put it into your own program as a progress indicator. For now just posting the demo program; you can see that there are 3 completely independent poles, each one a child control in the dialog. I'll post the complete control code shortly. Love to see someone actually use this in a program. (Hey, maybe we could come up with a whole retro user interface, maybe kind of a steampunk look ...)

** Not in this thread ...
Assembly language programming should be fun. That's why I do it.

zedd151

How quaint.  :thumbsup:   Still a bit of flickering.

NoCforMe

#6
Hmm; so any suggestions on how to get rid of flickering? I can post source later; for now, my WM_PAINT handler uses exactly two calls per animation "frame" (spaced at 30msec), one to BitBlt(), the other to TransparentBlt(). CPU usage is 0, according to Task Manager. (Oop,, miswrote there: only 1 animation call every 30ms, BitBlt(). The TransparentBlt() only gets called when the "frame" needs redrawn.)

With all 3 controls running I see little flashes maybe every 10-15 sec.
Assembly language programming should be fun. That's why I do it.

NoCforMe

For anyone interested in trying out this control, everything you need is attached here. There are two batch files, one to assemble the control, the other to compile the test program. You'll need the 2 bitmaps as well (for the control), loaded through the resource file.

To start and stop the control, use the private messages:


; To turn the pole on:
INVOKE SendMessage, <control handle>, WM_BARBERPOLE_ON, 0, 0

; To turn it off:
INVOKE SendMessage, <control handle>, WM_BARBERPOLE_OFF, 0, 0


Let me know how it works for you. Oh, and be sure to call InitBarberPole() before creating a window or using it in a dialog.
Assembly language programming should be fun. That's why I do it.

zedd151

Quote from: NoCforMe on January 02, 2023, 02:11:02 PM
Hmm; so any suggestions on how to get rid of flickering?
Nope. Some of my programs were notorious for the same thing.  :toothy:


Edit = correction.  :tongue:

NoCforMe

Oops--forgot one of the files needed to build the testbed. Attached below.
Assembly language programming should be fun. That's why I do it.

zedd151

#10
Quote from: zedd151 on January 02, 2023, 04:30:58 PM
Quote from: NoCforMe on January 02, 2023, 02:11:02 PM
Hmm; so any suggestions on how to get rid of flickering?
Nope.
But I may look into it at some point in the future. :cool:

fearless

Since your handling the background of the control yourself, I would add in

CMP EAX, WM_ERASEBKGND
JE do_paintbg


to the message section, and then:

do_paintbg:
   mov eax, 1
   ret



Probably some double buffering is required to eliminate any flickering. Also I would create the background brush beforehand and use the brush handle in the WM_PAINT rather than creating it each time, so at init of program gui stuff, or WM_INITDIALOG, but if not no worries, no harm with the way your doing it now anyhow.

TransparentBlt can be found in the msimg32.inc, so add this to the program to use it:

includelib msgimg32.lib
include msgimg32.inc

biscuits

Quote from: fearless on January 03, 2023, 05:27:33 AM
TransparentBlt can be found in the msimg32.inc, so add this to the program to use it:

includelib msgimg32.lib
include msgimg32.inc
That is good to know, fearless. Also I found there ... AlphaBlend and GradientFill.
These might be handy for me one day. Odd that they are here (msgimg.inc) instead of gdi32.inc. Microsoft, sometimes I wonder ...  :rolleyes:

jj2007

WinGdi.h:
WINGDIAPI BOOL WINAPI TransparentBlt(
    __in HDC hdcDest,
    __in int xoriginDest,
    __in int yoriginDest,
    __in int wDest,
    __in int hDest,
    __in HDC hdcSrc,
    __in int xoriginSrc,
    __in int yoriginSrc,
    __in int wSrc,
    __in int hSrc,
    __in UINT crTransparent);

NoCforMe

Quote from: fearless on January 03, 2023, 05:27:33 AM
Since your handling the background of the control yourself, I would add in

CMP EAX, WM_ERASEBKGND
JE do_paintbg


to the message section, and then:

do_paintbg:
   mov eax, 1
   ret


Thanks for that. But wouldn't I have to do this:


INVOKE BeginPaint, hWin, ADDR ps
INVOKE EndPaint, hWin, ADDR ps


in order to remove the paint request from the queue? or does just returning TRUE, as you suggested, do that?
Assembly language programming should be fun. That's why I do it.