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
. 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