REAL ImageButton control!
BlitzPlus Forums/BlitzPlus Programming/REAL ImageButton control!
| ||
| One simple command: SetButtonImage(button,image) ![]() I chose this so that you can change the button image at any time. The function accepts a regular old Blitz image. Use SetButtonImage(button,0) to change the ImageButton back into a regular button. win=CreateWindow("ImageButton",200,200,400,300,0,3)
i=LoadImage("blitzlogo.bmp")
w=ImageWidth(i)
h=ImageHeight(i)
button=CreateButton("",(ClientWidth(win)-w)/2,(ClientHeight(win)-h)/2,w,h,win)
SetButtonImage button,i
Repeat
Until WaitEvent()=$803
Const BM_SETIMAGE=247
Const IMAGE_BITMAP=0
Const IMAGE_ICON=1
Const BS_BITMAP=128
Const GWL_STYLE=-16
Const LR_DEFAULTSIZE=64
Const LR_LOADFROMFILE=16
Const LR_SHARED=32768
Function SetButtonImage(button,image)
hbutton=QueryObject(button,1)
flags=GetWindowLong(hbutton,GWL_STYLE)
If image
If Not (BS_BITMAP And flags) SetWindowLong hbutton,GWL_STYLE,flags+BS_BITMAP
Else
If (BS_BITMAP And flags) SetWindowLong hbutton,GWL_STYLE,flags-BS_BITMAP
Return
EndIf
w=ImageWidth(image)
h=ImageHeight(image)
ibuffer=ImageBuffer(image)
LockBuffer ibuffer
pixels=CreateBank(w*h*4)
For y=0 To h-1
For x=0 To w-1
PokeInt pixels,4*(y*w+x)+0,ReadPixelFast(x,y,ibuffer)
Next
Next
UnlockBuffer ibuffer
i=CreateBitmap(w,h,1,32,pixels)
FreeBank pixels
If Not i Return
oldimage=SendMessage(hbutton,BM_SETIMAGE,IMAGE_BITMAP,i)
If oldimage DeleteObject(oldimage)
Return True
End Function |
| ||
| CreateBitMap() function not found. |
| ||
| Function 'getwindowlong' not found |
| ||
| And I expect that SetWindowLong, SendMessage and DeleteObject will also not be found. Could you provide decls and supporting library references? |
| ||
| Those are all API functions, which you should already have installed. Get the gdi32, kernel32, and user32 decls files from the code archive. |
| ||
| Cool, this works great! You should post it in the code archives (and mention that it needs those userlibs)! |
| ||
| snagged kernal32.decls, user32.decls, and gdi32.decls. All stashed with my other .decl files. SetWindowLong, SendMessage, DeleteObject, GetWindowLong, and CreateBitmap still not found. Eyeballed the .decl files and see they all have api_ prefixes. Edited the above source into: api_SetWindowLong, api_SendMessage, api_DeleteObject, api_GetWindowLong, and api_CreateBitmap. It now passes the syntax check and runs before crashing. It abends at the following line: oldimage=api_SendMessage(hbutton,BM_SETIMAGE,IMAGE_BITMAP,i) The abend is your classic 0xc0000005 I did mod the source of the image to point to the ide_toolbar.bmp in the BlitzPlus\cfg subdirectory. What am I missing? |
| ||
| The user32.decls needs a tweak. Per aero: Use this: SendMessage%(hwnd%,wMsg%,wParam%,lParam%) : "SendMessageA" NOT this: SendMessage%(hwnd%,wMsg%,wParam%,lParam*) : "SendMessageA" |
| ||
| crashes here too |
| ||
| Use this: SendMessage%(hwnd%,wMsg%,wParam%,lParam%) : "SendMessageA" NOT this: SendMessage%(hwnd%,wMsg%,wParam%,lParam*) : "SendMessageA" |
| ||
| yup changed it but still crashes |
| ||
| Did all the above but the only thing i get is a blank button with width and height of the image loaded... (Tried bmp and jpg filetypes...) Any suggestions or advice? |
| ||
OK. Create a userlib file if you don't already have one..lib "user32.dll" USER32_SendMessage%(hWnd%,Msg%,wParam%,lParam%):"SendMessageA" USER32_GetWindowLong%(hWnd%,nIndex%):"GetWindowLongA" USER32_SetWindowLong%(hWnd%,nIndex%,dwNewLong%):"SetWindowLongA" .lib "gdi32.dll" GDI32_CreateBitmap%(nWidth%,nHeight%,nPlanes%,nBitCount%,lpBits*):"CreateBitmap" GDI32_DeleteObject%(hObject%):"DeleteObject" Change the code to this: win=CreateWindow("ImageButton",200,200,400,300,0,3)
i=LoadImage("blitzlogo.bmp")
w=ImageWidth(i)
h=ImageHeight(i)
button=CreateButton("",(ClientWidth(win)-w)/2,(ClientHeight(win)-h)/2,w,h,win)
SetButtonImage button,i
Repeat
Until WaitEvent()=$803
Const BM_SETIMAGE=247
Const IMAGE_BITMAP=0
Const IMAGE_ICON=1
Const BS_BITMAP=128
Const GWL_STYLE=-16
Const LR_DEFAULTSIZE=64
Const LR_LOADFROMFILE=16
Const LR_SHARED=32768
Function SetButtonImage(button,image)
hbutton=QueryObject(button,1)
flags=USER32_GetWindowLong(hbutton,GWL_STYLE)
If image
If Not (BS_BITMAP And flags) USER32_SetWindowLong hbutton,GWL_STYLE,flags+BS_BITMAP
Else
If (BS_BITMAP And flags) USER32_SetWindowLong hbutton,GWL_STYLE,flags-BS_BITMAP
Return
EndIf
w=ImageWidth(image)
h=ImageHeight(image)
ibuffer=ImageBuffer(image)
LockBuffer ibuffer
pixels=CreateBank(w*h*4)
For y=0 To h-1
For x=0 To w-1
PokeInt pixels,4*(y*w+x)+0,ReadPixelFast(x,y,ibuffer)
Next
Next
UnlockBuffer ibuffer
i=GDI32_CreateBitmap(w,h,1,32,pixels)
FreeBank pixels
If Not i Return
oldimage=USER32_SendMessage(hbutton,BM_SETIMAGE,IMAGE_BITMAP,i)
If oldimage GDI32_DeleteObject(oldimage)
Return True
End FunctionFind an image or whatever and put it in the same directory as the file (if it's saved then that directory, if not then its in program files\blitzplus\tmp\). Change the above "LoadImage" part to the name of the image file. |
| ||
I like the code.. Thanks! I hope you don't mind but I made an adjustment to it. Give this a try also:
win=CreateWindow("ImageButton",200,200,400,300,0,3)
i=LoadImage("test2.bmp"); These two images should be the same size but look different
j=LoadImage("test1.bmp"); (other image)
w=ImageWidth(i)
h=ImageHeight(i)
button=CreateButton("",(ClientWidth(win)-w)/2,(ClientHeight(win)-h)/2,w,h,win)
SetButtonImage button,i
current = i
Repeat
ID = WaitEvent(1)
Select ID
Case $401
Select EventSource()
Case button
If current = j Then current = i Else current = j
SetButtonImage button,current
End Select
Case $803
End
End Select
Forever
Const BM_SETIMAGE=247
Const IMAGE_BITMAP=0
Const IMAGE_ICON=1
Const BS_BITMAP=128
Const GWL_STYLE=-16
Const LR_DEFAULTSIZE=64
Const LR_LOADFROMFILE=16
Const LR_SHARED=32768
Function SetButtonImage(button,NEWimage)
hbutton=QueryObject(button,1)
flags=GetWindowLong(hbutton,GWL_STYLE)
If (Not image = NEWimage)
If Not (BS_BITMAP And flags) SetWindowLong hbutton,GWL_STYLE,flags+BS_BITMAP
Else
If (BS_BITMAP And flags) SetWindowLong hbutton,GWL_STYLE,flags-BS_BITMAP
Return
EndIf
w=ImageWidth(NEWimage)
h=ImageHeight(NEWimage)
ibuffer=ImageBuffer(NEWimage)
LockBuffer ibuffer
pixels=CreateBank(w*h*4)
For y=0 To h-1
For x=0 To w-1
PokeInt pixels,4*(y*w+x)+0,ReadPixelFast(x,y,ibuffer)
Next
Next
UnlockBuffer ibuffer
tmp=CreateBitmap(w,h,1,32,pixels)
FreeBank pixels
If Not tmp Return
oldimage=SendMessage(hbutton,BM_SETIMAGE,IMAGE_BITMAP,tmp)
If oldimage DeleteObject(oldimage)
image = NEWimage
Return True
End Function
|
| ||
| Is there any way to use transparent images on the buttons? I tried white, pink and black as transparent color but nothing works. Any ideas? |
