/// <summary> /// Check if current window handler is still valid (if another window cover the visual of this window, it must not be used as window) /// </summary> /// <param name="bCheck">Check if it is still valid. Set false if window is not proofed, true if pet is already walking on a window => check if window is still valid.</param> /// <returns>True if window is still valid and present. False if window is not anymore there.</returns> /// <seealso cref="NativeMethods.GetWindow(IntPtr, int)"/> /// <seealso cref="NativeMethods.GetTitleBarInfo(IntPtr, ref NativeMethods.TITLEBARINFO)"/> private bool CheckTopWindow(bool bCheck) { // Check only if we have a valid window handler if ((int)hwndWindow != 0) { NativeMethods.RECT rctO; NativeMethods.RECT rct; // Get window size and position of the current pet NativeMethods.GetWindowRect(new HandleRef(this, hwndWindow), out rctO); // If pet was walking on a window, check if window is still in the same position if (bCheck) { if (rctO.Top > dPosY + Height + 2) { return(true); } else if (rctO.Top < dPosY + Height - 2) { return(true); } else if (rctO.Left > dPosX + Width - 5) { return(true); } else if (rctO.Right < dPosX + 5) { return(true); } } // Get more informations about the current window title bar NativeMethods.TITLEBARINFO titleBarInfo = new NativeMethods.TITLEBARINFO(); titleBarInfo.cbSize = Marshal.SizeOf(titleBarInfo); // Get the handle to the next window (to user visual, in Z-order) IntPtr hwnd2 = NativeMethods.GetWindow(hwndWindow, 3); // Loop until there are windows over the current window (in Z-Order) while (hwnd2 != (IntPtr)0) { StringBuilder sTitle = new StringBuilder(128); NativeMethods.GetWindowText(hwnd2, sTitle, 128); // If window has a title bar if (NativeMethods.GetTitleBarInfo(hwnd2, ref titleBarInfo)) { // If window has a title name and a valid size and is not fullscreen if (sTitle.Length > 0 && NativeMethods.GetWindowRect(new HandleRef(this, hwnd2), out rct) && (titleBarInfo.rcTitleBar.Bottom > 0 || sTitle.ToString() == "sheep")) { if (rct.Top < rctO.Top && rct.Bottom > rctO.Top) { if (rct.Left < dPosX && rct.Right > dPosX + 40 && iAnimationStep > 4) { return(true); } } } } // Get the handle to the next window (to user visual, in Z-order) hwnd2 = NativeMethods.GetWindow(hwnd2, 3); } } return(false); }
/// <summary> /// Detect if pet is still falling or if taskbar/window was detected. /// </summary> /// <param name="y">Y moves in pixels for the next step (function will detect if window/taskbar is inside the movement).</param> /// <returns>Y position of the window or taskbar. -1 if pet is still falling.</returns> private int FallDetect(int y) { NativeMethods.RECT rct; Dictionary <IntPtr, string> windows = new Dictionary <IntPtr, string>(); NativeMethods.TITLEBARINFO titleBarInfo = new NativeMethods.TITLEBARINFO(); titleBarInfo.cbSize = Marshal.SizeOf(titleBarInfo); // Enumerate all windows on the desktop. NativeMethods.EnumWindows(delegate(IntPtr hWnd, int lParam) { if (hWnd == Handle) { return(true); // form itself, don't parse } // Enumerate only visible windows if (NativeMethods.IsWindowVisible(hWnd)) { StringBuilder sTitle = new StringBuilder(128); NativeMethods.GetWindowText(hWnd, sTitle, 128); // Sheep windows doesn't have a title bar, but we want detect if another pet is present if (sTitle.ToString() == "Sheep") { } // If there is no title bar, continue enumerating other windows else if (!NativeMethods.GetTitleBarInfo(hWnd, ref titleBarInfo)) { return(true); } // If title bar is not visible, continue enumerating other windows else if ((titleBarInfo.rgstate[0] & 0x00008000) > 0) { return(true); // invisible } // If window has a title, add this window to list if (sTitle.Length > 0) { windows[hWnd] = sTitle.ToString(); } } return(true); }, (IntPtr)0); // For each valid window found: foreach (KeyValuePair <IntPtr, string> window in windows) { // Get size and position of window if (NativeMethods.GetWindowRect(new HandleRef(this, window.Key), out rct)) { // If vertical position is in the falling range and pet is over window and window is at least 20 pixels under the screen border if (dPosY + Height < rct.Top && dPosY + Height + y >= rct.Top && dPosX >= rct.Left - Width / 2 && dPosX + Width <= rct.Right + Width / 2 && dPosY > 20 + Screen.PrimaryScreen.WorkingArea.Y) { // Pet need to walk over THIS window! hwndWindow = window.Key; // If window is not covered by other windows, set this as current window for the pet. if (!CheckTopWindow(false)) { //NativeMethods.ShowWindow(window.Key, 0); // hide window NativeMethods.ShowWindow(window.Key, 5); // show window again NativeMethods.SetForegroundWindow(window.Key); // set focus to window return(rct.Top); // return the position for the pet } else { hwndWindow = (IntPtr)0; // window is covered by other windows, reset handle } } } } return(-1); // no windows detected. }