Beispiel #1
0
        private void AdjustSystemMenuForSecurity(IntPtr hmenu) {
            if (formState[FormStateAddedSecurityMenuItem] == 0) {
                formState[FormStateAddedSecurityMenuItem] = 1;

                SecurityMenuItem securitySystemMenuItem = new SecurityMenuItem(this);
                Properties.SetObject(PropSecuritySystemMenuItem, securitySystemMenuItem);

                NativeMethods.MENUITEMINFO_T info = new NativeMethods.MENUITEMINFO_T();
                info.fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE |
                             NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE | NativeMethods.MIIM_DATA;
                info.fType = 0;
                info.fState = 0;
                info.wID = securitySystemMenuItem.ID;
                info.hbmpChecked = IntPtr.Zero;
                info.hbmpUnchecked = IntPtr.Zero;
                info.dwItemData = IntPtr.Zero;

                // Note:  This code is not shipping in the final product.  We do not want to measure the
                //     :  performance hit of loading the localized resource for this at startup, so I
                //     :  am hard-wiring the strings below.  If you need to localize these, move them to
                //     :  a SECONDARY resource file so we don't have to contend with our big error message
                //     :  file on startup.
                //
                if (IsRestrictedWindow) {
                    info.dwTypeData = ".NET Restricted Window...";
                }
                else {
                    info.dwTypeData = ".NET Window...";
                }
                info.cch = 0;
                UnsafeNativeMethods.InsertMenuItem(new HandleRef(this, hmenu), 0, true, info);


                NativeMethods.MENUITEMINFO_T sep = new NativeMethods.MENUITEMINFO_T();
                sep.fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE |
                             NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE | NativeMethods.MIIM_DATA;
                sep.fType = NativeMethods.MFT_MENUBREAK;
                UnsafeNativeMethods.InsertMenuItem(new HandleRef(this, hmenu), 1, true, sep);

            }
        }
Beispiel #2
0
 public static extern BOOL GetMenuItemInfo(IntPtr hMenu, int uItem, bool fByPosition, [In, Out] NativeMethods.MENUITEMINFO_T lpmii);
Beispiel #3
0
        public static BOOL GetMenuItemInfo(HandleRef hMenu, int uItem, bool fByPosition, NativeMethods.MENUITEMINFO_T lpmii)
        {
            BOOL result = GetMenuItemInfo(hMenu.Handle, uItem, fByPosition, lpmii);

            GC.KeepAlive(hMenu.Wrapper);
            return(result);
        }
Beispiel #4
0
 public extern static bool InsertMenuItem(HandleRef hMenu, int uItem, bool fByPosition, NativeMethods.MENUITEMINFO_T lpmii);
        private NativeMethods.MENUITEMINFO_T CreateMenuItemInfo() {
            NativeMethods.MENUITEMINFO_T info = new NativeMethods.MENUITEMINFO_T();
            info.fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE |
                         NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE | NativeMethods.MIIM_DATA;
            info.fType = data.State & (STATE_BARBREAK | STATE_BREAK | STATE_RADIOCHECK | STATE_OWNERDRAW);

            // V7#646 - Top level menu items shouldn't have barbreak or break
            //          bits set on them...
            //
            bool isTopLevel = false;
            if (menu == GetMainMenu()) {
                isTopLevel = true;
            }

            if (data.caption.Equals("-")) {
                if (isTopLevel) {
                    data.caption = " ";
                    info.fType |= NativeMethods.MFT_MENUBREAK;
                }
                else {
                    info.fType |= NativeMethods.MFT_SEPARATOR;
                }
            }

                                                                  
            info.fState = data.State & (STATE_CHECKED | STATE_DEFAULT | STATE_DISABLED);

            info.wID = MenuID;
            if (IsParent) {
                info.hSubMenu = Handle;
            }
            info.hbmpChecked = IntPtr.Zero;
            info.hbmpUnchecked = IntPtr.Zero;

            // Assign a unique ID to this menu item object...
            //    The ID is stored in the dwItemData of the corresponding Win32 menu item, so that when we get Win32
            //    messages about the item later, we can delegate to the original object menu item object. A static
            //    hash table is used to map IDs to menu item objects.
            //
            if (uniqueID == 0) {
                lock(allCreatedMenuItems) {
                    uniqueID = (uint)Interlocked.Increment(ref nextUniqueID);
                    Debug.Assert(uniqueID >= firstUniqueID); // ...check for ID range exhaustion (unlikely!)
                    // We add a weak ref wrapping a MenuItem to the static hash table, as supposed to adding the item 
                    // ref itself, to allow the item to be finalized in case it is not disposed and no longer referenced 
                    // anywhere else, hence preventing leaks. See bug#352644
                    allCreatedMenuItems.Add(uniqueID, new WeakReference(this));
                }
            }

            // To check it's 32-bit OS or 64-bit OS.
            if (IntPtr.Size == 4) {
                // Store the unique ID in the dwItemData...
                //     For simple menu items, we can just put the unique ID in the dwItemData. But for owner-draw items,
                //     we need to point the dwItemData at an MSAAMENUINFO structure so that MSAA can get the item text.
                //     To allow us to reliably distinguish between IDs and structure pointers later on, we keep IDs in
                //     the 0xC0000000-0xFFFFFFFF range. This is the top 1Gb of unmananged process memory, where an app's
                //     heap allocations should never come from. So that we can still get the ID from the dwItemData for
                //     an owner-draw item later on, a copy of the ID is tacked onto the end of the MSAAMENUINFO structure.
                //
                if (data.OwnerDraw)
                    info.dwItemData = AllocMsaaMenuInfo();
                else
                    info.dwItemData = (IntPtr) unchecked((int) uniqueID);
            }
            else {
                // On Win64, there are no reserved address ranges we can use for menu item IDs. So instead we will
                // have to allocate an MSAMENUINFO heap structure for all menu items, not just owner-drawn ones.
                info.dwItemData = AllocMsaaMenuInfo();
            }
            
            // We won't render the shortcut if: 1) it's not set, 2) we're a parent, 3) we're toplevel
            //
            if (data.showShortcut && data.shortcut != 0 && !IsParent && !isTopLevel) {
                info.dwTypeData = data.caption + "\t" + TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString((Keys)(int)data.shortcut);
            }
            else {
                // Windows issue: Items with empty captions sometimes block keyboard
                // access to other items in same menu.
                info.dwTypeData = (data.caption.Length == 0 ? " " : data.caption);
            }
            info.cch = 0;

            return info;
        }
        internal virtual void CreateMenuItem() {
            if ((data.State & STATE_HIDDEN) == 0) {
                NativeMethods.MENUITEMINFO_T info = CreateMenuItemInfo();
                UnsafeNativeMethods.InsertMenuItem(new HandleRef(menu, menu.handle), -1, true, info);

                hasHandle = info.hSubMenu != IntPtr.Zero;
                dataVersion = data.version;

                menuItemIsCreated = true;
                if(RenderIsRightToLeft) {
                    Menu.UpdateRtl(true);
                }

#if DEBUG
                NativeMethods.MENUITEMINFO_T infoVerify = new NativeMethods.MENUITEMINFO_T();
                infoVerify.cbSize = Marshal.SizeOf(typeof(NativeMethods.MENUITEMINFO_T));
                infoVerify.fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE |
                                   NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE;
                UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(menu, menu.handle), MenuID, false, infoVerify);
#endif
            }
        }
        internal void UpdateMenuItem(bool force) {
            if (menu == null || !menu.created) {
                return;
            }

            if (force || menu is MainMenu || menu is ContextMenu) {
                NativeMethods.MENUITEMINFO_T info = CreateMenuItemInfo();
                UnsafeNativeMethods.SetMenuItemInfo(new HandleRef(menu, menu.handle), MenuID, false, info);
#if DEBUG
                NativeMethods.MENUITEMINFO_T infoVerify = new NativeMethods.MENUITEMINFO_T();
                infoVerify.cbSize = Marshal.SizeOf(typeof(NativeMethods.MENUITEMINFO_T));
                infoVerify.fMask = NativeMethods.MIIM_ID | NativeMethods.MIIM_STATE |
                                   NativeMethods.MIIM_SUBMENU | NativeMethods.MIIM_TYPE;
                UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(menu, menu.handle), MenuID, false, infoVerify);
#endif

                if (hasHandle && info.hSubMenu == IntPtr.Zero) {
                    ClearHandles();
                }
                hasHandle = info.hSubMenu != IntPtr.Zero;
                dataVersion = data.version;
                if (menu is MainMenu) {                    
                    Form f = ((MainMenu)menu).GetFormUnsafe();
                    if (f != null) {
                        SafeNativeMethods.DrawMenuBar(new HandleRef(f, f.Handle));
                    }
                }
            }
        }
        internal void UpdateItemRtl(bool setRightToLeftBit) {
            if(!menuItemIsCreated) {
                return;
            }
                
            NativeMethods.MENUITEMINFO_T info = new NativeMethods.MENUITEMINFO_T();
            info.fMask          = NativeMethods.MIIM_TYPE | NativeMethods.MIIM_STATE | NativeMethods.MIIM_SUBMENU;
            info.dwTypeData     = new string('\0', Text.Length + 2);
            info.cbSize         = Marshal.SizeOf(typeof(NativeMethods.MENUITEMINFO_T));
            info.cch            = info.dwTypeData.Length - 1;
            UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(menu, menu.handle), MenuID, false, info);
            if(setRightToLeftBit) {
                info.fType |= NativeMethods.MFT_RIGHTJUSTIFY | NativeMethods.MFT_RIGHTORDER;
            } else {
                info.fType &= ~(NativeMethods.MFT_RIGHTJUSTIFY | NativeMethods.MFT_RIGHTORDER);
            }            
            UnsafeNativeMethods.SetMenuItemInfo(new HandleRef(menu, menu.handle), MenuID, false, info);

#if DEBUG

            info.fMask          = NativeMethods.MIIM_TYPE | NativeMethods.MIIM_STATE | NativeMethods.MIIM_SUBMENU;
            info.dwTypeData     = new string('\0', 256);
            info.cbSize         = Marshal.SizeOf(typeof(NativeMethods.MENUITEMINFO_T));
            info.cch            = info.dwTypeData.Length - 1;
            UnsafeNativeMethods.GetMenuItemInfo(new HandleRef(menu, menu.handle), MenuID, false, info);
            Debug.Assert(((info.fType & NativeMethods.MFT_RIGHTORDER) != 0) == setRightToLeftBit, "Failed to set bit!");
            
#endif
        }