C# WinAPI 单击菜单项 [英] C# WinAPI Clicking on menu items
问题描述
我试图点击名为 Media Subtitler 的程序中的菜单项,但无论我尝试做什么,它都不起作用.
I'm trying to click on a menu item inside a program called Media Subtitler and whatever I'm trying to do it's not working.
首先,我尝试使用函数 GetMenu 但它返回 IntPtr.Zero.然后,我尝试使用 ALT 键 + 使用菜单的第一个字母(F 代表文件),但它什么也没做.然后,我尝试使用简单的 MOUSEDOWN 和 MOUSEUP 消息,但同样,它什么也没做(我还尝试创建一个循环,点击该范围内的所有内容,但没有点击该区域).
First, I tried to use the function GetMenu but it returned IntPtr.Zero. Then, I tried using the ALT key + using the first letter of my menu (F stands for file) but it did nothing. Then, I tried using a simple MOUSEDOWN and MOUSEUP messages but again, it did nothing (I also tried creating a loop that clicks on everything in that range but there was no click in that area).
我清楚地知道我在正确的窗口上工作.
What I clearly know is that I'm working on the correct window.
我做错了什么?
如果有人想测试一下,您可以免费下载 Media Subtitler,它的重量并不大.
If someone wants to test it out you can download Media Subtitler for free and it doesn't weight that much.
另外,这是我一直在测试的代码:
Also, Here's the code I've been testing:
Process p = Process.Start(@"C:Program FilesDivXLandMedia SubtitlerMediaSub.exe");
p.WaitForInputIdle(1500);
Thread.Sleep(3000);
SetForegroundWindow(p.MainWindowHandle);
ShowWindow(p.MainWindowHandle, SW_MAXIMIZE);
IntPtr handle = p.MainWindowHandle;
SendMessage(handle, WM_NCHITTEST, 0, MakeLParam(18, 29));
//for (int i = 0; i < 200; i++)
//{
// for (int x = 0; x < 200; x++)
// {
// SendMessage(p.MainWindowHandle, WM_LBUTTONDOWN, 0, MakeLParam(i, x));
// SendMessage(p.MainWindowHandle, WM_LBUTTONUP, 0, MakeLParam(i, x));
// }
//}
//IntPtr menuItems = GetMenu(p.MainWindowHandle);
return;
//SendMessage(p.MainWindowHandle, WM_COMMAND, 6, 0);
SendMessage(p.MainWindowHandle, WM_KEYDOWN, VK_MENU, 0);
SendMessage(p.MainWindowHandle, WM_KEYUP, VK_MENU, 0);
SendMessage(p.MainWindowHandle, WM_KEYDOWN, VK_F, 0);
SendMessage(p.MainWindowHandle, WM_KEYUP, VK_F, 0);
感谢您的帮助!
推荐答案
通过监视发送到应用程序主窗口的消息,我提取了菜单项的菜单标识符.您可以将 WM_COMMAND
消息发送到窗口,菜单项的 ID 为 wParam
:
By monitoring the messages sent to the main window of the application, I extracted the menu identifiers for the menu items. You can post WM_COMMAND
message to the window, with the ID of the menu items as the wParam
:
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, Message msg, int wParam, int lParam);
PostMessage(handle, WM_COMMAND, 2, 0); // File->New subtitle
PostMessage(handle, WM_COMMAND, 3, 0); // File->New from clipboard
PostMessage(handle, WM_COMMAND, 5, 0); // File->Open text or subtitle
PostMessage(handle, WM_COMMAND, 6, 0); // File->Open video
...
我已经使用 Media Subtitler 测试了代码,它的效果非常棒!这将不起作用的唯一情况是,在 Windows Vista 或 7 上,您的目标程序以管理员身份运行,而您的 C# 程序则不是.请注意这一点!
I've tested the code with Media Subtitler, and it works like a charm! The only situation that this will not work, is when on windows Vista or Seven, your target program is running as Administrator and you C# program is not. Be aware of that!
可以通过监视 WM_COMMAND
消息(使用 Spy++)轻松检查菜单 ID.
您也可以使用 SendMessage
而不是 PostMessage
,但是您的程序会冻结,直到用户关闭由菜单操作打开的窗口.
The menu IDs can be easily examined by monitoring the WM_COMMAND
message (using Spy++).
You can also use SendMessage
instead of PostMessage
, but then your program freezes until the user closes the window opened by the menu action.
您可以使用相同的方法向应用程序的其他窗口发送其他命令.例如,点击打开视频"窗口的打开"按钮.
You can use the same approach to send other command to other windows of the application. For example, clicking the 'Open' button of the 'Open video' window.
这篇关于C# WinAPI 单击菜单项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!