/// <summary> /// Abort resetting if the user types anything, anywhere. /// Also sets the flag (if it returns true) to indicate the search WAS aborted. /// </summary> /// <returns></returns> private bool ShouldAbort() { Win32.MSG msg = new Win32.MSG(); if (Win32.PeekMessage(ref msg, IntPtr.Zero, (uint)Win32.WinMsgs.WM_KEYDOWN, (uint)Win32.WinMsgs.WM_KEYDOWN, (uint)Win32.PeekFlags.PM_NOREMOVE)) { m_fResetSearchAborted = true; if (m_resetTimer == null) { m_resetTimer = new System.Windows.Forms.Timer(); m_resetTimer.Interval = 100; // try again in 1/10 second. m_resetTimer.Tick += new EventHandler(m_resetTimer_Tick); m_resetTimer.Start(); } return true; } return false; }
/// ----------------------------------------------------------------------------------- /// <summary> /// Collect whatever keyboard input is available--whatever the user has typed ahead. /// Includes backspaces and delete forwards, but not any more special keys like arrow keys. /// </summary> /// <param name="chsFirst">the first character the user typed, which started the whole /// process.</param> /// <param name="stuBuffer">buffer in which to put data characters.</param> /// <param name="cchBackspace">number of backspaces the user typed, in addition to any that /// just cancel stuff from the input buffer.</param> /// <param name="cchDelForward">any del forward keys the user typed</param> /// <remarks> /// <para>REVIEW JohnT: probably we should not accumulate both typed characters and /// sequences of extra Dels and Bs's, as it leads to ambiguity in character properties.</para> /// </remarks> /// ----------------------------------------------------------------------------------- protected void CollectTypedInput(char chsFirst, out string stuBuffer, out int cchBackspace, out int cchDelForward) { cchBackspace = 0; cchDelForward = 0; StringBuilder stuTmpBuffer = new StringBuilder(); // The first character goes into the buffer, unless it is a backspace or delete, // in which case it affects the counts. switch ((int)chsFirst) { case (int)VwSpecialChars.kscBackspace: cchBackspace++; break; case (int)VwSpecialChars.kscDelForward: cchDelForward++; break; default: stuTmpBuffer.Append(chsFirst); break; } // Collect any characters that are currently in the message queue // Note: When/if porting to MONO, the following block of code can be removed // and still work. However, make sure the final line in the method still remains // (i.e. the line where stuBuffer is being set). Win32.MSG msg = new Win32.MSG(); while (true) { if (Win32.PeekMessage(ref msg, this.Handle, (uint)Win32.WinMsgs.WM_KEYDOWN, (uint)Win32.WinMsgs.WM_KEYUP, (uint)Win32.PeekFlags.PM_REMOVE)) { Win32.TranslateMessage(ref msg); } else if (Win32.PeekMessage(ref msg, this.Handle, (uint)Win32.WinMsgs.WM_CHAR, (uint)Win32.WinMsgs.WM_CHAR, (uint)Win32.PeekFlags.PM_REMOVE)) { char nextChar = (char)msg.wParam; switch ((int)nextChar) { case (int)VwSpecialChars.kscBackspace: // handle backspace characters. If there are are characters in // the buffer then remove the last one. If not, then count // the backspace so it will be processed later. if (stuTmpBuffer.Length > 0) stuTmpBuffer.Remove(stuTmpBuffer.Length - 1, 1); else cchBackspace++; break; case (int)VwSpecialChars.kscDelForward: // let DEL keys be handled later by the views framework cchDelForward++; break; default: // regular characters get added to the buffer stuTmpBuffer.Append(nextChar); break; } } else break; } stuBuffer = stuTmpBuffer.ToString(); // Shows that the buffering is working // if (stuBuffer.Length > 1) // Debug.WriteLine("typeahead : >" + stuBuffer + "< len = " + stuBuffer.Length); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Peeks at the pending messages and if it finds any message in the given range, that /// message is removed from the stack and passed back to be handled immediately. /// </summary> /// <param name="min">The minumum message to handle.</param> /// <param name="max">The maximum message to handle.</param> /// <param name="msg">The message found, if any.</param> /// <returns><c>true</c> if a matching message is found; <c>false</c> otherwise.</returns> /// ------------------------------------------------------------------------------------ private bool PeekMessage(Win32.WinMsgs min, Win32.WinMsgs max, out Win32.MSG msg) { msg = new Win32.MSG(); return Win32.PeekMessage(ref msg, m_ownerControl.Handle, (uint)min, (uint)max, (uint)Win32.PeekFlags.PM_REMOVE); }
internal void ConsumerThreadStart() { CheckDisposed(); try { // REVIEW JohnH(RandyR): Is it legal to use MTA, now that ParseFiler isn't COM? //JH says: I don't know... the cache still is COM // I notice that w/ STA, it crashes silently, but w/ MTA, it "HRESULTS" in the cache code. //- Thread.CurrentThread.SetApartmentState(ApartmentState.STA); Debug.Assert( Thread.CurrentThread.GetApartmentState() == ApartmentState.STA, "Could not set the apartment state to STA"); // first time through, show thread ID in debug output Trace.WriteLineIf(tracingSwitch.TraceInfo, "=======>Scheduler Thread: " + Thread.CurrentThread.ManagedThreadId.ToString()); Trace.WriteLineIf(tracingSwitch.TraceInfo, "ConsumerThreadStart(): CurrentThreadId = " + Win32.GetCurrentThreadId().ToString()); // Create the list of wait events, order is important here. Highest priority first. WaitHandle[] waitEvents = new WaitHandle[3]; waitEvents[0] = m_StopEvent; // Stop Event for this thread waitEvents[1] = m_TryAWordEvent; // Trace word event waitEvents[2] = m_QueueEvent; // hvo has been put in the Queue // Create the XAmpleWrapper on the consumer thread so that the XAmple code will // run on the consumer thread! See LT-3546 for what happens if it runs on the // UI thread! Also ensure that this thread can receive messages as per MSDN. m_parserWorker.InitParser(); Win32.MSG msg = new Win32.MSG(); Win32.PeekMessage(ref msg, (IntPtr)null, (uint)Win32.WinMsgs.WM_USER, (uint)Win32.WinMsgs.WM_USER, (uint)Win32.PeekFlags.PM_NOREMOVE); bool bIdle = false; // main thread loop MainLoop(waitEvents, bIdle); } // The process of loading the Lexicon and Grammar can be a long process, // if the user tries to stop the parser while doing this - the only quick // way to end the thread is to 'Interupt' it. catch (System.Threading.ThreadInterruptedException error) { m_caughtException = error; } catch (System.Threading.ThreadAbortException error) { m_caughtException = error; } catch (Exception error) { // The sky is *not* falling, // so don't scare up any more snakes than you can kill. // Try and be nice and give them a benign warning, // but all you get is a zillion JIRA issues. // Cf. LTB-4, LT-5590, LT-6627, LT-6675, LT-6766, LT-7236, LTB-45, LT-6185, and LT-7414. // Let's throw in the two omnibus JIRA issues, as well: LT-6759 and LT-5659. // NO: SIL.Utils.ErrorReporter.ReportException(error,null, false);//non-fatal to the whole app... m_caughtException = error; //but this thread is hosed } }