/// <summary> /// Closes the form by click the 'x' in the top right hand corner of the form /// </summary> public void Close() { if (NM.IsWindow(Identity.Handle)) { if (NM.IsWindowVisible(Identity.Handle)) { if (NM.IsIconic(Identity.Handle)) { throw new Exception("Can not close the window as it is minimised"); } GUI.m_APE.AddFirstMessageGetTitleBarItemRectangle(Identity.Handle, NM.TitleBarStateElement.Close); 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 NM.StateSystem State = (NM.StateSystem)GUI.m_APE.GetValueFromMessage(); int Top = GUI.m_APE.GetValueFromMessage(); int Left = GUI.m_APE.GetValueFromMessage(); int Bottom = GUI.m_APE.GetValueFromMessage(); int Right = GUI.m_APE.GetValueFromMessage(); // Check the close button is actually displayed if (State != NM.StateSystem.STATE_SYSTEM_NORMAL && State != NM.StateSystem.STATE_SYSTEM_PRESSED) { throw new Exception("Can not close the window as the close button is in state '" + State.ToString() + "'"); } NM.tagRect WindowRect; NM.GetWindowRect(Identity.Handle, out WindowRect); int X = Left + ((Right - Left) / 2) - WindowRect.left; int Y = Top + ((Bottom - Top) / 2) - WindowRect.top; Input.Block(Identity.ParentHandle, Identity.Handle); try { GUI.Log("Close the " + Identity.Description, LogItemType.Action); base.SingleClickInternal(X, Y, MouseButton.Left, MouseKeyModifier.None); //Wait for the window to disappear base.WaitForControlToNotBeVisible(); } finally { Input.Unblock(); } } } }
private unsafe void GetToolTip(Message *ptrMessage, int messageNumber) { //must be first message if (messageNumber != 1) { throw new Exception("GetToolTip must be first message"); } // p1 = handle IntPtr handle = GetParameterIntPtr(ptrMessage, 0); CleanUpMessage(ptrMessage); NM.EnumWindowsProc windowsToGetToolTipsCallback = new NM.EnumWindowsProc(EnumWindowsToGetToolTips); m_ToolTipWindows = new List <IntPtr>(); NM.EnumWindows(windowsToGetToolTipsCallback, IntPtr.Zero); IntPtr toolTipHandle = IntPtr.Zero; string toolTipTitle = null; Rectangle toolTipRectangle = new Rectangle(0, 0, 0, 0); foreach (IntPtr hWnd in m_ToolTipWindows) { NM.ToolInfo info = NM.GetToolInfo(hWnd, TimeOut); if (info.hWnd == handle) { //we have the tooltip so return infomation about it toolTipHandle = hWnd; toolTipTitle = GetWindowTextViaWindowMessage(toolTipHandle); NM.tagRect windowPosition; NM.tagRect windowSize; NM.GetWindowRect(toolTipHandle, out windowPosition); windowSize = NM.GetClipBox(toolTipHandle); toolTipRectangle = new Rectangle(windowPosition.left, windowPosition.top, windowSize.right, windowSize.bottom); break; } } AddReturnValue(new Parameter(this, toolTipHandle)); AddReturnValue(new Parameter(this, toolTipTitle)); AddReturnValue(new Parameter(this, toolTipRectangle.X)); AddReturnValue(new Parameter(this, toolTipRectangle.Y)); AddReturnValue(new Parameter(this, toolTipRectangle.Width)); AddReturnValue(new Parameter(this, toolTipRectangle.Height)); }
/// <summary> /// Moves the specified window to the specified location by clicking at the specified point to drag the form /// </summary> /// <param name="MouseDownX">The x coordinate inside the form to perform a mouse down at</param> /// <param name="MouseDownY">The y coordinate inside the form to perform a mouse down at</param> /// <param name="DestinationUpperLeftX">The new location for the left side of the form</param> /// <param name="DestinationUpperLeftY">The new location for the top of the form</param> public void Move(int MouseDownX, int MouseDownY, int DestinationUpperLeftX, int DestinationUpperLeftY) { GUI.Log("Move the " + Identity.Description + " window to " + DestinationUpperLeftX.ToString() + ", " + DestinationUpperLeftY.ToString(), LogItemType.Action); NM.tagRect WindowRect; NM.GetWindowRect(Identity.Handle, out WindowRect); Input.Block(Identity.ParentHandle, Identity.Handle); try { base.MouseDownInternal(MouseDownX, MouseDownY, MouseButton.Left, MouseKeyModifier.None); base.MouseUpInternal(DestinationUpperLeftX + MouseDownX - WindowRect.left, DestinationUpperLeftY + MouseDownY - WindowRect.top, MouseButton.Left, MouseKeyModifier.None); } finally { Input.Unblock(); } }
public static NM.tagPoint MouseMove(IntPtr Handle, int x, int y, bool PerformCheck = true) { NM.tagRect WindowRect; NM.tagRect ClientRect; NM.tagPoint thePoint; int xOffset; int yOffset; Stopwatch timer = Stopwatch.StartNew(); while (true) { NM.GetWindowRect(Handle, out WindowRect); NM.GetClientRect(Handle, out ClientRect); //TODO fix this as -1 might be a valid move,,, maybe 0 instead or... if (x == -1) { xOffset = ClientRect.right / 2; } else { xOffset = x; } if (y == -1) { yOffset = ClientRect.bottom / 2; } else { yOffset = y; } //Convert the window area to screen point thePoint.x = WindowRect.left + xOffset; thePoint.y = WindowRect.top + yOffset; if (NM.MonitorFromPoint(thePoint, NM.MonitorOptions.MONITOR_DEFAULTTONULL) == null) { throw new Exception("coordinate appears to be offscreen"); } if (PerformCheck) { IntPtr ChildHandle; thePoint.x = xOffset + WindowRect.left; thePoint.y = yOffset + WindowRect.top; ChildHandle = NM.WindowFromPoint(thePoint); //Make sure we are inside the controls window area if (Handle == ChildHandle) { break; } else { //Try to scroll it into view GUI.m_APE.AddFirstMessageScrollControlIntoView(Handle); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); if (timer.ElapsedMilliseconds > GUI.GetTimeOut()) { throw new Exception("Coordinates are not inside the controls area"); } } } else { break; } } //Get the current mouse location NM.tagPoint currentPoint; NM.GetCursorPos(out currentPoint); //X direction int DirectionX; if (currentPoint.x <= WindowRect.left + xOffset) { DirectionX = 1; //right } else { DirectionX = -1; //left } //Y direction int DirectionY; if (currentPoint.y <= WindowRect.top + yOffset) { DirectionY = 1; //down } else { DirectionY = -1; //up } int MoveX = currentPoint.x; int MoveY = currentPoint.y; while (MoveX != WindowRect.left + xOffset || MoveY != WindowRect.top + yOffset) { if (MoveX != WindowRect.left + xOffset) { if (DirectionX == 1) { if (MoveX + MoveSize > WindowRect.left + xOffset) { MoveX = MoveX + 1; } else { MoveX = MoveX + MoveSize; } } else { if (MoveX - MoveSize < WindowRect.left + xOffset) { MoveX = MoveX - 1; } else { MoveX = MoveX - MoveSize; } } } if (MoveY != WindowRect.top + yOffset) { if (DirectionY == 1) { if (MoveY + MoveSize > WindowRect.top + yOffset) { MoveY = MoveY + 1; } else { MoveY = MoveY + MoveSize; } } else { if (MoveY - MoveSize < WindowRect.top + yOffset) { MoveY = MoveY - 1; } else { MoveY = MoveY - MoveSize; } } } MoveMouse(MoveX, MoveY); } return(thePoint); }
public static void MouseUp(IntPtr ParentHandle, IntPtr Handle, int x, int y, MouseButton Button, MouseKeyModifier Keys) { bool hooked = false; WaitToBeVisibleAndEnabled(Handle); Block(ParentHandle, Handle); try { NM.tagPoint thePoint = new NM.tagPoint(); thePoint.x = x; thePoint.y = y; IntPtr TopLevelHandle = NM.ChildWindowFromPoint(NM.GetDesktopWindow(), thePoint); NM.tagRect WindowSize; NM.GetWindowRect(Handle, out WindowSize); thePoint.x = x + WindowSize.left; thePoint.y = y + WindowSize.top; IntPtr ChildHandle = NM.WindowFromPoint(thePoint); if (!WaitForInputIdle(ChildHandle, GUI.m_APE.TimeOut)) { throw new Exception("Window did not go idle within timeout"); } IntPtr ActualParent; if (ParentHandle == IntPtr.Zero) { ActualParent = Handle; } else { ActualParent = ParentHandle; } TimerResolution.SetMaxTimerResolution(); //TODO this looks wrong should use clickcommon only for this if (ChildHandle == ActualParent) { ClickCommon(ParentHandle, Handle, x, y); } else { MouseMove(Handle, x, y, false); } if (Handle == ActualParent) { GUI.m_APE.AddFirstMessageAddMouseHook(Handle); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); hooked = true; } MouseClick(Button, false, true, 1, Keys.HasFlag(MouseKeyModifier.Control), Keys.HasFlag(MouseKeyModifier.Shift)); if (Handle == ActualParent) { GUI.m_APE.AddFirstMessageWaitForMouseState((APEIPC.MouseButton)Button, false, true); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); } } catch { Reset(); //Reset the mouse blocking throw; } finally { try { if (hooked) { GUI.m_APE.AddFirstMessageRemoveMouseHook(Handle); GUI.m_APE.SendMessages(EventSet.APE); GUI.m_APE.WaitForMessages(EventSet.APE); } } finally { TimerResolution.UnsetMaxTimerResolution(); Unblock(); IsMouseDown = false; } } }
internal void MouseDownInternal(int X, int Y, MouseButton button, MouseKeyModifier keys, int preClickDelay, int intraClickDelay) { Input.MouseDown(Identity.ParentHandle, Identity.Handle, Identity.Description, X, Y, button, keys, this, preClickDelay, intraClickDelay); if (!Input.WaitForInputIdle(Identity.Handle, GUI.m_APE.TimeOut)) { throw GUI.ApeException(Identity.Description + " did not go idle within timeout"); } //get the current location NM.GetCursorPos(out NM.tagPoint currentPoint); // If we are doing separate calls to mouse down and up then its very likely we want to drag so make sure we are in dragmode NM.tagRect WindowRect; NM.tagRect ClientRect; NM.GetWindowRect(Handle, out WindowRect); NM.GetClientRect(Handle, out ClientRect); int middleOfClientAreaX = (ClientRect.right / 2); int middleOfClientAreaY = (ClientRect.bottom / 2); int dragTriggerHeight = SystemInformation.DragSize.Height; int dragTriggerWidth = SystemInformation.DragSize.Width; if (middleOfClientAreaX < dragTriggerWidth || middleOfClientAreaY < dragTriggerHeight) { throw GUI.ApeException(Description + " is to small to reliably enter drag mode"); } // Move the mouse a few times to make sure we are in drag mode Rectangle workingArea; int moveX1 = WindowRect.left; int moveY1 = WindowRect.top; int moveX2 = WindowRect.left + middleOfClientAreaX; int moveY2 = WindowRect.top + middleOfClientAreaY; workingArea = Screen.GetWorkingArea(new Point(moveX1, moveY1)); if (moveX1 < workingArea.Left + 3) { moveX1 = workingArea.Left + 3; } if (moveX1 > workingArea.Right - 3) { moveX1 = workingArea.Right - 3; } if (moveY1 < workingArea.Top + 3) { moveY1 = workingArea.Top + 3; } if (moveY1 > workingArea.Bottom - 3) { moveY1 = workingArea.Bottom - 3; } workingArea = Screen.GetWorkingArea(new Point(moveX2, moveY2)); if (moveX2 < workingArea.Left + 3) { moveX2 = workingArea.Left + 3; } if (moveX2 > workingArea.Right - 3) { moveX2 = workingArea.Right - 3; } if (moveY2 < workingArea.Top + 3) { moveY2 = workingArea.Top + 3; } if (moveY2 > workingArea.Bottom - 3) { moveY2 = workingArea.Bottom - 3; } for (int i = 0; i < 10; i++) { Input.MoveMouse(moveX1, moveY1); Input.MoveMouse(moveY2, moveY2); } if (!Input.WaitForInputIdle(Identity.Handle, GUI.m_APE.TimeOut)) { throw GUI.ApeException(Identity.Description + " did not go idle within timeout"); } //Move back to where we were before the above drag block of code Input.MoveMouse(currentPoint.x, currentPoint.y); if (!Input.WaitForInputIdle(Identity.Handle, GUI.m_APE.TimeOut)) { throw GUI.ApeException(Identity.Description + " did not go idle within timeout"); } }
/// <summary> /// Restores the window back clicking the restore button in the top right corner of the form /// Note if the window is minimised then a non-gui method is used to restore the form /// </summary> public void Restore() { GUI.Log("Restore the " + Identity.Description, LogItemType.Action); string windowState = FormWindowState(); if (windowState == "Normal") { throw new Exception("Can not restore the window as it already is"); } if (windowState == "Minimized") { Input.Block(Identity.ParentHandle, Identity.Handle); try { NM.ShowWindow(Identity.Handle, NM.SW_RESTORE); //Bring it to the front (can sometimes get restored to the background using the api) SetFocus(); // Wait for the animation to finish base.WaitForAnimation(Identity.Handle, true, AnimationUtils.WaitForAnimationSource.Form); // Check the window is now normal Stopwatch timer = Stopwatch.StartNew(); do { GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "WindowState", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "ToString", MemberTypes.Method); 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 windowState = GUI.m_APE.GetValueFromMessage(); if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { timer.Stop(); throw new Exception("Failed to restore the window"); } Thread.Sleep(15); }while (windowState != "Normal"); timer.Stop(); } finally { Input.Unblock(); } } else { GUI.m_APE.AddFirstMessageGetTitleBarItemRectangle(Identity.Handle, NM.TitleBarStateElement.Maximize); 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 NM.StateSystem State = (NM.StateSystem)GUI.m_APE.GetValueFromMessage(); int Top = GUI.m_APE.GetValueFromMessage(); int Left = GUI.m_APE.GetValueFromMessage(); int Bottom = GUI.m_APE.GetValueFromMessage(); int Right = GUI.m_APE.GetValueFromMessage(); // Check the maximise button is actually displayed if (State != NM.StateSystem.STATE_SYSTEM_NORMAL && State != NM.StateSystem.STATE_SYSTEM_PRESSED) { throw new Exception("Can not restore the window as the restore button is in state '" + State.ToString() + "'"); } NM.tagRect WindowRect; NM.GetWindowRect(Identity.Handle, out WindowRect); int X = Left + ((Right - Left) / 2) - WindowRect.left; int Y = Top + ((Bottom - Top) / 2) - WindowRect.top; Input.Block(Identity.ParentHandle, Identity.Handle); try { base.SingleClickInternal(X, Y, MouseButton.Left, MouseKeyModifier.None); // Wait for the animation to finish base.WaitForAnimation(Identity.Handle, true, AnimationUtils.WaitForAnimationSource.Form); // Check the window is now minimised Stopwatch timer = Stopwatch.StartNew(); do { GUI.m_APE.AddFirstMessageFindByHandle(DataStores.Store0, Identity.ParentHandle, Identity.Handle); GUI.m_APE.AddQueryMessageReflect(DataStores.Store0, DataStores.Store1, "WindowState", MemberTypes.Property); GUI.m_APE.AddQueryMessageReflect(DataStores.Store1, DataStores.Store2, "ToString", MemberTypes.Method); 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 windowState = GUI.m_APE.GetValueFromMessage(); if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { timer.Stop(); throw new Exception("Failed to restore the window"); } Thread.Sleep(15); }while (windowState != "Normal"); timer.Stop(); } finally { Input.Unblock(); } } }
/// <summary> /// Moves the specified window to the specified location by clicking at the specified point to drag the form /// </summary> /// <param name="mouseDownX">The x coordinate inside the form to perform a mouse down at</param> /// <param name="mouseDownY">The y coordinate inside the form to perform a mouse down at</param> /// <param name="destinationUpperLeftX">The new location for the left side of the form</param> /// <param name="destinationUpperLeftY">The new location for the top of the form</param> /// <param name="checkMoveCompleted">Whether to check if the form is now in the location specified</param> public void Move(int mouseDownX, int mouseDownY, int destinationUpperLeftX, int destinationUpperLeftY, bool checkMoveCompleted) { if (mouseDownX < 3) { mouseDownX = 3; } if (mouseDownY < 3) { mouseDownY = 3; } Rectangle workingArea = Screen.GetWorkingArea(new Point(destinationUpperLeftX, destinationUpperLeftY)); if (destinationUpperLeftX < workingArea.Left) { destinationUpperLeftX = workingArea.Left; } if (destinationUpperLeftY < workingArea.Top) { destinationUpperLeftY = workingArea.Top; } if (destinationUpperLeftX > workingArea.Right - mouseDownX - 3) { destinationUpperLeftX = workingArea.Right - mouseDownX - 3; } if (destinationUpperLeftY > workingArea.Bottom - mouseDownY - 3) { destinationUpperLeftY = workingArea.Bottom - mouseDownY - 3; } GUI.Log("Move the " + Identity.Description + " window to " + destinationUpperLeftX.ToString() + ", " + destinationUpperLeftY.ToString(), LogItemType.Action); NM.tagRect windowRect; NM.GetWindowRect(Identity.Handle, out windowRect); Input.Block(); try { base.MouseDownInternal(mouseDownX, mouseDownY, MouseButton.Left, MouseKeyModifier.None, 32, 32); base.MouseUpInternal(destinationUpperLeftX + mouseDownX - windowRect.left, destinationUpperLeftY + mouseDownY - windowRect.top, MouseButton.Left, MouseKeyModifier.None); if (checkMoveCompleted) { Stopwatch timer = Stopwatch.StartNew(); while (true) { NM.GetWindowRect(Identity.Handle, out windowRect); //if we are in the right place +/- 2 pixel then break the loop if (windowRect.left > destinationUpperLeftX - 3 && windowRect.left < destinationUpperLeftX + 3) { if (windowRect.top > destinationUpperLeftY - 3 && windowRect.top < destinationUpperLeftY + 3) { break; } } if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { throw GUI.ApeException("Failed to move the form"); } Thread.Sleep(15); } } } catch when(Input.ResetInputFilter()) { // Will never be reached as ResetInputFilter always returns false } finally { Input.Unblock(); } }
/// <summary> /// Minimises the form by clicking the minimise button in the top right hand corner of the form /// </summary> public void Minimise() { GUI.Log("Minimise the " + Identity.Description, LogItemType.Action); string windowState = FormWindowState(); if (windowState == "Minimized") { throw GUI.ApeException("Can not minimise the window as it already is"); } GUI.m_APE.AddFirstMessageGetTitleBarItemRectangle(Identity.Handle, NM.TitleBarStateElement.Minimize); 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 NM.StateSystem State = (NM.StateSystem)GUI.m_APE.GetValueFromMessage(); int Top = GUI.m_APE.GetValueFromMessage(); int Left = GUI.m_APE.GetValueFromMessage(); int Bottom = GUI.m_APE.GetValueFromMessage(); int Right = GUI.m_APE.GetValueFromMessage(); // Check the maximise button is actually displayed if (State != NM.StateSystem.STATE_SYSTEM_NORMAL && State != NM.StateSystem.STATE_SYSTEM_PRESSED) { throw GUI.ApeException("Can not minimise the window as the minimised button is in state '" + State.ToString() + "'"); } NM.tagRect WindowRect; NM.GetWindowRect(Identity.Handle, out WindowRect); int X = Left + ((Right - Left) / 2) - WindowRect.left; int Y = Top + ((Bottom - Top) / 2) - WindowRect.top; Input.Block(); try { base.SingleClickInternal(X, Y, MouseButton.Left, MouseKeyModifier.None, 32, 32); // Wait for the animation to finish base.WaitForAnimation(Identity.Handle, true, AnimationUtils.WaitForAnimationSource.Form); // Check the window is now minimised Stopwatch timer = Stopwatch.StartNew(); do { windowState = FormWindowState(); if (timer.ElapsedMilliseconds > GUI.m_APE.TimeOut) { timer.Stop(); throw GUI.ApeException("Failed to minimise the window"); } Thread.Sleep(15); }while (windowState != "Minimized"); timer.Stop(); } catch when(Input.ResetInputFilter()) { // Will never be reached as ResetInputFilter always returns false } finally { Input.Unblock(); } }