thanks for the link iblis.

But now i have a new problem, my version of masm32 is probably pretty old and its import libraries dont contain a definition of UpdateLayeredWindow.

Can anyone please send me the updated version of lib file containing a definition of UpdateLayeredWindow.

Btw is this definition of UpdateLayeredWindow which i have written myself is correct?

Posted on 2002-11-23 23:57:37 by clippy
This is the lib... you can create the inc yourself using l2inca.exe in the masm32 \include folder.
Posted on 2002-11-24 10:32:35 by Qweerdy
thanks for the lib.

Btw, when i open your pngskin sample, i notice that the cursor changes to the waiting cursor for about 2 secs. Why is this delay happening?
I got a 733 P3 with 128mb ram.
Posted on 2002-11-24 13:50:36 by clippy

Btw, when i open your pngskin sample, i notice that the cursor changes to the waiting cursor for about 2 secs. Why is this delay happening?

That's the slightly sucky listbox filling with items :) I still have to check where the big delay is happening, even with unoptimized linked list it shouldn't take this long.
Posted on 2002-11-25 07:43:58 by Qweerdy
I believe the "waiting cursor" thing also happens if you have NULL in
your wndclass.hCursor ... dunno if that is the case here, though :).
Posted on 2002-11-26 09:11:28 by f0dder
Here is why it was taking so long to create the window.
It was because of this line in SetScrollMaxL proc.
invoke PostMessage,hWnd,WM_PAINT,fRedraw+fPaint,0

So each time you added a string to the listbox, you were repainting it, thats why it was going so slow.

Just comment out that line and the winow would open superfast.
I tried by adding 1,000 items in the startup instead of your 50 and it still opened instantly without any sign of slowing down anywhere.

Also you will have to apply the following changes to your code once you comment out that line so as to not to screw up the sizing.

In the LayeredListBoxProc proc change-
invoke SetScrollMaxL,[ebx].hScrollbar,eax


push edx
invoke SetScrollMaxL,[ebx].hScrollbar,eax
pop edx
invoke PostMessage,edx,WM_PAINT,fRedraw+fPaint,0

So basically you will have to remember to post the wm_paint msg each time you call SetScrollMaxL.
Posted on 2002-11-27 05:34:28 by clippy
I fixed the bug, thanks gladiator :) Fixed version is now on my website.

I found a easier way to fix the sizing though, just look at the source.

Btw, your name is now officially in the "credits" :)
Posted on 2002-11-27 12:07:10 by Qweerdy
Thanks for putting my name in the credits :)

And yes, that is a much better way to fix the sizing.

Whats new in the latest version you are currently working on?
I was thinking if you could add support for png icons for the items in the listview it would be really cool.
Posted on 2002-11-28 05:22:26 by clippy
Actually I haven't done much programming lately, as I have been busy with various school projects. The little work that I have done, was debugging my old MSN Messenger code. I hope to eventually integrate the two projects to create the best looking messenger ever :)

I know about Trillian but I think it's even uglier than MSN Messenger.

To answer your question, it should be relatively easy to add png icons in the listbox. I may do that when I get bored, but I really think the messenger code deserves most of my attention since I have neglected it for far too long now.
Posted on 2002-11-28 06:51:03 by Qweerdy
If you look at your CreateBuffers proc, you will notice that (probably) by mistake you have put the code there in a loop of 2.

mov esi,2

;your code for creating the buffers
dec esi
jnz @B

Is there any special purpose for it or is it there by mistake? The window works perfectly fine without the loop.
Posted on 2002-11-28 12:52:56 by clippy
Ah yes... that is a leftover from the previous version where createbuffers was called for every resize. I changed it to just allocate the buffers with the screen width & height and use the visible part only. It resized the buffers by first resizing the backbuffer, the sending a WM_PAINT to swap the buffers, and then resize the new backbuffer (the old front buffer) too.

Just added cleaning up this proc to my to do list...
Posted on 2002-11-29 07:13:35 by Qweerdy
Hi Qweerdy,
A few suggestions for you pngskin. Pls take this as constructive criticsm only. The Scrollbars just dont seem right on it. I mean its a flat, plastic(in terms of looks), soft looking window and the scrollbars look metallic and sort of jutting out.
Dont want to criticize any part of your work, you done a really good job there and the scrolling is amazingly smooth but yeah the scrollbars can be improved.

Anyway, getting on with other things , i still cant understand your source code totally. I am pretty much a novice where all this graphics and all are concerned. I was sort of getting a bit of pngskin3 but pngskin4, just cant get it. Here are my questions a bit in detail-

What is PreMultiplying? What exactly does the PreMul proc do and why do you need to preMultiply?
What does the paint skin proc do?
If i were to change the color(hue) of the window by using the colorize sking proc, where would i place a call to it?

Can you just sort of explain a bit in detail how exactly does ths process of making transparent work?
Posted on 2002-11-29 12:06:27 by clippy
Okay, I'll try to explain it a bit...

To make windows transparent, windows XP uses the UpdateLayeredWindow API. This API requires you to do all the painting yourself, and pass it a complete bitmap with the contents of the window. A normal bitmap contains three values per pixel: the Red, Green, and Blue components of the color (RGB). To make a bitmap transparent, you need a fourth value, which specifies the transparency of the pixel. This is called the "Alpha channel". So now each pixel is a 32 bit RGBA value. The PNG image format also supports a alpha channel, so that explains why I use a PNG file to store the skin.
UpdateLayeredWindow uses a special optimization however, that requires you to "premultiply" the bitmap before passing it to the API. This means multiplying the R, G, and B values by the alpha value and then dividing by 256. bitRAKE's CompositeBlend (which can paint one transparent bitmap onto another) also uses this optimization. Of course if you had to do this before every call it wouldn't be a optimization, but you have to do this only once for a pixel. This means that you can load a PNG and then Premultiply it, and you don't have to premultiply again each time you repaint the window.
The PaintSkin proc paints the window's background onto the bitmap using the skin bitmap passed to it. All the push'es at the top of the proc specify the width and height of each 32*32 pixel tile. If you look at the skin bitmap in the rc directory you'll notice that every "block" is exactly 32x32 pixels. These are tiled to fill up the window bitmap.
After the window background has been painted by the PaintSkin proc, the child controls are painted by their WM_PAINT (with fPaint flag set) handlers.
To use ModifySkin, use it directly after the PNG is loaded into memory and use the PNG's handle as source and destination. To be able to change the hue, sat. or brightness again you might want to keep a clean copy of the skin in memory and use the output bitmap as the skin bitmap.
Posted on 2002-11-29 12:32:01 by Qweerdy
maybe i am getting a bit now. This might sound extremly silly but why do you always get the screen DC (invoke GetDC,0 ) and not the window's dc?
Posted on 2002-11-29 12:42:28 by clippy
The PNG skinned windows are nice, too bad you have to use M$ XP... (IMO a pice of crap with lots of make-up (nice look, but that's it) and I'm-the-dumbest-user-on-earth-terrorizing-"-user-firendly-"-wizardss, I hope the next version has more professionall friendly interface, ... well enougth of sulphur-spitting, for now ;) ).
Posted on 2002-11-29 13:41:39 by scientica