home *** CD-ROM | disk | FTP | other *** search
/ Dan Appleman's Visual Bas…s Guide to the Win32 API / Dan.Applmans.Visual.Basic.5.0.Programmers.Guide.To.The.Win32.API.1997.Ziff-Davis.Press.CD / VB5PG32.mdf / vbpg32 / samples5 / ch10 / menulook.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-02-16  |  22.4 KB  |  636 lines

  1. VERSION 5.00
  2. Begin VB.Form Menulook 
  3.    Appearance      =   0  'Flat
  4.    BackColor       =   &H80000005&
  5.    Caption         =   "Menulook demo program"
  6.    ClientHeight    =   4020
  7.    ClientLeft      =   1095
  8.    ClientTop       =   1770
  9.    ClientWidth     =   7365
  10.    BeginProperty Font 
  11.       Name            =   "MS Sans Serif"
  12.       Size            =   8.25
  13.       Charset         =   0
  14.       Weight          =   700
  15.       Underline       =   0   'False
  16.       Italic          =   0   'False
  17.       Strikethrough   =   0   'False
  18.    EndProperty
  19.    ForeColor       =   &H80000008&
  20.    LinkMode        =   1  'Source
  21.    LinkTopic       =   "Form1"
  22.    PaletteMode     =   1  'UseZOrder
  23.    ScaleHeight     =   4020
  24.    ScaleWidth      =   7365
  25.    Begin VB.ListBox List1 
  26.       Appearance      =   0  'Flat
  27.       Height          =   1785
  28.       Left            =   240
  29.       TabIndex        =   0
  30.       Top             =   2160
  31.       Width           =   6855
  32.    End
  33.    Begin VB.PictureBox Picture2 
  34.       Appearance      =   0  'Flat
  35.       AutoRedraw      =   -1  'True
  36.       BackColor       =   &H80000005&
  37.       ForeColor       =   &H80000008&
  38.       Height          =   375
  39.       Left            =   4440
  40.       ScaleHeight     =   345
  41.       ScaleWidth      =   1305
  42.       TabIndex        =   6
  43.       Top             =   1680
  44.       Width           =   1335
  45.    End
  46.    Begin VB.PictureBox Picture1 
  47.       Appearance      =   0  'Flat
  48.       BackColor       =   &H80000005&
  49.       ForeColor       =   &H80000008&
  50.       Height          =   495
  51.       Left            =   3720
  52.       Picture         =   "MENULOOK.frx":0000
  53.       ScaleHeight     =   465
  54.       ScaleWidth      =   465
  55.       TabIndex        =   5
  56.       Top             =   1560
  57.       Width           =   495
  58.    End
  59.    Begin VB.CommandButton CmdAnalyze 
  60.       Appearance      =   0  'Flat
  61.       BackColor       =   &H80000005&
  62.       Caption         =   "Analyze"
  63.       Height          =   495
  64.       Left            =   6000
  65.       TabIndex        =   1
  66.       Top             =   1140
  67.       Width           =   1215
  68.    End
  69.    Begin VB.CommandButton CmdTrack 
  70.       Appearance      =   0  'Flat
  71.       BackColor       =   &H80000005&
  72.       Caption         =   "TrackPopup"
  73.       Height          =   495
  74.       Left            =   6000
  75.       TabIndex        =   2
  76.       Top             =   600
  77.       Width           =   1215
  78.    End
  79.    Begin VB.CommandButton CmdEntry2Chk 
  80.       Appearance      =   0  'Flat
  81.       BackColor       =   &H80000005&
  82.       Caption         =   "Entry2-Check"
  83.       Height          =   495
  84.       Left            =   4560
  85.       TabIndex        =   8
  86.       Top             =   600
  87.       Width           =   1335
  88.    End
  89.    Begin VB.CommandButton CmdAddBitmap 
  90.       Appearance      =   0  'Flat
  91.       BackColor       =   &H80000005&
  92.       Caption         =   "Add Bitmap"
  93.       Height          =   495
  94.       Left            =   6000
  95.       TabIndex        =   4
  96.       Top             =   60
  97.       Width           =   1215
  98.    End
  99.    Begin VB.CommandButton CmdAddRandom 
  100.       Appearance      =   0  'Flat
  101.       BackColor       =   &H80000005&
  102.       Caption         =   "AddRandom"
  103.       Height          =   495
  104.       Left            =   4560
  105.       TabIndex        =   7
  106.       Top             =   60
  107.       Width           =   1335
  108.    End
  109.    Begin VB.Label Label1 
  110.       Appearance      =   0  'Flat
  111.       BackColor       =   &H80000005&
  112.       BorderStyle     =   1  'Fixed Single
  113.       ForeColor       =   &H80000008&
  114.       Height          =   255
  115.       Left            =   240
  116.       TabIndex        =   3
  117.       Top             =   1680
  118.       Width           =   3255
  119.    End
  120.    Begin VB.Menu MenuTop 
  121.       Caption         =   "Menu1"
  122.       HelpContextID   =   500
  123.       Begin VB.Menu MenuEntry1 
  124.          Caption         =   "Entry1"
  125.       End
  126.       Begin VB.Menu MenuEntry2 
  127.          Caption         =   "Entry2"
  128.       End
  129.       Begin VB.Menu MenuEntry3 
  130.          Caption         =   "-"
  131.       End
  132.       Begin VB.Menu MenuArray1 
  133.          Caption         =   "Array1"
  134.          Index           =   0
  135.       End
  136.       Begin VB.Menu MenuArray1 
  137.          Caption         =   "Array1B"
  138.          Index           =   1
  139.       End
  140.       Begin VB.Menu MenuSubMenu1 
  141.          Caption         =   "SubMenu1"
  142.          Begin VB.Menu MenuSub1Entry1 
  143.             Caption         =   "Sub1Entry1"
  144.          End
  145.          Begin VB.Menu MenuSub1Entry2 
  146.             Caption         =   "Sub1Entry2"
  147.          End
  148.       End
  149.    End
  150.    Begin VB.Menu MenuFloat 
  151.       Caption         =   "Floating"
  152.       Begin VB.Menu MenuFloat1 
  153.          Caption         =   "Float1"
  154.          Index           =   0
  155.       End
  156.       Begin VB.Menu MenuFloat1 
  157.          Caption         =   "Float2"
  158.          Index           =   1
  159.       End
  160.    End
  161.    Begin VB.Menu MenuRandomTop 
  162.       Caption         =   "Random"
  163.       Begin VB.Menu MenuArt 
  164.          Caption         =   "Art1"
  165.          Index           =   0
  166.       End
  167.    End
  168. Attribute VB_Name = "Menulook"
  169. Attribute VB_GlobalNameSpace = False
  170. Attribute VB_Creatable = False
  171. Attribute VB_PredeclaredId = True
  172. Attribute VB_Exposed = False
  173. Option Explicit
  174. ' Copyright 
  175.  1997 by Desaware Inc. All Rights Reserved.
  176. Dim IsWindows95 As Boolean
  177. ' This command adds the bitmap that is in the Picture1
  178. ' control to the Floating menu.
  179. Private Sub CmdAddBitmap_Click()
  180. #If Win32 Then
  181.     Dim topmenuhnd&
  182.     Dim floatmenu&
  183.     Dim menuid&
  184. #Else
  185.     Dim topmenuhnd%
  186.     Dim floatmenu%
  187.     Dim menuid%
  188. #End If
  189.     Dim di&
  190.     ' Get a handle to the top level menu
  191.     topmenuhnd = GetMenu(Menulook.hwnd)
  192.     ' And get a handle to the Floating popup menu.
  193.     floatmenu = GetSubMenu(topmenuhnd, 1)
  194.     ' If 3rd (bitmap) entry is already loaded, exit now
  195.     ' (we only load the bitmap once)
  196.     If GetMenuItemCount(floatmenu) >= 3 Then Exit Sub
  197.     ' First, add a menu entry under VB - this provides us
  198.     ' with a menu entry that can be replaced with a bitmap,
  199.     ' but whose menu ID will be the same (so it will work
  200.     ' properly
  201.     Load MenuFloat1(2)
  202.     ' Now get the ID of that entry
  203.     menuid = GetMenuItemID(floatmenu, 2)
  204.     If FloatBitmap = 0 Then FloatBitmap = CopyPictureImage(Picture1)
  205.     ' And replace it with a bitmap.
  206.     di = ModifyMenuBynum(floatmenu, 2, MF_BITMAP Or MF_BYPOSITION, menuid, FloatBitmap)
  207. End Sub
  208. ' This command creates a random bitmap and loads it into
  209. ' the Random popup menu.
  210. Private Sub CmdAddRandom_Click()
  211. #If Win32 Then
  212.     Dim topmenuhnd&
  213.     Dim floatmenu&
  214.     Dim menuid&
  215.     Dim newmenupos&
  216.     Dim newbm&
  217. #Else
  218.     Dim topmenuhnd%
  219.     Dim floatmenu%
  220.     Dim menuid%
  221.     Dim newmenupos%
  222.     Dim newbm%
  223. #End If
  224.     Dim pw!, ph!
  225.     Dim x%, di&
  226.     ' First get the width and height of the picture2 control
  227.     pw! = Picture2.ScaleWidth
  228.     ph! = Picture2.ScaleHeight
  229.     ' Get a handle to the Random popup menu
  230.     topmenuhnd = GetMenu(Menulook.hwnd)
  231.     floatmenu = GetSubMenu(topmenuhnd, 2)
  232.     ' Find out how many menu items are already in the popup
  233.     newmenupos = GetMenuItemCount(floatmenu)
  234.     ' Load a VB menu entry at that position
  235.     Load MenuArt(newmenupos)
  236.     ' And get the MenuID for that entry
  237.     menuid = GetMenuItemID(floatmenu, newmenupos)
  238.     ' Draw some stuff on picture2
  239.     Picture2.Cls
  240.     For x% = 0 To 5 ' Random rectangles
  241.         Picture2.Line (Rnd * pw!, Rnd * ph!)-(Rnd * pw!, Rnd * ph!), QBColor(CInt(Rnd * 15)), B
  242.     Next x%
  243.     ' Get a bitmap that is a copy of the picture2 control
  244.     newbm = CopyPictureImage(Picture2)
  245.     For x% = 0 To 32
  246.         If BMHandles(x%) = 0 Then Exit For
  247.     Next x%
  248.     If x% = 32 Then ' No room to store the bitmap handle
  249.         di = DeleteObject(newbm)
  250.         Exit Sub
  251.     End If
  252.     BMHandles(x%) = newbm
  253.     ' And place that bitmap in the menu
  254.     di = ModifyMenuBynum(floatmenu, newmenupos, MF_BITMAP Or MF_BYPOSITION, menuid, newbm)
  255. End Sub
  256. '   Get the form's menu and analyze it.
  257. Private Sub CmdAnalyze_Click()
  258. #If Win32 Then
  259.     Dim menuhnd&
  260. #Else
  261.     Dim menuhnd%
  262. #End If
  263.     ' Clear the listbox
  264.     'dl& = SendMessage(List1.hwnd, LB_RESETCONTENT, 0, 0&)
  265.     List1.Clear
  266.     ' Get a handle to the top level menu for this window
  267.     menuhnd = GetMenu(Menulook.hwnd)
  268.     ' And analyze it
  269.     ViewMenu menuhnd
  270. End Sub
  271. ' Create a box checkmark bitmap for the Entry2 menu
  272. Private Sub CmdEntry2Chk_Click()
  273. #If Win32 Then
  274.     Dim topmenuhnd&
  275.     Dim floatmenu&
  276.     Dim NewCheck&
  277. #Else
  278.     Dim NewCheck%
  279.     Dim topmenuhnd%
  280.     Dim floatmenu%
  281. #End If
  282.     Dim oldbkcolor&
  283.     Dim di&
  284.     ' Get the new checkmark bitmap
  285.     NewCheck = GetNewCheck()
  286.     ' Get a handle to the top level menu
  287.     topmenuhnd = GetMenu(Menulook.hwnd)
  288.     ' Get a handle to the first popup
  289.     floatmenu = GetSubMenu(topmenuhnd, 0)
  290.     ' And set the new check bitmap for the first (entry1) menu item
  291.     di = SetMenuItemBitmaps(floatmenu, 1, MF_BYPOSITION, 0, NewCheck)
  292.     ' Check the entry
  293.     MenuEntry2.Checked = -1
  294.     ' Remind the user to look at it.
  295.     MsgBox "Look at the Menu1 - Entry2 menu"
  296. End Sub
  297. '   Hides the Floating menu entry in the caption,
  298. '   and turns it into a tracked popup menu
  299. Private Sub CmdTrack_Click()
  300. #If Win32 Then  ' Port to correct handle type
  301.     Dim topmenuhnd&
  302.     Dim floatmenu&
  303. #Else
  304.     Dim topmenuhnd%
  305.     Dim floatmenu%
  306. #End If
  307.     Dim oldcap$, di&
  308.     Dim pt As POINTAPI
  309.     ' Get a handle to the popup menu
  310.     topmenuhnd = GetMenu(Menulook.hwnd)
  311.     floatmenu = GetSubMenu(topmenuhnd, 1)
  312.     ' Hide the menu entry by clearing the string
  313.     ' temporarily. Note, don't make it invisible or the
  314.     ' menu will go away!
  315.     oldcap$ = MenuFloat.Caption
  316.     MenuFloat.Caption = ""
  317.     ' Find where the mouse cursor is and place the
  318.     ' popup at that point
  319.     GetCursorPos pt
  320.     di = TrackPopupMenuBynum(floatmenu, TPM_CENTERALIGN, pt.x, pt.y, 0, Menulook.hwnd, 0&)
  321.     ' Restore the original popup name
  322.     MenuFloat.Caption = oldcap$
  323. End Sub
  324. '   This function makes a copy of the Image property
  325. '   of the specified image control and returns a handle to that bitmap
  326. Private Function CopyPictureImage(SourceImage As PictureBox) As Long
  327.     Dim bm As BITMAP
  328.     #If Win32 Then
  329.     Dim newbm&
  330.     Dim tdc&, oldbm&
  331.     #Else
  332.     Dim newbm%
  333.     Dim tdc%, oldbm%
  334.     #End If
  335.     Dim di&
  336.     ' First get the information about the image bitmap
  337.     di = GetObjectAPI(SourceImage.Image, Len(bm), bm)
  338.     bm.bmBits = 0
  339.     ' Create a new bitmap with the same structure and size
  340.     ' of the image bitmap
  341.     newbm = CreateBitmapIndirect(bm)
  342.     ' Create a temporary memory device context to use
  343.     tdc = CreateCompatibleDC(SourceImage.hdc)
  344.     ' Select in the newly created bitmap
  345.     oldbm = SelectObject(tdc, newbm)
  346.     ' Now copy the bitmap from the persistant bitmap in
  347.     ' picture 2 (note that picture2 has AutoRedraw set TRUE
  348.     di = BitBlt(tdc, 0, 0, bm.bmWidth, bm.bmHeight, SourceImage.hdc, 0, 0, SRCCOPY)
  349.     ' Select out the bitmap and delete the memory DC
  350.     oldbm = SelectObject(tdc, oldbm)
  351.     di = DeleteDC(tdc)
  352.     ' And return the new bitmap
  353.     CopyPictureImage = newbm
  354. End Function
  355. ' Clicking anywhere on the form triggers the CmdTrack command
  356. ' button.
  357. Private Sub Form_Load()
  358. #If Win32 Then
  359.     Dim os As OSVERSIONINFO
  360.     Dim di&
  361.     Print "Click anywhere on the form to"
  362.     Print "bring up a tracked popup menu"
  363.     Randomize
  364.     os.dwOSVersionInfoSize = Len(os)
  365.     di = GetVersionEx(os)
  366.     If os.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then IsWindows95 = True
  367. #End If
  368.     ' We never let IsWindows95 get set to True in 16 bits, because
  369.     ' it is only used for Win32 specific APIs
  370. End Sub
  371. Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
  372.     ' Clicking anywhere on the form triggers the CmdTrack button
  373.     CmdTrack.value = -1
  374. End Sub
  375. Private Sub Form_Unload(Cancel As Integer)
  376.     Dim x%, di&
  377.     ' If a new check bitmap was set, we need to destroy it
  378.     ' otherwise the resources used by the bitmap will not
  379.     ' be freed.
  380.     If NewCheck <> 0 Then
  381.         di = DeleteObject(NewCheck)
  382.     End If
  383.     ' The same applies to the random menu bitmaps
  384.     For x% = 0 To 32
  385.         If BMHandles(x%) <> 0 Then
  386.             di = DeleteObject(BMHandles(x%))
  387.         End If
  388.     Next x%
  389.     If FloatBitmap <> 0 Then
  390.         Call DeleteObject(FloatBitmap)
  391.     End If
  392. End Sub
  393. '   Gets a string containing a description of the flags
  394. '   set for this menu item.
  395. Private Function GetFlagString$(menuflags%)
  396.     Dim f$
  397.     If (menuflags% And MF_CHECKED) <> 0 Then
  398.         f$ = f$ + "Checked "
  399.     Else
  400.         f$ = f$ + "Unchecked "
  401.     End If
  402.     If (menuflags% And MF_DISABLED) <> 0 Then
  403.         f$ = f$ + "Disabled "
  404.     Else
  405.         f$ = f$ + "Enabled "
  406.     End If
  407.     If (menuflags% And MF_GRAYED) <> 0 Then f$ = f$ + "Grayed "
  408.     If (menuflags% And MF_BITMAP) <> 0 Then f$ = f$ + "Bitmap "
  409.     If (menuflags% And MF_MENUBARBREAK) <> 0 Then f$ = f$ + "Bar-break "
  410.     If (menuflags% And MF_MENUBREAK) <> 0 Then f$ = f$ + "Break "
  411.     If (menuflags% And MF_SEPARATOR) <> 0 Then f$ = f$ + "Seperator "
  412.     GetFlagString$ = f$
  413. End Function
  414. ' Create a custom bitmap checkmark and return a
  415. ' handle to that bitmap.
  416. Private Function GetNewCheck&()
  417.     Dim bm As BITMAP
  418.     Dim pt As POINTS
  419.     #If Win32 Then
  420.     Dim newbm&
  421.     Dim tdc&, oldbm&
  422.     Dim br&, oldbrush&
  423.     #Else
  424.     Dim newbm%
  425.     Dim tdc%, oldbm%
  426.     Dim br%, oldbrush%
  427.     #End If
  428.     Dim markdims&
  429.     Dim di&
  430.     ' Find out how big the checkmark should be.
  431.     markdims& = GetMenuCheckMarkDimensions()
  432.     agDWORDto2Integers markdims&, pt.x, pt.y
  433.     ' And create a magenta brush (the check mark will be
  434.     ' a magenta filled rectangle
  435.     br = CreateSolidBrush(QBColor(5))
  436.     Picture2.Cls
  437.     oldbrush = SelectObject(Picture2.hdc, br)
  438.     ' Draw the rectangle.
  439.     di = Rectangle(Picture2.hdc, 2, 2, pt.x - 2, pt.y - 2)
  440.     di = SelectObject(Picture2.hdc, oldbrush)
  441.     di = DeleteObject(br) ' Dump the brush.
  442.     ' Create a compatible bitmap of the right size
  443.     ' was: di% = GetObjectAPI(Picture2.Image, 14, agGetAddressForObject&(bm))
  444.     di = GetObjectAPI(Picture2.Image, Len(bm), bm)
  445.     bm.bmBits = 0
  446.     bm.bmWidth = pt.x
  447.     bm.bmHeight = pt.y
  448.     newbm = CreateBitmapIndirect(bm)
  449.     ' And create a memory device context to use
  450.     tdc = CreateCompatibleDC(Picture2.hdc)
  451.     oldbm = SelectObject(tdc, newbm)
  452.     ' Copy in the new check mark
  453.     di = BitBlt(tdc, 0, 0, pt.x, pt.y, Picture2.hdc, 0, 0, SRCCOPY)
  454.     oldbm = SelectObject(tdc, oldbm)
  455.     di = DeleteDC(tdc)
  456.     GetNewCheck = newbm
  457. End Function
  458. ' Let the system know this menu has been clicked
  459. Private Sub MenuArray1_Click(Index As Integer)
  460.     Label1.Caption = "Array1(" + Str$(Index) + ") selected."
  461. End Sub
  462. ' Let the system know this menu has been clicked'
  463. Private Sub MenuArt_Click(Index As Integer)
  464.     Label1.Caption = "Menu Random Art (" + Str$(Index) + ") selected."
  465. End Sub
  466. ' Let the system know this menu has been clicked'
  467. Private Sub MenuEntry1_Click()
  468.     ' Check or uncheck the menu each time it is clicked
  469.     Label1.Caption = "Entry1 selected."
  470.     MenuEntry1.Checked = Not MenuEntry1.Checked
  471. End Sub
  472. ' Let the system know this menu has been clicked'
  473. Private Sub MenuEntry2_Click()
  474.     ' Check or uncheck the menu each time it is clicked
  475.     If MenuEntry2.Checked Then MenuEntry2.Checked = 0 Else MenuEntry2.Checked = -1
  476.     Label1.Caption = "Entry2 selected."
  477. End Sub
  478. ' Let the system know this menu has been clicked'
  479. Private Sub MenuFloat_Click()
  480.     Label1.Caption = "Floating selected."
  481. End Sub
  482. ' Let the system know this menu has been clicked'
  483. Private Sub MenuFloat1_Click(Index As Integer)
  484.     Label1.Caption = "Float1(" + Str$(Index) + ") selected."
  485. End Sub
  486. ' Let the system know this menu has been clicked'
  487. Private Sub MenuRandomTop_Click()
  488.     Label1.Caption = "Menu Random selected."
  489. End Sub
  490. ' Let the system know this menu has been clicked'
  491. Private Sub MenuSub1Entry1_Click()
  492.     Label1.Caption = "Sub1Entry1 selected."
  493. End Sub
  494. ' Let the system know this menu has been clicked'
  495. Private Sub MenuSub1Entry2_Click()
  496.     Label1.Caption = "Sub1Entry2 selected."
  497. End Sub
  498. ' Let the system know this menu has been clicked'
  499. Private Sub MenuSubMenu1_Click()
  500.     Label1.Caption = "SubMenu1 selected."
  501. End Sub
  502. ' Let the system know this menu has been clicked'
  503. Private Sub MenuTop_Click()
  504.     Label1.Caption = "MenuTop selected."
  505. End Sub
  506. '   This function loads into list1 an analysis of the
  507. '   specified menu
  508. Private Sub ViewMenu(ByVal menuhnd&)
  509.     Dim menulen&
  510.     Dim di&
  511. #If Win32 Then
  512.     Dim thismenu&
  513.     Dim menuid&
  514.     Dim currentpopup&
  515.     Dim menuinfo As MENUITEMINFO
  516. #Else
  517.     Dim thismenu%
  518.     Dim menuid%
  519.     Dim currentpopup%
  520. #End If
  521.     Dim db%
  522.     Dim menuflags%
  523.     Dim flagstring$
  524.     Dim menustring(128) As Byte
  525.     Dim menustring2 As String * 128
  526.     Dim context&
  527.     ' This routine can analyze up to 32 popup sub-menus
  528.     ' for each menu. We keep track of them here so that
  529.     ' we can recursively analyze the popups after we
  530.     ' analyze the main menu.
  531.     Dim trackpopups&(32)
  532.     currentpopup = 0
  533.     List1.AddItem "Analysis of Menu handle# " & Hex$(menuhnd)
  534.     ' Find out how many entries are in the menu.
  535.     menulen = GetMenuItemCount(menuhnd)
  536.     List1.AddItem "# of entries = " & Str$(menulen)
  537.     #If Win32 Then
  538.     context& = GetMenuContextHelpId(menuhnd)
  539.     If context& > 0 Then List1.AddItem "Help Context ID = " & Str$(context&)
  540.     #End If
  541.     If IsWindows95 Then
  542.         #If Win32 Then
  543.             menuinfo.cbSize = Len(menuinfo)
  544.             
  545.             For thismenu = 0 To menulen - 1
  546.                 ' cch field is reset each time
  547.                 menuinfo.cch = 127
  548.                 menuinfo.dwTypeData = agGetAddressForObject(menustring(0))
  549.                 menuinfo.fMask = MIIM_DATA Or MIIM_ID Or MIIM_STATE Or MIIM_SUBMENU Or MIIM_TYPE Or MIIM_CHECKMARKS
  550.                 
  551.                 ' Get the ID for this menu
  552.                 ' It's a command ID, -1 for a popup, 0 for a seperator
  553.                 di = GetMenuItemInfo(menuhnd, thismenu, True, menuinfo)
  554.                 If di = 0 Then
  555.                     List1.AddItem "Entry #" + Str$(thismenu) + " is unaccessable via GetMenuItemInfo"
  556.                 Else
  557.                     With menuinfo
  558.                         ' Obtain all information about a menu
  559.                         If .hSubMenu <> 0 Then
  560.                             ' Save it in the list of popups
  561.                             trackpopups&(currentpopup) = thismenu
  562.                             currentpopup = currentpopup + 1
  563.                             ' Why do we use left$?
  564.                             List1.AddItem "Entry #" + Str$(thismenu) + " is a submenu. Handle = " + Hex$(.hSubMenu) + " is " + Left$(StrConv(menustring, vbUnicode), .cch)
  565.                             List1.AddItem "Flags: " + GetFlagStringNew$(.fType, .fState)
  566.                         Else
  567.                             If .fType = MFT_STRING Then
  568.                                 List1.AddItem "Entry #" + Str$(thismenu) + " is a string = " + Left$(StrConv(menustring, vbUnicode), .cch)
  569.                                 List1.AddItem "Flags: " + GetFlagStringNew$(.fType, .fState)
  570.                             Else
  571.                                 ' Menu type is a bitmap, or otherwise not supported by this application
  572.                                 List1.AddItem "Entry #" & Str$(thismenu) & " has flags: " + GetFlagStringNew$(.fType, .fState)
  573.                             End If
  574.                             
  575.                         End If
  576.                         
  577.                     End With
  578.                 End If
  579.             Next thismenu
  580.         #End If
  581.     Else
  582.         For thismenu = 0 To menulen - 1
  583.             ' Get the ID for this menu
  584.             ' It's a command ID, -1 for a popup, 0 for a seperator
  585.             menuid = GetMenuItemID(menuhnd, thismenu)
  586.             Select Case menuid
  587.                 Case 0  ' It's a seperator
  588.                     List1.AddItem "Entry #" + Str$(thismenu) + "is a seperator"
  589.                 Case -1 ' It's a popup menu
  590.                     ' Save it in the list of popups
  591.                     trackpopups&(currentpopup) = thismenu
  592.                     currentpopup = currentpopup + 1
  593.                     ' And report that it's here
  594.                     db = GetMenuString(menuhnd, thismenu, menustring2, 127, MF_BYPOSITION)
  595.                     menuflags = GetMenuState(menuhnd, thismenu, MF_BYPOSITION)
  596.                     List1.AddItem "Entry #" + Str$(thismenu) + " is a submenu. Handle = " + Hex$(GetSubMenu(menuhnd, thismenu)) + " is " + Left$(menustring2, db)
  597.                     List1.AddItem "Flags: " + GetFlagString$(menuflags)
  598.                     
  599.                 Case Else ' A regular entry
  600.                     db = GetMenuString(menuhnd, menuid, menustring2, 127, MF_BYCOMMAND)
  601.                     List1.AddItem "Entry #" + Str$(thismenu) + " cmd = " + Str$(menuid) + " is " + Left$(menustring2, db)
  602.                     menuflags = GetMenuState(menuhnd, menuid, MF_BYCOMMAND)
  603.                     List1.AddItem "Flags: " + GetFlagString$(menuflags)
  604.             End Select
  605.         Next thismenu
  606.     End If
  607.     If currentpopup > 0 Then ' At least one popup was found
  608.         List1.AddItem "Sub menus:"
  609.         For thismenu = 0 To currentpopup - 1
  610.             menuid = trackpopups&(thismenu)
  611.             ' Recursively analyze the popup menu.
  612.             ViewMenu GetSubMenu(menuhnd, menuid)
  613.         Next thismenu
  614.     End If
  615. End Sub
  616. Public Function GetFlagStringNew$(ByVal fType&, ByVal fState&)
  617.     Dim f$
  618.     If (fState And MFS_CHECKED) <> 0 Then
  619.         f$ = f$ + "Checked "
  620.     Else
  621.         f$ = f$ + "Unchecked "
  622.     End If
  623.     If (fState And MFS_DISABLED) <> 0 Then
  624.         f$ = f$ + "Disabled "
  625.     Else
  626.         f$ = f$ + "Enabled "
  627.     End If
  628.     If (fState And MFS_GRAYED) <> 0 Then f$ = f$ + "Grayed "
  629.     If (fType And MFT_BITMAP) <> 0 Then f$ = f$ + "Bitmap "
  630.     If (fType And MFT_MENUBARBREAK) <> 0 Then f$ = f$ + "Bar-break "
  631.     If (fType And MFT_RADIOCHECK) <> 0 Then f$ = f$ + "Radio "
  632.     If (fType And MFT_MENUBREAK) <> 0 Then f$ = f$ + "Break "
  633.     If (fType And MFT_SEPARATOR) <> 0 Then f$ = f$ + "Seperator "
  634.     GetFlagStringNew$ = f$
  635. End Function
  636.