Menu item with file icon

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • Bernhard Fomm
    Member
    • Oct 2001
    • 816

    Menu item with file icon

    How can I insert a file icon in a menu item?

    The file icon probably needs to be converted to BMP. How does it work?


    Code:
    #COMPILE EXE
    #DIM ALL
    %UNICODE = 1
    #INCLUDE "Win32api.inc"
    
    
    GLOBAL hDlg, hMenu, hMenuFile AS DWORD
    
    
    FUNCTION PBMAIN()
       DIALOG NEW PIXELS, 0, "Icon in Menu",300,300,250,150, %WS_OVERLAPPEDWINDOW TO hDlg
       AddMenu("C:\Windows\Explorer.exe")
       'AddMenu(exe.path$ + "test.docx")
       DIALOG SHOW MODAL hDlg
    END FUNCTION
    
    
    SUB AddMenu((pFile AS WSTRINGZ)
    LOCAL  hh AS DWORD
    LOCAL  fi AS SHFILEINFO
    
        IF ISFILE(pFile) THEN
            MENU NEW BAR TO hMenu
            MENU NEW POPUP TO hMenuFile
            MENU ADD POPUP, hMenu, "&File", hMenuFile, %MF_ENABLED
            MENU ADD STRING, hMenuFile, pFile, 100, %MF_ENABLED
            MENU ATTACH hMenu, hDlg
    
            hh = SHGetFileInfo (pFile, 0, fi, LEN(fi), %SHGFI_SMALLICON)
    [B][COLOR=#FF0000]       SetMenuItemBitmaps hMenuFile, 0, %MF_ByPosition, fi.hIcon, fi.hIcon[/COLOR][/B]
        END IF
    
    END SUB
  • Anne Wilson
    Member
    • Oct 2015
    • 1204

    #2
    Hi BernHard

    Try this

    Comment

    • Bernhard Fomm
      Member
      • Oct 2001
      • 816

      #3
      I want to display the associated file icons as icons in a menu item.
      For example, for a Word file, the corresponding word file icon should be inserted into the menu.

      I extract the symbol with "SHGetFileInfo".
      How do I get "fi.hIcon" in a menu item?

      Comment

      • Michael Mattias
        Member
        • Aug 1998
        • 43447

        #4
        I'd probably just owner-draw the menu item.

        FWIW, this may come in handy if you are making a menu of files....

        Add a 'Favorite Files' menu to your application 10-25-07

        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment

        • Bernhard Fomm
          Member
          • Oct 2001
          • 816

          #5
          The file icons are not inserted. Or, I do not see it.

          Comment

          • Pierre Bellisle
            Member
            • Dec 2001
            • 5272

            #6
            I got this, it is based on some old Semen code...

            Click image for larger version  Name:	MenuIcon.png Views:	86 Size:	14.2 KB ID:	766838

            Code:
            #COMPILE EXE '#Win 9.07#
            #DIM ALL
            #REGISTER NONE
            #INCLUDE "Win32Api.Inc"
            #INCLUDE "CommCtrl.Inc"
            
            GLOBAL hDlg AS DWORD
            
            %ItemFirst = 101
            %ItemCount = 4
            
            TYPE PopMenuItemType
              SizeA    AS SizeL
              zItem    AS ASCIIZ * 255
              FileName AS ASCIIZ * %MAX_PATH
            END TYPE
            '_____________________________________________________________________________
            
            CALLBACK FUNCTION DlgProc
             LOCAL  pPopItemSize             AS MEASUREITEMSTRUCT POINTER
             LOCAL  pPopItemDrawInfo         AS DRAWITEMSTRUCT POINTER
             LOCAL  MousePos                 AS POINTAPI
             LOCAL  shFileInf                AS SHFILEINFO
             LOCAL  pPopItem                 AS PopMenuItemType POINTER
             LOCAL  zWinDir                  AS ASCIIZ * %MAX_PATH
             LOCAL  zSysDir                  AS ASCIIZ * %MAX_PATH
             DIM    PopItem(1 TO %ItemCount) AS STATIC PopMenuItemType
             STATIC hPopup                   AS DWORD
             LOCAL  hdc                      AS DWORD
             LOCAL  hBrush                   AS DWORD
             LOCAL  hImg                     AS DWORD
             LOCAL  Looper                   AS LONG
            
             SELECT CASE CBMSG
            
               CASE %WM_COMMAND
                 SELECT CASE CBCTL
                   CASE %ItemFirst + 1 TO %ItemFirst + %ItemCount
                     SetWindowText(hDlg, STR$(CBCTL))
                 END SELECT
            
               CASE %WM_CONTEXTMENU
                 IF hPopup = 0 THEN
                   GetWindowsDirectory(zWinDir, %MAX_PATH)
                   GetSystemDirectory(zSysDir, %MAX_PATH)
                   hPopup = CreatePopupMenu
                   FOR Looper = 1 TO %ItemCount
                     SELECT CASE Looper
                       CASE 1: PopItem(1).zItem    = "&Explorer"
                               PopItem(1).FileName = zWinDir & "\Explorer.exe"
                       CASE 2: PopItem(2).zItem    = "&Notepad"
                               PopItem(2).FileName = zSysDir & "\NotePad.exe"
                       CASE 3: PopItem(3).zItem    = "&WinVer"
                               PopItem(3).FileName = zSysDir & "\WinVer.exe"
                       CASE 4: PopItem(4).zItem    = "&Empty"
                               PopItem(4).FileName = ""
                     END SELECT
                     InsertMenu(hPopup, 0, %MF_BYCOMMAND OR %MF_CHECKED OR %MF_STRING, _
                                %ItemFirst + Looper, PopItem(Looper).zItem)
                     ModifyMenu(hPopup, %ItemFirst + Looper, %MF_BYCOMMAND OR %MF_OWNERDRAW, _
                                %ItemFirst + Looper, BYVAL VARPTR(PopItem(Looper)))
                   NEXT
                 END IF
                 GetCursorPos(MousePos)
                 TrackPopupMenu(hPopup, %TPM_LEFTALIGN OR %TPM_RIGHTBUTTON, _
                                MousePos.x, MousePos.y, BYVAL 0, hDlg, BYVAL 0)
            
               CASE %WM_MEASUREITEM 'wParam is control identifier, lParam is item-size information
                 hdc          = GetDC(hDlg)
                 pPopItemSize = CBLPARAM
                 pPopItem     = @pPopItemSize.itemData
                 GetTextExtentPoint32(hdc, @pPopItem.zItem, LEN(@pPopItem.zItem), @pPopItem.SizeA)
                 @pPopItemSize.itemWidth  = 4 + GetSystemMetrics(%SM_CYSMICON) + @pPopItem.sizeA.cx
                 @pPopItemSize.itemHeight = 3 + MAX(GetSystemMetrics(%SM_CYSMICON), @pPopItem.sizeA.cy)
                 ReleaseDC(hDlg, hdc)
                 FUNCTION = %TRUE
            
               CASE %WM_DRAWITEM 'wParam is control id, lParam is item-drawing info
                 pPopItemDrawInfo = CBLPARAM
                 pPopItem         = @pPopItemDrawInfo.itemData
                 IF (@pPopItemDrawInfo.itemState AND %ODS_SELECTED) THEN
                   SetTextColor(@pPopItemDrawInfo.hDC, GetSysColor(%COLOR_HIGHLIGHTTEXT))
                   SetBkColor(@pPopItemDrawInfo.hDC, GetSysColor(%COLOR_HIGHLIGHT))
                   hBrush = GetSysColorBrush(%COLOR_HIGHLIGHT)
                 ELSE 'Item is not selected
                   SetTextColor(@pPopItemDrawInfo.hDC, GetSysColor(%COLOR_MENUTEXT))
                   SetBkColor(@pPopItemDrawInfo.hDC, GetSysColor(%COLOR_MENU))
                   hBrush = GetSysColorBrush(%COLOR_MENU)
                 END IF
                 FillRect(@pPopItemDrawInfo.hDC, @pPopItemDrawInfo.rcItem, hBrush)
            
                 IF LEN(@pPopItem.FileName) THEN 'A filename is given
                   hImg = SHGetFileInfo(@pPopItem.FileName, 0, shFileInf, SIZEOF(SHFILEINFO), _
                                        %SHGFI_TYPENAME OR %SHGFI_SHELLICONSIZE OR %SHGFI_SYSICONINDEX OR _
                                        %SHGFI_DISPLAYNAME OR %SHGFI_EXETYPE OR %SHGFI_SMALLICON)
                   ImageList_Draw(hImg, shFileInf.iIcon, @pPopItemDrawInfo.hDC, @pPopItemDrawInfo.rcItem.nleft, _
                                  @pPopItemDrawInfo.rcItem.nTop, %ILD_TRANSPARENT)
                   IF shFileInf.hIcon THEN DestroyIcon(shFileInf.hIcon)
                 ELSE 'No filename, so use IDI_INFORMATION icon
                   hImg = LoadIcon(BYVAL %NULL, BYVAL %IDI_INFORMATION)
                   DrawIconEx(@pPopItemDrawInfo.hDC, @pPopItemDrawInfo.rcItem.nleft, @pPopItemDrawInfo.rcItem.nTop, _
                              hImg, 16, 16, 0, BYVAL 0, %DI_NORMAL)
                   IF hImg THEN DestroyIcon(hImg)
                 END IF
            
                 @pPopItemDrawInfo.rcItem.nLeft = 4 + @pPopItemDrawInfo.rcItem.nLeft + GetSystemMetrics(%SM_CXSMICON)
                 DrawText(@pPopItemDrawInfo.hDC, @pPopItem.zItem, LEN(@pPopItem.zItem), _
                          @pPopItemDrawInfo.rcItem, %DT_SINGLELINE)
            
                 FUNCTION = %TRUE
            
               CASE %WM_DESTROY
                 IF IsMenu(hPopUp) THEN DestroyMenu(hPopUp)
            
             END SELECT
            
            END FUNCTION
            '_____________________________________________________________________________
            
            FUNCTION PBMAIN
             LOCAL hIcon AS DWORD
            
             DIALOG FONT "Segoe UI", 9
             DIALOG NEW %HWND_DESKTOP, "Right-Click me", , , 130, 100, %WS_CAPTION OR %WS_SYSMENU TO hDlg
            
             hIcon = ExtractIcon(GetModuleHandle(""), "%SystemRoot%\system32\PowrProf.dll", 1)
             SetClassLong(hDlg, %GCL_HICONSM, hIcon)
             SetClassLong(hDlg, %GCL_HICON, hIcon)
            
             DIALOG SHOW MODAL hDlg CALL DlgProc
            
             DestroyIcon(hIcon)
            
            END FUNCTION
            '_____________________________________________________________________________
            '
            Last edited by Pierre Bellisle; 13 Apr 2021, 05:43 PM.

            Comment

            • Michael Mattias
              Member
              • Aug 1998
              • 43447

              #7
              Instead of hard-coding ...

              Code:
              [COLOR=#0000FF]SELECT CASE[/COLOR] Looper
              [COLOR=#0000FF]CASE[/COLOR] [COLOR=#FF0000]1[/COLOR]: PopItem([COLOR=#FF0000]1[/COLOR]).zItem    = [COLOR=#800040]"&Explorer"[/COLOR]
                                 PopItem([COLOR=#FF0000]1[/COLOR]).FileName = zWinDir & [COLOR=#800040]"\Explorer.exe"[/COLOR]
              [COLOR=#0000FF]CASE[/COLOR] [COLOR=#FF0000]2[/COLOR]: PopItem([COLOR=#FF0000]2[/COLOR]).zItem    = [COLOR=#800040]"&Notepad"[/COLOR]
                                 PopItem([COLOR=#FF0000]2[/COLOR]).FileName = zSysDir & [COLOR=#800040]"\NotePad.exe"[/COLOR]
              [COLOR=#0000FF]CASE[/COLOR] [COLOR=#FF0000]3[/COLOR]: PopItem([COLOR=#FF0000]3[/COLOR]).zItem    = [COLOR=#800040]"&WinVer"[/COLOR]
                                 PopItem([COLOR=#FF0000]3[/COLOR]).FileName = zSysDir & [COLOR=#800040]"\WinVer.exe"[/COLOR]
              [COLOR=#0000FF]CASE[/COLOR] [COLOR=#FF0000]4[/COLOR]: PopItem([COLOR=#FF0000]4[/COLOR]).zItem    = [COLOR=#800040]"&Empty"[/COLOR]
                                 PopItem([COLOR=#FF0000]4[/COLOR]).FileName = [COLOR=#800040]""[/COLOR]
              [COLOR=#0000FF]END SELECT[/COLOR]
              .. I suggest you learn how to use the "FindExecutable" Windows' API function.

              You will have noticed in the "Favorites" code I posted (Post #4) I already have in there the code to check if the file currently exists. You only need to "FindExecutable()" if if DOES exist. MCM
              Last edited by Michael Mattias; 16 Nov 2017, 12:17 PM. Reason: Manually fix up the "help" provided by the auto-formatting of anything you try to cut and paste.
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment

              • Pierre Bellisle
                Member
                • Dec 2001
                • 5272

                #8
                Another way that may be more in sync with your code...

                Click image for larger version  Name:	IconMenu.png Views:	1 Size:	10.9 KB ID:	766885

                Code:
                #COMPILE EXE '#Win 9.07#
                #DIM ALL
                #INCLUDE "Win32Api.inc"
                
                GLOBAL hDlg AS DWORD
                '_____________________________________________________________________________
                
                FUNCTION hIconTohBmp(BYREF hIcon AS DWORD) AS DWORD
                 LOCAL MemDc      AS DWORD
                 LOCAL hDC        AS DWORD
                 LOCAL hbrush     AS DWORD
                 LOCAL hBitmap    AS DWORD
                 LOCAL hBitmapOld AS DWORD
                
                 hDC        = GetDC(hDlg)
                 MemDc      = CreateCompatibleDC(hDC)
                 hBitmap    = CreateBitmap(16, 16, 1, 32, BYVAL 0)
                 hBitmapOld = SelectObject(MemDc, hBitmap)
                 hbrush     = CreateSolidBrush(GetSysColor(%COLOR_MENU))
                 DrawIconEx(MemDc, 0, 0, hIcon, 16, 16, 0, BYVAL hbrush, %DI_NORMAL)
                
                 SelectObject(MemDc, hBitmapOld)
                 DeleteObject(hBrush)
                 DeleteDC(MemDc)
                 ReleaseDC(hDlg, hDC)
                 FUNCTION = hBitmap 'Call DeleteObject when bitmap are no longer needed
                
                END FUNCTION
                '_____________________________________________________________________________
                
                FUNCTION PBMAIN()
                 LOCAL FileInfo  AS SHFILEINFO
                 LOCAL hMenu     AS DWORD
                 LOCAL hMenuFile AS DWORD
                 LOCAL hBmpExp   AS DWORD
                 LOCAL hBmpReg   AS DWORD
                 LOCAL RetVal    AS DWORD
                
                 DIALOG FONT "Segoe UI", 9
                 DIALOG NEW %HWND_DESKTOP, "Icons in menu", , , 150, 50, %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
                
                 MENU NEW BAR TO hMenu
                 MENU NEW POPUP TO hMenuFile
                 MENU ADD POPUP, hMenu, "&File", hMenuFile,   %MF_ENABLED
                 MENU ADD STRING, hMenuFile, "Explorer", 101, %MF_ENABLED
                 MENU ADD STRING, hMenuFile, "RegEdit",  102, %MF_ENABLED
                 MENU ATTACH hMenu, hDlg
                
                 RetVal  = SHGetFileInfo("C:\Windows\Explorer.exe", 0, FileInfo, SIZEOF(FileInfo), %SHGFI_ICON OR %SHGFI_SMALLICON)
                 hBmpExp = hIconTohBmp(FileInfo.hIcon)
                 SetMenuItemBitmaps(hMenuFile, 0, %MF_BYPOSITION, hBmpExp, hBmpExp)
                
                 RetVal  = SHGetFileInfo("C:\Windows\RegEdit.exe", 0, FileInfo, SIZEOF(FileInfo), %SHGFI_ICON OR %SHGFI_SMALLICON)
                 hBmpReg = hIconTohBmp(FileInfo.hIcon)
                 SetMenuItemBitmaps(hMenuFile, 1, %MF_BYPOSITION, hBmpReg, hBmpReg)
                
                 DIALOG SHOW MODAL hDlg
                
                 DeleteObject(hBmpExp)
                 DeleteObject(hBmpReg)
                
                END FUNCTION
                '_____________________________________________________________________________
                '
                Last edited by Pierre Bellisle; 13 Apr 2021, 05:44 PM.

                Comment

                • Bernhard Fomm
                  Member
                  • Oct 2001
                  • 816

                  #9
                  Originally posted by Pierre Bellisle View Post
                  Another way that may be more in sync with your code...
                  That's what I need. The selected menu entries appear a bit strange. Somewhat intransparent. But I can live with that.

                  Comment

                  Working...
                  X