mateusz_lozo Ответов: 1

Как изменить/отредактировать пункты меню/подменю Во внешнем приложении


Я пытаюсь создать приложение, которое будет редактировать пункт меню (с элементом подменю) Во внешнем приложении. В настоящее время я провожу тесты на блокноте.

НВФ[^]

Что я уже пробовал:

Комментируемая часть кода, к сожалению, не работает...
<pre>using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ChangeMenu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        public static extern IntPtr GetMenu(IntPtr hWnd);

        [DllImport("user32.dll")]
        public static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);

        [DllImport("user32.dll")]
        public static extern int GetMenuItemCount(IntPtr hMenu);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

        [DllImport("user32.dll")]
        public static extern bool DrawMenuBar(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam);

        private const int WM_GETTEXT = 0x000D;
        private const int WM_SETTEXT = 0x000C;

        private void Button1_Click(object sender, EventArgs e)
        {
            foreach (Process proc in Process.GetProcesses())
            {
                if (proc.ProcessName.ToLower() == "notepad")
                {
                    var HMENU = GetMenu(proc.MainWindowHandle);
                    var count = GetMenuItemCount(HMENU);

                    //somehow change menu text
                    //var menu = FindWindowEx(HMENU, IntPtr.Zero, "File", null);
                    //SendMessage(menu, WM_SETTEXT, IntPtr.Zero, "New text1");

                    while (count > 0)
                    {
                        var HsubMENU = GetSubMenu(proc.MainWindowHandle, count);

                        //somehow change submenu text
                        //var submenu = FindWindowEx(HMENU, IntPtr.Zero, "Page Setup...", null);
                        //SendMessage(submenu, WM_SETTEXT, IntPtr.Zero, "New text2");

                        count--;
                    }

                    DrawMenuBar(proc.MainWindowHandle);
                    break;
                }
            }
        }
    }
}

Maciej Los

Почему? Есть ли какая-то причина для изменения меню во внешнем приложении?

mateusz_lozo

да, я готовлю перевод программы на другой язык - потому что в нынешнем виде она не полезна многим пользователям (автор программы разрешил мне сделать такую модификацию).

mateusz_lozo

Эй, Мацей Лос, ты можешь мне помочь? Я вижу, что вы очень опытный программист, пожалуйста, направьте меня, как этого достичь ...

Maciej Los

Прости, но я не могу.

1 Ответов

Рейтинг:
9

johannesnestler

Привет, матеуш_лозо,

Вашему вопросу уже почти два месяца. Не знаю, интересует ли это вас еще, но я знаю, как это сделать.

Вам нужно использовать функции ModifyMenu и GetMenuItemID Windows-API и вызывать их для каждого взаимодействия.

Здесь у вас есть пример, который показывает, как изменить меню notpads file:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ConsoleApp6
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern IntPtr GetMenu(IntPtr hWnd);

        [DllImport("user32.dll")]
        public static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);

        [DllImport("user32.dll")]
        public static extern int GetMenuItemCount(IntPtr hMenu);

        [DllImport("user32.dll")]
        static extern bool ModifyMenu(IntPtr hMnu, uint uPosition, uint uFlags,   IntPtr uIDNewItem, string lpNewItem);

        [DllImport("user32.dll")]
        static extern uint GetMenuItemID(IntPtr hMenu, int nPos);

        const uint MF_BYPOSITION = 0x00000400;

        static void ChangeText()
        {
            foreach (Process proc in Process.GetProcesses())
            {
                if (proc.ProcessName.ToLower() == "notepad")
                {
                    // Get the main menu handle of notepad
                    var hwndMenuMain = GetMenu(proc.MainWindowHandle);
                    // Get the file menu handle 
                    var hwndMenuFile = GetSubMenu(hwndMenuMain, 0);
                    uint menuItemIDFile = GetMenuItemID(hwndMenuFile, 0);

                    //change menu text
                    ModifyMenu(hwndMenuMain, 0, MF_BYPOSITION, (IntPtr)menuItemIDFile, "Test");

                    // Change sub-menus of file menu
                    var count = GetMenuItemCount(hwndMenuFile);
                    for (int i = 0; i < count; i++)
                    {
                        uint menuItemIDSub = GetMenuItemID(hwndMenuFile, i);

                        ModifyMenu(hwndMenuFile, (uint) i, MF_BYPOSITION, (IntPtr)menuItemIDSub, "SubMenu" + i);                        
                    }

                    break;
                }
            }
        }

        static void Main(string[] args)
        {
            ChangeText();
            Console.ReadKey();
        }
    }
}



Наслаждайтесь!

Иоганнес


mateusz_lozo

Большое вам спасибо, мне это было очень полезно!