private void AppbarQueryPos(ref NM.tagRect appRect) { float ScreenScalingFactor; using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { IntPtr desktop = g.GetHdc(); int LogicalScreenHeight = NM.GetDeviceCaps(desktop, NM.DeviceCap.VERTRES); int PhysicalScreenHeight = NM.GetDeviceCaps(desktop, NM.DeviceCap.DESKTOPVERTRES); g.ReleaseHdc(); ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight; } // prepare data structure of message NM.APPBARDATA msgData = new NM.APPBARDATA(); msgData.cbSize = (UInt32)Marshal.SizeOf(msgData); msgData.hWnd = Handle; msgData.uEdge = (UInt32)m_Edge; msgData.rc = appRect; // query postion for the appbar msgData.rc.left = (int)(Math.Round((float)msgData.rc.left * ScreenScalingFactor)); msgData.rc.right = (int)(Math.Round((float)msgData.rc.right * ScreenScalingFactor)); msgData.rc.top = (int)(Math.Round((float)msgData.rc.top * ScreenScalingFactor)); msgData.rc.bottom = (int)(Math.Round((float)msgData.rc.bottom * ScreenScalingFactor)); NM.SHAppBarMessage(NM.AppBarMessages.QueryPos, ref msgData); msgData.rc.left = (int)(Math.Round((float)msgData.rc.left / ScreenScalingFactor)); msgData.rc.right = (int)(Math.Round((float)msgData.rc.right / ScreenScalingFactor)); msgData.rc.top = (int)(Math.Round((float)msgData.rc.top / ScreenScalingFactor)); msgData.rc.bottom = (int)(Math.Round((float)msgData.rc.bottom / ScreenScalingFactor)); appRect = msgData.rc; }
private void ClearHighlight(NM.tagRect area) { NM.tagRect tmpArea = new NM.tagRect(); tmpArea.left = area.left - 3; tmpArea.top = area.top - 3; tmpArea.right = area.right + 3; tmpArea.bottom = area.bottom + 3; NM.RedrawWindow(IntPtr.Zero, ref tmpArea, IntPtr.Zero, NM.RedrawWindowFlags.UpdateNow | NM.RedrawWindowFlags.Invalidate | NM.RedrawWindowFlags.AllChildren); Thread.Sleep(50); }
private void LocateButton_Click(object sender, EventArgs e) { if (WindowTree.SelectedNode != null) { string[] SplitCharacters = { ":" }; string[] Handles = WindowTree.SelectedNode.Name.Split(SplitCharacters, StringSplitOptions.None); IntPtr ParentHandle = new IntPtr(int.Parse(Handles[0])); IntPtr Handle = new IntPtr(int.Parse(Handles[1])); if (NM.IsWindow(Handle) && NM.IsWindowVisible(Handle)) { if (ParentHandle == IntPtr.Zero) { NM.BringWindowToTop(Handle); } else { NM.BringWindowToTop(ParentHandle); } NM.tagRect area = Display.GetWindowRectangleDIP(Handle); IntPtr hWindowDC = NM.GetDC(IntPtr.Zero); IntPtr hRectanglePen = NM.CreatePen(NM.PenStyle.PS_SOLID, 3, (uint)ColorTranslator.ToWin32(Color.Red)); IntPtr hPrevPen = NM.SelectObject(hWindowDC, hRectanglePen); IntPtr hPrevBrush = NM.SelectObject(hWindowDC, NM.GetStockObject(NM.StockObjects.HOLLOW_BRUSH)); for (int i = 0; i < 3; i++) { NM.Rectangle(hWindowDC, area.left, area.top, area.right, area.bottom); Thread.Sleep(300); ClearHighlight(area); if (i < 2) { Thread.Sleep(300); } } NM.SelectObject(hWindowDC, hPrevPen); NM.SelectObject(hWindowDC, hPrevBrush); NM.ReleaseDC(Handle, hWindowDC); } else { BuildTree(); } } WindowTree.Focus(); }
private void Highlight(IntPtr hWnd) { m_Area = Display.GetWindowRectangleDIP(hWnd); IntPtr hWindowDC = NM.GetDC(IntPtr.Zero); IntPtr hRectanglePen = NM.CreatePen(NM.PenStyle.PS_SOLID, 3, (uint)ColorTranslator.ToWin32(Color.Red)); IntPtr hPrevPen = NM.SelectObject(hWindowDC, hRectanglePen); IntPtr hPrevBrush = NM.SelectObject(hWindowDC, NM.GetStockObject(NM.StockObjects.HOLLOW_BRUSH)); NM.Rectangle(hWindowDC, m_Area.left, m_Area.top, m_Area.right, m_Area.bottom); NM.SelectObject(hWindowDC, hPrevPen); NM.SelectObject(hWindowDC, hPrevBrush); NM.ReleaseDC(Handle, hWindowDC); }
private Rectangle GetItemRectangle(int itemIndex) { IntPtr sendResult; IntPtr messageResult; NM.tagRect rectangle = new NM.tagRect(); //Get the rectangle of the item sendResult = NM.SendMessageTimeout(Identity.Handle, NM.ListBoxMessages.LB_GETITEMRECT, new IntPtr(itemIndex), ref rectangle, NM.SendMessageTimeoutFlags.SMTO_NORMAL, GUI.m_APE.TimeOut, out messageResult); if (sendResult == IntPtr.Zero || messageResult.ToInt64() == NM.LB_ERR) //Failed { throw GUI.ApeException("Failed to get the rectangle of the " + Description); } return(new Rectangle(rectangle.left, rectangle.top, (rectangle.right - rectangle.left), (rectangle.bottom - rectangle.top))); }
private Rectangle GetItemRectangle(IntPtr listBox, int itemIndex) { IntPtr messageResult; IntPtr sendResult; NM.tagRect itemRect = new NM.tagRect(); //Locate the rect of the item sendResult = NM.SendMessageTimeout(listBox, NM.ListBoxMessages.LB_GETITEMRECT, new IntPtr(itemIndex), ref itemRect, NM.SendMessageTimeoutFlags.SMTO_NORMAL, GUI.m_APE.TimeOut, out messageResult); if (sendResult == IntPtr.Zero || unchecked ((int)messageResult.ToInt64()) == NM.LB_ERR) //Failed { if (sendResult == IntPtr.Zero) { throw GUI.ApeException("Failed to access the " + Description + " to locate the rectangle containing the item"); } else { throw GUI.ApeException("Failed to locate the rectangle containing the item in the " + Description); } } return(new Rectangle(itemRect.left, itemRect.top, itemRect.right - itemRect.left, itemRect.bottom - itemRect.top)); }
private void SizeAppBar() { NM.tagRect rt = new NM.tagRect(); // Set the rect to where we would like to place the AppBar rt.right = SystemInformation.PrimaryMonitorSize.Width; rt.left = 0; if (m_Edge == AppBarEdges.Top) { rt.bottom = this.Size.Height; rt.top = 0; } else { rt.bottom = SystemInformation.PrimaryMonitorSize.Height; rt.top = rt.bottom - this.Size.Height; } // Query to see if there are any other AppBars in the way AppbarQueryPos(ref rt); //If our position clashes with another AppBar then then adjust our position if (m_Edge == AppBarEdges.Top) { rt.bottom = rt.top + this.Size.Height; } else { rt.top = rt.bottom - this.Size.Height; } AppbarSetPos(ref rt); this.Location = new Point(rt.left, rt.top); this.Size = new Size(rt.right - rt.left, rt.bottom - rt.top); }
internal void WaitForAnimation(IntPtr Handle, bool ClearClientArea, WaitForAnimationSource Source) { if (Source == WaitForAnimationSource.Form) { if (GUI.FormAnimationDisabled) { return; } } Stopwatch timer = Stopwatch.StartNew(); do { if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw new Exception("Window is not visible"); } Thread.Sleep(15); }while (NM.IsWindowVisible(Handle) == false); NM.tagRect theRect = Display.GetWindowRectangleDIP(Handle); int Width; //if (theRect.Right - theRect.Left > 50) //{ // Width = 50; //} //else //{ Width = theRect.right - theRect.left; //} int Height; //if (theRect.Bottom - theRect.Top > 50) //{ // Height = 50; //} //else //{ Height = theRect.bottom - theRect.top; //} Bitmap A = new Bitmap(Width, Height, PixelFormat.Format24bppRgb); Bitmap B = new Bitmap(Width, Height, PixelFormat.Format24bppRgb); int SameCount = 0; int i = 0; int Loops = 0; //Debug.WriteLine("till bitmap loop " + timer.ElapsedMilliseconds.ToString()); do { Loops++; if (i == 0) { Display.GetWindowBitmap(Handle, theRect.left, theRect.top, ref A, false, ClearClientArea); //A.Save(@"c:\temp\" + y.ToString() + ".png"); //A.Save(@"c:\temp\a.png"); i++; } else { Display.GetWindowBitmap(Handle, theRect.left, theRect.top, ref B, false, ClearClientArea); //B.Save(@"c:\temp\" + y.ToString() + ".png"); //B.Save(@"c:\temp\b.png"); i--; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { timer.Stop(); throw new Exception("Failed to detect window finishing animation"); } if (Display.CompareBitmap(A, B)) { SameCount++; //Debug.WriteLine("same " + SameCount.ToString() + " " + timer.ElapsedMilliseconds.ToString()); } else { SameCount = 0; //Debug.WriteLine("reset " + timer.ElapsedMilliseconds.ToString()); } //Thread.Sleep(15); }while (SameCount < 2 || Loops < 9); timer.Stop(); //Debug.Listeners[0].WriteLine("\t Loops: " + Loops.ToString() + " Time: " + timer.ElapsedMilliseconds.ToString()); }
private void CheckNode(IntPtr Node, bool Check) { int position = 0; Stopwatch timer; bool isChecked = false; int left = 0; int top = 0; int right = 0; int bottom = 0; int imageIndex = -1; string imageKey = ""; NM.tagRect clientRect = new NM.tagRect(); // Check for checkbox style if (!m_CheckBoxes) { throw GUI.ApeException("TreeView does not have checkbox style"); } // Check for if its already in the correct state // Get state and bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "Checked", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call isChecked = GUI.m_APE.GetValueFromMessage(); if (isChecked == Check) { return; } // Treeviews have a habbit of scrolling the last selected node back into view so clicking the // Node we want to check to select it is a good idea although not in thoery needed ClickNode(Node, MouseButton.Left); do { // Get state and bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "EnsureVisible", MemberTypes.Method); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store8, "ImageIndex", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store9, "ImageKey", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store8); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store9); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call left = GUI.m_APE.GetValueFromMessage(); top = GUI.m_APE.GetValueFromMessage(); right = GUI.m_APE.GetValueFromMessage(); bottom = GUI.m_APE.GetValueFromMessage(); imageIndex = GUI.m_APE.GetValueFromMessage(); imageKey = GUI.m_APE.GetValueFromMessage(); NM.GetClientRect(Identity.Handle, out clientRect); if (top == 0) { if (bottom > clientRect.bottom) { bottom = clientRect.bottom; } } if (left < 0 || top < 0 || bottom > clientRect.bottom) { // Go round again } else { break; } }while (true); if (right > clientRect.right) { right = clientRect.right; } int imageWidth = 0; if (imageIndex != -1 || imageKey != "") { imageWidth = m_ImageWidth; } int stateImageWidth = m_StateImageWidth; // Scroll the checkbox in to view if need be int x = left - imageWidth - stateImageWidth; if (x != 0) { //get current scroll bar pos position = NM.GetScrollPos(Identity.Handle, NM.SBS_HORZ); //update the pos position = position + x; NM.SetScrollPos(Identity.Handle, NM.SBS_HORZ, position, true); //send the message to move IntPtr MessageResult; IntPtr SendResult = NM.SendMessageTimeout(Handle, NM.WM_HSCROLL, new IntPtr(MakeLParam((int)NM.SB_THUMBPOSITION, position)), IntPtr.Zero, NM.SendMessageTimeoutFlags.SMTO_NORMAL, (uint)GUI.GetTimeOut(), out MessageResult); //update the bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call left = GUI.m_APE.GetValueFromMessage(); top = GUI.m_APE.GetValueFromMessage(); right = GUI.m_APE.GetValueFromMessage(); bottom = GUI.m_APE.GetValueFromMessage(); } base.SingleClickInternal(left - imageWidth - (stateImageWidth / 2), top + ((bottom - top) / 2), MouseButton.Left, MouseKeyModifier.None); // Wait for it to be checked / unchecked bool isNowChecked = !Check; timer = Stopwatch.StartNew(); do { // Get the checked state GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "Checked", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call isNowChecked = GUI.m_APE.GetValueFromMessage(); if (isNowChecked == Check) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw GUI.ApeException("Failed to check / uncheck node"); } Thread.Sleep(15); }while (true); // After clicking sleep for a bit to give time for the treeview to update Thread.Sleep(30); }
private void ClickNode(IntPtr Node, MouseButton Button) { Stopwatch timer; bool IsSelected = false; int Left = 0; int Top = 0; int Right = 0; int Bottom = 0; NM.tagRect ClientRect = new NM.tagRect(); if (Button == MouseButton.Left) { // Get state and bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsSelected", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call IsSelected = GUI.m_APE.GetValueFromMessage(); // If we are left clicking and its already selected don't reselect if (IsSelected) { return; } } timer = Stopwatch.StartNew(); do { // Get state and bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "EnsureVisible", MemberTypes.Method); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call Left = GUI.m_APE.GetValueFromMessage(); Top = GUI.m_APE.GetValueFromMessage(); Right = GUI.m_APE.GetValueFromMessage(); Bottom = GUI.m_APE.GetValueFromMessage(); NM.GetClientRect(Identity.Handle, out ClientRect); if (Top == 0) { if (Bottom > ClientRect.bottom) { Bottom = ClientRect.bottom; } } if (Left < 0 || Top < 0 || Bottom > ClientRect.bottom) { // Go round again } else { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw GUI.ApeException("Failed to select node"); } }while (true); if (Right > ClientRect.right) { Right = ClientRect.right; } if (Button == MouseButton.Left) { // Click it base.SingleClickInternal(Right - 2, Top + ((Bottom - Top) / 2), Button, MouseKeyModifier.None); // Wait for it to be selected bool IsNowSelected = false; timer = Stopwatch.StartNew(); do { // Get if selected GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsSelected", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call IsNowSelected = GUI.m_APE.GetValueFromMessage(); if (IsNowSelected) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw GUI.ApeException("Failed to select node"); } Thread.Sleep(15); }while (true); // After clicking sleep for a bit to give time for the treeview to update Thread.Sleep(30); } else { // Click it base.SingleClickInternal(Right - 2, Top + ((Bottom - Top) / 2), Button, MouseKeyModifier.None); } }
private void ExpandNode(IntPtr Node) { int position = 0; Stopwatch timer; int left = 0; int top = 0; int right = 0; int bottom = 0; int imageIndex = -1; string imageKey = ""; NM.tagRect clientRect = new NM.tagRect(); // check if already expanded GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsExpanded", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call bool isExpanded = GUI.m_APE.GetValueFromMessage(); if (isExpanded) { return; } for (int i = 0; i < 2; i++) { // Get bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "EnsureVisible", MemberTypes.Method); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store8, "ImageIndex", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store9, "ImageKey", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store8); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store9); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call left = GUI.m_APE.GetValueFromMessage(); top = GUI.m_APE.GetValueFromMessage(); right = GUI.m_APE.GetValueFromMessage(); bottom = GUI.m_APE.GetValueFromMessage(); imageIndex = GUI.m_APE.GetValueFromMessage(); imageKey = GUI.m_APE.GetValueFromMessage(); NM.GetClientRect(Identity.Handle, out clientRect); if (left < 0 || top < 0 || bottom > clientRect.bottom) { // Go round again } else { break; } } if (right > clientRect.right) { right = clientRect.right; } bool waitForMove = false; if (bottom > clientRect.bottom) { waitForMove = true; bottom = clientRect.bottom; } // Expand it if (m_ShowPlusMinus) { int stateImageWidth = 0; if (m_CheckBoxes) { stateImageWidth = m_StateImageWidth; } int imageWidth = 0; if (imageIndex != -1 || imageKey != "") { imageWidth = m_ImageWidth; } int expandImageWidth = m_ImageWidth; // Scroll the expand icon in to view if need be int x = left - imageWidth - stateImageWidth - expandImageWidth; if (x != 0) { //get current scroll bar pos position = NM.GetScrollPos(Identity.Handle, NM.SBS_HORZ); //update the pos position = position + x; NM.SetScrollPos(Identity.Handle, NM.SBS_HORZ, position, false); //send the message to move IntPtr MessageResult; IntPtr SendResult = NM.SendMessageTimeout(Handle, NM.WM_HSCROLL, new IntPtr(MakeLParam((int)NM.SB_THUMBPOSITION, position)), IntPtr.Zero, NM.SendMessageTimeoutFlags.SMTO_NORMAL, (uint)GUI.GetTimeOut(), out MessageResult); //update the bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call left = GUI.m_APE.GetValueFromMessage(); top = GUI.m_APE.GetValueFromMessage(); right = GUI.m_APE.GetValueFromMessage(); bottom = GUI.m_APE.GetValueFromMessage(); } base.SingleClickInternal(left - imageWidth - stateImageWidth - (expandImageWidth / 2), top + ((bottom - top) / 2), MouseButton.Left, MouseKeyModifier.None); } else { base.DoubleClickInternal(right - 4, top + ((bottom - top) / 2), MouseButton.Left, MouseKeyModifier.None); } // Wait for it to be expanded bool isNowExpanded = false; timer = Stopwatch.StartNew(); do { // Get if expanded GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsExpanded", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call isNowExpanded = GUI.m_APE.GetValueFromMessage(); if (isNowExpanded) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw GUI.ApeException("Node failed to expand"); } Thread.Sleep(15); }while (true); //left clicking on a node which is partially off the bottom of the window will scroll it if (waitForMove) { timer = Stopwatch.StartNew(); do { // Get bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store2, DataStores.Store3, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store3); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call bottom = GUI.m_APE.GetValueFromMessage(); if (bottom >= clientRect.bottom) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw GUI.ApeException("Node failed to scroll fully into view"); } Thread.Sleep(15); }while (true); } // After clicking sleep for a bit to give time for the treeview to update Thread.Sleep(30); }
/// <summary> /// Selects the specified item in the combobox by clicking on it /// </summary> /// <param name="item">The item to select</param> public void SingleClickItem(string item) { Stopwatch timer; //Check if its already selected if (this.Text == item) { GUI.Log("Ensure " + Identity.Description + " is set to " + item, LogItemType.Action); return; } GUI.Log("Select [" + item + "] from " + Identity.Description, LogItemType.Action); //Get the style GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "DropDownStyle", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "ToString", MemberTypes.Method); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store3, "DroppedDown", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store3); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); //Get the value(s) returned MUST be done straight after the WaitForMessages call string Style = GUI.m_APE.GetValueFromMessage(); bool DroppedDown = GUI.m_APE.GetValueFromMessage(); IntPtr ListBox = IntPtr.Zero; Input.Block(Identity.ParentHandle, Identity.Handle); try { if (Style == "Simple") { //get the Simple mode listbox child window GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "childListBox", MemberTypes.Field); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "Handle", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); //Get the value(s) returned MUST be done straight after the WaitForMessages call ListBox = (IntPtr)GUI.m_APE.GetValueFromMessage(); } else { if (!DroppedDown) { //show the dropdown base.SingleClickInternal(Width - 5, -1, MouseButton.Left, MouseKeyModifier.None); } //find the dropdown Input.WaitForInputIdle(Identity.Handle, GUI.m_APE.TimeOut); GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "dropDownHandle", MemberTypes.Field); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store1); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); //Get the value(s) returned MUST be done straight after the WaitForMessages call dynamic DroppedDownHandle = GUI.m_APE.GetValueFromMessage(); if (DroppedDownHandle == null) { throw new Exception("Failed to find the ComboBox dropdown"); } ListBox = DroppedDownHandle; } //locate the item int Index = ItemIndex(item); if (Index == NM.CB_ERR) { throw new Exception("Failed to find the ComboBox item"); } IntPtr MessageResult; IntPtr SendResult; NM.tagRect ItemRect = new NM.tagRect(); //Locate the rect of the item SendResult = NM.SendMessageTimeout(ListBox, NM.ListBoxMessages.LB_GETITEMRECT, new IntPtr(Index), ref ItemRect, NM.SendMessageTimeoutFlags.SMTO_NORMAL, GUI.m_APE.TimeOut, out MessageResult); if (SendResult == IntPtr.Zero || unchecked ((int)MessageResult.ToInt64()) == NM.LB_ERR) //Failed { throw new Exception("Failed to access the combobox"); } NM.tagRect ClientRect; NM.GetClientRect(ListBox, out ClientRect); //scroll the item into view if needed if (((ItemRect.bottom - ItemRect.top) / 2) + ItemRect.top > ClientRect.bottom || ((ItemRect.bottom - ItemRect.top) / 2) + ItemRect.top < ClientRect.top) { SendResult = NM.SendMessageTimeout(ListBox, NM.ListBoxMessages.LB_SETTOPINDEX, new IntPtr(Index), ref ItemRect, NM.SendMessageTimeoutFlags.SMTO_NORMAL, GUI.m_APE.TimeOut, out MessageResult); if (SendResult == IntPtr.Zero || unchecked ((int)MessageResult.ToInt64()) == NM.LB_ERR) //Failed { throw new Exception("Failed to access the combobox"); } //Locate the rect of the item SendResult = NM.SendMessageTimeout(ListBox, NM.ListBoxMessages.LB_GETITEMRECT, new IntPtr(Index), ref ItemRect, NM.SendMessageTimeoutFlags.SMTO_NORMAL, GUI.m_APE.TimeOut, out MessageResult); if (SendResult == IntPtr.Zero || unchecked ((int)MessageResult.ToInt64()) == NM.LB_ERR) //Failed { throw new Exception("Failed to access the combobox"); } } //click the item IntPtr temp = Identity.Handle; try { Identity.Handle = ListBox; base.SingleClickInternal(-1, ((ItemRect.bottom - ItemRect.top) / 2) + ItemRect.top, MouseButton.Left, MouseKeyModifier.None); } finally { Identity.Handle = temp; } //wait for .Text to == text string CurrentText; timer = Stopwatch.StartNew(); do { CurrentText = GUI.m_APE.GetWindowTextViaWindowMessage(Identity.Handle); if (CurrentText == item) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw new Exception("Failed to set the text of the ComboBox"); } Thread.Sleep(15); }while (true); timer.Stop(); } finally { Input.Unblock(); } }
internal void WaitForAnimation(IntPtr Handle, bool ClearClientArea, WaitForAnimationSource Source) { if (GUI.m_APESpy) { return; } Stopwatch timer = Stopwatch.StartNew(); while (true) { if (NM.IsWindowVisible(Handle)) { break; } if (timer.ElapsedMilliseconds > GUI.GetTimeOut()) { throw GUI.ApeException("Window is not visible"); } Thread.Sleep(15); } if (Source == WaitForAnimationSource.Form) { // The window animations we care about are the following: // newly opened window // maximising a window // restoring a window // in all these cases the window should have focus, so if the window doesn't then return if (!Input.HasFocus(IntPtr.Zero, Handle)) { return; } if (GUI.FormAnimationDisabled) { return; } } NM.tagRect theRect = Display.GetWindowRectangleDIP(Handle); int width = theRect.right - theRect.left; int height = theRect.bottom - theRect.top; if (width < 1 || height < 1) { return; } Bitmap A = new Bitmap(width, height, PixelFormat.Format24bppRgb); Bitmap B = new Bitmap(width, height, PixelFormat.Format24bppRgb); try { if (WhiteWindow == null && Source == WaitForAnimationSource.Form) { // If the window has transparency and a window is animating in behind the window then we won't be able to determine // when the window we are interested in has finished animating, so place a solid white window behind the window we are // interested in to remove any possible background animations. Making the white window have WS_EX_TOOLWINDOW extended // style stops it animating when shown or hidden. WhiteWindow = new Form(); WhiteWindow.BackColor = Color.White; WhiteWindow.ShowInTaskbar = false; WhiteWindow.FormBorderStyle = FormBorderStyle.None; NM.SetWindowPos(WhiteWindow.Handle, Handle, theRect.left, theRect.top, width, height, NM.SetWindowPosFlags.HideWindow); long currentExStyle = NM.GetWindowLongPtr(Handle, NM.GWL.GWL_EXSTYLE).ToInt64(); NM.SetWindowLongPtr(WhiteWindow.Handle, NM.GWL.GWL_EXSTYLE, currentExStyle | WS_EX_TOOLWINDOW); } if (Source == WaitForAnimationSource.Form) { NM.SetWindowPos(WhiteWindow.Handle, Handle, theRect.left, theRect.top, width, height, NM.SetWindowPosFlags.ShowWindow); } int SameCount = 0; int i = 0; int Loops = 0; //Debug.WriteLine("till bitmap loop " + timer.ElapsedMilliseconds.ToString()); do { Loops++; if (i == 0) { Display.GetWindowBitmap(Handle, theRect.left, theRect.top, ref A, false, ClearClientArea); //A.Save(@"c:\temp\" + Loops.ToString() + ".png"); //A.Save(@"c:\temp\a.png"); i++; } else { Display.GetWindowBitmap(Handle, theRect.left, theRect.top, ref B, false, ClearClientArea); //B.Save(@"c:\temp\" + Loops.ToString() + ".png"); //B.Save(@"c:\temp\b.png"); i--; } if (timer.ElapsedMilliseconds > GUI.GetTimeOut()) { timer.Stop(); throw GUI.ApeException("Failed to detect window finishing animation"); } if (Display.CompareBitmap(A, B)) { SameCount++; //Debug.WriteLine("same " + SameCount.ToString() + " " + timer.ElapsedMilliseconds.ToString()); } else { SameCount = 0; //Debug.WriteLine("reset " + timer.ElapsedMilliseconds.ToString()); } //Thread.Sleep(15); }while (SameCount < 2 || Loops < 9); } finally { if (Source == WaitForAnimationSource.Form) { NM.SetWindowPos(WhiteWindow.Handle, Handle, theRect.left, theRect.top, width, height, NM.SetWindowPosFlags.HideWindow); } } timer.Stop(); //Debug.Listeners[0].WriteLine("\t Loops: " + Loops.ToString() + " Time: " + timer.ElapsedMilliseconds.ToString()); }
/// <summary> /// Gets the rectangle representing the window in device independant pixels /// </summary> /// <param name="window">The handle of the widown to to get the rectangle of</param> /// <returns>Rectangle representing the window</returns> public static NM.tagRect GetWindowRectangleDIP(IntPtr window) { int Adjustment = 1; int TitleBarRight = 0; string WindowState = ""; NM.tagRect ControlRect; bool topLevelWindow = NM.IsTopLevelWindow(window); if (topLevelWindow) { // Get the titlebar rectangle NM.TITLEBARINFO CurrentTitleBarInfo = new NM.TITLEBARINFO(); CurrentTitleBarInfo.cbSize = (uint)Marshal.SizeOf(CurrentTitleBarInfo); NM.GetTitleBarInfo(window, ref CurrentTitleBarInfo); TitleBarRight = CurrentTitleBarInfo.rcTitleBar.right; // Get the windows current state NM.WindowPlacement CurrentWindowPlacement = new NM.WindowPlacement(); CurrentWindowPlacement.length = (uint)Marshal.SizeOf(CurrentWindowPlacement); NM.GetWindowPlacement(window, ref CurrentWindowPlacement); if (CurrentWindowPlacement.showCmd.ToString() == "ShowMaximized") { WindowState = "Maximized"; } } //TODO screen capture broke for not toplevel windows / non dwm toplevel with dpi? NM.DwmIsCompositionEnabled(out bool desktopWindowManagerEnabled); if (desktopWindowManagerEnabled && topLevelWindow) { NM.DwmGetWindowAttribute(window, NM.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, out ControlRect, Marshal.SizeOf(typeof(NM.tagRect))); if (topLevelWindow && WindowState == "Maximized") { Adjustment += ControlRect.right - TitleBarRight; } ControlRect.left = ControlRect.left + Adjustment; ControlRect.top = ControlRect.top + Adjustment; ControlRect.right = ControlRect.right - Adjustment; ControlRect.bottom = ControlRect.bottom - Adjustment; } else { NM.GetWindowRect(window, out ControlRect); NM.tagRect clipBox = NM.GetClipBox(window); ControlRect.right = ControlRect.left + clipBox.right; ControlRect.bottom = ControlRect.top + clipBox.bottom; if (topLevelWindow && WindowState == "Maximized") { Adjustment += ControlRect.right - TitleBarRight; } float ScreenScalingFactor; using (Graphics desktopGraphics = Graphics.FromHwnd(window)) { IntPtr desktopDeviceContext = desktopGraphics.GetHdc(); int LogicalScreenHeight = NM.GetDeviceCaps(desktopDeviceContext, NM.DeviceCap.VERTRES); int PhysicalScreenHeight = NM.GetDeviceCaps(desktopDeviceContext, NM.DeviceCap.DESKTOPVERTRES); desktopGraphics.ReleaseHdc(); ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight; } ControlRect.left = (int)(Math.Round((float)(ControlRect.left + Adjustment) * ScreenScalingFactor)); ControlRect.top = (int)(Math.Round((float)(ControlRect.top + Adjustment) * ScreenScalingFactor)); ControlRect.right = (int)(Math.Round((float)(ControlRect.right - Adjustment) * ScreenScalingFactor)); ControlRect.bottom = (int)(Math.Round((float)(ControlRect.bottom - Adjustment) * ScreenScalingFactor)); } return(ControlRect); }
private void ExpandNode(IntPtr Node) { int Position = 0; Stopwatch timer; int Left = 0; int Top = 0; int Right = 0; int Bottom = 0; NM.tagRect ClientRect = new NM.tagRect(); // check if already expanded GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsExpanded", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call bool IsExpanded = GUI.m_APE.GetValueFromMessage(); if (IsExpanded) { return; } for (int i = 0; i < 2; i++) { // Get bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "EnsureVisible", MemberTypes.Method); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store3, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store4, "Left", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store5, "Top", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store6, "Right", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store3, DataStores.Store7, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store4); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store5); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store6); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store7); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call Left = GUI.m_APE.GetValueFromMessage(); Top = GUI.m_APE.GetValueFromMessage(); Right = GUI.m_APE.GetValueFromMessage(); Bottom = GUI.m_APE.GetValueFromMessage(); NM.GetClientRect(Identity.Handle, out ClientRect); if (Left < 0 || Top < 0 || Bottom > ClientRect.bottom) { // Go round again } else { break; } } if (Right > ClientRect.right) { Right = ClientRect.right; } bool WaitForMove = false; if (Bottom > ClientRect.bottom) { WaitForMove = true; Bottom = ClientRect.bottom; } // Expand it if (m_ShowPlusMinus) { int CheckBoxModifier = 0; if (m_CheckBoxes) { CheckBoxModifier = 12; } // Scroll the expand icon in to view if need be int X = Left - 7 - CheckBoxModifier - 5; if (X < 0) { //get current scroll bar pos Position = NM.GetScrollPos(Identity.Handle, NM.SBS_HORZ); //update the pos Position = Position + X; NM.SetScrollPos(Identity.Handle, NM.SBS_HORZ, Position, false); //send the message to move IntPtr MessageResult; IntPtr SendResult = NM.SendMessageTimeout(Handle, NM.WM_HSCROLL, new IntPtr(MakeLParam((int)NM.SB_THUMBPOSITION, Position)), IntPtr.Zero, NM.SendMessageTimeoutFlags.SMTO_NORMAL, (uint)GUI.GetTimeOut(), out MessageResult); base.SingleClickInternal(5, Top + ((Bottom - Top) / 2), MouseButton.Left, MouseKeyModifier.None); } else { base.SingleClickInternal(Left - 7 - CheckBoxModifier, Top + ((Bottom - Top) / 2), MouseButton.Left, MouseKeyModifier.None); } } else { base.DoubleClickInternal(Right - 4, Top + ((Bottom - Top) / 2), MouseButton.Left, MouseKeyModifier.None); } // Wait for it to be expanded bool IsNowExpanded = false; timer = Stopwatch.StartNew(); do { // Get if expanded GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "IsExpanded", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store2); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call IsNowExpanded = GUI.m_APE.GetValueFromMessage(); if (IsNowExpanded) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw new Exception("Node failed to expand"); } Thread.Sleep(15); }while (true); //left clicking on a node which is partially off the bottom of the window will scroll it if (WaitForMove) { timer = Stopwatch.StartNew(); do { // Get bounds GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "NodeFromHandle", MemberTypes.Method, new Parameter(GUI.m_APE, Node)); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "Bounds", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store2, DataStores.Store3, "Bottom", MemberTypes.Property); GUI.m_APE.AddRetrieveMessageGetValue(DataStores.Store3); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); // Get the value(s) returned MUST be done straight after the WaitForMessages call Bottom = GUI.m_APE.GetValueFromMessage(); if (Bottom >= ClientRect.bottom) { break; } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw new Exception("Node failed to scroll fully into view"); } Thread.Sleep(15); }while (true); } // After clicking sleep for a bit to give time for the treeview to update Thread.Sleep(30); }