2011-08-18 79 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