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.

433 lines
12 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: reader.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Implements support reader-mode routines for auto-scrolling and panning.
  7. *
  8. * History:
  9. * 31-Jan-1997 vadimg created
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #define TIMERID 1
  14. __inline FReader2Dim(PREADERINFO prdr)
  15. {
  16. return ((prdr->dwFlags & (RDRMODE_HORZ | RDRMODE_VERT)) ==
  17. (RDRMODE_HORZ | RDRMODE_VERT));
  18. }
  19. __inline FReaderVert(PREADERINFO prdr)
  20. {
  21. return (prdr->dwFlags & RDRMODE_VERT);
  22. }
  23. __inline FReaderHorz(PREADERINFO prdr)
  24. {
  25. return (prdr->dwFlags & RDRMODE_HORZ);
  26. }
  27. __inline FReaderDiag(PREADERINFO prdr)
  28. {
  29. return (prdr->dwFlags & RDRMODE_DIAG);
  30. }
  31. /***************************************************************************\
  32. * ReaderSetCursor
  33. *
  34. \***************************************************************************/
  35. void ReaderSetCursor(PREADERINFO prdr, UINT uCursor)
  36. {
  37. if (prdr->uCursor != uCursor) {
  38. NtUserSetCursor(LoadCursor(NULL, MAKEINTRESOURCE(uCursor)));
  39. prdr->uCursor = uCursor;
  40. }
  41. }
  42. /***************************************************************************\
  43. * ReaderMouseMove
  44. *
  45. * Calculate dx and dy based on the flags passed in. Provide visual
  46. * feedback for the reader mode by setting the correct cursor.
  47. *
  48. * 2-Feb-1997 vadimg created
  49. \***************************************************************************/
  50. void ReaderMouseMove(PWND pwnd, PREADERINFO prdr, LPARAM lParam)
  51. {
  52. int dx = 0, dy = 0;
  53. LPRECT prc = KPRECT_TO_PRECT(&pwnd->rcWindow);
  54. UINT uCursor;
  55. POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
  56. _ClientToScreen(pwnd, &pt);
  57. if (FReaderVert(prdr)) {
  58. if (pt.y < prc->top) {
  59. dy = pt.y - prc->top;
  60. } else if (pt.y > prc->bottom) {
  61. dy = pt.y - prc->bottom;
  62. }
  63. }
  64. if (FReaderHorz(prdr)) {
  65. if (pt.x < prc->left) {
  66. dx = pt.x - prc->left;
  67. } else if (pt.x > prc->right) {
  68. dx = pt.x - prc->right;
  69. }
  70. }
  71. if (FReader2Dim(prdr)) {
  72. if (dx == 0 && dy == 0) {
  73. ReaderSetCursor(prdr, OCR_RDR2DIM);
  74. goto Exit;
  75. }
  76. if (!FReaderDiag(prdr)) {
  77. if (prdr->dy != 0) {
  78. if (abs(dx) > abs(prdr->dy)) {
  79. dy = 0;
  80. } else {
  81. dx = 0;
  82. }
  83. } else if (prdr->dx != 0) {
  84. if (abs(dy) > abs(prdr->dx)) {
  85. dx = 0;
  86. } else {
  87. dy = 0;
  88. }
  89. } else if (dy != 0) {
  90. dx = 0;
  91. }
  92. }
  93. } else if (FReaderVert(prdr) && dy == 0) {
  94. ReaderSetCursor(prdr, OCR_RDRVERT);
  95. goto Exit;
  96. } else if (FReaderHorz(prdr) && dx == 0) {
  97. ReaderSetCursor(prdr, OCR_RDRHORZ);
  98. goto Exit;
  99. }
  100. if (dx == 0) {
  101. uCursor = (dy > 0) ? OCR_RDRSOUTH : OCR_RDRNORTH;
  102. } else if (dx > 0) {
  103. if (dy == 0) {
  104. uCursor = OCR_RDREAST;
  105. } else {
  106. uCursor = (dy > 0) ? OCR_RDRSOUTHEAST : OCR_RDRNORTHEAST;
  107. }
  108. } else if (dx < 0) {
  109. if (dy == 0) {
  110. uCursor = OCR_RDRWEST;
  111. } else {
  112. uCursor = (dy > 0) ? OCR_RDRSOUTHWEST : OCR_RDRNORTHWEST;
  113. }
  114. }
  115. ReaderSetCursor(prdr, uCursor);
  116. Exit:
  117. prdr->dx = dx;
  118. prdr->dy = dy;
  119. }
  120. /***************************************************************************\
  121. * ReaderFeedback
  122. *
  123. * 2-Feb-1997 vadimg created
  124. \***************************************************************************/
  125. void ReaderFeedback(PWND pwnd, PREADERINFO prdr)
  126. {
  127. if (prdr->dx == 0 && prdr->dy == 0)
  128. return;
  129. if (prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_SCROLL,
  130. prdr->dx, prdr->dy) == 0) {
  131. NtUserDestroyWindow(PtoH(pwnd));
  132. }
  133. }
  134. /***************************************************************************\
  135. * ReaderWndProc
  136. *
  137. * 31-Jan-1997 vadimg created
  138. \***************************************************************************/
  139. LRESULT CALLBACK ReaderWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  140. {
  141. HDC hdc, hdcMem;
  142. HPEN hpen, hpenOld;
  143. HBRUSH hbrOld;
  144. HRGN hrgn;
  145. RECT rc;
  146. POINT pt;
  147. int nBitmap, cx, cy;
  148. PREADERINFO prdr;
  149. PWND pwnd;
  150. LPCREATESTRUCT pcs;
  151. PREADERMODE prdrm;
  152. BITMAP bmp;
  153. if ((pwnd = ValidateHwnd(hwnd)) == NULL)
  154. return 0;
  155. prdr = ((PREADERWND)pwnd)->prdr;
  156. switch (msg) {
  157. case WM_TIMER:
  158. ReaderFeedback(pwnd, prdr);
  159. return 0;
  160. case WM_MOUSEWHEEL:
  161. case WM_LBUTTONUP:
  162. case WM_RBUTTONUP:
  163. case WM_XBUTTONUP:
  164. case WM_LBUTTONDOWN:
  165. case WM_RBUTTONDOWN:
  166. case WM_MBUTTONDOWN:
  167. case WM_XBUTTONDOWN:
  168. case WM_KEYDOWN:
  169. ReleaseCapture();
  170. return 0;
  171. case WM_MOUSEMOVE:
  172. ReaderMouseMove(pwnd, prdr, lParam);
  173. return 0;
  174. case WM_MBUTTONUP:
  175. pt.x = GET_X_LPARAM(lParam);
  176. pt.y = GET_Y_LPARAM(lParam);
  177. GetClientRect(hwnd, &rc);
  178. if (!PtInRect(&rc, pt)) {
  179. ReleaseCapture();
  180. }
  181. return 0;
  182. case WM_CAPTURECHANGED:
  183. NtUserDestroyWindow(hwnd);
  184. return 0;
  185. case WM_NCDESTROY:
  186. NtUserKillTimer(hwnd, TIMERID);
  187. prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_END, 0, 0);
  188. if (prdr->hbm != NULL) {
  189. DeleteObject(prdr->hbm);
  190. }
  191. UserLocalFree(prdr);
  192. return 0;
  193. case WM_CREATE:
  194. if ((prdr = UserLocalAlloc(HEAP_ZERO_MEMORY, sizeof(READERINFO))) == NULL)
  195. return -1;
  196. pcs = (LPCREATESTRUCT)lParam;
  197. prdrm = (PREADERMODE)pcs->lpCreateParams;
  198. RtlCopyMemory(prdr, prdrm, sizeof(READERMODE));
  199. SetWindowLongPtr(hwnd, 0, (LONG_PTR)prdr);
  200. if (prdr->pfnReaderModeProc == NULL) {
  201. return -1;
  202. }
  203. if (FReader2Dim(prdr)) {
  204. nBitmap = OBM_RDR2DIM;
  205. } else if (FReaderVert(prdr)) {
  206. nBitmap = OBM_RDRVERT;
  207. } else if (FReaderHorz(prdr)) {
  208. nBitmap = OBM_RDRHORZ;
  209. } else {
  210. return -1;
  211. }
  212. SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
  213. SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_CLIPSIBLINGS);
  214. prdr->hbm = LoadBitmap(hmodUser, MAKEINTRESOURCE(nBitmap));
  215. if (prdr->hbm == NULL ||
  216. GetObject(prdr->hbm, sizeof(BITMAP), &bmp) == 0) {
  217. return -1;
  218. }
  219. if (prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_START, 0, 0) == 0) {
  220. return -1;
  221. }
  222. prdr->dxBmp = bmp.bmWidth;
  223. prdr->dyBmp = bmp.bmHeight;
  224. cx = bmp.bmWidth + 1;
  225. cy = bmp.bmHeight + 1;
  226. GetCursorPos(&pt);
  227. pt.x -= cx/2;
  228. pt.y -= cy/2;
  229. if ((hrgn = CreateEllipticRgn(0, 0, cx, cy)) != NULL) {
  230. SetWindowRgn(hwnd, hrgn, FALSE);
  231. }
  232. NtUserSetWindowPos(hwnd, HWND_TOPMOST, pt.x, pt.y, cx, cy,
  233. SWP_SHOWWINDOW | SWP_NOACTIVATE);
  234. NtUserSetCapture(hwnd);
  235. NtUserSetFocus(hwnd);
  236. NtUserSetTimer(hwnd, TIMERID, 10, NULL);
  237. return 0;
  238. case WM_ERASEBKGND:
  239. hdc = (HDC)wParam;
  240. if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
  241. return FALSE;
  242. SelectObject(hdcMem, prdr->hbm);
  243. hpen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
  244. hpenOld = (HPEN)SelectObject(hdc, hpen);
  245. hbrOld = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
  246. BitBlt(hdc, 0, 0, prdr->dxBmp, prdr->dyBmp, hdcMem, 0, 0, SRCCOPY);
  247. Ellipse(hdc, 0, 0, prdr->dxBmp, prdr->dyBmp);
  248. SelectObject(hdc, hpenOld);
  249. SelectObject(hdc, hbrOld);
  250. DeleteObject(hpen);
  251. DeleteObject(hdcMem);
  252. return TRUE;
  253. }
  254. return DefWindowProc(hwnd, msg, wParam, lParam);
  255. }
  256. /***************************************************************************\
  257. * ReaderProcInternal
  258. *
  259. \***************************************************************************/
  260. LONG ReaderProcInternal(LPARAM lParam, int nCode, int dx, int dy)
  261. {
  262. DWORD dwDelay;
  263. UINT uMsg, uCode;
  264. int n, nAbs;
  265. if (nCode != RDRCODE_SCROLL)
  266. return TRUE;
  267. if (dy != 0) {
  268. uCode = SB_LINEUP;
  269. uMsg = WM_VSCROLL;
  270. n = dy;
  271. } else {
  272. uCode = SB_LINELEFT;
  273. uMsg = WM_HSCROLL;
  274. n = dx;
  275. }
  276. nAbs = abs(n);
  277. if (nAbs >= 120) {
  278. uCode += 2;
  279. dwDelay = 0;
  280. } else {
  281. dwDelay = 1000 - (nAbs / 2) * 15;
  282. }
  283. if (n > 0) {
  284. uCode += 1;
  285. }
  286. SendMessage((HWND)lParam, uMsg, MAKELONG(uCode, dwDelay), 0);
  287. UpdateWindow((HWND)lParam);
  288. return TRUE;
  289. }
  290. /***************************************************************************\
  291. * EnterReaderMode
  292. *
  293. \***************************************************************************/
  294. #define READERCLASS L"User32_ReaderMode"
  295. ATOM gatomReaderMode = 0;
  296. BOOL EnterReaderMode(PREADERMODE prdrm)
  297. {
  298. WNDCLASSEX wce;
  299. if (GetCapture() != NULL)
  300. return FALSE;
  301. if (gatomReaderMode == 0) {
  302. wce.cbSize = sizeof(wce);
  303. wce.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  304. wce.lpfnWndProc = ReaderWndProc;
  305. wce.cbClsExtra = 0;
  306. wce.cbWndExtra = sizeof(PREADERINFO);
  307. wce.hInstance = hmodUser;
  308. wce.hIcon = NULL;
  309. wce.hCursor = LoadCursor(NULL, IDC_ARROW);
  310. wce.hbrBackground = GetStockObject(WHITE_BRUSH);
  311. wce.lpszMenuName = NULL;
  312. wce.lpszClassName = READERCLASS;
  313. wce.hIconSm = NULL;
  314. if ((gatomReaderMode = RegisterClassExWOWW(&wce, NULL, FNID_DDE_BIT, 0)) == 0) {
  315. RIPMSG0(RIP_WARNING, "EnterReaderMode: failed to register ReaderMode");
  316. return 0;
  317. }
  318. }
  319. return (_CreateWindowEx(0, READERCLASS, NULL, 0, 0, 0, 0, 0,
  320. NULL, NULL, hmodUser, (PVOID)prdrm, 0) != NULL);
  321. }
  322. /***************************************************************************\
  323. * FScrollEnabled
  324. *
  325. \***************************************************************************/
  326. BOOL FScrollEnabled(PWND pwnd, BOOL fVert)
  327. {
  328. PSBINFO pw;
  329. int nFlags;
  330. if (!TestWF(pwnd, fVert ? WFVPRESENT : WFHPRESENT))
  331. return FALSE;
  332. if ((pw = (PSBINFO)REBASEALWAYS(pwnd, pSBInfo)) == NULL)
  333. return FALSE;
  334. nFlags = fVert ? (pw->WSBflags >> 2) : pw->WSBflags;
  335. if ((nFlags & SB_DISABLE_MASK) == SB_DISABLE_MASK)
  336. return FALSE;
  337. return TRUE;
  338. }
  339. /***************************************************************************\
  340. * EnterReaderModeHelper
  341. *
  342. \***************************************************************************/
  343. BOOL EnterReaderModeHelper(HWND hwnd)
  344. {
  345. PWND pwnd = ValidateHwnd(hwnd);
  346. READERMODE rdrm;
  347. rdrm.cbSize = sizeof(READERMODE);
  348. rdrm.pfnReaderModeProc = ReaderProcInternal;
  349. rdrm.lParam = (LPARAM)hwnd;
  350. rdrm.dwFlags = 0;
  351. if (FScrollEnabled(pwnd, TRUE)) {
  352. rdrm.dwFlags |= RDRMODE_VERT;
  353. }
  354. if (FScrollEnabled(pwnd, FALSE)) {
  355. rdrm.dwFlags |= RDRMODE_HORZ;
  356. }
  357. return EnterReaderMode(&rdrm);
  358. }