Hi,

How can I use Icons as images for toolbar buttons?

With LoadImage I can load icon as well as bitmaps, but when I load icon I can't use it as a toolbar button image.

Sami
Posted on 2003-11-02 13:39:42 by SamiP
Hi, SamiP.
I think there are some samples on that in the board... anyway the theory is simple:
1) Load the icon.
2) Create a DC (compatible to the display).
3) Create a bitmap (compatible to an EXISTING DC, not to the one you just created).
4) Select the bitmap into the DC you just created (keep the return value).
4) Draw the icon into the DC.
5) Select the old bitmap (return value from step 4) into de DC, releasing the one you created.
6) Destroy the DC and the icon.
Voila! :)
Posted on 2003-11-02 15:11:52 by QvasiModo
Thanks for the idea QvasiModo.
I tried the boards search function but was not able to find what I'm looking for.

Sami
Posted on 2003-11-02 15:34:14 by SamiP
This will convert an icon to a bitmap handle with mask, it is mostly the work of Milos...
IconToBmp PROC hICON :DWORD,ix:DWORD

LOCAL myDC :DWORD
LOCAL hDC :DWORD
LOCAL PrevBmp :DWORD
LOCAL hBrush :DWORD
LOCAL OldObj :DWORD
LOCAL hRgn :DWORD
LOCAL hBmp :DWORD

invoke GetDC, hManagerDlg
mov hDC,eax
invoke CreateCompatibleDC, hDC
mov myDC, eax
invoke CreateCompatibleBitmap,hDC, ix, ix
mov hBmp, eax
invoke SelectObject, myDC, eax
mov PrevBmp, eax
invoke ReleaseDC,hManagerDlg,hDC

invoke CreateSolidBrush, 0FFFFFFh
mov hBrush,eax
invoke SelectObject, myDC, hBrush
mov OldObj,eax

invoke CreateRectRgn, 0, 0, ix, ix
mov hRgn,eax
invoke PaintRgn, myDC, hRgn
invoke DeleteObject,hRgn
invoke SelectObject,myDC,OldObj
invoke DeleteObject,hBrush

invoke DrawIconEx, myDC, 0, 0, hICON, ix, ix, 0, FALSE, DI_NORMAL

invoke SelectObject, myDC, PrevBmp
invoke DeleteDC, myDC
invoke DestroyIcon, hICON

mov eax,hBmp
ret
IconToBmp ENDP


You can also just add an icon directly into the image list of the toolbar
invoke SendMessage,hToolbar,TB_GETIMAGELIST,0,0

invoke ImageList_ReplaceIcon,eax,-1,hIcon
Posted on 2003-11-02 23:14:19 by donkey
Of course you can use icons in tool bars. There is no any problems. Actually Toolbar uses image list to handle button images, but image list uses icons as internal image format.
Take a look in your API reference for:

TB_GETIMAGELIST - returns toolbar's internal imagelist.
ImageList_AddIcon function - adds icon to the image list.
Posted on 2003-11-02 23:29:49 by JohnFound
Why not use the GetIconInfo function, which takes in the icon handle and returns an ICONINFO structure, which contains a handle to the mask bitmap, and also a handle to the colour bitmap, amongst other things.

Nick
Posted on 2003-11-03 06:24:49 by Nick
Now the icon problem is solved thanks to you guys!

Next problem with my toolbar is background image. I have a dialog which gets its background image in WM_PAINT message and my toolbat is created with TBSTYLE_FLAT flag. So the toolbar and the buttons should be transparent, but the backgournd bitmap of the dialog is covered with gray toolbar and thats not the intention.

So I must be missing something (again), why the background bitmap of the dialog is not shown through the toolbar? And how to set the toolbar to use backgroung bitmap if it's true that the transparent toolbar is really not transparent?

Sami
Posted on 2003-11-05 16:13:46 by SamiP
(I'm guessing): maybe creating the toolbar with the WS_EX_TRANSPARENT extended style helps... windows created with that style get painted only after the windows beneath them.

I may also be worh mentioning that you can set a bitmap as a background for a toolbar (but this is not exactly what you are asking for).
Posted on 2003-11-05 17:00:48 by QvasiModo
The transparent styles dont work, you will have to super class the toolbar and give it a null brush. This proc will superclass the toolbar and set the background to transparent, you have to create your toolbar with the NewToolbar class name:
SuperClassTB proc

LOCAL wcx :WNDCLASSEX

jmp @F
tbclass db "ToolbarWindow32",0
tbnewclass db "NewToolbar",0
@@:

mov wcx.cbSize,SIZEOF WNDCLASSEX
invoke GetClassInfoEx,NULL,offset tbclass,ADDR wcx
invoke GetStockObject,NULL_BRUSH
mov wcx.hbrBackground,eax
mov wcx.style, CS_HREDRAW or CS_VREDRAW
mov eax,hInstance
mov wcx.hInstance,eax
mov wcx.lpszClassName,OFFSET tbnewclass
invoke RegisterClassEx,ADDR wcx

ret

SuperClassTB endp
Posted on 2003-11-05 17:45:40 by donkey
It should work without any superclassing and tricks. Check your parent window. I think that it should not have WS_CLIPCHILDREN.
The toolbar should have "TBSTYLE_FLAT" and maybe "TBSTYLE_TRANSPARENT" (I am not sure for the last one)

Regards.
Posted on 2003-11-06 02:54:57 by JohnFound
Hi JohnFound,

I tried that originally, I thought that was the way to do it but only the main window's background brush would show through, not any bitmap painted on.
Posted on 2003-11-06 07:32:59 by donkey
Hi,

Even the ToolbarClass is superclassed with Donkeys code the toolbar is still not transparent. My main window is dialog if it has something to do with problems.

Like you can see the blue bar at left is part of the dialogs bitmap background, but is is not showing through toolbar.

Sami
Posted on 2003-11-06 13:19:53 by SamiP
Looks like the toolbar is transparent, it will stretch to the left of the window. What you are looking for is to make your buttons transparent as well.
Posted on 2003-11-06 13:55:03 by donkey
Well the left blue bar is there because the toolbar starts 10 pixels after the window. So there are no toolbar at fisrt 10 pixels. If I make my window wider then there is (at right side) toolbar without any buttons ant it is still not transparent there.

I changed my program to use normal window instead of a dialog and that has not helped. Results are still the same.

If it is so hard to make toolbar (and the toolbar buttons) transparent is there a better way to have a background bitmap to toolbar and buttons?

What I want to have is a blue bar with those Office 2003 icons on it as buttons.

Sami
Posted on 2003-11-06 14:01:37 by SamiP
Something like this is my goal. This is created with mspaint ;)
Posted on 2003-11-06 14:06:11 by SamiP
I'll figure it out. there is bound to be a way to do it :)
Posted on 2003-11-06 14:09:18 by donkey
Thanks Donkey, I really appreciate your continuous and kind help!
Posted on 2003-11-06 14:52:27 by SamiP
Well, it is very very complicated but I managed to do it. It requires painting the toolbar yourself for both states.The toolbar must be superclassed as I had done earlier but you also have to intercept the custom draw notification and draw the buttons from the imagelist yourself. As with all CC custom draws this will not work on a dialog unless you use it as a dialog as window. My appologies to bcraven for swiping the banner from his home page for a background image. Do not set the style to transparent or flat for the toolbar, that is done in the draw cycle and will negate the effect if set.

invoke ImageList_LoadImage, hInstance,IDR_TBBITMAP, 16, 256, 0FF00FFh, IMAGE_BITMAP, LR_CREATEDIBSECTION

push eax
invoke ImageList_SetBkColor,eax,CLR_NONE
pop eax
invoke SendMessage,hToolBar,TB_SETIMAGELIST,0,eax
Posted on 2003-11-07 12:28:30 by donkey
Great Donkey... Thanks very much for your effort for helping me out. As I see your code snippet it really looks complicated and I'm sure that without your help I haven't never figured it out by myself.

One more thing, could you be so kind that you post the whole code to display that dialog you have made? So I can digest it in my own peace and also verify that I have understand all correctly. Atleast the whole DialogProc or WndProc would be very helpful.

Sami
Posted on 2003-11-07 12:41:25 by SamiP
Yeah, here it is. The RES and OBJ file are not there and no executable so you will have to build it yourself. It is in RadASM format. Be sure to compile the resources before you attempt to build the project.
Posted on 2003-11-07 13:04:09 by donkey