InsertMenuItem WinAPI problem
-
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.
-
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.
In Win64 all pointers take 64 bits, hence
uint hMenu
is wrong inpublic static extern bool InsertMenuItem(uint hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);
. One should always useIntPtr
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.
-
In Win64 all pointers take 64 bits, hence
uint hMenu
is wrong inpublic static extern bool InsertMenuItem(uint hMenu, uint uItem, bool fByPosition,[In] ref MENUITEMINFO lpmii);
. One should always useIntPtr
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.
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.
-
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.
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
-
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
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.
-
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.
-
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