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.

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