home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1999 April / CD_Shareware_Magazine_31.iso / Free / Prg / VertMenu.exe / MenuItem.cls < prev    next >
Encoding:
Visual Basic class definition  |  1997-03-26  |  13.2 KB  |  438 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "MenuItem"
  6. Attribute VB_GlobalNameSpace = False
  7. Attribute VB_Creatable = False
  8. Attribute VB_PredeclaredId = False
  9. Attribute VB_Exposed = False
  10. Option Explicit
  11. Private picMenu As PictureBox
  12. Private picCache As PictureBox
  13. Private msCaption As String      ' caption of MenuItem
  14. Private mlIndex As Long          ' index of icon on Menu (1 based)
  15. Private picButton As Picture    ' icon picture
  16. Private msCaptionX As Long
  17. Private msCaptionY As Long
  18. Private mlButtonHeight As Long
  19. Private mbButtonDownOnMe As Boolean
  20. Private msPictureURL As String
  21. Private msKey As String
  22. Private msTag As String
  23.  
  24. Private Type BUTTON_STRUCT
  25.     RECT     As RECT
  26.     State    As Long
  27.     OnScreen As Boolean
  28. End Type
  29. Private mButtonStruct As BUTTON_STRUCT
  30.  
  31. Private mHitStruct As RECT
  32. Private m3DStruct As RECT
  33.  
  34. #If USE_WING Then
  35.     Private Declare Function WinGBitBlt Lib "wing32.dll" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long) As Long
  36. #Else
  37.     Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
  38. #End If
  39. Private Declare Function CreateRectRgnIndirect Lib "gdi32" (lpRect As RECT) As Long
  40. Private Declare Function DeleteObject Lib "gdi32" (ByVal hMF As Long) As Long
  41. Private Declare Function SelectClipRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long) As Long
  42. Private Declare Function SaveDC Lib "gdi32" (ByVal hdc As Long) As Long
  43. Private Declare Function RestoreDC Lib "gdi32" (ByVal hdc As Long, ByVal SavedDC As Long) As Long
  44.  
  45. Const SRCCOPY = &HCC0020
  46.  
  47. Const ICON_SIZE = 32
  48. Const MOUSE_UP = 1
  49. Const MOUSE_DOWN = -1
  50. Const MOUSE_MOVE = 0
  51. Const RAISED = 1
  52. Const SUNKEN = -1
  53. Const NONE = 0
  54. Const HITTEXT_EXTRA_PIXELS = 4
  55. Const CLIPPING_NO = True
  56. Const CLIPPING_YES = False
  57.  
  58. Public Property Get Caption() As String
  59.     On Error Resume Next
  60.     Caption = msCaption
  61. End Property
  62.  
  63. Public Property Let Caption(ByVal sNewValue As String)
  64.     On Error Resume Next
  65.     msCaption = sNewValue
  66. End Property
  67.  
  68. Public Property Get Index() As Long
  69.     On Error Resume Next
  70.     Index = mlIndex
  71. End Property
  72.  
  73. Public Property Let Index(ByVal lNewValue As Long)
  74.     On Error Resume Next
  75.     mlIndex = lNewValue
  76. End Property
  77.  
  78. Public Property Get Button() As Object
  79.     On Error Resume Next
  80.     Set Button = picButton
  81. End Property
  82.  
  83. Public Property Set Button(ByVal vNewValue As Object)
  84.     On Error Resume Next
  85.     Set picButton = vNewValue
  86. End Property
  87.  
  88. Public Property Get Left() As Long
  89.     On Error Resume Next
  90.     Left = mButtonStruct.RECT.Left
  91. End Property
  92.  
  93. Public Property Let Left(ByVal lNewValue As Long)
  94.     On Error Resume Next
  95.     With mButtonStruct.RECT
  96.         .Left = lNewValue
  97.         .Right = lNewValue + ICON_SIZE
  98.     End With
  99. End Property
  100.  
  101. Public Property Get Top() As Long
  102.     On Error Resume Next
  103.     Top = mButtonStruct.RECT.Top
  104. End Property
  105.  
  106. Public Property Let Top(ByVal lNewValue As Long)
  107.     On Error Resume Next
  108.     With mButtonStruct.RECT
  109.         .Top = lNewValue
  110.         .Bottom = lNewValue + ICON_SIZE
  111.     End With
  112. End Property
  113.  
  114. Public Property Get Right() As Long
  115.     On Error Resume Next
  116.     Right = mButtonStruct.RECT.Right
  117. End Property
  118.  
  119. Public Property Get Bottom() As Long
  120.     On Error Resume Next
  121.     Bottom = mButtonStruct.RECT.Bottom
  122. End Property
  123.  
  124. Public Property Get State() As Long
  125.     On Error Resume Next
  126.     State = mButtonStruct.State
  127. End Property
  128.  
  129. Public Property Let State(ByVal lNewValue As Long)
  130.     On Error Resume Next
  131.     mButtonStruct.State = lNewValue
  132. End Property
  133.  
  134. Public Property Get CaptionX() As Long
  135.     On Error Resume Next
  136.     CaptionX = msCaptionX
  137. End Property
  138.  
  139. Public Property Let CaptionX(ByVal lNewValue As Long)
  140.     On Error Resume Next
  141.     msCaptionX = lNewValue
  142. End Property
  143.  
  144. Public Property Get CaptionY() As Long
  145.     On Error Resume Next
  146.     CaptionY = msCaptionY
  147. End Property
  148.  
  149. Public Property Let CaptionY(ByVal lNewValue As Long)
  150.     On Error Resume Next
  151.     msCaptionY = lNewValue
  152. End Property
  153.  
  154. ' paint the icon (32x32) and its caption
  155. Public Function PaintButton(lTopMenuItemDisplayed, lIconStart As Long, lMenuCur As Long, lClipY As Long) As Boolean
  156.     Dim lCenter As Long
  157.     Dim lLeft As Long
  158.     Dim lTop As Long
  159.     Dim lRight As Long
  160.     Dim lBottom As Long
  161.     Dim lResult As Long
  162.     Dim lHeight As Long
  163.     Dim bClipping As Boolean
  164.     Dim lPositionFromTop As Long
  165.     Dim RgnRect As RECT
  166.     Dim hRgn As Long
  167.     Dim lRetCod As Long
  168.     Dim hSavedDC As Long
  169.     
  170.     On Error Resume Next
  171.     
  172.     If mlIndex < lTopMenuItemDisplayed Then
  173.         mButtonStruct.OnScreen = False
  174.         PaintButton = CLIPPING_NO
  175.         Exit Function
  176.     End If
  177.     
  178.     ' position the image
  179.     lPositionFromTop = mlIndex - lTopMenuItemDisplayed + 1
  180.     Top = (lPositionFromTop * 2 * ICON_SIZE) - ICON_SIZE + ((lPositionFromTop + 1 = 1) * 4) + (lMenuCur - 1) * mlButtonHeight
  181.     With picMenu
  182.         .ScaleMode = vbPixels
  183.         lCenter = .ScaleWidth \ 2
  184.         Left = lCenter - (ICON_SIZE \ 2)
  185.     End With
  186.     
  187.     With mButtonStruct
  188.         lLeft = .RECT.Left
  189.         lTop = .RECT.Top
  190.         lRight = .RECT.Right
  191.         lBottom = .RECT.Bottom
  192.     
  193.         ' see if it will fit in the control's viewing area
  194.         If lTop > lClipY Then
  195.             .OnScreen = False
  196.             PaintButton = CLIPPING_YES
  197.             Exit Function
  198.         End If
  199.         If lBottom > lClipY Then
  200.             bClipping = True
  201.             lBottom = lClipY
  202.         End If
  203.         .OnScreen = True
  204.     End With
  205.     ' position the menu caption
  206.     CaptionX = lCenter - (CLng(picMenu.TextWidth(Caption())) \ 2)
  207.     CaptionY = lTop + ICON_SIZE + 4
  208.  
  209.     ' calculate the hittest structure
  210.     With mHitStruct
  211.         .Left = lLeft - HITTEXT_EXTRA_PIXELS - 2
  212.         .Top = lTop - HITTEXT_EXTRA_PIXELS - 2
  213.         .Right = lRight + HITTEXT_EXTRA_PIXELS + 2
  214.         ' hittest includes the caption below the icon
  215.         .Bottom = lBottom + picMenu.TextHeight(Caption()) + 5
  216.         If bClipping Then
  217.             .Bottom = lBottom
  218.         End If
  219.     End With
  220.         
  221.     ' calculate the 3d structure
  222.     With m3DStruct
  223.         .Left = lLeft - 2
  224.         .Top = lTop - 2
  225.         .Right = lRight + 2
  226.         ' hittest includes the caption below the icon
  227.         If Not bClipping Then
  228.             .Bottom = lBottom + 2
  229.         Else
  230.             .Bottom = lBottom
  231.         End If
  232.     End With
  233.     
  234.     With mButtonStruct.RECT
  235.         If Not bClipping Then
  236.             lHeight = ICON_SIZE
  237.         Else
  238.             lHeight = lBottom - lTop
  239.         End If
  240. #If USE_WING Then
  241.         lResult = WinGBitBlt(picMenu.hdc, .Left, _
  242.             .Top, _
  243.             ICON_SIZE, lHeight, _
  244.             picCache.hdc, 0, mlButtonHeight * 2 + (lIconStart + lPositionFromTop) * ICON_SIZE)
  245. #Else
  246.         lResult = BitBlt(picMenu.hdc, .Left, _
  247.             .Top, _
  248.             ICON_SIZE, lHeight, _
  249.             picCache.hdc, 0, mlButtonHeight * 2 + (lIconStart + lPositionFromTop) * ICON_SIZE, SRCCOPY)
  250. #End If
  251.     End With
  252.     
  253.     ' bClipping is set just for the icon
  254.     ' if we are already clipping, set a clipping region
  255.     ' so we can display part of the caption.
  256.     
  257.     ' position the caption
  258.     If Not bClipping Then
  259.         With picMenu
  260.             .CurrentX = msCaptionX
  261.             .CurrentY = msCaptionY
  262.             .ForeColor = vbWhite
  263.             If .CurrentY + .TextHeight(msCaption) < lClipY Then
  264.                 picMenu.Print msCaption
  265.                 PaintButton = CLIPPING_NO
  266.             Else
  267.                 ' set the region
  268.                 With picMenu
  269.                     RgnRect.Left = 0
  270.                     RgnRect.Top = msCaptionY
  271.                     RgnRect.Right = .Width
  272.                     RgnRect.Bottom = lClipY
  273.                     ' save the original DC
  274.                     hSavedDC = SaveDC(.hdc)
  275.                     ' create a region for the text
  276.                     hRgn = CreateRectRgnIndirect(RgnRect)
  277.                     ' set clipping
  278.                     lRetCod = SelectClipRgn(.hdc, hRgn)
  279.                     ' print the caption
  280.                     picMenu.Print msCaption
  281.                     ' delete the object
  282.                     hRgn = DeleteObject(hRgn)
  283.                     ' restore the original DC
  284.                     lRetCod = RestoreDC(.hdc, hSavedDC)
  285.                     
  286.                     PaintButton = CLIPPING_YES
  287.                 End With
  288.             End If
  289.         End With
  290.     Else
  291.         PaintButton = CLIPPING_YES
  292.     End If
  293. End Function
  294.  
  295. Public Property Set Parent(ByVal picNewValue As Control)
  296.     On Error Resume Next
  297.     Set picMenu = picNewValue
  298. End Property
  299.  
  300. Public Function HitTest(ByVal iMousePosition As Integer, ByVal X As Long, ByVal Y As Long) As Boolean
  301.     
  302.     ' don't bother if it is not on screen
  303.     If Not mButtonStruct.OnScreen Then
  304.         Exit Function
  305.     End If
  306.     
  307.     If PtInRect(mHitStruct, X, Y) Then
  308.         HitTest = True
  309.         
  310.         Select Case iMousePosition
  311.             Case MOUSE_UP
  312.                 Select Case mButtonStruct.State
  313.                     Case SUNKEN, NONE
  314.                         DrawBorder RAISED
  315.                     Case Else
  316.                         ' nothing to do
  317.                 End Select
  318.                 mbButtonDownOnMe = False
  319.             Case MOUSE_DOWN
  320.                 Select Case mButtonStruct.State
  321.                     Case SUNKEN
  322.                         ' nothing to do - it's already drawn
  323.                     Case Else
  324.                         DrawBorder SUNKEN
  325.                         mbButtonDownOnMe = True
  326.                 End Select
  327.             Case MOUSE_MOVE
  328.                 Select Case mButtonStruct.State
  329.                     Case RAISED
  330.                         ' nothing to do - it's already drawn
  331.                     Case NONE
  332.                         ' if the mouse went down on me, moved off me
  333.                         ' and now returns and no mouse up yet, draw
  334.                         ' me as down
  335.                         If Not mbButtonDownOnMe Then
  336.                             DrawBorder RAISED
  337.                         Else
  338.                             DrawBorder SUNKEN
  339.                         End If
  340.                     Case SUNKEN
  341.                         ' leave it that way
  342.                 End Select
  343.         End Select
  344.     Else
  345.         ' there is no hit
  346.         HitTest = False
  347.         
  348.         If iMousePosition <> MOUSE_MOVE Then
  349.             mbButtonDownOnMe = False
  350.         End If
  351.         
  352.         ' if any border is currently drawn, remove it
  353.         If mButtonStruct.State <> NONE Then
  354.             DrawBorder NONE
  355.         End If
  356.     End If
  357. End Function
  358.  
  359. Public Sub DrawBorder(iDirection As Integer)
  360.     On Error Resume Next
  361.     picMenu.ScaleMode = vbPixels
  362.        
  363.     If Not mButtonStruct.OnScreen Then
  364.         Exit Sub
  365.     End If
  366.     
  367.     ' save the state of the button
  368.     State = iDirection
  369.     
  370.     ' icon not clipped
  371.     If m3DStruct.Bottom - m3DStruct.Top = ICON_SIZE + 4 Then
  372.         Select Case iDirection
  373.             Case RAISED
  374.                 DrawEdge picMenu.hdc, m3DStruct, BDR_RAISEDOUTER, BF_RECT
  375.             Case SUNKEN
  376.                 DrawEdge picMenu.hdc, m3DStruct, BDR_SUNKENINNER, BF_RECT
  377.             Case NONE
  378.                 With m3DStruct
  379.                     picMenu.Line (.Left, .Top)-(.Right - 1, .Bottom - 1), BACKGROUND_COLOR, B
  380.                 End With
  381.         End Select
  382.     ' icon clipped
  383.     Else
  384.         Select Case iDirection
  385.             Case RAISED
  386.                 DrawEdge picMenu.hdc, m3DStruct, BDR_RAISEDOUTER, BF_LEFT Or BF_TOP Or BF_RIGHT
  387.             Case SUNKEN
  388.                 DrawEdge picMenu.hdc, m3DStruct, BDR_SUNKENINNER, BF_LEFT Or BF_TOP Or BF_RIGHT
  389.             Case NONE
  390.                 With m3DStruct
  391.                     picMenu.Line (.Left, .Top)-(.Right - 1, .Top), BACKGROUND_COLOR
  392.                     picMenu.Line (.Left, .Top)-(.Left, .Bottom), BACKGROUND_COLOR
  393.                     picMenu.Line (.Right - 1, .Top)-(.Right - 1, .Bottom), BACKGROUND_COLOR
  394.                 End With
  395.         End Select
  396.     End If
  397. End Sub
  398.  
  399. Public Property Set Cache(ByVal oNewValue As Object)
  400.     On Error Resume Next
  401.     Set picCache = oNewValue
  402. End Property
  403.  
  404. Public Property Let ButtonHeight(ByVal lNewValue As Long)
  405.     On Error Resume Next
  406.     mlButtonHeight = lNewValue
  407. End Property
  408.  
  409. Public Property Get PictureURL() As String
  410.     On Error Resume Next
  411.     PictureURL = msPictureURL
  412. End Property
  413.  
  414. Public Property Let PictureURL(ByVal sNewValue As String)
  415.     On Error Resume Next
  416.     msPictureURL = PictureURL
  417. End Property
  418.  
  419. Public Property Get Key() As String
  420.     On Error Resume Next
  421.     Key = msKey
  422. End Property
  423.  
  424. Public Property Let Key(ByVal sNewValue As String)
  425.     On Error Resume Next
  426.     msKey = sNewValue
  427. End Property
  428.  
  429. Public Property Get Tag() As String
  430.     On Error Resume Next
  431.     Tag = msTag
  432. End Property
  433.  
  434. Public Property Let Tag(ByVal sNewValue As String)
  435.     On Error Resume Next
  436.     msTag = sNewValue
  437. End Property
  438.