Adding to the global context menu
-
Friday, March 28, 2008 6:48 PM
I want to add a function to the global context menu. The same one used by Explorer. Being I havent found any managed code that can accomplish this task I got a sickening feeling that I need to use a COM object from the Windows API. Anybody got some insight?
This guy was trying to do this 2 years ago and never got an answer >.< http://www.thescripts.com/forum/thread235380.html
All Replies
-
Saturday, March 29, 2008 2:52 AM
Here you go. I just modified the Pinvoke.net example on how to remove the close button. This seems to work fine. Little sloppy though
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
AddMenuItem(this);
}
public static void RemoveCloseButton(Form frm)
{
IntPtr hMenu;
int n;
hMenu = GetSystemMenu(frm.Handle, false);
if (hMenu != IntPtr.Zero)
{
n = GetMenuItemCount(hMenu);
if (n > 0)
{
RemoveMenu(hMenu, (uint)(n - 1), MF_BYPOSITION | MF_REMOVE);
RemoveMenu(hMenu, (uint)(n - 2), MF_BYPOSITION | MF_REMOVE);
DrawMenuBar(frm.Handle);
}
}
}
public static void AddMenuItem(Form frm)
{
IntPtr hMenu;
int n;
hMenu = GetSystemMenu(frm.Handle, false);
if (hMenu != IntPtr.Zero)
{
n = GetMenuItemCount(hMenu);
if (n > 0)
{
//RemoveMenu(hMenu, (uint)(n - 1), MF_BYPOSITION | MF_REMOVE);
//RemoveMenu(hMenu, (uint)(n - 2), MF_BYPOSITION | MF_REMOVE);
MENUITEMINFO menuInfo = new MENUITEMINFO();
menuInfo.cbSize = MENUITEMINFO.sizeOf;
menuInfo.cch = 255;
menuInfo.dwTypeData = "Test Item";
menuInfo.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
menuInfo.fState = 0;
menuInfo.fType = MFT_STRING;
//menuInfo.hSubMenu =
InsertMenuItem(hMenu, (uint)n, true, ref menuInfo);
DrawMenuBar(frm.Handle);
}
}
}
private const int MIIM_STATE = 0x1;
private const int MIIM_ID = 0x2;
private const int MIIM_TYPE = 0x10;
private const int MFT_SEPARATOR = 0x800;
private const int MFT_STRING = 0x0;
private const int MFS_ENABLED = 0x0;
private const int MFS_CHECKED = 0x8;
private const Int32 MF_BYPOSITION = 0x400;
private const Int32 MF_REMOVE = 0x1000;
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
static extern int GetMenuItemCount(IntPtr hMenu);
[DllImport("user32.dll")]
static extern bool DrawMenuBar(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
[DllImport("user32.dll")]
static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition,
[In] ref MENUITEMINFO lpmii);
[DllImport("user32.dll")]
static extern bool SetMenuItemInfo(IntPtr 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 uint wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public IntPtr dwItemData; //<- ItemData is up! by haijer
public string dwTypeData;
public uint cch;
public IntPtr hbmpItem;
// return the size of the structure
internal static uint sizeOf
{
get { return (uint)Marshal.SizeOf(typeof(MENUITEMINFO)); }
}
}
} -
Thursday, May 01, 2008 9:56 AM
This is top article it even works in x64 version of Vista. I had a similar problem (trying to add to the shell context menu an item) and only this way of marshaling the structures/methods worked on x64.
-
Friday, August 29, 2008 1:53 PMHow do you hook the event with the new menu item?
Thanks.

