I've a small problem with the code, on my screen, some pixels on the left side disappear...
Made some graphics and the following code to demonstrate this...
Code: Select all
; Define
Global temperatur=250
Global WinID
Global ZiffID
Global WinDC
#BOffX=32
#BOffY=43
#BWidth=9
#ZiffX=11
#ZiffY=14
Enumeration
#MainWindow
#PopupMenu
#MenuQuit
#Image
#BalkenOriginal
#BalkenLeer
#BalkenVoll
#BalkenFein
#Balken
#Ziffern
#Tacho
EndEnumeration
Enumeration 2000
#TempMinus10
#TempMinus1
#TempPlus1
#TempPlus10
EndEnumeration
CatchImage(#Image,?_Thermometer)
CatchImage(#Ziffern,?_Ziffern)
GrabImage(#Image,#BalkenOriginal,#BOffX,#BOffY,#BWidth,274)
GrabImage(#Image,#Balken,#BOffX,#BOffY,#BWidth,274)
GrabImage(#Image,#BalkenLeer,#BOffX,#BOffY,#BWidth,124)
GrabImage(#Image,#BalkenFein,#BOffX,189,#BWidth,4)
GrabImage(#Image,#BalkenVoll,#BOffX,193,#BWidth,130)
GrabImage(#Image,#Tacho,16,374,41,24)
DataSection
_Thermometer: IncludeBinary "Data\ThermoX.bmp"
_Ziffern: IncludeBinary "Data\Ziffern.bmp"
EndDataSection
; EndDefine
ProcedureDLL GrabRegion(ImageID, transcolor)
; Paramter: HBITMAP ImageID, COLORREF transcolor
Structure RGBTRIPLEC
rgbtBlue.c
rgbtGreen.c
rgbtRed.c
EndStructure
GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP)
Protected width=bmp\bmWidth
Protected height=bmp\bmHeight
Protected hVisibleRgn=CreateRectRgn_(0,0,width,height)
Protected tred=Red(transcolor)
Protected tgreen=Green(transcolor)
Protected tblue=Blue(transcolor)
BmiInfo.BITMAPINFOHEADER
With BmiInfo
\biSize=SizeOf(BITMAPINFOHEADER)
\biWidth=width
\biHeight=-height
\biPlanes=1
\biBitCount=24
\biCompression=#BI_RGB
EndWith
bytesperrow=4*((3*width+3)/4)
*ColorBits=AllocateMemory(bytesperrow*height)
hDC=GetWindowDC_(#Null)
iRes=GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS)
ReleaseDC_(#Null, hDC)
Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER)
*Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max)
*rd.LONG=*Buffer+SizeOf(RGNDATAHEADER)
bufferloc=0
rectcount=0
For y=0 To height - 1
pxcount=0
For x=0 To bytesperrow-1 Step 3
*px.RGBTRIPLEC=*ColorBits+bytesperrow*y+x
If *px\rgbtRed=tred And *px\rgbtGreen=tgreen And *px\rgbtBlue=tblue
transcount=1
firsttrans=pxcount
While *px\rgbtRed=tred And *px\rgbtGreen=tgreen And *px\rgbtBlue=tblue And x <= bytesperrow - 4
transcount+1
pxcount+1
x+3
*px=*ColorBits+bytesperrow*y+x
Wend
rectcount+1
*rd\l=firsttrans : *rd+4
*rd\l=y : *rd+4
*rd\l=firsttrans+transcount : *rd+4
*rd\l=y+1 : *rd+4
EndIf
pxcount+1
Next
Next
With *Buffer
\dwSize=SizeOf(RGNDATAHEADER)
\iType=#RDH_RECTANGLES
\nCount=rectcount
\nRgnSize=rectcount*SizeOf(RECT)
\rcBound\left=0
\rcBound\top=0
\rcBound\right=width
\rcBound\bottom=height
EndWith
RegionSize=SizeOf(RGNDATAHEADER)+(rectcount*SizeOf(RECT))
hTransparentRgn=ExtCreateRegion_(#Null, RegionSize, *Buffer)
CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)
FreeMemory(*Buffer)
FreeMemory(*ColorBits)
DeleteObject_(hTransparentRgn)
ProcedureReturn hVisibleRgn
EndProcedure
Procedure Init()
WinID=OpenWindow(#MainWindow,0,0,ImageWidth(#Image),ImageHeight(#Image),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)
SetWindowLong_(WinID,#GWL_EXSTYLE,GetWindowLong_(WinID,#GWL_EXSTYLE)|#WS_EX_TOOLWINDOW)
CreateGadgetList(WinID) ; Event windows without gadgets neeed a gadget list
region=GrabRegion(ImageID(#Image),$ff00ff) ; Create the region for the included picture
SetWindowRgn_(WinID, region, #True) ; Clip the image to the calculated region
hBrush=CreatePatternBrush_(ImageID(#Image)) ; Set the window background to the image.
SetClassLong_(WinID, #GCL_HBRBACKGROUND, hBrush) ; Subclass the window to allow dragging around
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Escape,#MenuQuit)
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Shift|#PB_Shortcut_Up,#TempPlus1)
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Shift|#PB_Shortcut_Down,#TempMinus1)
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Up,#TempPlus10)
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Down,#TempMinus10)
WinDC=GetDC_(WinID)
ZiffID=CreateCompatibleDC_(WinDC)
SelectObject_(ZiffID,ImageID(#Ziffern))
StickyWindow(#MainWindow, 1) ; Make this window stay on top of all others
HideWindow(#MainWindow, 0) ; Show the window now
EndProcedure
Procedure Main()
Init()
Repeat
Select WaitWindowEvent(100)
Case #WM_PAINT,#WM_NCPAINT
y=270-temperatur>>1
StartDrawing(ImageOutput(#Balken))
DrawImage(ImageID(#BalkenOriginal),0,0)
If y>145
DrawImage(ImageID(#BalkenLeer),0,y-120-y%5)
EndIf
DrawImage(ImageID(#BalkenFein),0,y)
If y<145
DrawImage(ImageID(#BalkenVoll),0,y+4-y%5)
EndIf
StopDrawing()
StartDrawing(WindowOutput(#MainWindow))
DrawImage(ImageID(#Balken),#BOffX,#BOffY)
DrawImage(ImageID(#Tacho),16,374)
StopDrawing()
n=temperatur
y=0
For x=0 To 2
BitBlt_(WinDC,45-14*x,379+y,#ZiffX,#ZiffY,ZiffID,#ZiffX*n%10,0,#SRCPAINT)
y=(n%10)>>1-2
n/10
Next x
Case #WM_RBUTTONUP
CreatePopupMenu(#PopupMenu)
MenuItem(#MenuQuit, "Close")
DisplayPopupMenu(#PopupMenu,WinID)
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Menu
Select EventGadget()
Case #MenuQuit; Escape / Close
Break
Case #TempMinus10
If temperatur>15 : temperatur-10 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
Case #TempMinus1
If temperatur>5 : temperatur-1 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
Case #TempPlus1
If temperatur<510 : temperatur+1 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
Case #TempPlus10
If temperatur<500 : temperatur+10 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
EndSelect
Case #WM_LBUTTONDOWN
SendMessage_(WinID, #WM_NCLBUTTONDOWN, #HTCAPTION, 0) ; Allow the dragging of our image around
EndSelect
ForEver
ReleaseDC_(WinID,WinDC)
EndProcedure
Main()
Is this a "normal" behaviour with all graphic cards? Have I done something wrong? And, is there a more simple method (than Bitblt) to put images transparent over others?