private static bool IsTopLevelWindow(IntPtr Window) { NM.WindowStyles Style = (NM.WindowStyles)(long) NM.GetWindowLongPtr(Window, NM.GWL.GWL_STYLE); // WS_OVERLAPPED and WS_POPUP indicate a top level window. // WS_OVERLAPPED constant is 0, it does not make a good mask. But all // WS_OVERLAPPED windows MUST have a caption so use WS_CAPTION instead. return(Style.HasFlag(NM.WindowStyles.WS_CAPTION) || Style.HasFlag(NM.WindowStyles.WS_POPUP)); }
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()); }