Code: Select all
Procedure.l SetLayeredWindow(WindowID) ; Mettre l'attribut WS_EX_LAYERED à la fenêtre
SetWindowLong_(WindowID, #GWL_EXSTYLE, GetWindowLong_(WindowID, #GWL_EXSTYLE) | #WS_EX_LAYERED) ; Mettre l'attribut WS_EX_LAYERED à la fenêtre
EndProcedure
Procedure.l AlphaImageWindow(WindowID, ImageID) ; Mettre une image PNG comme fond d'une fenêtre
Protected Image_HDC.i, Image_Bitmap.BITMAP, Image_BitmapInfo.BITMAPINFO, ContextOffset.POINT, Blend.BLENDFUNCTION
Protected Image_Ancienne.i ,xx, yy, x, y, Rouge.l, Vert.l, Bleu.l, AlphaChannel.l
; Précalcul
Protected Dim Echelle.f($FF)
For x = 0 To $FF
Echelle(x) = x / $FF
Next
; Chargement du HDC
Image_HDC = CreateCompatibleDC_(#Null)
Image_Ancienne = SelectObject_(Image_HDC, ImageID)
; Dimension de l'image
GetObject_(ImageID, SizeOf(BITMAP), @Image_Bitmap)
Image_BitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
Image_BitmapInfo\bmiHeader\biWidth = Image_Bitmap\bmWidth
Image_BitmapInfo\bmiHeader\biHeight = Image_Bitmap\bmHeight
Image_BitmapInfo\bmiHeader\biPlanes = 1
Image_BitmapInfo\bmiHeader\biBitCount = 32
; Zone mémoire pour copier l'image
xx = Image_Bitmap\bmWidth - 1
yy = Image_Bitmap\bmHeight - 1
Protected Dim Image.l(xx, yy)
; Copie de l'image en mémoire
GetDIBits_(Image_HDC, ImageID, 0, Image_Bitmap\bmHeight, @Image(), @Image_BitmapInfo, #DIB_RGB_COLORS)
; Modification de l'image en mémoire
For x = 0 To xx
For y = 0 To yy
Couleur = Image(x, y)
AlphaChannel = Couleur >> 24 & $FF
If AlphaChannel < $FF
Rouge = (Couleur & $FF) * Echelle(AlphaChannel)
Vert = (Couleur >> 8 & $FF) * Echelle(AlphaChannel)
Bleu = (Couleur >> 16 & $FF) * Echelle(AlphaChannel)
Image(x, y) = Rouge | Vert << 8 | Bleu << 16 | AlphaChannel << 24
EndIf
Next
Next
; Transfert de la mémoire dans la l'image de base
SetDIBits_(Image_HDC, ImageID, 0, Image_Bitmap\bmHeight, @Image(), @Image_BitmapInfo, #DIB_RGB_COLORS)
; L'image est mise en skin de la fenêtre
Blend\SourceConstantAlpha = 255 ; niveau de transparence
Blend\AlphaFormat = 1 ; Support de la couche alpha
Blend\BlendOp = 0
Blend\BlendFlags = 0
UpdateLayeredWindow_(WindowID, 0, 0, @Image_BitmapInfo + 4, Image_HDC, @ContextOffset, 0, @Blend, 2)
; Fermeture du HDC
SelectObject_(Image_HDC, Image_Ancienne)
DeleteDC_(Image_HDC)
EndProcedure
Procedure Rotate(*oldPos.Point, *RotationCenter.Point, angle.f, *newPos.Point)
Protected xM, yM
angle = angle * #PI / 180
xM = *oldPos\x - *RotationCenter\x
yM = *oldPos\y - *RotationCenter\y
*newPos\x = Round(xM * Cos(angle) + yM * Sin(angle) + *RotationCenter\x, #PB_Round_Nearest)
*newPos\y = Round(- xM * Sin(angle) + yM * Cos(angle) + *RotationCenter\y, #PB_Round_Nearest)
EndProcedure
If OpenWindow(0, 0, 0, 200, 200, "", #PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible)
; SetWindowColor(0,$FFFFFF)
SetLayeredWindow(WindowID(0))
Define RotationCenter.Point : RotationCenter\x = 100 : RotationCenter\y = 100
Define startingPos.Point : startingPos\x = 180 : startingPos\y = 100
Define angle.f = 0
Define newpos_red.Point, newpos_green.Point
CreateImage(0, 200, 200, 32, #PB_Image_Transparent)
AddWindowTimer(0, 123, 200)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, OutputWidth(), OutputHeight(), $00FFFFFF)
StopDrawing()
StartVectorDrawing(ImageVectorOutput(0))
For i = 1 To 8
Rotate(startingPos, RotationCenter, angle, newpos_red)
AddPathCircle(newpos_red\x, newpos_red\y, 10, 0, 360) : VectorSourceColor(RGBA(255, 255, 0, 255)) : FillPath()
If angle = 315 : angle = 0 : Else : angle = angle + 45 : EndIf
Next
StopVectorDrawing()
AlphaImageWindow(WindowID(0), ImageID(0))
StickyWindow(0, 1)
HideWindow(0,0)
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Timer And EventTimer() = 123
; AlphaImageWindow(WindowID(0), ImageID(0)); <=======There is a bug somewhere
EndIf
Until event = #PB_Event_CloseWindow
EndIf
M.