2011-08-18 81 views
2

好吧,这似乎太简单了一个问题,但我浪费了足够的时间寻找如何做到这一点。我在移动设备上使用CE 6.5,并且我有一个包含六个MenuItem的ContextMenu。当菜单弹出时,列表中的第一个项目会自动突出显示。我想删除这个亮点,因为它让我的一些用户感到困惑,认为它是当前状态。我查看了ContextMenu及其所有变量和MenuItem,并没有发现如何去除第一项的自动高亮。 MainMenu也一样。C#ContextMenu删除默认选择

回答

3

我认为答案是,不幸的是,你不能。我今天下午花了很大努力去弄清楚这个菜单,但我无法得到一个有效的操作系统允许我使用的HMENU。如果你想继续尝试追寻下面的代码路径,但我真的认为它是一个死胡同。在这一点上,如果你真的需要这个功能,我会考虑P /调用菜单的所有内容(创建,人口等)。

using System; 
using System.Linq; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Reflection; 
using System.Runtime.InteropServices; 

using UINT = System.UInt32; 
using HMENU = System.IntPtr; 
using HBITMAP = System.IntPtr; 
using DWORD = System.UInt32; 
using LPTSTR = System.IntPtr; 

namespace MenuTest 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      contextMenu.MenuItems.Add(new MenuItem() { Text = "Item A" }); 
      contextMenu.MenuItems.Add(new MenuItem() { Text = "Item B" }); 
      contextMenu.MenuItems.Add(new MenuItem() { Text = "Item C" }); 
      contextMenu.MenuItems.Add(new MenuItem() { Text = "Item D" }); 

      this.MouseDown += new MouseEventHandler(Form1_MouseDown); 
      contextMenu.Popup += new EventHandler(contextMenu_Popup); 
     } 

     void contextMenu_Popup(object sender, EventArgs e) 
     { 
      var type = contextMenu.GetType(); 
      var members = type.GetMembers(
          BindingFlags.NonPublic | BindingFlags.Instance); 
      var menuMember = type.GetField("m_hmnu", 
          BindingFlags.NonPublic | BindingFlags.Instance); 
      var hMenu = (HMENU)menuMember.GetValue(contextMenu); 

      var info = new MENUITEMINFO(); 
      info.cbSize = (uint)Marshal.SizeOf(info); 
      info.fMask = MIIM_STATE; 
      var result = GetMenuItemInfo(hMenu, 0, true, out info); 
      if (!result) 
      { 
       var err = Marshal.GetLastWin32Error(); 
       if (err == 0x0579) MessageBox.Show("Invalid menu handle"); 
       return; 
      } 
      info.fMask = MIIM_STATE; 
      info.fState &= (~MFS_HILITE); 
      result = SetMenuItemInfo(hMenu, 0, true, ref info); 
     } 

     void Form1_MouseDown(object sender, MouseEventArgs e) 
     { 
      contextMenu.Show(this, new Point(e.X, e.Y)); 
     } 

     private const uint MIIM_STATE = 1; 
     private const uint MFS_UNHILITE = 0; 
     private const uint MFS_HILITE = 0x80;   

     //typedef struct tagMENUITEMINFO { 
     // UINT cbSize; 
     // UINT fMask; 
     // UINT fType; 
     // UINT fState; 
     // UINT wID; 
     // HMENU hSubMenu; 
     // HBITMAP hbmpChecked; 
     // HBITMAP hbmpUnchecked; 
     // DWORD dwItemData; 
     // LPTSTR dwTypeData; 
     // UINT cch; 
     //} MENUITEMINFO, FAR* LPMENUITEMINFO; 
     private struct MENUITEMINFO 
     { 
      public UINT cbSize; 
      public UINT fMask; 
      public UINT fType; 
      public UINT fState; 
      public UINT wID; 
      public HMENU hSubMenu; 
      public HBITMAP hbmpChecked; 
      public HBITMAP hbmpUnchecked; 
      public DWORD dwItemData; 
      public LPTSTR dwTypeData; 
      public UINT cch; 
     } 

     //BOOL SetMenuItemInfo(
     // HMENU hMenu, 
     // UINT uItem, 
     // BOOL fByPosition, 
     // LPCMENUITEMINFO lpmii 
     //); 
     [DllImport("coredll", SetLastError = true)] 
     private static extern bool SetMenuItemInfo(HMENU hMenu, UINT uItem, 
            [MarshalAs(UnmanagedType.Bool)]bool fByPosition, 
            ref MENUITEMINFO lpmii); 

     //BOOL GetMenuItemInfo(
     // HMENU hMenu, 
     // UINT uItem, 
     // BOOL fByPosition, 
     // LPMENUITEMINFO lpmii 
     //); 
     [DllImport("coredll", SetLastError = true)] 
     private static extern bool GetMenuItemInfo(HMENU hMenu, UINT uItem, 
            [MarshalAs(UnmanagedType.Bool)]bool fByPosition, 
            out MENUITEMINFO lpmii); 

     //HMENU GetSubMenu(
     // HMENU hMenu, 
     // int nPos 
     //); 
     [DllImport("coredll", SetLastError = true)] 
     private static extern HMENU GetSubMenu(HMENU hMenu, int nPos); 
    } 
} 

编辑

我知道我有什么地方的代码做了这一切。我们过去出售了一个商业PopupMenu控件,它包含了所有的P/Invokes菜单创建。控制的销售额很小,所以我们在几年前就将其从我们的产品线中抽出来。我现在将它作为开源over on Codeplex发布。

+0

如果您可以如此友善地向我展示如何P/Invoke它,因为我仍然是新的Windows CE/C#环境(Java代码交易) – JPM

+1

这将是一个长期的教训 - 不仅仅是一个方法张贴在这里。它与我上面所做的一致,但必须通过P/Invoke来创建菜单和项目,然后将菜单点击处理程序连接到托管代理。这不是太困难 - 我会在10分钟左右给它一个,但这会有点冗长。 – ctacke