Leaked source code of windows server 2003
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.

256 lines
7.2 KiB

  1. #include "ctlspriv.h"
  2. static struct {
  3. WPARAM vk1;
  4. WPARAM vk2;
  5. int dx;
  6. int dy;
  7. } arrNumMaps[] =
  8. {
  9. { VK_NUMPAD1, VK_END, -RM_SCROLLUNIT, RM_SCROLLUNIT,},
  10. { VK_NUMPAD2, VK_DOWN, 0, RM_SCROLLUNIT},
  11. { VK_NUMPAD3, VK_NEXT, RM_SCROLLUNIT, RM_SCROLLUNIT},
  12. { VK_NUMPAD4, VK_LEFT, -RM_SCROLLUNIT, 0},
  13. { VK_NUMPAD5, VK_CLEAR, 0, 0},
  14. { VK_NUMPAD6, VK_RIGHT, RM_SCROLLUNIT, 0},
  15. { VK_NUMPAD7, VK_HOME, -RM_SCROLLUNIT, -RM_SCROLLUNIT},
  16. { VK_NUMPAD8, VK_UP, 0, -RM_SCROLLUNIT},
  17. { VK_NUMPAD9, VK_PRIOR, RM_SCROLLUNIT, -RM_SCROLLUNIT},
  18. };
  19. // do some keyboard handling...
  20. // this works like USER's arrow keys for resizing
  21. // bugbug, diagonals don't work right now
  22. void RM_HandleKeyDown(LPRECT prcHot, WPARAM wParam, LPARAM lParam)
  23. {
  24. int i;
  25. POINT pt;
  26. GetCursorPos(&pt);
  27. for (i = ARRAYSIZE(arrNumMaps) - 1 ; i >= 0; i--) {
  28. if (wParam == arrNumMaps[i].vk1 ||
  29. wParam == arrNumMaps[i].vk2) {
  30. break;
  31. }
  32. }
  33. if (i == -1) {
  34. ReleaseCapture();
  35. return;
  36. }
  37. // this deals with if the cursor is within the bounds of the rect
  38. if (pt.x < prcHot->right &&
  39. pt.x >= prcHot->left &&
  40. arrNumMaps[i].dx) {
  41. if (arrNumMaps[i].dx > 0)
  42. pt.x = prcHot->right - 2;
  43. else
  44. pt.x = prcHot->left + 1;
  45. }
  46. if (pt.y < prcHot->bottom &&
  47. pt.y >= prcHot->top &&
  48. arrNumMaps[i].dy) {
  49. if (arrNumMaps[i].dy > 0)
  50. pt.y = prcHot->bottom - 2;
  51. else
  52. pt.y = prcHot->top + 1;
  53. }
  54. pt.x += arrNumMaps[i].dx;
  55. pt.y += arrNumMaps[i].dy;
  56. if (!arrNumMaps[i].dx && !arrNumMaps[i].dy) {
  57. // special case this for centering
  58. pt.x = (prcHot->right + prcHot->left) / 2;
  59. pt.y = (prcHot->top + prcHot->bottom) / 2;
  60. }
  61. // all we do is move the cursor.. the RM_CheckScroll will do the actual
  62. // scrolling for us.
  63. SetCursorPos(pt.x, pt.y);
  64. }
  65. void RM_GetScrollXY(PREADERMODEINFO prmi, LPRECT prcHot, LPINT pdx, LPINT pdy)
  66. {
  67. POINT pt;
  68. GetCursorPos(&pt);
  69. *pdx = 0;
  70. *pdy = 0;
  71. if (pt.x <= prcHot->left) {
  72. *pdx = ((pt.x - prcHot->left) / RM_SCROLLUNIT) - 1;
  73. } else if (pt.x >= prcHot->right) {
  74. *pdx = ((pt.x - prcHot->right) / RM_SCROLLUNIT) + 1;
  75. }
  76. if (pt.y <= prcHot->top) {
  77. *pdy = ((pt.y - prcHot->top) / RM_SCROLLUNIT) - 1;
  78. } else if (pt.y >= prcHot->bottom) {
  79. *pdy = ((pt.y - prcHot->bottom) / RM_SCROLLUNIT) + 1;
  80. }
  81. if (prmi->fFlags & RMF_VERTICALONLY)
  82. *pdx = 0;
  83. if (prmi->fFlags & RMF_HORIZONTALONLY)
  84. *pdy = 0;
  85. }
  86. void RM_CheckScroll(PREADERMODEINFO prmi, LPRECT prcHot)
  87. {
  88. int dx;
  89. int dy;
  90. RM_GetScrollXY(prmi, prcHot, &dx, &dy);
  91. prmi->pfnScroll(prmi, dx, dy);
  92. }
  93. void RM_SetCursor(PREADERMODEINFO prmi, LPRECT prcHot)
  94. {
  95. int dx;
  96. int dy;
  97. LPCTSTR pRes;
  98. RM_GetScrollXY(prmi, prcHot, &dx, &dy);
  99. // default is center
  100. if (prmi->fFlags & RMF_VERTICALONLY)
  101. pRes = IDC_VERTICALONLY;
  102. else if (prmi->fFlags & RMF_HORIZONTALONLY)
  103. pRes = IDC_HORIZONTALONLY;
  104. else
  105. pRes = IDC_MOVE2D;
  106. // multiply to figure out if either is zero and also the sign parity
  107. if (dy * dx) {
  108. // diagonal case
  109. if (dy > 0) {
  110. if (dx > 0)
  111. pRes = IDC_SOUTHEAST;
  112. else
  113. pRes = IDC_SOUTHWEST;
  114. } else {
  115. if (dx > 0)
  116. pRes = IDC_NORTHEAST;
  117. else
  118. pRes = IDC_NORTHWEST;
  119. }
  120. } else {
  121. // simple horizontal or vertical case
  122. if (dy > 0)
  123. pRes = IDC_SOUTH;
  124. else if (dy < 0)
  125. pRes = IDC_NORTH;
  126. else if (dx < 0)
  127. pRes = IDC_WEST;
  128. else if (dx > 0)
  129. pRes = IDC_EAST;
  130. }
  131. SetCursor(LoadCursor(HINST_THISDLL, pRes));
  132. }
  133. void DoReaderMode(PREADERMODEINFO prmi)
  134. {
  135. RECT rcHot;
  136. if (!prmi->hwnd || prmi->cbSize != sizeof(*prmi))
  137. return;
  138. SetCapture(prmi->hwnd);
  139. // if they didn't pass in a rect, then use the window
  140. if (!prmi->prc) {
  141. GetWindowRect(prmi->hwnd, &rcHot );
  142. } else {
  143. rcHot = *prmi->prc;
  144. MapWindowPoints(prmi->hwnd, HWND_DESKTOP, (LPPOINT)&rcHot, 2);
  145. }
  146. // set the cursor to the center of the hot rect if they ask us to
  147. if (prmi->fFlags & RMF_ZEROCURSOR) {
  148. SetCursorPos((rcHot.left + rcHot.right)/2,
  149. (rcHot.top + rcHot.bottom)/2);
  150. }
  151. while (GetCapture() == prmi->hwnd) {
  152. BOOL fMessage;
  153. MSG32 msg32;
  154. RM_CheckScroll(prmi, &rcHot);
  155. // Try to peek keyboard message first, then mouse message,
  156. // and finally, other message. This is for raid 44392.
  157. // During scrolling, Trident might generate too many WM_PAINT
  158. // messages that push keyboard/mouse message (that DoReaderMode()
  159. // uses to stop auto-scroll mode) down in message pump, and we can
  160. // not get those messages until we peek and process all these
  161. // WM_PAINT messages. This is way cuto-scroll mode can be stopped
  162. // only by moving cursor back to origin circle (Trident does not
  163. // scroll, so no need to paint). Trident's scroll performance
  164. // issue will be worked on after RTM (raid 33232).
  165. //
  166. fMessage = PeekMessage32(&msg32, NULL, WM_KEYFIRST, WM_KEYLAST,
  167. PM_REMOVE, TRUE);
  168. if (!fMessage)
  169. {
  170. fMessage = PeekMessage32(&msg32, NULL, WM_MOUSEFIRST, WM_MOUSELAST,
  171. PM_REMOVE, TRUE);
  172. if (!fMessage)
  173. {
  174. fMessage = PeekMessage32(&msg32, NULL, 0, 0, PM_REMOVE, TRUE);
  175. }
  176. }
  177. if (fMessage) {
  178. if (!prmi->pfnTranslateDispatch ||
  179. !prmi->pfnTranslateDispatch((LPMSG)&msg32)) {
  180. if (msg32.message == g_msgMSWheel)
  181. goto BailOut;
  182. switch(msg32.message) {
  183. case WM_LBUTTONUP:
  184. case WM_RBUTTONUP:
  185. case WM_MBUTTONUP:
  186. case WM_LBUTTONDOWN:
  187. case WM_RBUTTONDOWN:
  188. case WM_MBUTTONDOWN:
  189. case WM_SYSKEYDOWN:
  190. BailOut:
  191. ReleaseCapture();
  192. break;
  193. case WM_KEYDOWN:
  194. // if it's an arrow key, move the mouse cursor
  195. RM_HandleKeyDown(&rcHot, msg32.wParam, msg32.lParam);
  196. break;
  197. case WM_MOUSEMOVE:
  198. case WM_SETCURSOR:
  199. RM_SetCursor(prmi, &rcHot);
  200. break;
  201. default:
  202. TranslateMessage32(&msg32, TRUE);
  203. DispatchMessage32(&msg32, TRUE);
  204. }
  205. }
  206. }
  207. else WaitMessage();
  208. }
  209. }