Creating and editing Icons on runtime...
Posted: Sun Sep 07, 2003 10:03 pm
Hi all,
Since it is not possible, to create or paint Icon with the PureBasic Image
commands, i created 2 little procedures to still make this possible.
Since it is not possible to draw directly on a Icon at all with Windows API,
my procedures just copy the icon data to usual PB Images, where you
can then modify them, and create a new Icon out of them. You can use the
same #Image number for the icon when you recreate it, so you don't
waste any recources. All stuff is freed correctly.
Use the SplittIcon() function, to modify an existing icon, by extracting the
2 different Images out of them, and later combine them again with
CreateIcon()
As shown below, CreateIcon() can also be used to create a new Icon out
out of 2 Images.
Here we go:
And now, a little commented example:
At last, another small example, showing how to make a Progressbar-like
Icon in the systray:
That's it, hope it helps somebody...
Timo
Since it is not possible, to create or paint Icon with the PureBasic Image
commands, i created 2 little procedures to still make this possible.
Since it is not possible to draw directly on a Icon at all with Windows API,
my procedures just copy the icon data to usual PB Images, where you
can then modify them, and create a new Icon out of them. You can use the
same #Image number for the icon when you recreate it, so you don't
waste any recources. All stuff is freed correctly.
Use the SplittIcon() function, to modify an existing icon, by extracting the
2 different Images out of them, and later combine them again with
CreateIcon()
As shown below, CreateIcon() can also be used to create a new Icon out
out of 2 Images.
Here we go:
Code: Select all
; This Function creates 2 new Images out of the Icon.
; The Image specified in 'Image.l' will hold the Icon Image, and
; the one in 'Mask.l' will hold the Icon AND Mask. This is a Black&White
; Bitmap image, where all white parts are transparent in the Icon.
; All numbers here are PB #Image numbers.
Procedure SplittIcon(Icon.l, Image.l, Mask.l)
UseImage(Icon)
If CreateImage(Image, ImageWidth(), ImageHeight())
DC.l = StartDrawing(ImageOutput())
DrawIconEx_(DC, 0, 0, UseImage(Icon), 0, 0, 0, 0, 2)
StopDrawing()
EndIf
If CreateImage(Mask, ImageWidth(), ImageHeight())
DC.l = StartDrawing(ImageOutput())
DrawIconEx_(DC, 0, 0, UseImage(Icon), 0, 0, 0, 0, 1)
StopDrawing()
EndIf
UseImage(Image)
EndProcedure
; This Function creates a new Icon, out of the Images specified in Image and Mask.
; Both must be of the same size, and the Mask may only contain black and white.
Procedure.l CreateIcon(Icon.l, Image.l, Mask.l)
Protected *Bitmap.LONG
UseImage(Image)
CreateImage(Icon, ImageWidth(), ImageHeight())
!extrn _PB_Image_CurrentObject
!mov eax, [_PB_Image_CurrentObject]
!mov [esp+12], eax
DeleteObject_(*Bitmap\l)
NewIcon.ICONINFO
NewIcon\fIcon = #true
NewIcon\hbmMask = UseImage(Mask)
NewIcon\hbmColor = UseImage(Image)
*Bitmap\l = CreateIconIndirect_(@NewIcon)
ProcedureReturn UseImage(Icon)
EndProcedure
And now, a little commented example:
Code: Select all
#Icon = 0
#Image = 1
#Mask = 2
Font.l = LoadFont(0, "Times", 8)
If OpenWindow(0, 0, 0, 100, 50, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "Icon")
If CreateGadgetList(WindowID())
; Create and draw the Icon Image:
CreateImage(#Image, 16, 16)
StartDrawing(ImageOutput())
DrawingMode(1)
FrontColor($FF, $00, $00)
Locate(2, 2)
DrawingFont(Font)
DrawText("PB")
StopDrawing()
; See the result:
ImageGadget(1, 20, 20, 32, 32, ImageID())
; Create and draw the mask. Everything that is white
; will be transparent, everything black will be displayed.
; so we just draw the same as above in black on a white background.
CreateImage(#Mask, 16, 16)
StartDrawing(ImageOutput())
Box(1, 1, 14, 14, $FFFFFF)
FrontColor($00, $00, $00)
DrawingMode(1)
Locate(2, 2)
DrawingFont(Font)
DrawText("PB")
StopDrawing()
; Yet another test:
ImageGadget(1, 60, 20, 32, 32, ImageID())
; Now we make our new #Icon out of these 2...
CreateIcon(#Icon, #Image, #Mask)
; And place it in the systray.
AddSysTrayIcon(0, WindowID(), ImageID())
Repeat
Until WaitWindowEvent() = #PB_EventCloseWindow
EndIf
EndIf
End
At last, another small example, showing how to make a Progressbar-like
Icon in the systray:
Code: Select all
#Icon = 0
#Image = 1
#Mask = 2
If OpenWindow(0, 0, 0, 100, 50, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "Icon")
If CreateGadgetList(WindowID())
CreateImage(#Image, 16, 16)
StartDrawing(ImageOutput())
Box(1, 0, 14, 3, $0000FF)
Box(1, 4, 14, 3, $0000FF)
Box(1, 8, 14, 3, $0000FF)
Box(1, 12, 14, 3, $0000FF)
StopDrawing()
ImageGadget(1, 20, 20, 32, 32, ImageID())
CreateImage(#Mask, 16, 16)
ImageGadget(2, 60, 20, 32, 32, ImageID())
CreateIcon(#Icon, #Image, #Mask)
AddSysTrayIcon(0, WindowID(), ImageID())
time = 0
a = 0
Repeat
If time<GetTickCount_()-750
UseImage(#Mask)
StartDrawing(ImageOutput())
Box(0, 0, 16, 16, $FFFFFF)
Select a
Case 1: Box(0,11, 16, 16, 0)
Case 2: Box(0, 7, 16, 16, 0)
Case 3: Box(0, 3, 16, 16, 0)
Case 4: Box(0, 0, 16, 16, 0)
Default: a = 0
EndSelect
StopDrawing()
SetGadgetState(2, ImageID())
CreateIcon(#Icon, #Image, #Mask)
ChangeSysTrayIcon(0, ImageID())
a + 1
time = GetTickCount_()
EndIf
event = WindowEvent()
If event = #PB_EventCloseWindow
End
ElseIf event = 0
Delay(1)
EndIf
ForEver
EndIf
EndIf
End
That's it, hope it helps somebody...
Timo