コード例 #1
0
ファイル: FormHelper.cs プロジェクト: robguyoncourt/APE
        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);
        }