Very cool menu! Feel free to play! [WINDOWS]

Share your advanced PureBasic knowledge/code with the community.
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

Hey guys, I made something pretty cool, and I figured I'd share it with y'all.
Save this file as: "Transparent_Menu.pb"

Code: Select all


Global szClassNameXy.s = "CMClass"

Enumeration
  #MOUSE_IN_TIMER = 1
  #TIMER_SHRINK
  #TIMER_EXPAND
  
EndEnumeration

Structure CUSTOM_MENU_CREATE
  numFontItems.i
  numFontHeader.i
  hParent.i
  szMenuTitle.s
  x.i
  y.i
  cx.i
  cy.i
  rgb_title_color.i
  rgb_menu_unselected.i
  rgb_text_shadow_unselected.i
  rgb_menu_hilite.i
  rgb_text_shadow_hilite.i
  hWnd_To_Notify_Of_Menu_Events.i
  bHadBorder.b
EndStructure


Structure CUSTOM_MENU
  szItemName.s
  enumMenu.i
  rcItem.RECT
EndStructure


Structure IND_DC_INFO_2
  hDc.i
  hBitmap.i
  hOrinalBmp.i
EndStructure

Structure DC_INFO_2
  hDcParent.IND_DC_INFO_2
  hDcFinal.IND_DC_INFO_2
EndStructure

Structure ITEM_OPERATION
  iItem.i
  iColor.i
  rcItem.RECT
EndStructure


Structure CUSTOM_MENU_INFO
  szMenuTitle.s
  numFont.i
  numHeaderFont.i
  hParent.i
  iLastSelectedItem.i
  iCurrentItem.i
  mmTimerActive.i
  iMenuColor.i
  iShadowColor.i
  iShadowColorHilite.i
  iTitleColor.i
  iEndColor.i
  bButtonDown.b
  hWndToNotify.i
  x.i
  y.i
  cx.i
  cy.i
  dcs.DC_INFO_2
  List itemsToExpand.ITEM_OPERATION()
  List itemsToShrink.ITEM_OPERATION()
  List cm.CUSTOM_MENU()
EndStructure


Procedure RedrawDC( hWnd, *lpCMI.CUSTOM_MENU_INFO, expand = 0 )
      
      SendMessage_(*lpCMI\hParent, #WM_PRINT, *lpCMI\dcs\hDcParent\hDc, #PRF_CLIENT|#PRF_ERASEBKGND)
      BitBlt_(*lpCMI\dcs\hDcFinal\hDc, 0, 0, *lpCMI\cx, *lpCMI\cy, *lpCMI\dcs\hDcParent\hDc, *lpCMI\x, *lpCMI\y, #SRCCOPY)
      SelectObject_(*lpCMI\dcs\hDcFinal\hDc, FontID(*lpCMI\numHeaderFont))
      GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @ts.SIZE)
      
      text_truncated = #False
      While (ts\cx > (*lpCMI\cx - 30))
        text_truncated = #True
        *lpCMI\szMenuTitle = Left(*lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle) - 1)
        GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @ts.SIZE)
      Wend
      If text_truncated = #True
        *lpCMI\szMenuTitle + "..."
      EndIf
      
      rcDT.RECT\left = 6
      rcDT\right = *lpCMI\cx - 9
      rcDT\top = 5
      rcDT\bottom = rcDT\top + ts\cy
      SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iShadowColor)
      SetBkMode_(*lpCMI\dcs\hDcFinal\hDc, #TRANSPARENT)
      DrawText_(*lpCMI\dcs\hDcFinal\hDc, @*lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @rcDT.RECT, #DT_LEFT)
      
      rcDT.RECT\left = 5
      rcDT\right = *lpCMI\cx - 10
      rcDT\top = 5
      rcDT\bottom = rcDT\top + ts\cy
      SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iTitleColor)
      SetBkMode_(*lpCMI\dcs\hDcFinal\hDc, #TRANSPARENT)
      DrawText_(*lpCMI\dcs\hDcFinal\hDc, @*lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @rcDT.RECT, #DT_LEFT)
      
      
      rcDT\top = rcDT\bottom + 10
      ctr = 0
      SelectObject_(*lpCMI\dcs\hDcFinal\hDc, GetStockObject_(#NULL_BRUSH))
      SelectObject_(*lpCMI\dcs\hDcFinal\hDc, FontID(*lpCMI\numFont))
      ForEach *lpCMI\cm()
        myTextColor = *lpCMI\iMenuColor
        myshadowcolor = *lpCMI\iShadowColor
        GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @ts.SIZE)
        If ctr = 0
          rcDT\bottom = rcDT\top + ts\cy
        EndIf
        If rcDT\bottom > *lpCMI\cy
          Break
        EndIf
        text_truncated = #False
        While (ts\cx > ((*lpCMI\cx - 30) - (*lpCMI\cx / 8)) )
          text_truncated = #True
          *lpCMI\cm()\szItemName = Left(*lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName) - 1)
          GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @ts.SIZE)
        Wend
        If text_truncated = #True
          *lpCMI\cm()\szItemName + "..."
        EndIf
        expanding = #False
        shrinking = #False
        
        ResetList(*lpCMI\itemsToExpand())
        While NextElement(*lpCMI\itemsToExpand())
          If *lpCMI\itemsToExpand()\iItem = ctr
            If expand = #True
              ;*lpCMI\itemsToExpand()\rcItem\left + 5
              *lpCMI\itemsToExpand()\rcItem\left + ((*lpCMI\cx / 8) - *lpCMI\cm()\rcItem\left) / 10
              *lpCMI\itemsToExpand()\iColor = myTextColor
            EndIf
            myTextColor = *lpCMI\itemsToExpand()\iColor
            rcDT\left = *lpCMI\itemsToExpand()\rcItem\left
            CopyStructure(@rcDT, @rcInvalid.RECT, RECT)
            If (rcDT\left >= (*lpCMI\cx / 8))
              DeleteElement(*lpCMI\itemsToExpand())
            EndIf
            If ListSize(*lpCMI\itemsToExpand()) = 0
              myTextColor = *lpCMI\iEndColor
              myshadowcolor = *lpCMI\iShadowColorHilite
              KillTimer_(hWnd, #TIMER_EXPAND)
            EndIf
            expanding = #True
            Break
          EndIf
        Wend
        
        If expanding = #False
          ResetList(*lpCMI\itemsToShrink())
          While NextElement(*lpCMI\itemsToShrink())
            If *lpCMI\itemsToShrink()\iItem = ctr
              ;*lpCMI\itemsToShrink()\rcItem\left - 5
              *lpCMI\itemsToShrink()\rcItem\left - ( (*lpCMI\cx / 8) - *lpCMI\cm()\rcItem\left ) / 10
              
              *lpCMI\itemsToShrink()\iColor = myTextColor
              myTextColor = *lpCMI\itemsToShrink()\iColor
              rcDT\left = *lpCMI\itemsToShrink()\rcItem\left
              shrinking = #True
              CopyStructure(@rcDT, @rcInvalid.RECT, RECT)
              If rcDT\left < = *lpCMI\cm()\rcItem\left
                rcDT\left = *lpCMI\cm()\rcItem\left
                DeleteElement(*lpCMI\itemsToShrink())
              EndIf
              If ListSize(*lpCMI\itemsToShrink()) = 0
                myTextColor = *lpCMI\iMenuColor
                KillTimer_(hWnd, #TIMER_SHRINK)
              EndIf
              Break
            EndIf
          Wend
        EndIf
        
        If shrinking = #False And expanding = #False
          rcDT\left = *lpCMI\cm()\rcItem\left
        Else
          redraw = #True
        EndIf
        CopyStructure(@rcDT, @rcdt2.RECT, RECT)
        If ctr = *lpCMI\iCurrentItem
          DeleteObject_(SelectObject_(*lpCMI\dcs\hDcFinal\hDc, CreatePen_(#PS_SOLID, 1, myTextColor)))
          RoundRect_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\rcItem\left, *lpCMI\cm()\rcItem\top, *lpCMI\cm()\rcItem\right, *lpCMI\cm()\rcItem\bottom, 20, 20)
        EndIf
        SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, myshadowcolor);*lpCMI\iShadowColor)
        rcdt2\left + 1
        rcdt2\right + 1
        DrawText_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @rcdt2, #DT_LEFT)
        SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, myTextColor)
        DrawText_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @rcDT, #DT_LEFT)
        ;rcDT\top = rcDT\top + ts\cy ;rcDT\bottom
        rcDT\top + ts\cy ;rcDT\bottom
        rcDT\bottom + ts\cy 
        
        ctr + 1
      Next
      If redraw = #True
        InvalidateRect_(hWnd, 0, 0)
      EndIf
      
      If ListSize(*lpCMI\itemsToExpand()) = 0
        KillTimer_(hWnd, #TIMER_EXPAND)
      EndIf
      If ListSize(*lpCMI\itemsToShrink()) = 0
        KillTimer_(hWnd, #TIMER_SHRINK)
      EndIf

EndProcedure


Procedure Menu_Wnd_Proc( hWnd, uMsg, wParam, lParam )
  
  *lpCMI.CUSTOM_MENU_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
  Select uMsg
      
    Case #WM_LBUTTONDOWN
      *lpCMI\bButtonDown = #True
    Case #WM_LBUTTONUP
      If *lpCMI\bButtonDown = #True
        cItem = -1
        cursX = lParam & $0000FFFF
        cursY = (lParam & $FFFF0000) >> 16
        ForEach *lpCMI\cm()
          With *lpCMI\cm()\rcItem
            If cursX >= \left And cursX <= \right
              If cursY >= \top And cursY <= \bottom
                PostMessage_(*lpCMI\hWndToNotify, #WM_COMMAND, *lpCMI\cm()\enumMenu, 0)
                Break
              EndIf
            EndIf
          EndWith
        Next
      EndIf
      
      *lpCMI\bButtonDown = #False
    Case #WM_CREATE ;-WM_CREATE
      If lParam = 0
        ProcedureReturn -1
      EndIf
      *lpcs.CREATESTRUCT = lParam
      *lpCMI = *lpcs\lpCreateParams
      SetWindowLongPtr_(hWnd, #GWLP_USERDATA, *lpCMI)
      hDcCreate = GetDC_(#Null)
      *lpCMI\dcs\hDcFinal\hDc = CreateCompatibleDC_(hDcCreate)
      *lpCMI\dcs\hDcFinal\hBitmap = CreateCompatibleBitmap_(hDcCreate, *lpcs\cx, *lpcs\cy)
      *lpCMI\dcs\hDcFinal\hOrinalBmp = SelectObject_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\dcs\hDcFinal\hBitmap)
      
      *lpCMI\dcs\hDcParent\hDc = CreateCompatibleDC_(hDcCreate)
      GetWindowRect_(*lpCMI\hParent, @rcParent.RECT)
      *lpCMI\dcs\hDcParent\hBitmap = CreateCompatibleBitmap_(hDcCreate, rcParent\right - rcParent\left, rcParent\bottom - rcParent\top)
      *lpCMI\dcs\hDcParent\hOrinalBmp = SelectObject_(*lpCMI\dcs\hDcParent\hDc, *lpCMI\dcs\hDcParent\hBitmap)
      
      *lpCMI\cx = *lpcs\cx
      *lpCMI\cy = *lpcs\cy
      *lpCMI\x = *lpcs\x
      *lpCMI\y = *lpcs\y
      mr.rect\left = 0
      mr\top = 0
      mr\right = *lpcs\cx
      mr\bottom = *lpcs\cy
      SelectObject_(*lpCMI\dcs\hDcFinal\hDc, FontID(*lpCMI\numHeaderFont))
      SendMessage_(*lpCMI\hParent, #WM_PRINT, *lpCMI\dcs\hDcParent\hDc, #PRF_CLIENT|#PRF_ERASEBKGND)
      BitBlt_(*lpCMI\dcs\hDcFinal\hDc, 0, 0, *lpCMI\cx, *lpCMI\cy, *lpCMI\dcs\hDcParent\hDc, *lpCMI\x, *lpCMI\y, #SRCCOPY)
      
      GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @ts.SIZE)
      NewList *lpCMI\itemsToExpand.ITEM_OPERATION()
      NewList *lpCMI\itemsToShrink.ITEM_OPERATION()
      
      text_truncated = #False
      While (ts\cx > (*lpcs\cx - 30))
        text_truncated = #True
        *lpCMI\szMenuTitle = Left(*lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle) - 1)
        GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @ts.SIZE)
      Wend
      If text_truncated = #True
        *lpCMI\szMenuTitle + "..."
      EndIf
      
      *lpCMI\iCurrentItem = -1
      
      rcDT.RECT\left = 6
      rcDT\right = *lpcs\cx - 9
      rcDT\top = 5
      rcDT\bottom = rcDT\top + ts\cy
      SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iShadowColor)
      SetBkMode_(*lpCMI\dcs\hDcFinal\hDc, #TRANSPARENT)
      DrawText_(*lpCMI\dcs\hDcFinal\hDc, @*lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @rcDT.RECT, #DT_LEFT)
      
      rcDT.RECT\left = 5
      rcDT\right = *lpcs\cx - 10
      rcDT\top = 5
      rcDT\bottom = rcDT\top + ts\cy
      SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iTitleColor)
      SetBkMode_(*lpCMI\dcs\hDcFinal\hDc, #TRANSPARENT)
      DrawText_(*lpCMI\dcs\hDcFinal\hDc, @*lpCMI\szMenuTitle, Len(*lpCMI\szMenuTitle), @rcDT.RECT, #DT_LEFT)
      
      SelectObject_(*lpCMI\dcs\hDcFinal\hDc, FontID(*lpCMI\numFont))
      SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iMenuColor)
      ctr = 0 
      rcDT\top = rcDT\bottom + 10
      ForEach *lpCMI\cm()
        GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @ts.SIZE)
        If ctr = 0
          rcDT\bottom = rcDT\top + ts\cy
        EndIf
        If rcDT\bottom > *lpcs\cy
          Break
        EndIf
        
        text_truncated = #False
        While (ts\cx > ((*lpcs\cx - 30) - (*lpCMI\cx / 8))  )
          text_truncated = #True
          *lpCMI\cm()\szItemName = Left(*lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName) - 1)
          GetTextExtentPoint32_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @ts.SIZE)
        Wend
        If text_truncated = #True
          *lpCMI\cm()\szItemName + "..."
        EndIf
        
        CopyStructure(@rcDT, @rcdt2.RECT, RECT)
        rcdt2\left + 1
        rcdt2\right + 1
        SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iShadowColor)
        DrawText_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @rcdt2, #DT_LEFT)
        SetTextColor_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\iMenuColor)
        
        
        DrawText_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\cm()\szItemName, Len(*lpCMI\cm()\szItemName), @rcDT, #DT_LEFT)
        CopyStructure(@rcDT, @*lpCMI\cm()\rcItem, RECT)
        ;rcDT\top = rcDT\top + ts\cy ;rcDT\bottom
        rcDT\top + ts\cy 
        rcDT\bottom + ts\cy 
        ctr + 1
      Next
      
      
      ReleaseDC_(#Null, hDcCreate)
      ProcedureReturn 0
      
      
    Case #WM_TIMER
      Select wParam
        Case #MOUSE_IN_TIMER
          GetCursorPos_(@cpos.POINT)
          ScreenToClient_(hWnd, @cpos)
          stop_timer = #False
          If cpos\x < 0 Or cpos\y < 0
            stop_timer = #True
          Else
            If cpos\x > *lpCMI\cx Or cpos\y > *lpCMI\cy
              stop_timer = #True
            EndIf
          EndIf
          If stop_timer = #True
            need_to_start_shrink_timer = #False
            If ListSize(*lpCMI\itemsToShrink()) = 0
              need_to_start_shrink_timer = #True
            EndIf
            
            ResetList(*lpCMI\itemsToExpand())
            While NextElement(*lpCMI\itemsToExpand())
              ResetList(*lpCMI\itemsToShrink())
              While NextElement(*lpCMI\itemsToShrink())
                If *lpCMI\itemsToShrink()\iItem = *lpCMI\itemsToExpand()\iItem
                  DeleteElement(*lpCMI\itemsToShrink())
                EndIf
              Wend
              AddElement(*lpCMI\itemsToShrink())
              *lpCMI\itemsToShrink()\iColor = *lpCMI\itemsToExpand()\iColor
              *lpCMI\itemsToShrink()\iItem = *lpCMI\itemsToExpand()\iItem
              CopyStructure(@*lpCMI\itemsToExpand()\rcItem, @*lpCMI\itemsToShrink()\rcItem, RECT)
              DeleteElement(*lpCMI\itemsToExpand())
            Wend
            If *lpCMI\iCurrentItem <> -1
              SelectElement(*lpCMI\cm(), *lpCMI\iCurrentItem)
              AddElement(*lpCMI\itemsToShrink())
              *lpCMI\itemsToShrink()\iColor = *lpCMI\iEndColor
              ;*lpCMI\itemsToShrink()\iColor = $FFFFFF
              *lpCMI\itemsToShrink()\iItem = *lpCMI\iCurrentItem
              CopyStructure(@*lpCMI\cm()\rcItem, @*lpCMI\itemsToShrink()\rcItem, RECT)
              *lpCMI\itemsToShrink()\rcItem\left = (*lpCMI\cx / 8)
              *lpCMI\iCurrentItem = -1
              
            EndIf
            
            
            
            If ListSize(*lpCMI\itemsToShrink()) > 0
              If need_to_start_shrink_timer = #True
                SetTimer_(hWnd, #TIMER_SHRINK, 10, #Null)
              EndIf
            EndIf
            
              
            KillTimer_(hWnd, #MOUSE_IN_TIMER)
            *lpCMI\mmTimerActive = #False
            
          EndIf
          
          
        Case #TIMER_SHRINK
          RedrawDC( hWnd, *lpCMI )
        Case #TIMER_EXPAND
          RedrawDC( hWnd, *lpCMI, 1 )
      EndSelect
      ProcedureReturn 1
      
      
    Case #WM_MOUSEMOVE
      If *lpCMI\mmTimerActive = #False
        SetTimer_(hWnd, #MOUSE_IN_TIMER, 50, #Null)
        *lpCMI\mmTimerActive = #True
      EndIf
      
      cItem = -1
      cursX = lParam & $0000FFFF
      cursY = (lParam & $FFFF0000) >> 16
      ctr = 0
      ForEach *lpCMI\cm()
        With *lpCMI\cm()\rcItem
          If cursX >= \left And cursX <= \right
            If cursY >= \top And cursY <= \bottom
              cItem = ctr
              Break
            EndIf
          EndIf
        EndWith
        ctr + 1
      Next
      If *lpCMI\iCurrentItem > -1
        If *lpCMI\iCurrentItem <> cItem
          ; Remove item from expand queue
          item_found = #False
          ResetList(*lpCMI\itemsToExpand())
          While NextElement(*lpCMI\itemsToExpand())
            If *lpCMI\itemsToExpand()\iItem = *lpCMI\iCurrentItem
              item_found = #True
              CopyStructure(@*lpCMI\itemsToExpand()\rcItem, @rcfound.RECT, RECT)
              iCopyColor = *lpCMI\itemsToExpand()\iColor
              DeleteElement(*lpCMI\itemsToExpand())
            EndIf
          Wend
          AddElement(*lpCMI\itemsToShrink())
          *lpCMI\itemsToShrink()\iItem = *lpCMI\iCurrentItem
          If item_found = #True
            CopyStructure(@rcfound, @*lpCMI\itemsToShrink()\rcItem, RECT)
            *lpCMI\itemsToShrink()\iColor = iCopyColor
          Else
            CopyStructure(@*lpCMI\cm()\rcItem, @rcfound, RECT)
            rcfound\left = (*lpCMI\cx / 8)
            CopyStructure(@rcfound, @*lpCMI\itemsToShrink()\rcItem, RECT)
            *lpCMI\itemsToShrink()\iColor = #White
          EndIf
          
          If ListSize(*lpCMI\itemsToShrink()) = 1
            SetTimer_(hWnd, #TIMER_SHRINK, 10, #Null)
          EndIf
        EndIf
      EndIf
      If cItem <> *lpCMI\iCurrentItem
        *lpCMI\iCurrentItem = cItem
        If *lpCMI\iCurrentItem <> -1
          
          shrink_found = #False
          ResetList(*lpCMI\itemsToShrink())
          While NextElement(*lpCMI\itemsToShrink())
            If *lpCMI\itemsToShrink()\iItem = *lpCMI\iCurrentItem
              shrink_found = #True
              CopyStructure(@*lpCMI\itemsToShrink()\rcItem, @rcfound.RECT, RECT)
              icolor = *lpCMI\itemsToShrink()\iColor
              DeleteElement(*lpCMI\itemsToShrink())
            EndIf
            
          Wend
          
          
          ResetList(*lpCMI\itemsToExpand())
          While NextElement(*lpCMI\itemsToExpand())
            If *lpCMI\itemsToExpand()\iItem = *lpCMI\iCurrentItem
              DeleteElement(*lpCMI\itemsToExpand())
            EndIf
          Wend
          AddElement(*lpCMI\itemsToExpand())
          If shrink_found = #False
            *lpCMI\itemsToExpand()\iItem = cItem
            *lpCMI\itemsToExpand()\iColor = *lpCMI\iMenuColor
            CopyStructure(@*lpCMI\cm()\rcItem, @*lpCMI\itemsToExpand()\rcItem, RECT)
          Else
            *lpCMI\itemsToExpand()\iItem = cItem
            *lpCMI\itemsToExpand()\iColor = icolor
            CopyStructure(@rcfound, @*lpCMI\itemsToExpand()\rcItem, RECT)
          EndIf
          If ListSize(*lpCMI\itemsToExpand()) = 1
            SetTimer_(hWnd, #TIMER_EXPAND, 10, #Null)
          EndIf
        EndIf
      EndIf
      If *lpCMI\iCurrentItem <> -1
        nowCursor = LoadCursor_(#Null, #IDC_HAND)
        SetClassLongPtr_(hWnd, #GCL_HCURSOR, nowCursor)
        DestroyCursor_(SetCursor_(nowCursor))
      Else
        nowCursor = LoadCursor_(#Null, #IDC_ARROW)
        SetClassLongPtr_(hWnd, #GCL_HCURSOR, nowCursor)
        DestroyCursor_(SetCursor_(nowCursor))
      EndIf
      
      ProcedureReturn 0
      
      
      
      
      
      
    Case #WM_DESTROY
      ; Delete all bitmaps and DC's created
      DeleteObject_(SelectObject_(*lpCMI\dcs\hDcFinal\hDc, *lpCMI\dcs\hDcFinal\hOrinalBmp))
      DeleteDC_(*lpCMI\dcs\hDcFinal\hDc)
      
      DeleteObject_(SelectObject_(*lpCMI\dcs\hDcParent\hDc, *lpCMI\dcs\hDcParent\hOrinalBmp))
      DeleteDC_(*lpCMI\dcs\hDcParent\hDc)
      
      
      
      ; Free memory
      FreeList(*lpCMI\itemsToExpand())
      FreeList(*lpCMI\itemsToShrink())
      FreeList(*lpCMI\cm())
      FreeMemory(*lpCMI)
    Case #WM_WINDOWPOSCHANGED
      ; Resize all drawing operations...
    Case #WM_PAINT ;- WM_PAINT
      BeginPaint_(hWnd, @ps.PAINTSTRUCT)
      BitBlt_(ps\hdc, ps\rcPaint\left, ps\rcPaint\top, (ps\rcPaint\right-ps\rcPaint\left), ps\rcPaint\bottom-ps\rcPaint\top, *lpCMI\dcs\hDcFinal\hDc, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
      EndPaint_(hWnd, @ps)
      ProcedureReturn 0
  EndSelect
  
  ProcedureReturn DefWindowProc_(hWnd, uMsg, wParam, lParam)
EndProcedure


cmwcex.WNDCLASSEX\cbSize = SizeOf(WNDCLASSEX)
cmwcex\hbrBackground = GetStockObject_(#NULL_BRUSH)
cmwcex\hCursor = LoadCursor_(#Null, #IDC_ARROW)
cmwcex\hInstance = GetModuleHandle_(#Null)
cmwcex\lpfnWndProc = @Menu_Wnd_Proc()
cmwcex\lpszClassName = @szClassNameXy
cmwcex\style = #CS_HREDRAW|#CS_VREDRAW
RegisterClassEx_(@cmwcex)

Procedure Set_Menu_Item_Text( hMenu, enumMenu, szText.s )
  retVal = #False
  *lpCMI.CUSTOM_MENU_INFO = GetWindowLongPtr_(hMenu, #GWLP_USERDATA)
  If *lpCMI = 0
    ProcedureReturn 0
  EndIf
  ForEach *lpCMI\cm()
    If *lpCMI\cm()\enumMenu = enumMenu
      *lpCMI\cm()\szItemName = szText
      retVal = #True
      RedrawDC(hMenu, *lpCMI)
      InvalidateRect_(hMenu, 0, 1)
      Break
    EndIf
  Next
  ProcedureReturn retVal
EndProcedure

Procedure.s Get_Menu_Item_Text( hMenu, enumMenu )
  retVal.s = ""
  *lpCMI.CUSTOM_MENU_INFO = GetWindowLongPtr_(hMenu, #GWLP_USERDATA)
  If *lpCMI = 0
    ProcedureReturn retVal
  EndIf
  ForEach *lpCMI\cm()
    If *lpCMI\cm()\enumMenu = enumMenu
      retVal = *lpCMI\cm()\szItemName
      Break
    EndIf
  Next
  ProcedureReturn retVal
EndProcedure


Procedure Create_Custom_Menu( *lpCmc.CUSTOM_MENU_CREATE, List menuitems.CUSTOM_MENU() )
  hWnd = #Null
  If Not(IsFont(*lpCmc\numFontItems))
    *lpCmc\numFontItems = LoadFont(#PB_Any, "Times New Roman", 10)
  EndIf
  If Not(IsFont(*lpCmc\numFontHeader))
    *lpCmc\numFontHeader = LoadFont(#PB_Any, "Times New Roman", 20)
  EndIf
  *lpCMI.CUSTOM_MENU_INFO = AllocateMemory(SizeOf(CUSTOM_MENU_INFO))
  *lpCMI\numFont = *lpCmc\numFontItems
  *lpCMI\numHeaderFont = *lpCmc\numFontHeader
  *lpCMI\szMenuTitle = *lpCmc\szMenuTitle ;szMenuName
  *lpCMI\hParent = *lpCmc\hParent ;hParent
  *lpCMI\iMenuColor = *lpCmc\rgb_menu_unselected ;iColor
  *lpCMI\iShadowColor = *lpCmc\rgb_text_shadow_unselected ;iShadowColor
  *lpCMI\iEndColor = *lpCmc\rgb_menu_hilite ;iEndColor
  *lpCMI\iTitleColor = *lpCmc\rgb_title_color
  *lpCMI\iShadowColorHilite = *lpCmc\rgb_text_shadow_hilite
  If *lpCmc\hWnd_To_Notify_Of_Menu_Events = #Null
    *lpCMI\hWndToNotify = *lpCMI\hParent
  Else
    *lpCMI\hWndToNotify = *lpCmc\hWnd_To_Notify_Of_Menu_Events
  EndIf
  
  NewList *lpCMI\cm.CUSTOM_MENU()
  dwExStyle = #Null
  If *lpCmc\bHadBorder = #True
    dwStyle = #WS_CHILD|#WS_VISIBLE|#WS_BORDER
  Else
    dwStyle = #WS_CHILD|#WS_VISIBLE
  EndIf
  
  CopyList(menuitems(), *lpCMI\cm())
  hWnd = CreateWindowEx_(dwExStyle, @szClassNameXy, "", dwStyle, *lpCmc\x, *lpCmc\y, *lpCmc\cx, *lpCmc\cy, *lpCmc\hParent, #Null, GetModuleHandle_(#Null), *lpCMI)
  If Not( hWnd )
    FreeList(*lpCMI\cm())
    FreeMemory(*lpCMI)
  EndIf
  ProcedureReturn hWnd
EndProcedure
Last edited by JustinJack on Wed Aug 22, 2012 6:00 pm, edited 1 time in total.
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

And here is an example program. Pretty, cool. I'm going to use the HECK out of this. Ive been working on it for about 8 hrs straight!

Code: Select all

IncludeFile "Transparent_Menu.pb"

NewList miList.CUSTOM_MENU()

myWindow = OpenWindow(#PB_Any, 0, 0, 1000, 600, "Cool Menu Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
SetWindowColor(myWindow, $F4DBC4)
TextGadget(1, 220, 10, 100, 18, "Misc Text Field")
SetGadgetColor(1, #PB_Gadget_BackColor, $F4DBC4)
StringGadget(2, 220, 28, 200, 20, "Misc Text")
ListIconGadget(3, 220, 50, 770, 540, "Test", 300)

ButtonGadget(4, 500, 28, 70, 20, "Change")

TextGadget(5, 440, 10, 100, 18, "Menu Item")
StringGadget(6, 440, 28, 50, 20, "3")
SetGadgetColor(5, #PB_Gadget_BackColor, $F4DBC4)


For i = 1 To 10
  AddElement(miList())
  miList()\enumMenu= i
  miList()\szItemName = "Menu Item " + Str(i)
Next


cmc.CUSTOM_MENU_CREATE
cmc\x = 10
cmc\y = 10
cmc\bHadBorder = #True ; #False
cmc\hParent = WindowID(myWindow)
cmc\numFontItems = LoadFont(#PB_Any, "Bauhaus 93", 14)
cmc\numFontHeader = LoadFont(#PB_Any, "Times New Roman", 20)
cmc\szMenuTitle = "Menu Options"
cmc\rgb_title_color = #Black
cmc\rgb_menu_unselected = #Black
cmc\rgb_menu_hilite = $E41015
cmc\rgb_text_shadow_unselected = $A0A0A0 ; Used for title shadow, too
cmc\rgb_text_shadow_hilite = $A0A0A0
cmc\cx = 200
cmc\cy = 580


hMenu = Create_Custom_Menu(@cmc, miList())

SetActiveGadget(2)
okToClose = #False
Repeat 
  dwEvent = WaitWindowEvent()
  Select dwEvent
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 2, 6
          If EventType() = #PB_EventType_Focus
            SendMessage_(GadgetID(EventGadget()), #EM_SETSEL, 0, -1)
          EndIf
          
        Case 4
          If EventType() = #PB_EventType_LeftClick
            Set_Menu_Item_Text(hMenu, Val(GetGadgetText(6)), GetGadgetText(2))
            SetGadgetText(6, Str(Random(9) + 1))
            SetActiveGadget(2)
          EndIf
      EndSelect
      
    Case #PB_Event_Menu
      AddGadgetItem(3, -1, Get_Menu_Item_Text(hMenu, EventMenu()))
      
    Case #PB_Event_CloseWindow
      okToClose = #True
  EndSelect
  
Until okToClose = #True

jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by jassing »

When I tried to run the files, I got an error on LoadFont()
Image
Commenting out both LoadFont() lines:
Image
User avatar
Bisonte
Addict
Addict
Posts: 1313
Joined: Tue Oct 09, 2007 2:15 am

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by Bisonte »

Change the fontname "Bauhaus 93" to one wich is installed on your system...

Nice Menu btw. ;)
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by jassing »

Bisonte wrote:Change the fontname "Bauhaus 93" to one wich is installed on your system...
well - those fonts are installed, I checked those before I posted...
oh well; something wrong with my system then...
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

I don't know exactly WHAT difference this will make, but I did all my testing in PB v4.60...
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by Kwai chang caine »

Works good, very nice effect :shock:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 796
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by Zebuddi123 »

Very nice really like this !!! GREAT work thanks for sharing :lol: :) :) :) :) :)

Zebuddi.
malleo, caput, bang. Ego, comprehendunt in tempore
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

I'm very pleased everyone likes it! :D

Now, I only coded it juuuuuust a bit beyond the functionality that I needed. The code, now COULD have a problem if the control is right-justified in the parent window, and the parent window is resized to a LARGER size. The reason is, when I draw the background of the menu control, I send the PARENT window a WM_PRINT message with an hDC that I size and set up during WM_CREATE. So if the parent size increases, our background-handling functionality could bottle-neck. So if any one feels tinkery and wants to work on that, that would be just great! Man I love this forum.
User avatar
J@ckWhiteIII
Enthusiast
Enthusiast
Posts: 183
Joined: Fri May 25, 2012 7:39 pm

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by J@ckWhiteIII »

Do do this in full screen, I'd need a "fake" fullscreen aka borderless window, right?
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

@J@ckWhiteIII
Include this file in your project as: "Jelly_Window.pb"

Code: Select all

;- Jelly Window Library
;- by Justin Jack

Enumeration
  #DT_UNDERLINED = 4
EndEnumeration

Structure MOVE_TO
  x.i
  y.i
  cx.i
  cy.i
  cxAdjust.i
  bounceback.i
  iNumSteps.i
  iStepCounter.i
  iRemainder.i
  bIsAnimating.b
  changePerScoop.i
  cAlpha.i
EndStructure

Structure JELLY_CONTROL_SET
  iMouseInTimer.i
  bMouseIn.b
  moveto.MOVE_TO
EndStructure

Enumeration
  #MOUSE_TIMER = 763
  #ANIMATION_SHOW
EndEnumeration



Structure JELLY_WINDOW_INFO
  hDcWnd.i
  iJellyColor.i
  iWindowBMP.i
  hOldDcWnd.i
  hOldBMP.i
  numWindow.i
  hRgn.i
  *lpOldWndProc
  szWindowText.s
  iTextFont.i
  iOrientationFlags.i
  iColor.i
  iBkgr .i
  
  control.JELLY_CONTROL_SET
EndStructure


Procedure Make_Jelly_Images_Window( w_Window )
  If Not(IsWindow(w_Window))
    If Not(IsWindow_(w_Window))
      ProcedureReturn #False
    Else
      hWnd = w_Window
    EndIf
  Else
    hWnd = WindowID(w_Window)
  EndIf
  *lpjiw.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
  oldRgn = *lpjiw\hRgn
  
  
  btn_size.SIZE\cx = WindowWidth(*lpjiw\numWindow)
  btn_size\cy      = WindowHeight(*lpjiw\numWindow)
  jelly_color = *lpjiw\iJellyColor
  oldImage = *lpjiw\iWindowBMP
  If btn_size\cx <= 0 
    btn_size\cx = 1
  EndIf
  *lpjiw\iWindowBMP = CreateImage(#PB_Any, btn_size\cx, btn_size\cy, 24)
  StartDrawing(ImageOutput(*lpjiw\iWindowBMP))
  Box(0, 0, btn_size\cx, btn_size\cy, jelly_color)
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  RoundBox(0, 0, btn_size\cx, btn_size\cy, 20, 20, jelly_color)
  DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
  BackColor(RGBA(0, 0, 0, 130))
  FrontColor(RGBA(0, 0, 0, 00))
  LinearGradient(-10, 0, (btn_size\cx / 3), 0)
  RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
  FrontColor(RGBA(0, 0, 0, 130))
  BackColor(RGBA(0, 0, 0, 00))
  LinearGradient(btn_size\cx - (btn_size\cx / 3), 0, (btn_size\cx + 10), 0)
  RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
  FrontColor(RGBA($FF, $FF, $FF, 00))
  BackColor(RGBA($FF, $FF, $FF, 150))
  LinearGradient(0, 0, 0, (btn_size\cy / 3) * 2)
  RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
  
  DrawingMode( #PB_2DDrawing_Transparent )
  If *lpjiw\szWindowText <> ""
    If *lpjiw\iTextFont <> 0
      DrawingFont(FontID(*lpjiw\iTextFont))
    EndIf
    tcx = TextWidth(*lpjiw\szWindowText)
    tcy = TextHeight(*lpjiw\szWindowText)
    If (*lpjiw\iOrientationFlags & #DT_CENTER) = #DT_CENTER
      DrawText( ((btn_size\cx / 2) - (tcx / 2)) + 1, 11, *lpjiw\szWindowText, *lpjiw\iBkgr )
      DrawText( ((btn_size\cx / 2) - (tcx / 2)), 10, *lpjiw\szWindowText, *lpjiw\iColor )
      bx = ((btn_size\cx / 2) - (tcx / 2))
    ElseIf (*lpjiw\iOrientationFlags = 0 ) Or (*lpjiw\iOrientationFlags ! #DT_UNDERLINED = 0 )
      bx = 10
      DrawText( 11, 11, *lpjiw\szWindowText, *lpjiw\iBkgr )
      DrawText( 10, 10, *lpjiw\szWindowText, *lpjiw\iColor )
    Else
      bx = (btn_size\cx - tcx) - 10
      DrawText( (btn_size\cx - tcx) - 9, 11, *lpjiw\szWindowText, *lpjiw\iBkgr )
      DrawText( (btn_size\cx - tcx) - 10, 10, *lpjiw\szWindowText, *lpjiw\iColor )
    EndIf
    If ( *lpjiw\iOrientationFlags & #DT_UNDERLINED) = #DT_UNDERLINED
      LineXY(bx, 11 + tcy, (bx) + tcx, 11 + tcy, *lpjiw\iBkgr)
      LineXY(bx, 10 + tcy, (bx) + tcx, 10 + tcy, *lpjiw\iColor)
    EndIf
    
  EndIf
  StopDrawing()
  
  *lpjiw\hRgn = CreateRoundRectRgn_(0, 0, WindowWidth(*lpjiw\numWindow), WindowHeight(*lpjiw\numWindow), 20, 20)
  SetWindowRgn_(hWnd, *lpjiw\hRgn, 0)
  SelectObject_(*lpjiw\hDcWnd, ImageID(*lpjiw\iWindowBMP))
  DeleteObject_(oldRgn)
  
  
  If IsImage(oldImage)
    FreeImage(oldImage)
  EndIf
  
  
EndProcedure


Procedure enFunc( hWnd, hDc )
  Static ControlDC, OrigBmp, iCurrentBMP
  If ControlDC = 0
    hDcx = GetDC_(#Null)
    ControlDC = CreateCompatibleDC_(hDcX)
    iCurrentBMP = CreateCompatibleBitmap_(hDcx, 100, 100)
    OrigBmp = SelectObject_(ControlDC, iCurrentBMP)
    ReleaseDC_(#Null, hDcx)
  EndIf
  If hWnd <> 0
    snName.s = Space(100)
    GetClassName_(hWnd, @snName, 100)
    If snName <> "SysHeader32"
      GetWindowRect_(hWnd, @clrc.rect)
      gp.POINT\x = clrc\left
      gp\y = clrc\top
      ScreenToClient_(GetParent_(hWnd), @gp)
      xDiff = clrc\right - clrc\left
      ydiff = clrc\bottom- clrc\top
      clrc\left = gp\x
      clrc\top = gp\y
      clrc\right = gp\x + xDiff
      clrc\bottom = gp\y + ydiff
      iCurrentBMP = CreateCompatibleBitmap_(ControlDC, clrc\right - clrc\left, clrc\bottom - clrc\top)
      DeleteObject_(SelectObject_(ControlDC, iCurrentBMP))
      ;FillRect_(ControlDC, @clrc, GetStockObject_(#BLACK_BRUSH))
      ;SendMessage_(hWnd, #WM_PRINT, ControlDC, #PRF_CLIENT|#PRF_NONCLIENT|#PRF_CHILDREN)
      ;BitBlt_(hDc, clrc\left, clrc\top, clrc\right - clrc\left, clrc\bottom - clrc\top, ControlDC, 0, 0, #SRCCOPY)
      cx = clrc\right - clrc\left
      cy = clrc\bottom - clrc\top
      ;GdiTransparentBlt(hDc, clrc\left, clrc\top, cx, cy, ControlDC, 0, 0, cx, cy, 0)
    EndIf
  EndIf
  
  ProcedureReturn hWnd
EndProcedure


Procedure jelly_window_wndproc( hWnd, uMsg, wParam, lParam )
  *lpJwInfo.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
  If *lpJwInfo = 0
    ProcedureReturn 0
  EndIf
  Select uMsg
    Case #WM_ACTIVATE
      If wParam = #WA_INACTIVE
        *lpJwInfo\control\moveto\bIsAnimating = #False
        *lpJwInfo\control\bMouseIn = #False
        ShowWindow_(hWnd, #SW_HIDE)
      EndIf
    Case #WM_TIMER
      Select wParam
        Case #MOUSE_TIMER
          GetCursorPos_(@mt.POINT)
          inRect = #False
          If mt\x >= WindowX(*lpJwInfo\numWindow) And mt\x <= WindowX(*lpJwInfo\numWindow) + WindowWidth(*lpJwInfo\numWindow)
            If mt\y >= WindowY(*lpJwInfo\numWindow) And mt\y <= (WindowY(*lpJwInfo\numWindow) + WindowHeight(*lpJwInfo\numWindow))
              inRect = #True
            EndIf
          EndIf
          If inRect = #False
            *lpJwInfo\control\moveto\bIsAnimating = #False
            *lpJwInfo\control\bMouseIn = #False
            ShowWindow_(hWnd, #SW_HIDE)
            KillTimer_(hWnd, #MOUSE_TIMER)
          EndIf
        Case #ANIMATION_SHOW
          If *lpJwInfo\control\moveto\iStepCounter <= *lpJwInfo\control\moveto\iNumSteps
            cX = WindowX(*lpJwInfo\numWindow)
            cCx = *lpJwInfo\control\moveto\cx
            cX = cX - 100
            *lpJwInfo\control\moveto\iStepCounter + 1
            SetLayeredWindowAttributes_(hWnd, #Null, *lpJwInfo\control\moveto\cAlpha, #LWA_ALPHA)
            *lpJwInfo\control\moveto\cAlpha + *lpJwInfo\control\moveto\changePerScoop
            If *lpJwInfo\control\moveto\iStepCounter = *lpJwInfo\control\moveto\iNumSteps
              *lpJwInfo\control\moveto\cAlpha = 255
              SetLayeredWindowAttributes_(hWnd, #Null, 255, #LWA_ALPHA)
              KillTimer_(hWnd, #ANIMATION_SHOW)
              SetTimer_(hWnd, #ANIMATION_SHOW, 20, #Null)
            EndIf
            SetWindowPos_(hWnd, #Null, cX, *lpJwInfo\control\moveto\y, cCx, *lpJwInfo\control\moveto\cy, #SWP_NOZORDER|#SWP_SHOWWINDOW|#SWP_NOSENDCHANGING|#SWP_NOREDRAW|#SWP_NOACTIVATE)
            If *lpJwInfo\control\moveto\iStepCounter = 2
              Make_Jelly_Images_Window(*lpJwInfo\numWindow)
              hDc = GetDC_(hWnd)
              BitBlt_(hdc, 0, 0, cCx, *lpJwInfo\control\moveto\cy, *lpJwInfo\hDcWnd, 0, 0, #SRCCOPY)
              ReleaseDC_(hWnd, hdc)
              InvalidateRect_(hWnd, 0, 1)
              justMoved = #False
            Else
              justMoved = #True
            EndIf
          Else
            cX = WindowX(*lpJwInfo\numWindow)
            cCx = *lpJwInfo\control\moveto\cx
            If cX <> *lpJwInfo\control\moveto\x
              If cX < *lpJwInfo\control\moveto\x
                cX = cX + *lpJwInfo\control\moveto\bounceback
              Else
                cX = cX - 1
              EndIf
              cCx = *lpJwInfo\control\moveto\cx
              SetWindowPos_(hWnd, #Null, cX, *lpJwInfo\control\moveto\y, cCx, *lpJwInfo\control\moveto\cy, #SWP_NOZORDER|#SWP_NOSENDCHANGING|#SWP_NOACTIVATE)
            Else
              KillTimer_(hWnd, #ANIMATION_SHOW)
              *lpJwInfo\control\moveto\bIsAnimating = #False
              done = #True
              InvalidateRect_(hWnd, 0, 1)
            EndIf
          EndIf
          If justMoved = #True
            InvalidateRect_(hWnd, 0, 1)
          EndIf
      EndSelect
    Case #WM_DESTROY
      *lpOldWndProc = *lpJwInfo\lpOldWndProc
      SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, *lpOldWndProc)
      ProcedureReturn CallWindowProc_(*lpJwInfo\lpOldWndProc, hWnd, uMsg, wParam, lParam)
    Case #WM_MOUSEMOVE
      If *lpJwInfo\control\moveto\bIsAnimating = #False
        If *lpJwInfo\control\bMouseIn = #False
          *lpJwInfo\control\bMouseIn = #True
          SetTimer_(hWnd, #MOUSE_TIMER, 50, #Null)
        EndIf
      EndIf
    Case #WM_ERASEBKGND
      ProcedureReturn 1
    Case #WM_WINDOWPOSCHANGED
      If *lpJwInfo\control\moveto\bIsAnimating = #False
        *lpwposc.WINDOWPOS = lParam
        If (*lpwposc\flags & #SWP_NOSIZE) = 0
          Debug "Redrawing in windowposchanged"
          Make_Jelly_Images_Window( hWnd )
        EndIf
      EndIf
    Case #WM_PRINT
      BitBlt_(wParam, 0, 0, WindowWidth(*lpJwInfo\numWindow), WindowHeight(*lpJwInfo\numWindow), *lpJwInfo\hDcWnd, 0, 0, #SRCCOPY)
      ProcedureReturn 1
      
    Case #WM_PAINT
      BeginPaint_(hWnd, @ps.PAINTSTRUCT)
      BitBlt_(ps\hdc, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right - ps\rcPaint\left, ps\rcPaint\bottom - ps\rcPaint\top, *lpJwInfo\hDcWnd, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
      EndPaint_(hWnd, @ps)
      ProcedureReturn 0
  EndSelect
  
  ProcedureReturn CallWindowProc_(*lpJwInfo\lpOldWndProc, hWnd, uMsg, wParam, lParam)
  
EndProcedure




Procedure Make_Jelly_Window( w_Window, iColor = #White, jwText.s = "" )
  If Not(IsWindow(w_Window))
    ProcedureReturn #False
  EndIf
  hWnd = WindowID(w_Window)
  dwStyle = #WS_POPUP
  dwExStyle = #WS_EX_TOOLWINDOW|#WS_EX_LAYERED
  SetWindowLongPtr_(hWnd, #GWL_STYLE, dwStyle)
  SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, dwExStyle)
  
  *lpjwi.JELLY_WINDOW_INFO = AllocateMemory(SizeOf(JELLY_WINDOW_INFO))
  *lpjwi\szWindowText = jwText
  *lpjwi\iJellyColor = iColor
  *lpjwi\lpOldWndProc = GetWindowLongPtr_(hWnd, #GWLP_WNDPROC)
  *lpjwi\numWindow = w_Window
  hdc = GetDC_(#Null)
  *lpjwi\hDcWnd = CreateCompatibleDC_(hdc)
  ReleaseDC_(#Null, hDc)
  SetWindowLongPtr_(hWnd, #GWLP_USERDATA, *lpjwi)
  SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @jelly_window_wndproc())
  Make_Jelly_Images_Window(w_Window)
  *lpjwi\hOldBMP = SelectObject_(*lpjwi\hDcWnd, ImageID(*lpjwi\iWindowBMP))
  *lpjwi\hRgn = CreateRoundRectRgn_(0, 0, WindowWidth(w_Window), WindowHeight(w_Window), 20, 20)
  SetWindowRgn_(hWnd, *lpjwi\hRgn, #False)
  
  SetWindowPos_(hWnd, #Null, #Null, #Null, #Null, #Null, #SWP_NOZORDER|#SWP_NOSIZE|#SWP_NOMOVE)
  ProcedureReturn *lpjwi\iWindowBMP
  
EndProcedure

Procedure Show_Jelly_Window( w_Window, x, y, cx, cy )
  If Not(IsWindow(w_Window))
    ProcedureReturn #False
  EndIf
  hWnd = WindowID(w_Window)
  *lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
  *lpjwi\control\moveto\bIsAnimating = #True
  *lpjwi\control\moveto\x = x
  *lpjwi\control\moveto\y = y
  *lpjwi\control\moveto\cx = WindowWidth(w_Window)
  *lpjwi\control\moveto\cy = WindowHeight(w_Window)
  GetWindowRect_(GetDesktopWindow_(), @rcdt.RECT)
  *lpjwi\control\moveto\iStepCounter = 1
  *lpjwi\control\moveto\iNumSteps = ((rcdt\right - x) / 100) + 1
  *lpjwi\control\moveto\iRemainder = Abs((rcdt\Right - x) - (*lpjwi\control\moveto\iNumSteps * 100))
  *lpjwi\control\moveto\cxAdjust  = (cx / *lpjwi\control\moveto\iNumSteps) 
  *lpjwi\control\moveto\bounceback = *lpjwi\control\moveto\iRemainder / 10
  *lpjwi\control\moveto\changePerScoop = 205 / *lpjwi\control\moveto\iNumSteps
  *lpjwi\control\moveto\cAlpha = 50
  SetWindowPos_(hWnd, #Null, rcdt\right, y, 0, WindowHeight(*lpjwi\numWindow), #SWP_NOZORDER|#SWP_SHOWWINDOW)
  SetLayeredWindowAttributes_(hWnd, #Null, 00, #LWA_ALPHA)
  SetTimer_(hWnd, #ANIMATION_SHOW, 10, #Null)
  
EndProcedure


Procedure Create_Jelly_Window( cx, cy, iColor, jwText.s = "" )
  mWindow = OpenWindow(#PB_Any, 0, 0, cx, cy, "", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_Invisible)
  StickyWindow(mWindow, 1)
  Make_Jelly_Window(mWindow, iColor, jwText)
  ProcedureReturn mWindow
EndProcedure

Procedure Set_Jelly_Window_Font( w_Window, numFont )
  If Not(IsFont(numFont))
    ProcedureReturn 0
  EndIf
  If IsWindow(w_Window)
    hWnd = WindowID(w_Window)
    *lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
    If *lpjwi <> 0
      *lpjwi\iTextFont = numFont
    EndIf
  EndIf
  Make_Jelly_Images_Window( w_Window )
  ProcedureReturn numFont
EndProcedure

Procedure Set_Jelly_Window_Text( w_Window, szText.s, enumOrietation = -1)
  If IsWindow(w_Window)
    hWnd = WindowID(w_Window)
    *lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
    If *lpjwi <> 0
      *lpjwi\szWindowText = szText
      If enumOrietation <> -1
        *lpjwi\iOrientationFlags = enumOrietation
      EndIf
    EndIf
    Make_Jelly_Images_Window( w_Window )
    InvalidateRect_(hWnd, 0, 0)
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure.s Get_Jelly_Window_Text( w_Window )
  jwText.s = ""
  If IsWindow(w_Window)
    hWnd = WindowID(w_Window)
    *lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
    If *lpjwi <> 0
      jwText.s = *lpjwi\szWindowText
    EndIf
  EndIf
  ProcedureReturn jwText.s
EndProcedure


Procedure Set_Jelly_Window_Text_Color( w_Window, iColor.i = #White)
  If IsWindow(w_Window)
    hWnd = WindowID(w_Window)
    *lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
    If *lpjwi <> 0
      *lpjwi\iColor = iColor
    EndIf
    Make_Jelly_Images_Window( w_Window )
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure Set_Jelly_Window_Text_BackGround_Color( w_Window, iColor.i = #Black)
  If IsWindow(w_Window)
    hWnd = WindowID(w_Window)
    *lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
    If *lpjwi <> 0
      *lpjwi\iBkgr = iColor
    EndIf
  EndIf
  Make_Jelly_Images_Window( w_Window )
  ProcedureReturn 1
EndProcedure
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

Now run THIS sample program that uses "Transparent-Menu.pb"

Code: Select all

IncludeFile "Transparent_Menu.pb"
IncludeFile "jelly_window.pb"

NewList miList.CUSTOM_MENU()


GetWindowRect_(GetDesktopWindow_(), @rcDesktop.rect ) ;----

myWindow = Create_Jelly_Window(rcDesktop\right-rcDesktop\left, rcDesktop\bottom-rcDesktop\top, $DA1BAC, "")
ButtonGadget(5, rcDesktop\right - 120, 10, 100, 20, "Close")
SetWindowColor(myWindow, $F4DBC4)
For i = 1 To 10
  AddElement(miList())
  miList()\enumMenu= i
  miList()\szItemName = "Menu Item " + Str(i)
Next


cmc.CUSTOM_MENU_CREATE
cmc\x = 20
cmc\y = 80
cmc\bHadBorder = #False ;#True
cmc\hParent = WindowID(myWindow)
cmc\numFontItems = LoadFont(#PB_Any, "Bauhaus 93", 20)
cmc\numFontHeader = LoadFont(#PB_Any, "Times New Roman", 20)
;cmc\szMenuTitle = "Please Select Your Option"
cmc\szMenuTitle = "Full Screen Example"
cmc\rgb_title_color = #Black
cmc\rgb_menu_unselected = #Black
cmc\rgb_menu_hilite = #White
cmc\rgb_text_shadow_unselected = $A0A0A0 ; Used for title shadow, too
cmc\rgb_text_shadow_hilite = #Black
cmc\cx = (rcDesktop\right - rcDesktop\left) - 30
cmc\cy = (rcDesktop\bottom - rcDesktop\top) - 90


Set_Jelly_Window_Text(myWindow, "Full Screen Example.", #DT_LEFT|#DT_UNDERLINED)
Set_Jelly_Window_Text_Color(myWindow, #Black)
Set_Jelly_Window_Text_BackGround_Color(myWindow, #White)
Set_Jelly_Window_Font(myWindow, cmc\numFontHeader)
hMenu = Create_Custom_Menu(@cmc, miList())

;- This MUST come after the Custom_Menu is created!
;Show_Jelly_Window(myWindow, 200, 100, 500, 500)
Show_Jelly_Window(myWindow, 0, 0, 500, 500) ;---

okToClose = #False
Repeat 
  dwEvent = WaitWindowEvent()
  Select dwEvent
    Case #PB_Event_Gadget
      If EventGadget() = 5 And EventType() = #PB_EventType_LeftClick
        okToClose = #True
      EndIf
      
    Case #PB_Event_Menu
      Debug "PB Menu event: " + Str(EventMenu())
      
    Case #PB_Event_CloseWindow
      okToClose = #True
  EndSelect
Until (okToClose = #True) Or ( Not(IsWindowVisible_(WindowID(myWindow))))
Last edited by JustinJack on Wed Aug 22, 2012 6:00 pm, edited 1 time in total.
JustinJack
User
User
Posts: 89
Joined: Thu Feb 04, 2010 7:34 am
Location: Decatur, TX
Contact:

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by JustinJack »

The Transparent-Menu, can be drawn with or without a border, to use it full-screen, just set the bound of it as full screen, then you can use a regular window, or a borderless window, or any kind. It just draws itself over whatever you've specified as the parent window.

*** EDITED ***

I just made a change to Transparent_Menu.pb <--- Important! So copy and paste the top code with the updates.
I also just changed the last sample program that uses "Jelly_Window.pb", so it is full-screen.
User avatar
J@ckWhiteIII
Enthusiast
Enthusiast
Posts: 183
Joined: Fri May 25, 2012 7:39 pm

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by J@ckWhiteIII »

Small "wishlist":

1.: How about the possibility of setting a value for the time the menu item needs to move as it's been covered by the mouse?
2.: Being able to place the single menu items anywhere on the screen?
3.: The frame around the menu text to be just as big as the menu text?

Your code is awesome, great work! :D
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Very cool menu! Feel free to play! [WINDOWS]

Post by RichAlgeni »

It is great!

But one question: How do you maintain it with so few comments???
Post Reply