
Text over ImageButton()
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
Text over ImageButton()
OK Aside from creating the picture with the text already in it... is there a way to use an imagebutton and have TEXT floating over the top that could be changed? Easily?
You know... by some lazy idiot like me?

- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
This may be a little more than you need Rook, but it should help you get started. 
http://www.purebasic.fr/english/viewtop ... 458#227458

http://www.purebasic.fr/english/viewtop ... 458#227458
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Here's an abbreviated version for you Rook.
Code: Select all
UseJPEGImageDecoder()
Procedure myWindowCallback(hwnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_DRAWITEM
*dis.DRAWITEMSTRUCT = lParam
If *dis\CtlType = #ODT_BUTTON
buttonBrush = GetGadgetData(0)
buttonNum = *dis\CtlID
SetBkMode_(*dis\hdc, #TRANSPARENT)
doFlags = #DFCS_BUTTONPUSH | #DFCS_ADJUSTRECT
DrawFocusRect = #False
Select *dis\itemState
Case #ODS_DISABLED
SetTextColor_(*dis\hdc, RGB(125, 125, 125))
Case #ODS_FOCUS
DrawFocusRect = #True
Case #ODS_FOCUS | #ODS_SELECTED
doFlags = #DFCS_BUTTONPUSH | #DFCS_PUSHED | #DFCS_ADJUSTRECT
EndSelect
EndIf
DrawFrameControl_(*dis\hdc, *dis\rcItem, #DFC_BUTTON, doFlags)
FillRect_(*dis\hdc, *dis\rcItem, buttonBrush)
DrawText_(*dis\hdc, GetGadgetText(buttonNum), Len(GetGadgetText(buttonNum)), *dis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER)
If DrawFocusRect
DrawFocusRect_(*dis\hdc, *dis\rcItem)
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 100, 100, 500, 400, "Custom Button", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SetWindowCallback(@myWindowCallback())
ButtonGadget(0, 10, 10, 100, 100, "Ownerdrawn")
ButtonGadget(1, 120, 10, 100, 100, "Normal")
bStyle = GetWindowLong_(GadgetID(0), #GWL_STYLE)
SetWindowLong_(GadgetID(0), #GWL_STYLE, bStyle &~#BS_PUSHBUTTON | #BS_OWNERDRAW)
;... Create button background brush
buttonBrush = CreatePatternBrush_(CatchImage(0, ?myImage))
SetGadgetData(0, buttonBrush)
Repeat
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow
EndIf
DeleteObject_(buttonBrush)
End
DataSection
myImage:
Data.b $FF,$D8,$FF,$E0,$00,$10,$4A,$46,$49,$46,$00,$01,$01,$01,$00,$60
Data.b $00,$60,$00,$00,$FF,$DB,$00,$43,$00,$28,$1C,$1E,$23,$1E,$19,$28
Data.b $23,$21,$23,$2D,$2B,$28,$30,$3C,$64,$41,$3C,$37,$37,$3C,$7B,$58
Data.b $5D,$49,$64,$91,$80,$99,$96,$8F,$80,$8C,$8A,$A0,$B4,$E6,$C3,$A0
Data.b $AA,$DA,$AD,$8A,$8C,$C8,$FF,$CB,$DA,$EE,$F5,$FF,$FF,$FF,$9B,$C1
Data.b $FF,$FF,$FF,$FA,$FF,$E6,$FD,$FF,$F8,$FF,$C0,$00,$0B,$08,$00,$64
Data.b $00,$64,$01,$01,$11,$00,$FF,$C4,$00,$17,$00,$01,$01,$01,$01,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$02,$01,$00,$03,$FF
Data.b $C4,$00,$1A,$10,$01,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$01,$11,$02,$12,$21,$31,$FF,$DA,$00,$08,$01
Data.b $01,$00,$00,$3F,$00,$EA,$59,$AD,$39,$5B,$06,$A6,$A6,$B6,$A6,$B6
Data.b $B1,$4F,$8C,$5E,$4B,$92,$1A,$E7,$D0,$DA,$96,$A6,$AC,$AB,$0A,$16
Data.b $36,$3A,$79,$1A,$A9,$5C,$EC,$1B,$11,$11,$61,$F2,$E9,$21,$48,$56
Data.b $8B,$35,$F8,$36,$0D,$83,$60,$D8,$D8,$B2,$1C,$98,$71,$D2,$0D,$69
Data.b $19,$A8,$54,$4B,$13,$16,$72,$53,$93,$9C,$EA,$F9,$C6,$2B,$C8,$5F
Data.b $83,$E9,$35,$64,$6C,$6B,$12,$43,$9C,$9F,$92,$9C,$AF,$91,$F2,$B5
Data.b $CB,$B7,$2E,$92,$53,$94,$A2,$B1,$73,$0D,$A5,$2D,$F8,$C1,$6B,$9F
Data.b $6E,$3D,$0C,$28,$7C,$D3,$BF,$83,$A5,$3A,$2F,$49,$E8,$B9,$E8,$B4
Data.b $77,$E3,$9F,$55,$CB,$A1,$C5,$91,$D3,$95,$B4,$2D,$59,$D3,$7A,$69
Data.b $5D,$25,$2D,$0B,$46,$D1,$A8,$B1,$65,$5B,$42,$A5,$A9,$29,$F2,$E9
Data.b $17,$41,$2D,$0B,$59,$4A,$35,$14,$C5,$90,$A2,$EB,$68,$DA,$35,$0A
Data.b $45,$65,$FD,$16,$D6,$D6,$95,$75,$75,$2A,$34,$56,$66,$4A,$8A,$2B
Data.b $09,$FF,$D9
EndDataSection
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Nice job, Sparkie! Very compact and functional.
I did see one difference in the way your ownerdrawn button performs compared to the standard one. If you click it a lot quickly, the standard one presses and releases as fast as you can work the mouse while the ownerdrawn version is quite "speed limited". Try it, see what I mean?
It took me a while to pinpoint this one, but I came to the conclusion eventually that faster clicks are being taken as doubleclick events from the button and are thus ignored as buttons don't natively process doubleclicks. The two single clicks get eaten up. So:
Adding this bit of code makes your ownerdrawn button perform like the standard one in this regard, here at least.
The only other thing would be that you could lower the text a pixel or two for the pushed state, then it's pretty much perfect.
I did see one difference in the way your ownerdrawn button performs compared to the standard one. If you click it a lot quickly, the standard one presses and releases as fast as you can work the mouse while the ownerdrawn version is quite "speed limited". Try it, see what I mean?
It took me a while to pinpoint this one, but I came to the conclusion eventually that faster clicks are being taken as doubleclick events from the button and are thus ignored as buttons don't natively process doubleclicks. The two single clicks get eaten up. So:
Code: Select all
Procedure ButtonCallback(hwnd, msg, wparam, lparam)
oldproc = GetProp_(hwnd, "oldproc")
Select msg
Case #WM_NCDESTROY
RemoveProp_(hwnd, "oldproc")
Case #WM_LBUTTONDBLCLK
PostMessage_(hwnd, #WM_LBUTTONDOWN,0,0)
EndSelect
ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure
;
;button creation here
;
SetProp_(GadgetID(0),"oldproc", SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@ButtonCallback()))
The only other thing would be that you could lower the text a pixel or two for the pushed state, then it's pretty much perfect.
BERESHEIT
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
Actually you can just remove the class style using this line:
Here's a little demo for you:
Code: Select all
SetClassLong_(hWnd,#GCL_STYLE,GetClassLong_(hWnd,#GCL_STYLE) ! #CS_DBLCLKS)
Code: Select all
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
Select uMsg
Case #WM_DRAWITEM
*lpdis.DRAWITEMSTRUCT = lParam
SetBkMode_(*lpdis\hDC,#TRANSPARENT)
If *lpdis\itemState & #ODS_SELECTED
SelectObject_(*lpdis\hDC,GetStockObject_(#BLACK_BRUSH))
SetTextColor_(*lpdis\hDC,#White)
Else
SelectObject_(*lpdis\hDC,GetStockObject_(#WHITE_BRUSH))
SetTextColor_(*lpdis\hDC,0)
EndIf
Rectangle_(*lpdis\hDC,0,0,*lpdis\rcItem\right,*lpdis\rcItem\bottom)
DrawText_(*lpdis\hDC,GetGadgetText(0),-1,*lpdis\rcItem,#DT_CENTER | #DT_VCENTER | #DT_SINGLELINE)
ProcedureReturn 0
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0,0,0,320,240,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ButtonGadget(0,5,5,150,25,"OWNERDRAW BUTTON",#BS_OWNERDRAW)
SetClassLong_(GadgetID(0),#GCL_STYLE,GetClassLong_(GadgetID(0),#GCL_STYLE) ! #CS_DBLCLKS)
SetWindowCallback(@WindowCallback())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Thanks netmaestro, I never even noticed that doubleclick issue before. In addition to your fix, you can also removes the CS_DBLCLKS from the button. The only drawback is you won't be able to trap doubleclicks from any and all buttons in your app.
Here's the modified code using my fix and adding netmaesto's drop-text effect. It's no better than what netmaestro posted, it's just an alternative for you to choose from.
*Edit* Thanks Fluid BYte, you post faster than I type. GMTA 
Here's the modified code using my fix and adding netmaesto's drop-text effect. It's no better than what netmaestro posted, it's just an alternative for you to choose from.

Code: Select all
UseJPEGImageDecoder()
Procedure myWindowCallback(hwnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_DRAWITEM
*dis.DRAWITEMSTRUCT = lParam
If *dis\CtlType = #ODT_BUTTON
buttonBrush = GetGadgetData(0)
buttonNum = *dis\CtlID
SetBkMode_(*dis\hdc, #TRANSPARENT)
doFlags = #DFCS_BUTTONPUSH | #DFCS_ADJUSTRECT
DrawFocusRect = #False
Select *dis\itemState
Case #ODS_DISABLED
SetTextColor_(*dis\hdc, RGB(125, 125, 125))
Case #ODS_FOCUS
DrawFocusRect = #True
pressed = #False
Case #ODS_FOCUS | #ODS_SELECTED
DrawFocusRect = #True
pressed = #True
doFlags = #DFCS_BUTTONPUSH | #DFCS_PUSHED | #DFCS_ADJUSTRECT
EndSelect
EndIf
DrawFrameControl_(*dis\hdc, *dis\rcItem, #DFC_BUTTON, doFlags)
FillRect_(*dis\hdc, *dis\rcItem, buttonBrush)
If DrawFocusRect And pressed
DrawFocusRect_(*dis\hdc, *dis\rcItem)
*dis\rcItem\top + 2
*dis\rcItem\left + 2
DrawText_(*dis\hdc, GetGadgetText(buttonNum), Len(GetGadgetText(buttonNum)), *dis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER)
ElseIf DrawFocusRect And Not pressed
DrawFocusRect_(*dis\hdc, *dis\rcItem)
DrawText_(*dis\hdc, GetGadgetText(buttonNum), Len(GetGadgetText(buttonNum)), *dis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER)
Else
DrawText_(*dis\hdc, GetGadgetText(buttonNum), Len(GetGadgetText(buttonNum)), *dis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER)
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 100, 100, 500, 400, "Custom Button", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SetWindowCallback(@myWindowCallback())
ButtonGadget(0, 10, 10, 100, 100, "Ownerdrawn")
ButtonGadget(1, 120, 10, 100, 100, "Normal")
bStyle = GetWindowLong_(GadgetID(0), #GWL_STYLE)
SetWindowLong_(GadgetID(0), #GWL_STYLE, bStyle &~#BS_PUSHBUTTON | #BS_OWNERDRAW | #BS_NOTIFY)
;... Create button background brush
buttonBrush = CreatePatternBrush_(CatchImage(0, ?myImage))
SetGadgetData(0, buttonBrush)
SetClassLong_(GadgetID(0), #GCL_STYLE, GetClassLong_(GadgetID(0), #GCL_STYLE) &(~#CS_DBLCLKS))
Repeat
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow
EndIf
DeleteObject_(buttonBrush)
End
DataSection
myImage:
Data.b $FF,$D8,$FF,$E0,$00,$10,$4A,$46,$49,$46,$00,$01,$01,$01,$00,$60
Data.b $00,$60,$00,$00,$FF,$DB,$00,$43,$00,$28,$1C,$1E,$23,$1E,$19,$28
Data.b $23,$21,$23,$2D,$2B,$28,$30,$3C,$64,$41,$3C,$37,$37,$3C,$7B,$58
Data.b $5D,$49,$64,$91,$80,$99,$96,$8F,$80,$8C,$8A,$A0,$B4,$E6,$C3,$A0
Data.b $AA,$DA,$AD,$8A,$8C,$C8,$FF,$CB,$DA,$EE,$F5,$FF,$FF,$FF,$9B,$C1
Data.b $FF,$FF,$FF,$FA,$FF,$E6,$FD,$FF,$F8,$FF,$C0,$00,$0B,$08,$00,$64
Data.b $00,$64,$01,$01,$11,$00,$FF,$C4,$00,$17,$00,$01,$01,$01,$01,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$02,$01,$00,$03,$FF
Data.b $C4,$00,$1A,$10,$01,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$01,$11,$02,$12,$21,$31,$FF,$DA,$00,$08,$01
Data.b $01,$00,$00,$3F,$00,$EA,$59,$AD,$39,$5B,$06,$A6,$A6,$B6,$A6,$B6
Data.b $B1,$4F,$8C,$5E,$4B,$92,$1A,$E7,$D0,$DA,$96,$A6,$AC,$AB,$0A,$16
Data.b $36,$3A,$79,$1A,$A9,$5C,$EC,$1B,$11,$11,$61,$F2,$E9,$21,$48,$56
Data.b $8B,$35,$F8,$36,$0D,$83,$60,$D8,$D8,$B2,$1C,$98,$71,$D2,$0D,$69
Data.b $19,$A8,$54,$4B,$13,$16,$72,$53,$93,$9C,$EA,$F9,$C6,$2B,$C8,$5F
Data.b $83,$E9,$35,$64,$6C,$6B,$12,$43,$9C,$9F,$92,$9C,$AF,$91,$F2,$B5
Data.b $CB,$B7,$2E,$92,$53,$94,$A2,$B1,$73,$0D,$A5,$2D,$F8,$C1,$6B,$9F
Data.b $6E,$3D,$0C,$28,$7C,$D3,$BF,$83,$A5,$3A,$2F,$49,$E8,$B9,$E8,$B4
Data.b $77,$E3,$9F,$55,$CB,$A1,$C5,$91,$D3,$95,$B4,$2D,$59,$D3,$7A,$69
Data.b $5D,$25,$2D,$0B,$46,$D1,$A8,$B1,$65,$5B,$42,$A5,$A9,$29,$F2,$E9
Data.b $17,$41,$2D,$0B,$59,$4A,$35,$14,$C5,$90,$A2,$EB,$68,$DA,$35,$0A
Data.b $45,$65,$FD,$16,$D6,$D6,$95,$75,$75,$2A,$34,$56,$66,$4A,$8A,$2B
Data.b $09,$FF,$D9
EndDataSection

What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
I thought Sparkman ignored me but we posted in the same minute. 

Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
I was 20 minutes behind you Fluid Byte. I had my post ready to go when I got sidetracked (at work). Then I come back to my computer to post and see you had already snuck in there with your code.
I would never ignore you Fluid Byte. It's been a pleasure to see your nice side around here latelty

I would never ignore you Fluid Byte. It's been a pleasure to see your nice side around here latelty

What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Just tried this on my laptop running Vista and unfortunately Sparkies code doesn't seem to do anything other than have a button with a nice background, no droptext, no moving or highlighting.
Fluid Bytes code does work and flashes the colour of the button whenever clicked on.
I'm guessing this is a Vista issue as I haven't tried it on my XP computer but it seems to be working for others.
Unless of course there isn't supposed to be any indication that the button was pressed, in which case just ignore me.
Fluid Bytes code does work and flashes the colour of the button whenever clicked on.
I'm guessing this is a Vista issue as I haven't tried it on my XP computer but it seems to be working for others.

Unless of course there isn't supposed to be any indication that the button was pressed, in which case just ignore me.
