• Welcome to Valhalla Legends Archive.
 

"Copying" menus?

Started by MyndFyre, April 21, 2005, 10:46 PM

Previous topic - Next topic

MyndFyre

So -- I've been playing around with the HMENU GetSystemMenu() function in an attempt to figure out how to either access the system menu items and "copy" them to a menu bar I have already, or to append the system menu (both preferably -- the first just for kicks, the second for utility).

I've tried a couple of things --

1.) Get a handle to the system menu and my target menu.
2.) Get the number of items in the system menu (comes back correct).
3.) Iterate over the items in the system menu:
for each item:
4.) Create a new MENUITEMINFO structure
5.) Get the MENUITEMINFO structure via GetMenuItemInfo() (works).
6.) Insert the MENUITEMINFO into my target menu with InsertMenuItem(HMENU, uint, bool, LPCMENUITEMINFO)

The call to InsertMenuItem fails with error code 0x7e, which resolves to "The specified module could not be found. "  The same when I try to go the other direction an add menus to the system menu.

Any idea?
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Adron

Show some code. You're probably doing something wrong. Some field you're not getting or setting right.

MyndFyre

This is my exported function class:

using System;
using System.Runtime.InteropServices;

namespace CsMenus
{
public sealed class Win32
{
private Win32()
{
}

[DllImport("user32.dll"), CLSCompliant(false)]
public static extern int GetMenuItemCount(
IntPtr hMenu
);

[DllImport("user32.dll"), CLSCompliant(false)]
public static extern bool GetMenuItemInfo(
IntPtr hMenu,
uint uItem,
bool fByPosition,
[MarshalAs(UnmanagedType.Struct)] ref MenuItemInfo lpmii
);

[DllImport("user32.dll"), CLSCompliant(false)]
public static extern bool InsertMenuItem(
IntPtr hMenu,
uint uItem,
bool fByPosition,
[MarshalAs(UnmanagedType.Struct)] ref MenuItemInfo lpmii
);

[DllImport("user32.dll"), CLSCompliant(false)]
public static extern IntPtr GetSystemMenu(
IntPtr hWnd,
bool bRevert
);

[DllImport("user32.dll"), CLSCompliant(false)]
public static extern bool IsMenu(
IntPtr hMenu
);

}

[CLSCompliant(false)]
public struct MenuItemInfo
{
public uint cbSize;
public MIIRequests fMask;
public MIITypes fType;
public MIIStates fState;
public uint wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public uint dwItemData;
[MarshalAs(UnmanagedType.LPTStr)]
public string dwTypeData;
public uint cch;
public IntPtr hbmpItem;
}

[Flags, CLSCompliant(false)]
public enum MIIRequests : uint
{
MIIM_BITMAP = 0x80,
MIIM_CHECKMARKS = 0x08,
MIIM_DATA = 0x20,
MIIM_FTYPE = 0x100,
MIIM_ID = 0x02,
MIIM_STATE = 0x01,
MIIM_STRING = 0x40,
MIIM_SUBMENU = 0x04,
MIIM_TYPE = 0x10
}

[Flags, CLSCompliant(false)]
public enum MIIStates : uint
{
MFS_CHECKED = 0x08,
MFS_DEFAULT = 0x1000,
MFS_DISABLED = 0x01,
MFS_ENABLED = 0,
MFS_GRAYED = 0x03,
MFS_HILITE = 0x80,
MFS_UNCHECKED = 0,
MFS_UNHILITE = 0
}

[Flags, CLSCompliant(false)]
public enum MIITypes : uint
{
MFT_BITMAP = 0x04,
MFT_MENUBARBREAK = 0x20,
MFT_OWNERDRAW = 0x100,
MFT_RADIOCHECK = 0x200,
MFT_RIGHTJUSTIFY = 0x4000,
MFT_RIGHTORDER = 0x2000,
MFT_SEPARATOR = 0x800,
MFT_STRING = 0
}
}


This is the code from the Form that I'm using.  Note that this.Handle returns the handle to the window, miFileMenu is the MenuItem object of the File menu on my main menu bar, and the miSystemMenuCopy is the MenuItem object that corresponds to a menu on my main menu bar where I'm trying to copy my system menu to.  All of my managed menus return true when I check them with IsMenu(HMENU).

private void CopySystemToManagedMenu()
{
IntPtr hSysMenu = Win32.GetSystemMenu(this.Handle, false);
int nItemCount = Win32.GetMenuItemCount(hSysMenu);
for (int i = 0; i < nItemCount; i++)
{
MenuItemInfo mii = new MenuItemInfo();
mii.fMask = MIIRequests.MIIM_BITMAP | MIIRequests.MIIM_CHECKMARKS | MIIRequests.MIIM_DATA |
MIIRequests.MIIM_FTYPE | MIIRequests.MIIM_ID | MIIRequests.MIIM_STATE | MIIRequests.MIIM_STRING |
MIIRequests.MIIM_SUBMENU | MIIRequests.MIIM_TYPE;
bool retrieved = Win32.GetMenuItemInfo(hSysMenu, (uint)i, true, ref mii);
if (!retrieved)
Debug.WriteLine(
System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString("x8"),
"Error retrieving menu item (System to Managed Menu)"
);
Debug.WriteLine(mii.wID, "Menu item ID");
bool added = Win32.InsertMenuItem(this.miSystemMenuCopy.Handle, (uint)i, true, ref mii);
if (!added)
Debug.WriteLine(
System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString("x8"),
"Error adding menu item (System to Managed Menu)"
);
}
}

private void CopyFileToSystemMenu()
{
IntPtr hSysMenu = Win32.GetSystemMenu(this.Handle, false);
int nItemCount = Win32.GetMenuItemCount(miFileMenu.Handle);
for (int i = 0; i < nItemCount; i++)
{
MenuItemInfo mii = new MenuItemInfo();
mii.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(MenuItemInfo));
mii.fMask = MIIRequests.MIIM_BITMAP | MIIRequests.MIIM_CHECKMARKS | MIIRequests.MIIM_DATA |
MIIRequests.MIIM_FTYPE | MIIRequests.MIIM_ID | MIIRequests.MIIM_STATE | MIIRequests.MIIM_STRING |
MIIRequests.MIIM_SUBMENU | MIIRequests.MIIM_TYPE;
bool retrieved = Win32.GetMenuItemInfo(miFileMenu.Handle, (uint)i, true, ref mii);
if (!retrieved)
Debug.WriteLine(
System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString("x8"),
"Error retrieving menu item (File to System Menu)"
);
Debug.WriteLine(mii.wID, "Menu item ID");
bool added = Win32.InsertMenuItem(hSysMenu, (uint)i, true, ref mii);
if (!added)
Debug.WriteLine(
System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString("x8"),
"Error adding menu item (File to System Menu)"
);
}
}


This is the output:

Error retrieving menu item (System to Managed Menu): 0000007f
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
Error retrieving menu item (System to Managed Menu): 00000000
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
Error retrieving menu item (System to Managed Menu): 00000000
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
Error retrieving menu item (System to Managed Menu): 00000000
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
Error retrieving menu item (System to Managed Menu): 00000000
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
Error retrieving menu item (System to Managed Menu): 00000000
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
Error retrieving menu item (System to Managed Menu): 00000000
Menu item ID: 0
Error adding menu item (System to Managed Menu): 00000000
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.