Page 1 of 1

Hoverbuttons

Posted: Mon Nov 28, 2005 12:48 am
by localmotion34
Code updated For 5.20+

in the process of making my outlook gadget, i wanted to include a functionality of a hover button in a group like in the outlook-type gadget of spybot and some others. so i had to hand code a way to detect and respond to the hover, while keeping the ability of the button to still be recognized in the native PB event loop.

i subclassed an imagegadget and processed the WM_paint, wm_lbutondown,wm_lbuttonup, and the Wm_mousemove messages combined with drawing DIRECTLY to memory, and then a bitblt to completely eliminate flickering.

i figured id post the simple source of the hoverbutton because i know many of you have asked for or tried at a similar idea, and might want this right away.

my outlook gadet WILL contain an option to include this type of button in the outlook groups, but it still needs polishing. this is just the absolute BASICS of how to do this:

Code: Select all

#TME_LEAVE = 2
#WM_MOUSELEAVE = $2A3
#WM_MOUSEHOVER = $2A1
Global buttondown

Procedure callback(hwnd,msg,wParam,lParam)
  Select msg
    Case #WM_MOUSEMOVE
      If buttondown=1
      Else
        Structure myTRACKMOUSEEVENT
          cbSize.l
          dwFlags.l
          hwndTrack.l 
          dwHoverTime.l
        EndStructure
        mte.myTRACKMOUSEEVENT
        mte\cbSize = SizeOf(myTRACKMOUSEEVENT)
        mte\dwFlags = #TME_LEAVE
        mte\hwndTrack = hwnd
        hdc=GetDC_(hwnd)
        GetClientRect_(hwnd,@rct.RECT)
        TrackMouseEvent_(mte)
        DrawEdge_(hdc,@rct,#EDGE_RAISED,#BF_RECT)
      EndIf
    Case #WM_MOUSEHOVER
      
    Case #WM_MOUSELEAVE
      dc=GetDC_(hwnd)
      newdc=CreateCompatibleDC_(dc)
      membmp=CreateCompatibleBitmap_(dc,100,100)
      brush=CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
      pen=CreatePen_(#PS_SOLID,0,GetSysColor_(#COLOR_BTNFACE))
      SelectObject_(newdc,membmp)
      SelectObject_(newdc,brush)
      SelectObject_(newdc,pen)
      Rectangle_(newdc,0,0,100,100)
      rect.RECT
      rect\left=0:rect\right=100:rect\top=0:rect\bottom=100
      text.s=Space(255)
      fontid=GetStockObject_(#ANSI_VAR_FONT)   
      SelectObject_(newdc,fontid)
      GetWindowText_(hwnd,text.s,255)
      SetBkColor_(newdc,GetSysColor_(#COLOR_BTNFACE))
      SetTextAlign_(newdc,#TA_CENTER)
      ExtTextOut_(newdc,50,40,#ETO_CLIPPED,@rect,text.s,Len(text),0)
      BitBlt_(dc,0,0,100,100,newdc,0,0,#SRCCOPY)
      ReleaseDC_(hwnd,dc)
      DeleteDC_(newdc)
      DeleteObject_(membmp)
      buttondown=0
      ProcedureReturn 0
    Case #WM_PAINT
      dc=GetDC_(hwnd)
      newdc=CreateCompatibleDC_(dc)
      membmp=CreateCompatibleBitmap_(dc,100,100)
      brush=CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
      pen=CreatePen_(#PS_SOLID,0,GetSysColor_(#COLOR_BTNFACE))
      SelectObject_(newdc,membmp)
      SelectObject_(newdc,brush)
      SelectObject_(newdc,pen)
      Rectangle_(newdc,0,0,100,100)
      rect.RECT
      rect\left=0:rect\right=100:rect\top=0:rect\bottom=100
      text.s=Space(255)
      fontid=GetStockObject_(#ANSI_VAR_FONT)   
      SelectObject_(newdc,fontid)
      GetWindowText_(hwnd,text.s,255)
      SetBkColor_(newdc,GetSysColor_(#COLOR_BTNFACE))
      SetTextAlign_(newdc,#TA_CENTER)
      ExtTextOut_(newdc,50,40,#ETO_CLIPPED,@rect,text.s,Len(text),0)
      BitBlt_(dc,0,0,100,100,newdc,0,0,#SRCCOPY)
      ReleaseDC_(hwnd,dc)
      DeleteDC_(newdc)
      DeleteObject_(membmp)
      ;ProcedureReturn 0
    Case #WM_LBUTTONDOWN
      buttondown=1
      rect.RECT
      dc=GetDC_(hwnd)
      newdc=CreateCompatibleDC_(dc)
      membmp=CreateCompatibleBitmap_(dc,100,100)
      brush=CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE ))
      pen=CreatePen_(#PS_SOLID,1,GetSysColor_(#COLOR_GRAYTEXT ))
      SelectObject_(newdc,membmp)
      SelectObject_(newdc,brush)
      SelectObject_(newdc,pen)
      Rectangle_(newdc,0,0,100,100)
      rect\left=0:rect\right=100:rect\top=0:rect\bottom=100
      text.s=Space(255)
      fontid=GetStockObject_(#ANSI_VAR_FONT)   
      SelectObject_(newdc,fontid)
      GetWindowText_(hwnd,text.s,255)
      SetBkColor_(newdc,GetSysColor_(#COLOR_BTNFACE))
      SetTextAlign_(newdc,#TA_CENTER)
      ExtTextOut_(newdc,52,42,#ETO_CLIPPED,@rect,text.s,Len(text),0)
      DrawEdge_(newdc,@rect,#EDGE_SUNKEN,#BF_TOP|#BF_LEFT|#BF_RIGHT|#BF_BOTTOM   )
      BitBlt_(dc,0,0,100,100,newdc,0,0,#SRCCOPY)
      ReleaseDC_(GadgetID(0),dc)
      DeleteDC_(newdc)
      DeleteObject_(membmp)
    Case #WM_LBUTTONUP
      dc=GetDC_(hwnd)
      newdc=CreateCompatibleDC_(dc)
      membmp=CreateCompatibleBitmap_(dc,100,100)
      brush=CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
      pen=CreatePen_(#PS_SOLID,0,GetSysColor_(#COLOR_BTNFACE))
      SelectObject_(newdc,membmp)
      SelectObject_(newdc,brush)
      SelectObject_(newdc,pen)
      Rectangle_(newdc,0,0,100,100)
      rect.RECT
      rect\left=0:rect\right=100:rect\top=0:rect\bottom=100
      text.s=Space(255)
      fontid=GetStockObject_(#ANSI_VAR_FONT)   
      SelectObject_(newdc,fontid)
      GetWindowText_(hwnd,text.s,255)
      SetBkColor_(newdc,GetSysColor_(#COLOR_BTNFACE))
      SetTextAlign_(newdc,#TA_CENTER)
      ExtTextOut_(newdc,50,40,#ETO_CLIPPED,@rect,text.s,Len(text),0)
      DrawEdge_(newdc,@rect,#EDGE_RAISED,#BF_RECT)
      BitBlt_(dc,0,0,100,100,newdc,0,0,#SRCCOPY)
      ReleaseDC_(GadgetID(0),dc)
      DeleteDC_(newdc)
      DeleteObject_(membmp)
      buttondown=0
  EndSelect
  ProcedureReturn CallWindowProc_(GetProp_(hwnd,"OldProc"),hwnd,msg,wParam,lParam)
EndProcedure

OpenWindow(0,0,0,470,460,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

ImageGadget(0,20,20,100,100,0)
txt.s="test"
SetWindowText_(GadgetID(0),txt)
SetProp_(GadgetID(0),"OldProc",SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@callback()))


Repeat
  Select WindowEvent()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Debug 65656
          
      EndSelect
    Case #PB_Event_CloseWindow
      Quit=1
  EndSelect
Until Quit=1

as usual, comments and suggestions are always welcome.

@@@ sparkie. you da man for the memory drawing help.

Posted: Mon Nov 28, 2005 1:12 am
by Straker
Very nice effect. However, it's eating my CPU for breakfast.

Posted: Mon Nov 28, 2005 1:18 am
by Kale
Straker wrote:Very nice effect. However, it's eating my CPU for breakfast.
Just use WaitWindowEvent() instead of WindowEvent() :)

Posted: Mon Nov 28, 2005 1:23 am
by Straker
Thanks Kale. That did it. I didn't bother to peruse the code, but I probably would have glossed over that anyway.