Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.7 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 00
  5. *
  6. * File: kbdnav.cpp
  7. *
  8. * Contents: Implementation of CKeyboardNavDelayTimer
  9. *
  10. * History: 4-May-2000 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stdafx.h"
  14. #include "kbdnav.h"
  15. #ifdef DBG
  16. CTraceTag tagKeyboardNavDelay (_T("Keyboard Navigation"), _T("Keyboard Navigation Delay"));
  17. #endif
  18. /*+-------------------------------------------------------------------------*
  19. * CKeyboardNavDelayTimer::CKeyboardNavDelayTimer
  20. *
  21. * Constructs a CKeyboardNavDelayTimer object.
  22. *--------------------------------------------------------------------------*/
  23. CKeyboardNavDelayTimer::CKeyboardNavDelayTimer () :
  24. m_nTimerID (0)
  25. {
  26. }
  27. /*+-------------------------------------------------------------------------*
  28. * CKeyboardNavDelayTimer::~CKeyboardNavDelayTimer
  29. *
  30. * Destroys a CKeyboardNavDelayTimer object.
  31. *--------------------------------------------------------------------------*/
  32. CKeyboardNavDelayTimer::~CKeyboardNavDelayTimer ()
  33. {
  34. ScStopTimer();
  35. }
  36. /*+-------------------------------------------------------------------------*
  37. * CKeyboardNavDelayTimer::TimerProc
  38. *
  39. * Callback function called when a timer started by this class fires.
  40. *--------------------------------------------------------------------------*/
  41. VOID CALLBACK CKeyboardNavDelayTimer::TimerProc (
  42. HWND hwnd,
  43. UINT uMsg,
  44. UINT_PTR idEvent,
  45. DWORD dwTime)
  46. {
  47. CTimerMap& TimerMap = GetTimerMap();
  48. /*
  49. * locate the CKeyboardNavDelayTimer object corresponding to this timer event
  50. */
  51. CTimerMap::iterator itTimer = TimerMap.find (idEvent);
  52. // ASSERT(itTimer != TimerMap.end());
  53. // The above assertion is not valid because: (From the SDK docs):
  54. // The KillTimer function does not remove WM_TIMER messages already posted to the message queue.
  55. if (itTimer != TimerMap.end())
  56. {
  57. CKeyboardNavDelayTimer *pNavDelay = itTimer->second;
  58. if (pNavDelay != NULL)
  59. {
  60. Trace (tagKeyboardNavDelay, _T ("Timer fired: id=%d"), pNavDelay->m_nTimerID);
  61. pNavDelay->OnTimer();
  62. }
  63. }
  64. }
  65. /*+-------------------------------------------------------------------------*
  66. * CKeyboardNavDelayTimer::ScStartTimer
  67. *
  68. *
  69. *--------------------------------------------------------------------------*/
  70. SC CKeyboardNavDelayTimer::ScStartTimer()
  71. {
  72. DECLARE_SC (sc, _T("CKeyboardNavDelayTimer::ScStartTimer"));
  73. /*
  74. * shouldn't start a timer if it's started already
  75. */
  76. ASSERT (m_nTimerID == 0);
  77. /*
  78. * Get the menu popout delay and use that for the delay before
  79. * changing the result pane. If the system doesn't support
  80. * SPI_GETMENUSHOWDELAY (i.e. Win95, NT4), use a value slightly
  81. * longer than the longer of keyboard repeat delay and keyboard
  82. * repeat rate.
  83. */
  84. DWORD dwDelay;
  85. if (!SystemParametersInfo (SPI_GETMENUSHOWDELAY, 0, &dwDelay, false))
  86. {
  87. /*
  88. * Get the keyboard delay and convert to milliseconds. The ordinal
  89. * range is from 0 (approximately 250 ms dealy) to 3 (approximately
  90. * 1 sec delay). The equation to convert from ordinal to approximate
  91. * milliseconds is:
  92. *
  93. * msec = (ordinal + 1) * 250;
  94. */
  95. DWORD dwKeyboardDelayOrdinal;
  96. SystemParametersInfo (SPI_GETKEYBOARDDELAY, 0, &dwKeyboardDelayOrdinal, false);
  97. DWORD dwKeyboardDelay = (dwKeyboardDelayOrdinal + 1) * 250;
  98. /*
  99. * Get the keyboard speed and convert to milliseconds. The ordinal
  100. * range is from 0 (approximately 2.5 reps per second, or 400 msec
  101. * interval) to 31 (approximately 30 reps per second, or 33 msec
  102. * interval). (The documentation has this reversed.) The equation
  103. * to convert from ordinal to approximate milliseconds is:
  104. *
  105. * msec = (ordinal * -12) + 400;
  106. */
  107. DWORD dwKeyboardRateOrdinal;
  108. SystemParametersInfo (SPI_GETKEYBOARDSPEED, 0, &dwKeyboardRateOrdinal, false);
  109. DWORD dwKeyboardRate = (dwKeyboardRateOrdinal * -12) + 400;
  110. dwDelay = std::_MAX (dwKeyboardDelay, dwKeyboardRate) + 50;
  111. }
  112. m_nTimerID = SetTimer(NULL, 0, dwDelay, TimerProc);
  113. if (m_nTimerID == 0)
  114. return (sc.FromLastError());
  115. GetTimerMap()[m_nTimerID] = this; // set up the timer map.
  116. Trace (tagKeyboardNavDelay, _T("Started new timer: id=%d, delay=%d milliseconds"), m_nTimerID, dwDelay);
  117. return (sc);
  118. }
  119. /*+-------------------------------------------------------------------------*
  120. * CKeyboardNavDelayTimer::ScStopTimer
  121. *
  122. * Stops the timer running for this CKeyboardNavDelayTimer, if it is running
  123. *--------------------------------------------------------------------------*/
  124. SC CKeyboardNavDelayTimer::ScStopTimer()
  125. {
  126. DECLARE_SC (sc, _T("CKeyboardNavDelayTimer::ScStopTimer"));
  127. if (m_nTimerID != 0)
  128. {
  129. CTimerMap& TimerMap = GetTimerMap();
  130. CTimerMap::iterator itTimer = TimerMap.find (m_nTimerID);
  131. ASSERT (itTimer != TimerMap.end());
  132. TimerMap.erase (itTimer);
  133. Trace (tagKeyboardNavDelay, _T("Stopped timer: id=%d"), m_nTimerID);
  134. UINT_PTR nTimerID = m_nTimerID;
  135. m_nTimerID = 0;
  136. if (!KillTimer (NULL, nTimerID))
  137. return (sc.FromLastError());
  138. }
  139. return (sc);
  140. }
  141. /*+-------------------------------------------------------------------------*
  142. * CKeyboardNavDelayTimer::GetTimerMap
  143. *
  144. * Returns a reference to the data structure that maps timer IDs to
  145. * CKeyboardNavDelayTimer objects.
  146. *--------------------------------------------------------------------------*/
  147. CKeyboardNavDelayTimer::CTimerMap& CKeyboardNavDelayTimer::GetTimerMap()
  148. {
  149. static CTimerMap map;
  150. return (map);
  151. }