Hook up click event after AppendMenu of 3rd party Application
我正在尝试使用从DLLImort导入的user32.dll的DLL Fucntions向我的WPF应用程序之外的第三方应用程序添加新的MenuItem。
否,我不想获取新生成的MenuItem的click事件。有任何想法吗?
到目前为止,这是代码。我知道有SetWindowHookEx或其他功能,但是我被卡住了。
这是一些测试代码,没有防弹..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | public partial class MainWindow : Window { [DllImport("user32.dll")] private static extern IntPtr GetMenu(IntPtr hWnd); [DllImport("user32.dll")] private static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos); [DllImport("user32.dll")] private static extern int GetMenuItemCount(IntPtr hMenu); [DllImport("user32.dll")] private static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition, [In] ref MENUITEMINFO lpmii); [DllImport("user32.dll")] private static extern bool DrawMenuBar(IntPtr hWnd); internal const UInt32 MIIM_FTYPE = 0x00000100; internal const UInt32 MF_STRING = 0x00000000; internal const UInt32 MF_OWNERDRAW = 0x00000100; const uint MF_POPUP = 0x00000010; [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern bool AppendMenu(IntPtr hMenu, MenuFlags uFlags, uint uIDNewItem, string lpNewItem); [DllImport("user32.dll")] static extern IntPtr CreatePopupMenu(); [Flags] public enum MenuFlags : uint { MF_STRING = 0, MF_BYPOSITION = 0x400, MF_SEPARATOR = 0x800, MF_REMOVE = 0x1000, MF_POPUP = 0x00000010, } [StructLayout(LayoutKind.Sequential)] struct MENUITEMINFO { public uint cbSize; public uint fMask; public uint fType; public uint fState; public uint wID; public IntPtr hSubMenu; public IntPtr hbmpChecked; public IntPtr hbmpUnchecked; public IntPtr dwItemData; public string dwTypeData; public uint cch; public IntPtr hbmpItem; // return the size of the structure public static uint sizeOf { get { return (uint)Marshal.SizeOf(typeof(MENUITEMINFO)); } } } public MainWindow() { InitializeComponent(); Loaded += OnLoaded; } private void OnLoaded(object sender, RoutedEventArgs e) { createMenuEntry(); } private void createMenuEntry() { Process[] proceses = Process.GetProcessesByName("spotify"); Process process = proceses.Where(e => e.MainWindowTitle =="Spotify").First(); IntPtr handle = process.MainWindowHandle; IntPtr mainMenu = GetMenu(handle); int mainMenuItemCount = GetMenuItemCount(mainMenu); AppendMenu(mainMenu, MenuFlags.MF_STRING, 555,"TestEntry"); } protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); //HwndSource source = PresentationSource.FromVisual(this) as HwndSource; //source.AddHook(WndProc); } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { // Handle messages... Debug.WriteLine((int)wParam); if (((int)wParam == 555)) { MessageBox.Show("Click"); } return IntPtr.Zero; } } |
感谢您的任何想法或建议。
您的第一步是放下C#并了解本机菜单API的工作方式。从这里开始:https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms647553.aspx
我强烈建议您创建一个新的C项目并编写一个简单的程序来添加菜单并响应单击。
关键信息可在我链接的文档中找到,重点是:
When the user chooses a command item, the system sends a command message to the window that owns the menu. If the command item is on the window menu, the system sends the WM_SYSCOMMAND message. Otherwise, it sends the WM_COMMAND message.
您需要拦截该消息。我怀疑这意味着需要使用全局