Code: Select all
EnableExplicit
#AC_SRC_OVER = $0
#AC_SRC_ALPHA = $1
#ULW_ALPHA = $2
Macro WindowAlphaInit(WindowNr)
SetWindowLongPtr_(WindowID(WindowNr), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(WindowNr), #GWL_EXSTYLE) | #WS_EX_LAYERED)
EndMacro
Macro WindowAlphaColor(WindowNr, Color)
SetLayeredWindowAttributes_(WindowID(WindowNr), Color, 0, #LWA_COLORKEY)
EndMacro
Procedure WindowAlphaImage(WindowNr, ImageNr, Alpha=$FF)
Protected ImageID, X, Y, Width, Height
Protected hDC, bmi.BITMAPINFO, pt.POINT, Blend.BLENDFUNCTION
Protected Color, R, G, B, A
Protected Result = #False
If IsImage(ImageNr) = 0 Or ImageDepth(ImageNr) <> 32 : ProcedureReturn Result : EndIf
ImageID = ImageID(ImageNr)
Width = ImageWidth(ImageNr)
Height = ImageHeight(ImageNr)
; Precalculate scale:
Protected Dim Scale.f($FF)
For X = 0 To $FF
Scale(X) = X / $FF
Next
; Prepare array size:
Protected Dim Image.l(Width - 1, Height - 1)
hDC = StartDrawing(ImageOutput(ImageNr))
If hDC
With bmi\bmiHeader
\biSize = SizeOf(BITMAPINFOHEADER)
\biWidth = Width
\biHeight = Height
\biPlanes = 1
\biBitCount = 32
\biCompression = #BI_RGB
EndWith
GetDIBits_(hDC, ImageID, 0, Height, @Image(), @bmi, #DIB_RGB_COLORS) ; Copy image to memory
; Modify memory:
For Y = 0 To Height - 1
For X = 0 To Width - 1
Color = Image(X, Y)
A = Alpha(Color)
If A < $FF
R = Red(Color) * Scale(A)
G = Green(Color) * Scale(A)
B = Blue(Color) * Scale(A)
Image(X, Y) = RGBA(R, G, B, A)
EndIf
Next
Next
SetDIBits_(hDC, ImageID, 0, Height, @Image(), @bmi, #DIB_RGB_COLORS) ; Copy memory back to image
; Set image to window background:
With Blend
\BlendOp = #AC_SRC_OVER
\BlendFlags = 0
\SourceConstantAlpha = Alpha
\AlphaFormat = #AC_SRC_ALPHA
EndWith
Result = UpdateLayeredWindow_(WindowID(WindowNr), #Null, #Null, @bmi + SizeOf(Long), hDC, @pt, 0, @Blend, #ULW_ALPHA)
StopDrawing()
EndIf
ProcedureReturn Result
EndProcedure
Procedure MainCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_SIZE, #WM_MOVE, #WM_PAINT
ResizeWindow(0, WindowX(1), WindowY(1), #PB_Ignore, #PB_Ignore) ; Synchronize both windows
EndSelect
ProcedureReturn Result
EndProcedure
UsePNGImageDecoder()
Define File.s = OpenFileRequester("Load the window background image", "", "PNG|*.png", 0)
If File And LoadImage(123, File)
If OpenWindow(0, 0, 0, ImageWidth(123), ImageHeight(123), "Alpha Window Test", #PB_Window_BorderLess | #PB_Window_Invisible | #PB_Window_ScreenCentered) ; Just has the image
WindowAlphaInit(0)
WindowAlphaImage(0, 123)
If OpenWindow(1, 0, 0, ImageWidth(123), ImageHeight(123), "", #PB_Window_BorderLess | #PB_Window_Invisible | #PB_Window_ScreenCentered, WindowID(0)) ; Just has all gadgets etc.
SetWindowColor(1, $FF00FF)
WindowAlphaInit(1)
WindowAlphaColor(1, $FF00FF)
ButtonGadget(3, (ImageWidth(123) - 150) / 2, (ImageHeight(123) - 30) / 2, 150, 30, "Close window") ; Button centered to the image
SetWindowCallback(@MainCallback(), 1)
HideWindow(0, #False)
HideWindow(1, #False)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
If EventGadget() = 3
Break
EndIf
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(1), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndSelect
ForEver
EndIf
EndIf
EndIf