Как вызвать меню приложения программно? - PullRequest
2 голосов
/ 17 февраля 2010

У меня непрямоугольное прозрачное окно с нестандартным стилем.

<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 ]

3 голосов
/ 17 февраля 2010

Итак, после двух часов, проведенных в Google, я наконец нашел решение.

Шаг 1: определить структуру 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;
                   }                   
             }   
       }
0 голосов
/ 28 мая 2011

Мне пришлось изменить код Раено следующим образом, чтобы заставить пункты меню работать ...

//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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...