Добавить в меню приложения правой кнопкой мыши на панели задач в .NET

В большинстве приложений есть только «Восстановить, Переместить, Размер, Свернуть, Развернуть и Закрыть», однако MS SQL предлагает дополнительные параметры «Справка, Настроить вид». Можно ли добавить в контекстное меню приложения на панели задач?

Примечание. Я нет имею в виду значок в области уведомлений рядом с часами.

Я не могу вам помочь напрямую, но меню, о котором вы говорите, - это системное меню. Это то же самое, что отображается при нажатии на значок приложения в строке заголовка окна. Может быть, это поможет вам или другим найти ответ :)

OregonGhost 30.09.2008 19:07
эта статья gives you a walk through in C#!
Mitchel Sellers 30.09.2008 19:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
2
5 601
2

Ответы 2

Я нашел более простой отвечать. Я быстро протестировал его, и он работает.

Мой код:

    private const int WMTaskbarRClick = 0x0313;

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WMTaskbarRClick:
                {
                    // Show your own context menu here, i do it like this
                    // there's a context menu present on my main form so i use it

                    MessageBox.Show("I see that.");

                    break;
                }
            default:
                {
                    base.WndProc(ref m);
                    break;
                }
        }
    }

Но это не будет интегрировано с существующим меню, если вы просто покажете свое меню.

Mitchel Sellers 30.09.2008 19:32

Кажется, это работает только при удерживании клавиши SHIFT при щелчке правой кнопкой мыши

farosch 23.09.2019 02:49

Меню при щелчке правой кнопкой мыши свернутой программы, Alt + Пробел или щелчком правой кнопкой мыши значка окна в строке заголовка называется SysMenu.

Вот вариант для WPF:

// License MIT 2019 Mitch Gaffigan
// https://stackoverflow.com/a/58160366/138200
public class SysMenu
{
    private readonly Window Window;
    private readonly List<MenuItem> Items;
    private bool isInitialized;
    private IntPtr NextID = (IntPtr)1000;
    private int StartPosition = 5;

    public SysMenu(Window window)
    {
        this.Items = new List<MenuItem>();
        this.Window = window ?? throw new ArgumentNullException(nameof(window));
        this.Window.SourceInitialized += this.Window_SourceInitialized;
    }

    class MenuItem
    {
        public IntPtr ID;
        public string Text;
        public Action OnClick;
    }

    public void AddSysMenuItem(string text, Action onClick)
    {
        if (string.IsNullOrWhiteSpace(text))
        {
            throw new ArgumentNullException(nameof(text));
        }
        if (onClick == null)
        {
            throw new ArgumentNullException(nameof(onClick));
        }

        var thisId = NextID;
        NextID += 1;

        var newItem = new MenuItem()
        {
            ID = thisId,
            Text = text,
            OnClick = onClick
        };
        Items.Add(newItem);
        var thisPosition = StartPosition + Items.Count;

        if (isInitialized)
        {
            var hwndSource = PresentationSource.FromVisual(Window) as HwndSource;
            if (hwndSource == null)
            {
                return;
            }
            var hSysMenu = GetSystemMenu(hwndSource.Handle, false);
            InsertMenu(hSysMenu, thisPosition, MF_BYPOSITION, thisId, text);
        }
    }

    private void Window_SourceInitialized(object sender, EventArgs e)
    {
        var hwndSource = PresentationSource.FromVisual(Window) as HwndSource;
        if (hwndSource == null)
        {
            return;
        }

        hwndSource.AddHook(WndProc);

        var hSysMenu = GetSystemMenu(hwndSource.Handle, false);

        /// Create our new System Menu items just before the Close menu item
        InsertMenu(hSysMenu, StartPosition, MF_BYPOSITION | MF_SEPARATOR, IntPtr.Zero, string.Empty);
        int pos = StartPosition + 1;
        foreach (var item in Items)
        {
            InsertMenu(hSysMenu, pos, MF_BYPOSITION, item.ID, item.Text);
            pos += 1;
        }

        isInitialized = true;
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_SYSCOMMAND)
        {
            var item = Items.FirstOrDefault(d => d.ID == wParam);
            if (item != null)
            {
                item.OnClick();
                handled = true;
                return IntPtr.Zero;
            }
        }

        return IntPtr.Zero;
    }

    #region Win32

    private const Int32 WM_SYSCOMMAND = 0x112;
    private const Int32 MF_SEPARATOR = 0x800;
    private const Int32 MF_BYPOSITION = 0x400;
    private const Int32 MF_STRING = 0x0;

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

    [DllImport("user32.dll")]
    private static extern bool InsertMenu(IntPtr hMenu, int wPosition, int wFlags, IntPtr wIDNewItem, string lpNewItem);

    #endregion
}

Пример использования:

internal partial class MainWindow : Window
{
    public MainWindow()
    {
        var sysMenu = new SysMenu(this);
        sysMenu.AddSysMenuItem("Quit", miQuit_Click);
        sysMenu.AddSysMenuItem("Show debug tools", miShowDebug_Click);
    }

    private void miQuit_Click()
    {
        // "On-Click" logic here
    }

    private void miShowDebug_Click()
    {
        // "On-Click" logic here
    }
}

Другие вопросы по теме