Text over ImageButton()

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

I was 20 minutes behind you Fluid Byte.
I read too fast and just saw the "3" at right of the time. Image
I would never ignore you Fluid Byte. It's been a pleasure to see your nice side around here latelty :)
Yeah, I'm trying to watch my temper more often. I hope ... Image
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.
It does work, but randomly. I pasted the code and it ran without a problem. Then I closed the program did something else and ran it again and it failed. I compiled it like 20 more times but it didn't do a thing. After closing and starting the IDE again it worked well. No clue why it's doing that.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Just had a brain ripple (not quite a brain wave), checked to see if I had XP skin support on and I have, turned it off and Sparkies code works fine but doesn't look so nice.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@srod: ME...busy....pffff :P

@Fluid BYte: Good job on the temper control. It gets easier as you get older. 8)

@Derek: I'll have a look when I get home to my Vista laptop.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Just tested my code on my Vista laptop and it works just as well as it does on my XP box. Maybe it's an Aero issue. My laptop video doesn't support it so I have no way to test that here.

As for the XP skins issue, I think I can fix that. 8)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

IMO, I say that as of Win XP, BS_OWNERDRAW is not the best choice, as hottracking is not active by default. Therefore, I put this next piece of code together for XP or later only. Still some minor details to take care of but it works fine for me on both XP and Vista (sans Aero).

Enable XP skins before running code.

Code: Select all

UseJPEGImageDecoder() 
#Button1 = 1
#Button2 = 2
#DrawFrame = 1
#DrawFocus = 2
Structure MYBRUSHES
  hotBrush.l
  defaultBrush.l
  frameBrush.l
  disabledBrush.l
EndStructure
Procedure myWindowCallback(hwnd, msg, wParam, lParam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_NOTIFY 
      *nmhdr.NMHDR = lParam 
      If *nmhdr\code = #NM_CUSTOMDRAW And *nmhdr\idFrom = #Button1
        DrawFocusRect = #False 
        pressed = #False
        *nmcd.NMCUSTOMDRAW = lParam
        *buttonBrushes.MYBRUSHES = GetGadgetData(*nmhdr\idFrom) 
        Select *nmcd\dwDrawStage 
          Case #CDDS_PREERASE 
            result = #CDRF_NOTIFYPOSTERASE 
          Case #CDDS_PREPAINT 
            iState = *nmcd\uItemState &~ #CDIS_SHOWKEYBOARDCUES
            Select iState
              Case #CDIS_DISABLED
                ;... Button is diaabled
                drawDetail = 0
                SetTextColor_(*nmcd\hdc, #Gray)
                brush = *buttonBrushes\disabledBrush
              Case #CDIS_FOCUS
                ;... Button has keyboard focus, button has been clicked
                drawDetail = #DrawFocus
                brush = *buttonBrushes\defaultBrush
                doFlags = #DFCS_HOT | #DFCS_BUTTONPUSH 
              Case #CDIS_FOCUS | #CDIS_HOT | #CDIS_SELECTED
                ;... Button has keyboard, mouse is over button, button is being clicked
                drawDetail = #DrawFocus | #DrawFrame
                brush = *buttonBrushes\defaultBrush
                doFlags = #DFCS_HOT | #DFCS_BUTTONPUSH | #DFCS_PUSHED 
              Case #CDIS_FOCUS | #CDIS_HOT
                ;... Button has keyboard focus, mouse is over button, button has been clicked
                drawDetail = #DrawFocus  | #DrawFrame 
                brush = *buttonBrushes\hotBrush
                doFlags = #DFCS_HOT
              Case #CDIS_HOT
                ;... Button does not have keyboard focus, mouse is over button, button has not been clicked
                drawDetail = #DrawFrame
                brush = *buttonBrushes\hotBrush
                doFlags = #DFCS_HOT | #DFCS_BUTTONPUSH 
              Default
                drawDetail = 0
                brush = *buttonBrushes\defaultBrush
                doFlags = #DFCS_BUTTONPUSH
                DrawFocusRect = #False
                DrawFrame = #False
            EndSelect
            SetBkMode_(*nmcd\hdc, #TRANSPARENT) 
            DrawFrameControl_(*nmcd\hdc, *nmcd\rc, #DFC_BUTTON, doFlags) 
            FillRect_(*nmcd\hdc, *nmcd\rc, brush) 
            Select drawDetail
              Case #DrawFrame
                brush = *buttonBrushes\frameBrush
                DrawText_(*nmcd\hdc, GetGadgetText(*nmhdr\idFrom), Len(GetGadgetText(*nmhdr\idFrom)), *nmcd\rc, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER) 
                FrameRect_(*nmcd\hdc, *nmcd\rc, brush)
              Case #DrawFocus
                brush = *buttonBrushes\frameBrush
                DrawText_(*nmcd\hdc, GetGadgetText(*nmhdr\idFrom), Len(GetGadgetText(*nmhdr\idFrom)), *nmcd\rc, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER) 
                *nmcd\rc\left + 1
                *nmcd\rc\top + 1
                *nmcd\rc\right - 1
                *nmcd\rc\bottom - 1
                DrawFocusRect_(*nmcd\hdc, *nmcd\rc) 
              Case #DrawFocus | #DrawFrame
                brush = *buttonBrushes\frameBrush
                DrawText_(*nmcd\hdc, GetGadgetText(*nmhdr\idFrom), Len(GetGadgetText(*nmhdr\idFrom)), *nmcd\rc, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER) 
                FrameRect_(*nmcd\hdc, *nmcd\rc, brush)
                *nmcd\rc\left + 1
                *nmcd\rc\top + 1
                *nmcd\rc\right - 1
                *nmcd\rc\bottom - 1
                DrawFocusRect_(*nmcd\hdc, *nmcd\rc) 
              Default
                DrawText_(*nmcd\hdc, GetGadgetText(*nmhdr\idFrom), Len(GetGadgetText(*nmhdr\idFrom)), *nmcd\rc, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER) 
            EndSelect
            result = #CDRF_SKIPDEFAULT 
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

Procedure.l DoBrushes(gad)
  ;... Store brush data
  *bBrushes.MYBRUSHES = AllocateMemory(SizeOf(MYBRUSHES))
  ;... Create default button background brush 
  *bBrushes\defaultBrush = CreatePatternBrush_(CatchImage(0, ?myImage)) 
  ;... Create hot button background brush 
  GrabImage(0, 1, 0, 0, 100, 100)
  StartDrawing(ImageOutput(1))
  For x = 0 To ImageWidth(1)
    For y = 0 To ImageHeight(1)
      Plot(x, y, Point(x, y) + RGB(25, 25, 25))
    Next y
  Next x
  StopDrawing()
  *bBrushes\hotBrush = CreatePatternBrush_(ImageID(1)) 
  ;... Create button frame color brush 
  *bBrushes\frameBrush = CreateSolidBrush_(#Yellow)
  ;... Create disabled button background brush 
  *bBrushes\disabledBrush = GetStockObject_(#LTGRAY_BRUSH)
  FreeImage(0) 
  FreeImage(1) 
  ProcedureReturn *bBrushes
EndProcedure

If OpenWindow(0, 100, 100, 230, 120, "Custom Button", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  SetWindowCallback(@myWindowCallback()) 
  ButtonGadget(#Button1, 10, 10, 100, 100, "Customdrawn") 
  *brushes.MYBRUSHES = DoBrushes(#Button1)
  SetGadgetData(#Button1, *brushes) 
  ButtonGadget(#Button2, 120, 10, 100, 100, "Normal") 
  
  Repeat 
    event = WaitWindowEvent() 
  Until event = #PB_Event_CloseWindow 
  DeleteObject_(*brushes\defaultBrush) 
  DeleteObject_(*brushes\hotBrush)
  DeleteObject_(*brushes\frameBrush)
EndIf 
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 
Last edited by Sparkie on Fri Apr 04, 2008 8:32 pm, edited 1 time in total.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Nice snippet Sparkman but the problem remains. Sometimes it works, sometimes it doesn't. I think it's because of the focus rectangle issue. Applications compiled with XP skin sometimes show the focus rectangle, sometimes they don't. I think there was a thread about this as well as a workaround.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Works on mine every time, it does show the focus rectangle after the first click but it does respond to every click, no matter how fast you click.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Thanks guys :)

Like Derek, it works each and every time for me as well. :?

Here's another one that works fine for me on Xp and Vista...

Code: Select all

UseJPEGImageDecoder()

Structure SPARKEDBUTTONINFO
  iNum.l
  iId.l
EndStructure

Procedure.l SparkedButtonGadget(gad, x, y, w, h, text$, imageNum, imageId, icoW, icoH) 
  originalImage = GrabImage(imageNum, #PB_Any, 0, 0, ImageWidth(imageNum), ImageHeight(imageNum))
  StartDrawing(ImageOutput(imageNum)) 
  DrawImage(imageId, 0, 0, w, h) 
  DrawingFont(GetStockObject_(#DEFAULT_GUI_FONT)) 
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText((w - TextWidth(text$))/2, (h - TextHeight(text$))/2, text$, #Black) 
  StopDrawing() 
  gadId = ButtonImageGadget(gad, x, y, w, h, ImageID(imageNum)) 
  *sbi.SPARKEDBUTTONINFO = AllocateMemory(SizeOf(SPARKEDBUTTONINFO))
  *sbi\iNum = imageNum
  *sbi\iId = ImageID(originalImage)
  SetGadgetData(gad, *sbi)
  ProcedureReturn gadId 
EndProcedure 

Procedure.l SetSparkedButtonGadgetText(gad, text$)
  *currentImageInfo.SPARKEDBUTTONINFO = GetGadgetData(gad)
  StartDrawing(ImageOutput(*currentImageInfo\iNum)) 
  DrawImage(*currentImageInfo\iId, 0, 0, ImageWidth(*currentImageInfo\iNum), ImageHeight(*currentImageInfo\iNum)) 
  DrawingFont(GetStockObject_(#DEFAULT_GUI_FONT)) 
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText((ImageWidth(*currentImageInfo\iNum) - TextWidth(text$))/2, (ImageHeight(*currentImageInfo\iNum) - TextHeight(text$))/2, text$, #Black) 
  StopDrawing() 
  SetGadgetState(gad, ImageID(*currentImageInfo\iNum)) 
EndProcedure

If OpenWindow(0, 0, 0, 230, 120, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  SparkedButtonGadget(0, 10, 10, 100, 100, "*********", 0, CatchImage(0, ?myImage), 100, 100) 
  SparkedButtonGadget(1, 120, 10, 100, 100, "*****", 1, CatchImage(1, ?myImage), 100, 100) 
  Repeat 
    event = WaitWindowEvent() 
    If EventType() = #PB_EventType_LeftClick And EventGadget() = 0
      SetSparkedButtonGadgetText(1, "Rocks")
    EndIf
    If EventType() = #PB_EventType_LeftClick And EventGadget() = 1
      SetSparkedButtonGadgetText(0, "PureBasic")
    EndIf
  Until event = #PB_Event_CloseWindow 
EndIf 
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
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Great bit of code Sparkie, works brilliantly now, no focus rectangle showing up now and very responsive. :)
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Confirmed. Image
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Fluid Byte wrote:Applications compiled with XP skin sometimes show the focus rectangle, sometimes they don't. I think there was a thread about this as well as a workaround.
Thanks for reminding me of that one Fluid Byte. :)

I applied a fix to the code in post http://www.purebasic.fr/english/viewtop ... 143#239143 if you'd like to try it again.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
mrjiles
Enthusiast
Enthusiast
Posts: 238
Joined: Fri Aug 18, 2006 7:21 pm
Location: IL

Post by mrjiles »

Started coding before I reviewed Sparkie's code. Mine is very similar but it appears he has some fancy footwork going on (not sure what everything does either!). Here's my Imagebutton + Text. It uses a 16x16 icon.

Code: Select all

#Window = 1
#Button = 2

Procedure ButtonImageTextGadget(Gadget, x, y, Width, Height, Text$, ImageID)
	hImage = CreateImage(#PB_Any, Width, Height)
	clrBack = GetSysColor_(#COLOR_3DFACE)
	StartDrawing(ImageOutput(hImage))
		Box(0, 0, Width, Height, clrBack)
		DrawImage(ImageID, 8, 7)
		DrawText(40, 7, Text$, 0, clrBack)
	StopDrawing()
	
	ButtonImageGadget(Gadget, x, y, Width, Height, ImageID(hImage))
EndProcedure



OpenWindow(#Window, 0, 0, 300, 300, "ImageButton + Text", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CreateGadgetList(WindowID(#Window))

ButtonImageTextGadget(#PB_Any, 10, 10, 100, 30, "Test", ImageID(LoadImage(#PB_Any, "c:\test.ico")))


Repeat
	Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
End
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

This is very useful and extremely cool! Great Job Sparkie, and Mr. Jiles...

@Jiles: Take a look at my nerd pickup lines... it will help with the sequel to your avatar (and wear a cup! ) :wink: (I am teasing!(except about the cup!))
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Post Reply