Code: Select all
;/****************************************************************
;/ Title: Ownerdraw Hover Buttons
;/ Author: Sparkie
;/ Date: January 11, 2008 (original code December 22, 2004)
;/ Modifier : RASHAD
;/ Date: 8/7/2019
;/ Ref: http://www.purebasic.fr/english/viewtopic.php?p = 76316#76316
;/****************************************************************
#TME_HOVER = 1
#TME_LEAVE = 2
#TME_NONCLIENT = $10
#TME_QUERY = $40000000
#DoHover = 1
#DoLeave = 2
#MainWindow = 0
#GradeWindow = 1
Global hevent.i
Enumeration
#MyButton1 = 100
#MyButton2
#MyButton3
#Grade_Name
#Grade_Level
#Grade_cancel
#Grade_insert
EndEnumeration
Structure ButtonData
oldCallback.i
brushLeave.l
brushClick.l
brushHover.l
brushDisabled.l
EndStructure
;... Declare Globals
Global mte.TRACKMOUSEEVENT, doWhat,buttonBrushClick2
mte\cbSize = SizeOf(TRACKMOUSEEVENT)
;... Create button background brushes
buttonBrushLeave = CreateSolidBrush_(RGB(237, 233, 177))
buttonBrushClick = CreateSolidBrush_(RGB(207, 203, 147))
buttonBrushClick2 = CreateSolidBrush_(RGB(140, 253, 137))
buttonBrushHover = CreateSolidBrush_(RGB(254, 250, 194))
buttonBrushDisabled = CreateSolidBrush_(RGB(227, 227, 227))
bData.ButtonData
bData\brushHover = buttonBrushHover
bData\brushLeave = buttonBrushLeave
bData\brushClick = buttonBrushClick
bData\brushDisabled = buttonBrushDisabled
;... Main WindowCallback
Procedure myWindowCallback(hwnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_DRAWITEM
*dis.DRAWITEMSTRUCT = lParam
If *dis\CtlType = #ODT_BUTTON
buttonNum = *dis\CtlID
*bData.ButtonData = GetGadgetData(buttonNum)
;... Default button attributes
SetBkMode_(*dis\hdc, #TRANSPARENT)
doWhatBrush = *bData\brushLeave
doFlags = #DFCS_FLAT | #DFCS_BUTTONPUSH | #DFCS_MONO | #DFCS_ADJUSTRECT
If *dis\itemState >= $300
*dis\itemState = *dis\itemState ! $300
EndIf
Select *dis\itemState
Case #ODS_SELECTED
;... DoHover or DoLeave
If *dis\itemAction = 1 And doWhat = #DoHover
;... DoHover
SetTextColor_(*dis\hdc, RGB(255, 0, 0))
doWhatBrush = *bData\brushHover
doFlags = #DFCS_BUTTONPUSH | #DFCS_MONO | #DFCS_ADJUSTRECT
ElseIf *dis\itemAction = 1 And doWhat = #DoLeave
;... DoLeave
SetTextColor_(*dis\hdc, RGB(255, 0, 0))
doWhatBrush = *bData\brushLeave
doFlags = #DFCS_FLAT | #DFCS_BUTTONPUSH | #DFCS_MONO | #DFCS_ADJUSTRECT
EndIf
Case #ODS_DISABLED
SetTextColor_(*dis\hdc, RGB(125, 125, 125))
doWhatBrush = *bData\brushDisabled
Case *dis\itemState & #ODS_FOCUS
;... ClickDown
SetTextColor_(*dis\hdc, RGB(255, 0, 0))
doWhatBrush = *bData\brushLeave
doFlags = #DFCS_BUTTONPUSH | #DFCS_MONO | #DFCS_ADJUSTRECT
;drawFocus = 1
If *dis\itemAction = 2 And doWhat = #DoLeave
;... DoHover
doWhatBrush = *bData\brushHover
EndIf
If *dis\itemAction = 1 And doWhat = #DoHover
;... DoHover
doWhatBrush = *bData\brushHover
EndIf
Case*dis\itemState & ( #ODS_FOCUS | #ODS_SELECTED)
;... ClickUp
SetTextColor_(*dis\hdc, RGB(255, 0, 0))
If buttonNum = #MyButton1
doWhatBrush = buttonBrushClick2
Else
doWhatBrush = *bData\brushClick
EndIf
doFlags = #DFCS_BUTTONPUSH | #DFCS_PUSHED | #DFCS_ADJUSTRECT
EndSelect
EndIf
DrawFrameControl_(*dis\hdc, *dis\rcItem, #DFC_BUTTON, doFlags)
SetRect_(r.RECT,0,0,100,100)
DrawEdge_(*dis\hdc, r,#EDGE_ETCHED ,#BF_RECT )
FillRect_(*dis\hdc, *dis\rcItem, doWhatBrush)
*dis\rcItem\top = 2
SelectObject_(*dis\hdc,FontID(0))
DrawText_(*dis\hdc, GetGadgetText(buttonNum), Len(GetGadgetText(buttonNum)), *dis\rcItem, #DT_CENTER | #DT_WORDBREAK )
; If drawFocus = 1
; DrawFocusRect_(*dis\hDC, *dis\rcItem)
; EndIf
EndSelect
ProcedureReturn result
EndProcedure
;... ButtonCallback
Procedure myButtonCallback(hwnd, msg, wParam, lParam)
Shared mouseLeave, hover, hot
buttonID = GetDlgCtrlID_(hwnd)
*bData.ButtonData = GetGadgetData(buttonID)
Select msg
Case #WM_MOUSEMOVE
If wParam <> #MK_LBUTTON And mouseLeave = 0
mouseLeave = 1
doWhat = #DoHover
;... Force #WM_DRAWITEM
InvalidateRect_(GadgetID(buttonID), 0, 0)
; Track mouse leaving button
mte\dwFlags = #TME_LEAVE
mte\hwndTrack = GadgetID(buttonID)
TrackMouseEvent_(mte)
EndIf
Case #WM_MOUSELEAVE
mouseLeave = 0
doWhat = #DoLeave
;... Force #WM_DRAWITEM
InvalidateRect_(GadgetID(buttonID), 0, 0)
Case #WM_LBUTTONDOWN
;... Set flag to reset previous down botton
doWhat = #DoLeave
EndSelect
ProcedureReturn CallWindowProc_(*bData\oldCallback, hwnd, msg, wParam, lParam)
EndProcedure
LoadFont(0,"Tahoma",10)
If OpenWindow(#MainWindow, 0,0,400,200, "Custom Hover Buttons", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
SetWindowCallback(@myWindowCallback())
CreateStatusBar(0, WindowID(#MainWindow))
AddStatusBarField(350)
ButtonGadget(#MyButton1, 10, 10, 100, 100, "Test"+#LF$+"button 1" )
ButtonGadget(#MyButton2, 120, 10, 100, 100, "Test"+#LF$+"button 2")
ButtonGadget(#MyButton3, 230, 10, 100, 100, "Test"+#LF$+"button 3")
;... Remove #BS_PUSHBUTTON and add #BS_OWNERDRAW to buttons
For b = #MyButton1 To #MyButton3
bStyle = GetWindowLongPtr_(GadgetID(b), #GWL_STYLE)
SetWindowLongPtr_(GadgetID(b), #GWL_STYLE, bStyle & ~#BS_PUSHBUTTON | #BS_OWNERDRAW)
bData\oldCallback = SetWindowLongPtr_(GadgetID(b), #GWL_WNDPROC, @myButtonCallback())
SetGadgetData(b, bData)
Next b
SetCursorPos_(WindowX(0),WindowY(0))
Repeat
event = WaitWindowEvent()
EvWindow = EventWindow()
Select EvWindow
;- Main events
Case #MainWindow
Select event
Case #PB_Event_CloseWindow
Quit = 1
Case #PB_Event_Gadget
evnt = EventGadget()
Select evnt
Case #MyButton1 To #MyButton3
OpenWindow(#GradeWindow,0,0,250,100,"insert level",#PB_Window_SystemMenu | #PB_Window_WindowCentered, WindowID(#MainWindow))
TextGadget(#Grade_Name,10,10,230,40,GetGadgetText(evnt),#PB_Text_Center)
StringGadget(#Grade_Level,105,40,40,20,"")
ButtonGadget(#Grade_Insert,30,70,80,20,"insert")
ButtonGadget(#Grade_Cancel,140,70,80,20,"cancel")
DisableWindow(#MainWindow,#True)
SetActiveGadget(#Grade_Level)
hevent = evnt
EndSelect
EndSelect
Case #GradeWindow
Select event
Case #PB_Event_CloseWindow
CloseWindow(#GradeWindow)
DisableWindow(#MainWindow,#False)
Case #PB_Event_Gadget
Select EventGadget()
Case #Grade_cancel
CloseWindow(#GradeWindow)
DisableWindow(#MainWindow,#False)
Case #Grade_insert
SetGadgetText(hevent,GetGadgetText(hevent) + #LF$ + #LF$ + UCase(GetGadgetText(#Grade_Level)))
CloseWindow(#GradeWindow)
DisableWindow(#MainWindow,#False)
EndSelect
EndSelect
EndSelect
Until Quit = 1
EndIf
DeleteObject_(buttonBrushLeave)
DeleteObject_(buttonBrushClick)
DeleteObject_(buttonBrushHover)
DeleteObject_(buttonBrushDisabled)