如何以编程方式调用应用程序菜单?

时间:2010-02-17 09:31:13

标签: c# wpf contextmenu

我有自定义样式的非矩形透明窗口。

<Window
    x:Class="TestWindow" x:Name="Window"
    Width="350" Height="450"  AllowsTransparency="True"  WindowStyle="None"
WindowStartupLocation="CenterScreen" FontSize="14 px" FontFamily="Fonts/#Tahoma" 
Background="Transparent">

我有一个标题和系统按钮的网格,并希望通过右键单击显示应用程序菜单。目前仅通过按ALT +空格键显示应用程序菜单。 我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

所以,在Google上花了两个小时后,我终于找到了解决方案。

Step1:像这样定义RECT结构:

 [StructLayout(LayoutKind.Sequential)]
 public struct RECT
     {
          public int Left;
          public int Top;
          public int Right;
          public int Bottom;
     }

Step2:导入两个user32.dll函数:

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

[DllImport("user32.dll")]
public static extern int TrackPopupMenu(int hMenu, int wFlags, int x, int y, int nReserved, int hwnd, ref RECT lprc);

步骤3:添加'鼠标右键单击标题'事件处理程序:

private void headerArea_PreviewMouseDown(object sender, MouseButtonEventArgs e)
       {               
          switch (e.ChangedButton)
            {
              case MouseButton.Right:
                   {
                      // need to get handle of window
                      WindowInteropHelper _helper = new WindowInteropHelper(this);

                      //translate mouse cursor porition to screen coordinates
                      Point p = PointToScreen(e.GetPosition(this));

                      //get handler of system menu
                      IntPtr systemMenuHandle = GetSystemMenu(_helper.Handle, false);

                      RECT rect = new RECT();
                      // and calling application menu at mouse position.
                      int menuItem = TrackPopupMenu(systemMenuHandle.ToInt32(), 1,(int)p.X, (int) p.Y, 0, _helper.Handle.ToInt32(), ref rect);
                      break;
                   }                   
             }   
       }

答案 1 :(得分:0)

我必须按如下方式更改Raeno的代码才能使菜单项正常工作......

//Get the hWnd, because I need to re-use it...
int hWnd = helper.Handle.ToInt32();
//Change the wFlags from 1 to TPM_RIGHTBUTTON | TPM_RETURNCMD...
int menuItem = TrackPopupMenu(systemMenuHandle.ToInt32(), TPM_RIGHTBUTTON | TPM_RETURNCMD, (int)point.X, (int)point.Y, 0, hWnd, ref rect);

// The return value from TrackPopupMenu now need posting...
if (menuItem != 0)
{
    PostMessage(hWnd, WM_SYSCOMMAND, menuItem, 0);
}

这需要以下声明......

private const int WM_SYSCOMMAND = 0x0112;
private const int TPM_RIGHTBUTTON = 0x0002;
private const int TPM_RETURNCMD = 0x0100;

[DllImport("User32.dll")]
public static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam);