/************************************************************************************/
        /// <summary>
        /// Releases a key but only if we were the one who pressed it in the first place.
        /// This prevents interference with user action.
        /// </summary>
        protected static void ReleaseKey(string strKey)
        {
            string strIndexedKey = strKey.ToLower().Trim();

            if (s_PressedKeys.Contains(strIndexedKey))
            {
                Program.Log("Releasing keyboard key: {0}", strKey);
                LavishScriptAPI.LavishScript.ExecuteCommand("press -release " + strKey);
                s_PressedKeys.Remove(strIndexedKey);
            }
            return;
        }
Пример #2
0
        /************************************************************************************/
        /// <summary>
        /// Retrieves a message from the queue.
        /// </summary>
        /// <remarks>
        /// This function will throw an exception if called from outside the context of the owner thread.
        /// </remarks>
        /// <param name="bWaitForMessageIfEmpty"></param>
        /// <returns>Returns NULL if no message was in the queue.</returns>
        protected ThreadMessage GetMessage(bool bWaitForMessageIfEmpty)
        {
            int iWaitObjectIndex = -1;

            if (bWaitForMessageIfEmpty)
            {
                iWaitObjectIndex = WaitHandle.WaitAny(m_aWaitHandles);                 // TODO: Should we figure a way to abort this?
            }
            else
            {
                iWaitObjectIndex = WaitHandle.WaitAny(m_aWaitHandles, 0, false);
            }

            WaitHandle ThisSignalledHandle = null;

            if (iWaitObjectIndex != WaitHandle.WaitTimeout)
            {
                ThisSignalledHandle = m_aWaitHandles[iWaitObjectIndex];
            }

            /// If a wait was signalled and it wasn't the standard queue filled event, return it.
            /// The recipient has an obligation to clear the signal or unregister the handle,
            /// otherwise the next call to GetMessage will return the same handle.
            if (ThisSignalledHandle != null && ThisSignalledHandle.SafeWaitHandle != m_QueueFilledEvent.SafeWaitHandle)
            {
                return(new WaitHandleSignalledMessage(ThisSignalledHandle));
            }

            ThreadMessage NewIncomingMessage = null;

            lock (m_Lock)
            {
                // Dummy check.
                if (m_Thread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)
                {
                    throw new Exception("TekMessageThread.GetMessage can only be called from the context of the owner thread.");
                }

                /// Check for any legit messages.
                if (m_MessageQueue.Count > 0)
                {
                    NewIncomingMessage = m_MessageQueue.Dequeue();
                }

                /// Check our timer list and generate a pseudo-message.
                /// Timers have lowest priority just like Win32 because if the messages build
                /// up and if the message handler takes time to process (such as connection timeout),
                /// then the backlog of messages will drown out any other processing.
                else if (m_PulsedTimers.Count > 0)
                {
                    int iTimerID = m_PulsedTimers[0];
                    m_PulsedTimers.Remove(iTimerID);

                    TimerDesc ThisTimerDesc = m_Timers[iTimerID];
                    NewIncomingMessage = new TimerMessage(iTimerID, ThisTimerDesc.m_Context, ThisTimerDesc.m_Timer.Interval);
                }

                /// Now that there is NOTHING to retrieve, make the event block again.
                if (QueuedMessageCount == 0)
                {
                    m_QueueFilledEvent.Reset();
                }
            }

            return(NewIncomingMessage);
        }