Imr*_*arr 4 c# winapi automation menu
我试图点击一个名为Media Subtitler的程序中的菜单项,无论我想做什么都不行.
首先,我尝试使用GetMenu函数,但它返回了IntPtr.Zero.然后,我尝试使用ALT键+使用我的菜单的第一个字母(F代表文件),但它没有做任何事情.然后,我尝试使用一个简单的MOUSEDOWN和MOUSEUP消息,但同样,它没有做任何事情(我也尝试创建一个循环,点击该范围内的所有内容,但该区域没有点击).
我清楚知道的是,我正在研究正确的窗口.
我究竟做错了什么?
如果有人想测试它,你可以免费下载Media Subtitler,它不会那么重.
另外,这是我一直在测试的代码:
Process p = Process.Start(@"C:\Program Files\DivXLand\Media Subtitler\MediaSub.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);
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助!
通过监视发送到应用程序主窗口的消息,我提取了菜单项的菜单标识符.您可以将WM_COMMAND消息发布到窗口,其中菜单项的ID为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
...
Run Code Online (Sandbox Code Playgroud)
我用Media Subtitler测试了代码,它就像一个魅力!唯一不会起作用的情况是,在Windows Vista或Seven上,你的目标程序是以管理员身份运行而你的C#程序不是.请注意这一点!
通过监视WM_COMMAND消息(使用Spy ++)可以轻松检查菜单ID .
您也可以使用SendMessage而不是PostMessage,但程序冻结,直到用户关闭菜单操作打开的窗口.
您可以使用相同的方法将其他命令发送到应用程序的其他窗口.例如,单击"打开视频"窗口的"打开"按钮.
小智 5
您还可以使用System.Windows.Automation命名空间完成所有这些操作:http : //msdn.microsoft.com/zh-cn/library/ms590934.aspx
使用此命名空间,您无需与Win32 API进行任何互操作。这是一个如何通过搜索名称包含的字符串来获取窗口的示例:
public static AutomationElement GetWindowByName(string name)
{
AutomationElement root = AutomationElement.RootElement;
foreach (AutomationElement window in root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window)))
{
if (window.Current.Name.Contains(name) && window.Current.IsKeyboardFocusable)
{
return window;
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
将窗口作为AutomationElement对象之后,可以在窗口中搜索控件并在这些控件上执行操作,等等。
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
7725 次 |
| 最近记录: |