我正在尝试在应用程序中自动化进程。手动执行此过程的Spy ++表示形式如下:
WINDOW 002F0B08
002F0B08 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPOS:# ypos:# (Start Pos)
002F0B08 P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPOS:# ypos:#
...
002F0B08 P WM_LBUTTONUP fwKeys:MK_LBUTTON xPOS:# ypos:# (Final Pos)
WINDOW 007406BC
007406BC P WM_KEYDOWN fwKeys:VK_CONTROL ...
007406BC P WM_KEYDOWN fwKeys:VK_C ...
007406BC P WM_KEYUP fwKeys:VK_CONTROL ...
007406BC P WM_KEYUP fwKeys:VK_C ...
目标是选择一个区域并将区域复制到剪贴板。我可以使用PostMessage执行第一部分:
PostMessage(PanelHandle, WM_LBUTTONDOWN, (int)MK_LBUTTON, new IntPtr(lParam)); //send left mouse button down
这反映在Spy ++ Message Window中,但由于某种原因,当我手动执行时,它不适用于反映CTRL + C的窗口。
整个代码是:
class MouseControl
{
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
static extern void mouse_event(MouseEventFlags flags, uint dx, uint dy, uint delta, IntPtr extraInfo);
public static void Select(AutomationElement window)
{
AutomationElement main = null;
AutomationElement panel = window.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "2"));
main = window.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Session A - [24 x 80]"));
Console.WriteLine("Got Panel: {0} , {1}", panel.ToString(), (new IntPtr(panel.Current.NativeWindowHandle)).ToString());
Console.WriteLine("Got Main: {0} , {1}", main.ToString(), (new IntPtr(main.Current.NativeWindowHandle)).ToString());
if (main == null)
Console.WriteLine("Could not find main");
// GET REF POINT IN WINDOW
System.Windows.Point p = panel.GetClickablePoint();
// LeftMouseDown();
// LeftMouseUp();
double new_X = p.X-400;
double new_Y = p.Y-800;
const uint WM_LBUTTONDOWN = 0x0201;
const uint WM_LBUTTONUP = 0x0202;
const uint MK_LBUTTON = 0x1;
const uint WM_MOUSEMOVE = 0x0200;
const uint WM_KEYDOWN = 0x100;
const uint WM_KEYUP = 0x101;
const uint VK_C = 0x043;
const uint VK_CONTROL = 0x011;
IntPtr PanelHandle = new IntPtr(panel.Current.NativeWindowHandle);
IntPtr WindowHandle = new IntPtr(main.Current.NativeWindowHandle);
Console.WriteLine("Press Return To Start");
Console.ReadLine();
//LeftMouseDown();
int lParam = (((int)new_Y << 16) | ((int)new_X & 0xffff));
PostMessage(PanelHandle, WM_LBUTTONDOWN, (int)MK_LBUTTON, new IntPtr(lParam));//send left mouse button down
Console.WriteLine("Tried");
while (new_X < p.X + 100)
{
lParam = (((int)new_X << 16) | ((int)new_Y & 0xffff));
PostMessage(PanelHandle, WM_MOUSEMOVE, (int)MK_LBUTTON, new IntPtr(lParam));//send left mouse button down
new_X += 1;
new_Y += 1;
}
PostMessage(PanelHandle, WM_LBUTTONUP, (int)MK_LBUTTON, new IntPtr(lParam));//send left mouse button down
Console.WriteLine("WM_LBUTTONUP, MK_LBUTTON, {1} was sent to {0}", PanelHandle, lParam);
PostMessage(WindowHandle, WM_KEYDOWN, (int)VK_CONTROL, IntPtr.Zero);
Console.WriteLine("WM_KEYDOWN, VK_CONTROL was sent to {0}", WindowHandle);
PostMessage(WindowHandle, WM_KEYDOWN, (int)VK_C, IntPtr.Zero);
Console.WriteLine("WM_KEYDOWN, VK_C was sent to {0}", WindowHandle);
PostMessage(WindowHandle, WM_KEYUP, (int)VK_CONTROL, IntPtr.Zero);
Console.WriteLine("WM_KEYUP, VK_CONTROL was sent to {0}", WindowHandle);
PostMessage(WindowHandle, WM_KEYUP, (int)VK_C, IntPtr.Zero);
Console.WriteLine("WM_KEYUP, VK_C was sent to {0}", WindowHandle);
}
}
控制台显示:
获得Panel:...,3083016(在Spy ++中显示的句柄:002F0B08
得到主要:...,0(在间谍++中显示的句柄:007406BC
按返回开始
尝试
WM_LBUTTONUP,MK_LBUTTON,61538539已发送至3213992
WM_KEYDOWN,VK_CONTROL被发送到0
WM_KEYDOWN,VK_C被发送到0
WM_KEYUP,VK_CONTROL被发送到0
WM_KEYUP,VK_C被发送到0
成功选择了该区域但无法复制该区域。 CTRL + C消息未发送到执行复制功能的窗口。
编辑:我设法通过使用以下方法从Spy ++手动检索句柄来使其工作(不是所希望的,但现在很好)
var hwnd = new IntPtr(Convert.ToInt32(Console.ReadLine(), 16));
IntPtr WindowHandle = hwnd;
然而,它不执行副本。这是Spy ++的手册副本:
<00271> 00390640 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00368> 00390640 P WM_KEYDOWN nVirtKey:'C' cRepeat:1 ScanCode:2E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00375> 00390640 P WM_KEYUP nVirtKey:'C' cRepeat:1 ScanCode:2E fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00376> 00390640 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1
这就是我的计划所做的:
<00013> 00390640 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00014> 00390640 P WM_KEYDOWN nVirtKey:'C' cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00015> 00390640 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00016> 00390640 P WM_KEYUP nVirtKey:'C' cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
关于为什么这不起作用的任何想法?
答案 0 :(得分:2)
这里有些不对劲。
NativeWindowHandle
通常可以为0。由于所有无窗口控件都必须托管在某些窗口中(即使它是顶级窗口),Spy ++将始终显示消息将进入的(主机)窗口。如果您确实需要NativeWindowHandle
,则可以走自动化父链,直到找到不为NULL的NativeWindowHandle
。