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.

215 lines
5.1 KiB

  1. // Copyright (c) 2000 Microsoft Corporation. All rights reserved.
  2. //
  3. // Implementation of CSliderValue.
  4. //
  5. #include "stdafx.h"
  6. #include "ControlHelp.h"
  7. #include <commctrl.h>
  8. #include <stdio.h>
  9. //////////////////////////////////////////////////////////////////////////////
  10. // CSliderValue
  11. const short g_sMaxContinuousTicks = 100;
  12. const int g_iMaxCharBuffer = 50; // # characters big enough to hold -FLT_MAX with room to spare
  13. CSliderValue::CSliderValue()
  14. : m_fInit(false)
  15. {
  16. }
  17. void CSliderValue::Init(
  18. HWND hwndSlider,
  19. HWND hwndEdit,
  20. float fMin,
  21. float fMax,
  22. bool fDiscrete)
  23. {
  24. m_hwndSlider = hwndSlider;
  25. m_hwndEdit = hwndEdit;
  26. m_fMin = fMin;
  27. m_fMax = fMax;
  28. m_fDiscrete = fDiscrete;
  29. short sMin;
  30. short sMax;
  31. short sTicks = 4; // Lots of ticks become less useful as guides. Use quarters for fine-grained sliders.
  32. if (m_fDiscrete)
  33. {
  34. sMin = static_cast<short>(fMin);
  35. sMax = static_cast<short>(fMax);
  36. if (sMax - sMin <= 10)
  37. sTicks = sMax - sMin;
  38. }
  39. else
  40. {
  41. sMin = 0;
  42. sMax = g_sMaxContinuousTicks;
  43. }
  44. SendMessage(m_hwndSlider, TBM_SETRANGE, TRUE, MAKELONG(sMin, sMax));
  45. SendMessage(m_hwndSlider, TBM_SETTICFREQ, (sMax - sMin) / sTicks, 0);
  46. m_fInit = true;
  47. }
  48. void CSliderValue::SetValue(float fPos)
  49. {
  50. if (!m_fInit)
  51. return;
  52. UpdateEditBox(fPos);
  53. UpdateSlider();
  54. }
  55. float CSliderValue::GetValue()
  56. {
  57. if (!m_fInit)
  58. return 0;
  59. LRESULT lrLen = SendMessage(m_hwndEdit, WM_GETTEXTLENGTH, 0, 0);
  60. if (lrLen >= g_iMaxCharBuffer)
  61. return 0;
  62. char szText[g_iMaxCharBuffer] = "";
  63. SendMessage(m_hwndEdit, WM_GETTEXT, g_iMaxCharBuffer, reinterpret_cast<LPARAM>(szText));
  64. float fVal = static_cast<float>(m_fDiscrete ? atoi(szText) : atof(szText));
  65. if (fVal < m_fMin) fVal = m_fMin;
  66. if (fVal > m_fMax) fVal = m_fMax;
  67. return fVal;
  68. }
  69. float CSliderValue::GetSliderValue()
  70. {
  71. short sPos = static_cast<short>(SendMessage(m_hwndSlider, TBM_GETPOS, 0, 0));
  72. if (m_fDiscrete)
  73. {
  74. return sPos;
  75. }
  76. float fRet = (m_fMax - m_fMin) * sPos / g_sMaxContinuousTicks + m_fMin;
  77. return fRet;
  78. }
  79. LRESULT CSliderValue::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  80. {
  81. if (!m_fInit)
  82. return FALSE;
  83. bHandled = FALSE;
  84. switch (uMsg)
  85. {
  86. case WM_HSCROLL:
  87. if (reinterpret_cast<HWND>(lParam) == m_hwndSlider && LOWORD(wParam) >= TB_LINEUP && LOWORD(wParam) <= TB_ENDTRACK)
  88. {
  89. UpdateEditBox(GetSliderValue());
  90. bHandled = TRUE;
  91. }
  92. break;
  93. case WM_COMMAND:
  94. if (HIWORD(wParam) == EN_KILLFOCUS && reinterpret_cast<HWND>(lParam) == m_hwndEdit)
  95. {
  96. UpdateSlider();
  97. bHandled = TRUE;
  98. }
  99. break;
  100. }
  101. return 0;
  102. }
  103. void CSliderValue::UpdateEditBox(float fPos)
  104. {
  105. char szText[g_iMaxCharBuffer] = "";
  106. if (m_fDiscrete)
  107. {
  108. short sPos = static_cast<short>(fPos);
  109. sprintf(szText, "%hd", sPos);
  110. }
  111. else
  112. {
  113. sprintf(szText, "%.3hf", fPos);
  114. }
  115. SendMessage(m_hwndEdit, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(szText));
  116. }
  117. void CSliderValue::UpdateSlider()
  118. {
  119. float fVal = GetValue();
  120. short sPos = static_cast<short>(m_fDiscrete ? fVal : g_sMaxContinuousTicks * ((fVal - m_fMin) / (m_fMax - m_fMin)));
  121. SendMessage(m_hwndSlider, TBM_SETPOS, TRUE, sPos);
  122. UpdateEditBox(fVal); // this resets the input box back to the set float value in case the input was invalid
  123. }
  124. //////////////////////////////////////////////////////////////////////////////
  125. // CSliderValue
  126. CRadioChoice::CRadioChoice(const ButtonEntry *pButtonInfo)
  127. : m_pButtonInfo(pButtonInfo)
  128. {
  129. }
  130. void CRadioChoice::SetChoice(HWND hDlg, LONG lValue)
  131. {
  132. for (const ButtonEntry *p = m_pButtonInfo; p->nIDDlgItem; ++p)
  133. {
  134. if (p->lValue == lValue)
  135. {
  136. CheckDlgButton(hDlg, p->nIDDlgItem, BST_CHECKED);
  137. return;
  138. }
  139. }
  140. }
  141. LONG CRadioChoice::GetChoice(HWND hDlg)
  142. {
  143. for (const ButtonEntry *p = m_pButtonInfo; p->nIDDlgItem; ++p)
  144. {
  145. if (BST_CHECKED == IsDlgButtonChecked(hDlg, p->nIDDlgItem))
  146. {
  147. return p->lValue;
  148. }
  149. }
  150. return 0;
  151. }
  152. LRESULT CRadioChoice::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  153. {
  154. bHandled = FALSE;
  155. if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED)
  156. {
  157. for (const ButtonEntry *p = m_pButtonInfo; p->nIDDlgItem; ++p)
  158. {
  159. if (p->nIDDlgItem == LOWORD(wParam))
  160. {
  161. bHandled = TRUE;
  162. return 0;
  163. }
  164. }
  165. }
  166. return 0;
  167. }
  168. //////////////////////////////////////////////////////////////////////////////
  169. // MessageHandlerChain
  170. LRESULT MessageHandlerChain(Handler **ppHandlers, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  171. {
  172. LRESULT lr = 0;
  173. bHandled = FALSE;
  174. for (Handler **pp = ppHandlers; *pp && !bHandled; ++pp)
  175. {
  176. lr = (*pp)->MessageHandler(uMsg, wParam, lParam, bHandled);
  177. }
  178. return lr;
  179. }