/// <summary> /// Calls this method on each frame. /// </summary> /// <returns><c>true</c> if if the control is still active, <c>false</c> otherwise.</returns> /// <exception cref="System.InvalidOperationException">An error occurred </exception> public bool NextFrame() { // Setup new control // TODO this is not completely thread-safe. We should use a lock to handle this correctly if (switchControl && control != null) { controlHandle = control.Handle; control.Disposed += ControlDisposed; isControlAlive = true; switchControl = false; } if (isControlAlive) { if (UseApplicationDoEvents) { // Revert back to Application.DoEvents in order to support Application.AddMessageFilter // Seems that DoEvents is compatible with Mono unlike Application.Run that was not running // correctly. Application.DoEvents(); } else { var localHandle = controlHandle; if (localHandle != IntPtr.Zero) { // Previous code not compatible with Application.AddMessageFilter but faster then DoEvents Win32Native.NativeMessage msg; while (Win32Native.PeekMessage(out msg, IntPtr.Zero, 0, 0, Win32Native.PM_REMOVE) != 0) { // NCDESTROY event? if (msg.msg == 130) { isControlAlive = false; } var message = new Message() { HWnd = msg.handle, LParam = msg.lParam, Msg = (int)msg.msg, WParam = msg.wParam }; // Skip special message //if (gameForm != null && message.HWnd == gameForm.Handle && gameForm.FilterWindowsKeys(ref message)) //{ // continue; //} if (!Application.FilterMessage(ref message)) { Win32Native.TranslateMessage(ref msg); Win32Native.DispatchMessage(ref msg); } } } } } return(isControlAlive || switchControl); }
/// <summary> /// Calls this method on each frame. /// </summary> /// <returns><c>true</c> if if the control is still active, <c>false</c> otherwise.</returns> /// <exception cref="System.InvalidOperationException">An error occurred </exception> public bool NextFrame() { // Setup new control // TODO this is not completely thread-safe. We should use a lock to handle this correctly if (switchControl && control != null) { controlHandle = control.Handle; control.Disposed += ControlDisposed; isControlAlive = true; switchControl = false; } if (isControlAlive) { if (UseApplicationDoEvents) { // Revert back to Application.DoEvents in order to support Application.AddMessageFilter // Seems that DoEvents is compatible with Mono unlike Application.Run that was not running // correctly. Application.DoEvents(); } else { var localHandle = controlHandle; if (localHandle != IntPtr.Zero) { // Previous code not compatible with Application.AddMessageFilter but faster then DoEvents Win32Native.NativeMessage msg; while (Win32Native.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0) != 0) { if (Win32Native.GetMessage(out msg, IntPtr.Zero, 0, 0) == -1) { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "An error happened in rendering loop while processing windows messages. Error: {0}", Marshal.GetLastWin32Error())); } // NCDESTROY event? if (msg.msg == 130) { isControlAlive = false; } var message = new Message() { HWnd = msg.handle, LParam = msg.lParam, Msg = (int)msg.msg, WParam = msg.wParam }; // Skip special message //if (gameForm != null && message.HWnd == gameForm.Handle && gameForm.FilterWindowsKeys(ref message)) //{ // continue; //} if (!Application.FilterMessage(ref message)) { Win32Native.TranslateMessage(ref msg); Win32Native.DispatchMessage(ref msg); } } } } } return(isControlAlive || switchControl); }