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; } } }