/************************************************************************************/ /// <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; }
/************************************************************************************/ /// <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); }