public ClickerHeroesSteamController() { windowHandle = WinApi.FindWindow(null, WindowTitle); if (windowHandle == IntPtr.Zero) { throw new TargetWindowNotFoundException(); } WinApi.RECT windowRect; WinApi.GetWindowRect(windowHandle, out windowRect); WinApi.POINT topLeft; WinApi.ClientToScreen(windowHandle, out topLeft); leftBorderWidth = topLeft.X - windowRect.Left; topBorderHeight = topLeft.Y - windowRect.Top; }
public CHController() { targetHandle = WinApi.FindWindow(null, ClickerHeroesWindowTitle); if (targetHandle == IntPtr.Zero) { throw new TargetWindowNotFoundException("Could not locate the Clicker Heroes (Steam) window."); } WinApi.RECT chRect; WinApi.GetWindowRect(targetHandle, out chRect); WinApi.POINT topLeft; WinApi.ClientToScreen(targetHandle, out topLeft); leftOffset = topLeft.X - chRect.Left; topOffset = topLeft.Y - chRect.Top; }
public bool PreFilterMessage(ref Message m) { if (m.Msg == WinApi.WM_MOUSEMOVE && autoHideCursor) { Point p = new Point(m.LParam.ToInt32()); WinApi.ClientToScreen(m.HWnd, ref p); if (p != lastMousePoint) { lastMousePoint = p; ShowCursor(); hideCursorTimer.Reset(); } return(false); // Don't block this message } else if (m.Msg == WinApi.WM_MOUSEWHEEL && dispatchMouseWheel) { Point p = new Point(m.LParam.ToInt32()); // First, see whether there's an open combobox list popup that must be handled differently WindowProperties prop = new WindowProperties(); prop.ProcessId = new Window(m.HWnd).ProcessId; prop.ClassName = "ComboLBox"; prop.Visible = true; Window popup; if (Window.TryFind(prop, out popup)) { // Found a combobox popup window, check coordinates if (popup.Rectangle.Contains(p)) { // Mouse cursor is over visible combo listbox popup, let the message pass return(false); } // Mouse cursor is outside the popup, block the message // (Do not scroll the popup because the mouse is not in it; // but also do not scroll anything else outside the popup) return(true); } // Regular window surface: find the deepest control below the mouse cursor Control control = Form.ActiveForm; while (control != null) { Point clientPoint = control.PointToClient(p); Control subControl = control.GetChildAtPoint(clientPoint, GetChildAtPointSkip.Invisible); if (subControl == null || subControl is ScrollBar || subControl is ComboBox) { break; } //System.Diagnostics.Debug.WriteLine("Found control in " + control.Name + " at " + clientPoint + ": " + subControl.Name); control = subControl; } if (control != null) { if (control.Handle == m.HWnd) { return(false); // The message already arrived for this control, let it pass } // Search up the parents for a scrollable panel Control c = control; while (!(c is Form)) { Panel panel = c as Panel; if (panel != null && panel.AutoScroll) { Point scrollPos = panel.AutoScrollPosition; // Position report is always negative, but new values must be set positive... scrollPos.X = -scrollPos.X; scrollPos.Y = -scrollPos.Y; int delta = m.WParam.ToInt32() >> 16; delta /= 120; // Convert to number of wheel notches scrollPos.Y += -delta * 20; // Delta value is "negative" (neg is downwards, pos is upwards) panel.AutoScrollPosition = scrollPos; return(true); // Block this message } c = c.Parent; } // NOTE: Possible performance improvement: Flag the re-posted message so that we can // recognise it faster when it re-arrives here and we can let it pass. // Use either a very high delta value (HIWORD(wParam)) or one of the modifier // keys MK_* (LOWORD(wParam)) or an unassigned bit of lParam. //System.Diagnostics.Debug.WriteLine("Re-posting message to " + control.Name); WinApi.PostMessage(control.Handle, WinApi.WM_MOUSEWHEEL, m.WParam, m.LParam); // If IMessageModifyAndFilter wasn't System.Windows.Form's internal, we could just // implement that interface, modify the message and let it pass changed. But so we // need to block the message and send a new one that we're going to let pass then. } return(true); // Block this message } return(false); // Don't block this message }