2011-08-18 6 views
2

그래,이 질문은 너무 단순 해 보일 수 있지만이 작업을 수행하는 방법을 찾기에는 충분한 시간을 낭비했습니다. 모바일 장치에서 CE 6.5를 사용하고 있으며 6 개의 MenuItem이있는 ContextMenu가 있습니다. 메뉴가 나타나면 목록의 첫 번째 항목이 자동으로 강조 표시됩니다. 나는 그것이 현재의 상태라고 생각하는 일부 사용자를 혼란스럽게하므로이 하이라이트를 제거하고 싶다. ContextMenu 및 모든 변수 및 MenuItem을 살펴본 후 첫 번째 항목의 자동 강조 표시를 제거하는 방법을 찾지 못했습니다. MainMenu도 마찬가지입니다.C# ContextMenu 기본 선택 제거

답변

3

나는 대답이 불행하게도 불가능하다고 생각합니다. 나는 그 메뉴를 잡기 위해 오늘 오후에 강한 노력을 기울 였고 OS가 나를 사용할 수있게하는 유효한 HMENU를 얻을 수 없었다. 코드에 있던 경로를 계속 추적하려는 경우 아래에 있지만 실제로는 막 다른 길이라고 생각합니다. 이 시점에서 나는 당신이 정말로 그 특징을 필요로한다면 메뉴 (생성, 모집단 등)에 대한 모든 것을 호출하는 P/Invoking를 고려할 것이다.

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); 
    } 
} 

편집

은 내가이 모든 일을 어딘가에 코드를 알고 있었다. 우리는 메뉴 생성을 위해 모든 P/Invokes를 감싸는 상용 PopupMenu 컨트롤을 판매했습니다. 컨트롤 판매가 적기 때문에 몇 년 전에 제품 라인에서 판매를 시작했습니다. 나는 오픈 소스 over on Codeplex으로 발표했다.

+0

Windows CE/C# 환경 (무역으로 Java 코더)에 익숙하지 않으므로 P/Invoke하는 방법을 보여줄만큼 친절 할 수만 있다면 – JPM

+1

그건 긴 교훈 일 것입니다. 여기에 게시하십시오. 위에서 다룬 내용을 따르므로 P/Invoke를 사용하여 메뉴 및 항목을 만든 다음 메뉴 클릭 핸들러를 관리되는 위임자로 연결해야합니다. 지나치게 힘들지는 않습니다. 10 점 만점에 4 점 정도 줄 것입니다. 그러나 조금 길어질 것입니다. – ctacke