Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. InsertMenuItem WinAPI problem

InsertMenuItem WinAPI problem

Scheduled Pinned Locked Moved C#
helpcsharplinux
7 Posts 4 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nematjon Rahmanov
    wrote on last edited by
    #1

    Hi ! I'm working shell context menu on 64 pc. I rebuild app under x64 pc. I want add menu item to windows context menu.Registery is OK and windows explorer find my dll. But InsertMenuItem WinAPI function not working!

    MENUITEMINFO mii = new MENUITEMINFO();
    mii.cbSize =(uint)Marshal.SizeOf(typeof(MENUITEMINFO));// 0x30;
    mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE |(uint)MIIM.SUBMENU;
    mii.fType =(uint) MF.STRING;
    mii.wID = idCmdFirst + num;
    mii.dwTypeData = "My menu text";
    mii.fState =(uint)MF.ENABLED;
    mii.cch = (uint)mii.dwTypeData.Length;

    InsertMenuItem(hmenu, iMenu+1, true, ref mii);

    My defenition :

    [DllImport("user32.dll")]
    public static extern bool InsertMenuItem(uint hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);

    [StructLayout(LayoutKind.Sequential)]
    public struct MENUITEMINFO
    {
    public uint cbSize;
    public uint fMask;
    public uint fType;
    public uint fState;
    public int wID;
    public int hSubMenu;
    public int hbmpChecked;
    public int hbmpUnchecked;
    public int dwItemData;
    public String dwTypeData;
    public uint cch;
    public int hbmpItem;
    }

    Please help me. (I know writing shell menu under .net is not good,but i very want see it). Thanks.

    We are haven't bug,just temporarily undecided problems.

    L 1 Reply Last reply
    0
    • N Nematjon Rahmanov

      Hi ! I'm working shell context menu on 64 pc. I rebuild app under x64 pc. I want add menu item to windows context menu.Registery is OK and windows explorer find my dll. But InsertMenuItem WinAPI function not working!

      MENUITEMINFO mii = new MENUITEMINFO();
      mii.cbSize =(uint)Marshal.SizeOf(typeof(MENUITEMINFO));// 0x30;
      mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE |(uint)MIIM.SUBMENU;
      mii.fType =(uint) MF.STRING;
      mii.wID = idCmdFirst + num;
      mii.dwTypeData = "My menu text";
      mii.fState =(uint)MF.ENABLED;
      mii.cch = (uint)mii.dwTypeData.Length;

      InsertMenuItem(hmenu, iMenu+1, true, ref mii);

      My defenition :

      [DllImport("user32.dll")]
      public static extern bool InsertMenuItem(uint hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);

      [StructLayout(LayoutKind.Sequential)]
      public struct MENUITEMINFO
      {
      public uint cbSize;
      public uint fMask;
      public uint fType;
      public uint fState;
      public int wID;
      public int hSubMenu;
      public int hbmpChecked;
      public int hbmpUnchecked;
      public int dwItemData;
      public String dwTypeData;
      public uint cch;
      public int hbmpItem;
      }

      Please help me. (I know writing shell menu under .net is not good,but i very want see it). Thanks.

      We are haven't bug,just temporarily undecided problems.

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      In Win64 all pointers take 64 bits, hence uint hMenu is wrong in public static extern bool InsertMenuItem(uint hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);. One should always use IntPtr when passing a handle or pointer; and yes, www.pinvoke.net has some errors in that regard. Another potential problem may be the string in your structure; not sure that gets marshaled automatically. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


      I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
      All Toronto weekends should be extremely wet until we get it automated in regular forums, not just QA.


      N 1 Reply Last reply
      0
      • L Luc Pattyn

        In Win64 all pointers take 64 bits, hence uint hMenu is wrong in public static extern bool InsertMenuItem(uint hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);. One should always use IntPtr when passing a handle or pointer; and yes, www.pinvoke.net has some errors in that regard. Another potential problem may be the string in your structure; not sure that gets marshaled automatically. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


        I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.
        All Toronto weekends should be extremely wet until we get it automated in regular forums, not just QA.


        N Offline
        N Offline
        Nematjon Rahmanov
        wrote on last edited by
        #3

        Hi Luc. Thanks for your reply. I change my code like that :

        [DllImport("user32.dll")]
        public static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);

            \[DllImport("user32.dll")\]
            public static extern int SetMenuItemBitmaps(IntPtr hmenu, uint uposition, uint uFlags, IntPtr hBitmapUnchecked, IntPtr hBitmapChecked);
        

        InsertMenuItem not yet working , but SetMenuItemBitmaps working well. Please help me . Thanks .

        We are haven't bug,just temporarily undecided problems.

        C 1 Reply Last reply
        0
        • N Nematjon Rahmanov

          Hi Luc. Thanks for your reply. I change my code like that :

          [DllImport("user32.dll")]
          public static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);

              \[DllImport("user32.dll")\]
              public static extern int SetMenuItemBitmaps(IntPtr hmenu, uint uposition, uint uFlags, IntPtr hBitmapUnchecked, IntPtr hBitmapChecked);
          

          InsertMenuItem not yet working , but SetMenuItemBitmaps working well. Please help me . Thanks .

          We are haven't bug,just temporarily undecided problems.

          C Offline
          C Offline
          Covean
          wrote on last edited by
          #4

          1. You have used the flag MIIM.SUBMENU (fMask) but you hasn't set the hSubMenu value. 2. You also should adjust your struct to use IntPtr instead of int. Like this:

          \[StructLayout(LayoutKind.Sequential)\]
          public struct MENUITEMINFO
          {
              public uint cbSize;
              public uint fMask;
              public uint fType;
              public uint fState;
              public int wID;
              public IntPtr hSubMenu;
              public IntPtr hbmpChecked;
              public IntPtr hbmpUnchecked;
              public IntPtr dwItemData;
              public String dwTypeData;
              public uint cch;
              public IntPtr hbmpItem;
          }
          

          There may be also the problem with the (LPTSTR)String dwTypeData. If it doesn't work you could try StringBuilder instead.

          Greetings Covean

          N 1 Reply Last reply
          0
          • C Covean

            1. You have used the flag MIIM.SUBMENU (fMask) but you hasn't set the hSubMenu value. 2. You also should adjust your struct to use IntPtr instead of int. Like this:

            \[StructLayout(LayoutKind.Sequential)\]
            public struct MENUITEMINFO
            {
                public uint cbSize;
                public uint fMask;
                public uint fType;
                public uint fState;
                public int wID;
                public IntPtr hSubMenu;
                public IntPtr hbmpChecked;
                public IntPtr hbmpUnchecked;
                public IntPtr dwItemData;
                public String dwTypeData;
                public uint cch;
                public IntPtr hbmpItem;
            }
            

            There may be also the problem with the (LPTSTR)String dwTypeData. If it doesn't work you could try StringBuilder instead.

            Greetings Covean

            N Offline
            N Offline
            Nematjon Rahmanov
            wrote on last edited by
            #5

            Thanks Covean. You are right .Problem is fixed. Now i have shell menu working both 32 bit and 64 bit Windows version! Thank you very much!:rose:

            We are haven't bug,just temporarily undecided problems.

            C 1 Reply Last reply
            0
            • N Nematjon Rahmanov

              Thanks Covean. You are right .Problem is fixed. Now i have shell menu working both 32 bit and 64 bit Windows version! Thank you very much!:rose:

              We are haven't bug,just temporarily undecided problems.

              C Offline
              C Offline
              Covean
              wrote on last edited by
              #6

              You're welcome! :-D

              Greetings Covean

              D 1 Reply Last reply
              0
              • C Covean

                You're welcome! :-D

                Greetings Covean

                D Offline
                D Offline
                Decco
                wrote on last edited by
                #7

                Thanks, I had exactly the same problem ! Here my new code, if it can help someone esle :)

                \[StructLayout(LayoutKind.Sequential)\]
                public struct MENUITEMINFO
                {
                	public uint cbSize;
                	public uint fMask;
                	public uint fType;
                	public uint fState;
                	public uint wID;
                	public IntPtr hSubMenu;
                	public IntPtr hbmpChecked;
                	public IntPtr hbmpUnchecked;
                	public IntPtr dwItemData;
                	public string dwTypeData;
                	public uint cch;
                	public IntPtr hbmpItem;
                }
                
                public class DllImports
                {
                \[DllImport("user32.dll")\]
                    public static extern bool InsertMenuItem(IntPtr hMenu, uint uPosition, uint uFlags, \[In\] ref MENUITEMINFO mii);
                
                    \[DllImport("user32")\]
                    public static extern UInt32 SetMenuItemBitmaps(IntPtr hMenu, uint uPosition, uint uFlags, IntPtr hBitmapUnchecked, IntPtr hBitmapChecked);
                }
                
                    private void AddMenuItem(IntPtr hMenu, uint id, uint position, string text, Bitmap icon, IntPtr? hSubMenu)
                    {
                        MENUITEMINFO mii = new MENUITEMINFO();
                        mii.cbSize = (uint)Marshal.SizeOf(typeof(MENUITEMINFO)); //48;
                        mii.fMask = (uint)MIIM.ID | (uint)MIIM.STRING | (uint)MIIM.SUBMENU;
                        mii.wID = id;
                        mii.dwTypeData = text;
                
                        if (hSubMenu.HasValue)
                        {
                            mii.hSubMenu = hSubMenu.Value;
                        }
                
                        DllImports.InsertMenuItem(hMenu, position, (uint)MF.BYPOSITION, ref mii);
                
                        if (icon != null)
                        {
                            DllImports.SetMenuItemBitmaps(hMenu, id, (uint)MF.BYCOMMAND, icon.GetHbitmap(), icon.GetHbitmap());
                        }
                    }
                

                The biggest problem was this line :

                        mii.cbSize = (uint)Marshal.SizeOf(typeof(MENUITEMINFO)); //48;
                

                As in all exemples you found on web, the size is set to 48 by default and not calculate. Thanks again. Decco

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups