private unsafe void PeakMessage(Message *ptrMessage, int messageNumber) { //must be first message if (messageNumber != 1) { throw new Exception("PeakMessage must be the first message"); } // p1 = handle IntPtr handle = GetParameterIntPtr(ptrMessage, 0); int timeoutMS = GetParameterInt32(ptrMessage, 1); int threadId = NM.GetWindowThreadProcessId(handle, out int pid); m_AllControls = new List <IntPtr>(); NM.EnumThreadWindows((uint)threadId, EnumThreadProcedue, IntPtr.Zero); Stopwatch timer = Stopwatch.StartNew(); for (int loop = 0; loop < 2; loop++) { foreach (IntPtr hWnd in m_AllControls) { WF.Control control = WF.Control.FromHandle(hWnd); if (control == null) { //Todo } else { while (true) { bool messageAvailble = false; if (control.IsDisposed) { // Nothing } else if (control.Disposing) { messageAvailble = true; // Don't invoke anything just continue to loop till the control is fully disposed } else if (!control.IsHandleCreated) { // Nothing as to get to here the handle must have existed at some point so it must have been destroyed } else if (control.RecreatingHandle) { messageAvailble = true; // Don't invoke anything just continue to loop till the control has recreated the handle } else if (!control.Enabled) { // Nothing move on to the next window } else { try { //control.BeginInvoke(m_RefreshControlDelegater, new object[] { control }); IAsyncResult result = control.BeginInvoke(m_PeakMessagDelegater, null); while (true) { int innerLoop = 0; if (result.IsCompleted) { messageAvailble = (bool)control.EndInvoke(result); break; } if (control.IsDisposed) { // Nothing break; } else if (control.Disposing) { // Don't do anything just continue to loop till the control is fully disposed } else if (!control.IsHandleCreated) { // Nothing as to get to here the handle must have existed at some point so it must have been destroyed break; } else if (control.RecreatingHandle) { messageAvailble = true; // Don't invoke anything just continue to loop till the control has recreated the handle break; } else if (!control.Enabled) { // Nothing move on to the next window break; } if (timer.ElapsedMilliseconds > timeoutMS) { throw new Exception("Thread failed to have zero messages within timeout"); } innerLoop++; if (innerLoop == 100) { innerLoop = 0; Thread.Sleep(15); } else { Thread.Yield(); } } } catch (ObjectDisposedException) { } catch (InvalidAsynchronousStateException) { } catch (NullReferenceException) { } catch (InvalidOperationException) { } } if (!messageAvailble) { break; } if (timer.ElapsedMilliseconds > timeoutMS) { throw new Exception("Thread failed to have zero messages within timeout"); } Thread.Sleep(15); } break; } } } CleanUpMessage(ptrMessage); }