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.

1000 lines
26 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // bscroll.c - bitmap scroll functions
  24. ////
  25. #include "winlocal.h"
  26. #include <stdlib.h>
  27. #include "bscroll.h"
  28. #include "gfx.h"
  29. #include "mem.h"
  30. #include "sys.h"
  31. #include "trace.h"
  32. #include "wnd.h"
  33. ////
  34. // private definitions
  35. ////
  36. #define BSCROLLCLASS TEXT("BScrollClass")
  37. #define ID_TIMER_SCROLL 1024
  38. #define BSCROLL_SCROLLING 0x00000001
  39. #define BSCROLL_DRAGGING 0x00000002
  40. #define BSCROLL_PAUSED 0x00000004
  41. // bscroll control struct
  42. //
  43. typedef struct BSCROLL
  44. {
  45. DWORD dwVersion;
  46. HINSTANCE hInst;
  47. HWND hwndParent;
  48. HTASK hTask;
  49. HBITMAP hbmpBackground; // $FIXUP - make copy during BScrollInit
  50. HBITMAP hbmpForeground; // $FIXUP - make copy during BScrollInit
  51. COLORREF crTransparent;
  52. HPALETTE hPalette;
  53. UINT msScroll;
  54. int pelScroll;
  55. DWORD dwReserved;
  56. DWORD dwFlags;
  57. HWND hwndBScroll;
  58. HDC hdcMem;
  59. HBITMAP hbmpMem;
  60. HBITMAP hbmpMemSave;
  61. HRGN hrgnLeft;
  62. HRGN hrgnRight;
  63. HRGN hrgnUp;
  64. HRGN hrgnDown;
  65. DWORD dwState;
  66. int xDrag;
  67. int yDrag;
  68. } BSCROLL, FAR *LPBSCROLL;
  69. // helper functions
  70. //
  71. LRESULT DLLEXPORT CALLBACK BScrollWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  72. static BOOL BScrollOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);
  73. static BOOL BScrollOnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
  74. static void BScrollOnDestroy(HWND hwnd);
  75. static void BScrollOnSize(HWND hwnd, UINT state, int cx, int cy);
  76. static void BScrollOnPaint(HWND hwnd);
  77. static void BScrollOnTimer(HWND hwnd, UINT id);
  78. static void BScrollOnChar(HWND hwnd, UINT ch, int cRepeat);
  79. static void BScrollOnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
  80. static void BScrollOnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags);
  81. static void BScrollOnRButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
  82. static void BScrollOnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags);
  83. static void BScrollOnMouseMove(HWND hwnd, int x, int y, UINT keyFlags);
  84. static int BScrollChangeDirection(LPBSCROLL lpBScroll, int x, int y, DWORD dwFlags);
  85. static LPBSCROLL BScrollGetPtr(HBSCROLL hBScroll);
  86. static HBSCROLL BScrollGetHandle(LPBSCROLL lpBScroll);
  87. ////
  88. // public functions
  89. ////
  90. // BScrollInit - initialize bscroll engine
  91. // <dwVersion> (i) must be BSCROLL_VERSION
  92. // <hInst> (i) instance handle of calling module
  93. // <hwndParent> (i) window which will own the bscroll window
  94. // <hbmpBackground> (i) bitmap to display in background
  95. // NULL no background bitmap
  96. // <hbmpForeground> (i) bitmap to display in foreground
  97. // NULL no foreground bitmap
  98. // <crTransparent> (i) transparent color in foreground bitmap
  99. // <hPalette> (i) palette
  100. // NULL use default palette
  101. // <msScroll> (i) scroll rate in milleseconds
  102. // 0 do not scroll
  103. // <pelScroll> (i) scroll amount in pixels
  104. // <dwReserved> (i) reserved; must be zero
  105. // <dwFlags> (i) control flags
  106. // BSCROLL_BACKGROUND scroll the background bitmap (default)
  107. // BSCROLL_FOREGROUND scroll the foreground bitmap
  108. // BSCROLL_UP scroll the window up
  109. // BSCROLL_DOWN scroll the window down
  110. // BSCROLL_LEFT scroll the window left
  111. // BSCROLL_RIGHT scroll the window right
  112. // BSCROLL_MOUSEMOVE change scroll direction on mouse movement
  113. // BSCROLL_FLIGHTSIM reverses BSCROLL_MOUSEMOVE direction
  114. // BSCROLL_DRAG allow scrolling using mouse drag
  115. // return handle (NULL if error)
  116. //
  117. // NOTE: BScrollInit creates the window but does not start the scrolling.
  118. // See BScrollStart and BScrollStop
  119. //
  120. HBSCROLL DLLEXPORT WINAPI BScrollInit(DWORD dwVersion, HINSTANCE hInst,
  121. HWND hwndParent, HBITMAP hbmpBackground, HBITMAP hbmpForeground,
  122. COLORREF crTransparent, HPALETTE hPalette, UINT msScroll,
  123. int pelScroll, DWORD dwReserved, DWORD dwFlags)
  124. {
  125. BOOL fSuccess = TRUE;
  126. LPBSCROLL lpBScroll = NULL;
  127. WNDCLASS wc;
  128. RECT rcParent;
  129. int idChild = 1;
  130. if (dwVersion != BSCROLL_VERSION)
  131. fSuccess = TraceFALSE(NULL);
  132. else if (hInst == NULL)
  133. fSuccess = TraceFALSE(NULL);
  134. else if ((lpBScroll = (LPBSCROLL) MemAlloc(NULL, sizeof(BSCROLL), 0)) == NULL)
  135. fSuccess = TraceFALSE(NULL);
  136. else if (!GetClientRect(hwndParent, &rcParent))
  137. fSuccess = TraceFALSE(NULL);
  138. else
  139. {
  140. lpBScroll->dwVersion = dwVersion;
  141. lpBScroll->hInst = hInst;
  142. lpBScroll->hTask = GetCurrentTask();
  143. lpBScroll->hwndParent = hwndParent;
  144. lpBScroll->hbmpBackground = hbmpBackground;
  145. lpBScroll->hbmpForeground = hbmpForeground;
  146. lpBScroll->crTransparent = crTransparent;
  147. lpBScroll->hPalette = hPalette;
  148. lpBScroll->msScroll = msScroll;
  149. lpBScroll->pelScroll = pelScroll;
  150. lpBScroll->dwReserved = dwReserved;
  151. lpBScroll->dwFlags = dwFlags;
  152. lpBScroll->hwndBScroll = NULL;
  153. lpBScroll->hdcMem = NULL;
  154. lpBScroll->hbmpMem = NULL;
  155. lpBScroll->hbmpMemSave = NULL;
  156. lpBScroll->hrgnLeft = NULL;
  157. lpBScroll->hrgnRight = NULL;
  158. lpBScroll->hrgnUp = NULL;
  159. lpBScroll->hrgnDown = NULL;
  160. lpBScroll->dwState = 0;
  161. lpBScroll->xDrag = -1;
  162. lpBScroll->yDrag = -1;
  163. }
  164. //
  165. // We should verify lpBScroll before use it
  166. //
  167. if( NULL == lpBScroll )
  168. {
  169. return NULL;
  170. }
  171. // register bscroll window class unless it has been already
  172. //
  173. if (fSuccess && GetClassInfo(lpBScroll->hInst, BSCROLLCLASS, &wc) == 0)
  174. {
  175. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  176. wc.hIcon = (HICON) NULL;
  177. wc.lpszMenuName = NULL;
  178. wc.hInstance = lpBScroll->hInst;
  179. wc.lpszClassName = BSCROLLCLASS;
  180. wc.hbrBackground = NULL;
  181. wc.lpfnWndProc = BScrollWndProc;
  182. wc.style = 0L;
  183. wc.cbWndExtra = sizeof(lpBScroll);
  184. wc.cbClsExtra = 0;
  185. if (!RegisterClass(&wc))
  186. fSuccess = TraceFALSE(NULL);
  187. }
  188. // create a bscroll window
  189. //
  190. if (fSuccess && (lpBScroll->hwndBScroll = CreateWindowEx(
  191. 0L,
  192. BSCROLLCLASS,
  193. (LPTSTR) TEXT(""),
  194. WS_CHILD | WS_VISIBLE,
  195. 0, 0, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top,
  196. hwndParent,
  197. (HMENU)IntToPtr(idChild),
  198. lpBScroll->hInst,
  199. lpBScroll)) == NULL)
  200. {
  201. fSuccess = TraceFALSE(NULL);
  202. }
  203. else
  204. {
  205. // set the cursor to something appropriate
  206. //
  207. SetClassLongPtr(lpBScroll->hwndBScroll, GCLP_HCURSOR,
  208. (dwFlags & BSCROLL_DRAG) ?
  209. (LONG_PTR) LoadCursor(NULL, IDC_SIZEALL) :
  210. (LONG_PTR) LoadCursor(NULL, IDC_ARROW));
  211. }
  212. if (!fSuccess)
  213. {
  214. BScrollTerm(BScrollGetHandle(lpBScroll));
  215. lpBScroll = NULL;
  216. }
  217. return fSuccess ? BScrollGetHandle(lpBScroll) : NULL;
  218. }
  219. // BScrollTerm - shutdown bscroll engine
  220. // <hBScroll> (i) handle returned from BScrollInit
  221. // return 0 if success
  222. //
  223. int DLLEXPORT WINAPI BScrollTerm(HBSCROLL hBScroll)
  224. {
  225. BOOL fSuccess = TRUE;
  226. LPBSCROLL lpBScroll;
  227. if (BScrollStop(hBScroll) != 0)
  228. fSuccess = TraceFALSE(NULL);
  229. else if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
  230. fSuccess = TraceFALSE(NULL);
  231. else if (lpBScroll->hwndBScroll != NULL &&
  232. !DestroyWindow(lpBScroll->hwndBScroll))
  233. fSuccess = TraceFALSE(NULL);
  234. else if ((lpBScroll = MemFree(NULL, lpBScroll)) != NULL)
  235. fSuccess = TraceFALSE(NULL);
  236. return fSuccess ? 0 : -1;
  237. }
  238. // BScrollStart - start bscroll animation
  239. // <hBScroll> (i) handle returned from BScrollInit
  240. // return 0 if success
  241. //
  242. int DLLEXPORT WINAPI BScrollStart(HBSCROLL hBScroll)
  243. {
  244. BOOL fSuccess = TRUE;
  245. LPBSCROLL lpBScroll;
  246. if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
  247. fSuccess = TraceFALSE(NULL);
  248. // set scroll timer if necessary
  249. //
  250. else if (!(lpBScroll->dwState & BSCROLL_SCROLLING) && lpBScroll->msScroll > 0)
  251. {
  252. if (!SetTimer(lpBScroll->hwndBScroll, ID_TIMER_SCROLL,
  253. lpBScroll->msScroll, NULL))
  254. fSuccess = TraceFALSE(NULL);
  255. else
  256. lpBScroll->dwState |= BSCROLL_SCROLLING;
  257. }
  258. return fSuccess ? 0 : -1;
  259. }
  260. // BScrollStop - stop bscroll animation
  261. // <hBScroll> (i) handle returned from BScrollInit
  262. // return 0 if success
  263. //
  264. int DLLEXPORT WINAPI BScrollStop(HBSCROLL hBScroll)
  265. {
  266. BOOL fSuccess = TRUE;
  267. LPBSCROLL lpBScroll;
  268. if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
  269. fSuccess = TraceFALSE(NULL);
  270. // kill scroll timer if necessary
  271. //
  272. else if (lpBScroll->dwState & BSCROLL_SCROLLING)
  273. {
  274. if (!KillTimer(lpBScroll->hwndBScroll, ID_TIMER_SCROLL))
  275. fSuccess = TraceFALSE(NULL);
  276. else
  277. lpBScroll->dwState &= ~BSCROLL_SCROLLING;
  278. }
  279. return fSuccess ? 0 : -1;
  280. }
  281. // BScrollGetWindowHandle - get bscroll screen window handle
  282. // <hBScroll> (i) handle returned from BScrollInit
  283. // return window handle (NULL if error)
  284. //
  285. HWND DLLEXPORT WINAPI BScrollGetWindowHandle(HBSCROLL hBScroll)
  286. {
  287. BOOL fSuccess = TRUE;
  288. LPBSCROLL lpBScroll;
  289. if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
  290. fSuccess = TraceFALSE(NULL);
  291. return fSuccess ? lpBScroll->hwndBScroll : NULL;
  292. }
  293. ////
  294. // helper functions
  295. ////
  296. // BScrollWndProc - window procedure for bscroll screen
  297. //
  298. LRESULT DLLEXPORT CALLBACK BScrollWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  299. {
  300. BOOL fSuccess = TRUE;
  301. LRESULT lResult;
  302. switch (msg)
  303. {
  304. case WM_NCCREATE:
  305. lResult = (LRESULT) HANDLE_WM_NCCREATE(hwnd, wParam, lParam, BScrollOnNCCreate);
  306. break;
  307. case WM_CREATE:
  308. lResult = (LRESULT) HANDLE_WM_CREATE(hwnd, wParam, lParam, BScrollOnCreate);
  309. break;
  310. case WM_DESTROY:
  311. lResult = (LRESULT) HANDLE_WM_DESTROY(hwnd, wParam, lParam, BScrollOnDestroy);
  312. break;
  313. case WM_SIZE:
  314. lResult = (LRESULT) HANDLE_WM_SIZE(hwnd, wParam, lParam, BScrollOnSize);
  315. break;
  316. case WM_PAINT:
  317. lResult = (LRESULT) HANDLE_WM_PAINT(hwnd, wParam, lParam, BScrollOnPaint);
  318. break;
  319. case WM_TIMER:
  320. lResult = (LRESULT) HANDLE_WM_TIMER(hwnd, wParam, lParam, BScrollOnTimer);
  321. break;
  322. case WM_CHAR:
  323. lResult = (LRESULT) HANDLE_WM_CHAR(hwnd, wParam, lParam, BScrollOnChar);
  324. break;
  325. case WM_LBUTTONDOWN:
  326. lResult = (LRESULT) HANDLE_WM_LBUTTONDOWN(hwnd, wParam, lParam, BScrollOnLButtonDown);
  327. break;
  328. case WM_LBUTTONUP:
  329. lResult = (LRESULT) HANDLE_WM_LBUTTONUP(hwnd, wParam, lParam, BScrollOnLButtonUp);
  330. break;
  331. case WM_RBUTTONDOWN:
  332. lResult = (LRESULT) HANDLE_WM_RBUTTONDOWN(hwnd, wParam, lParam, BScrollOnRButtonDown);
  333. break;
  334. case WM_RBUTTONUP:
  335. lResult = (LRESULT) HANDLE_WM_RBUTTONUP(hwnd, wParam, lParam, BScrollOnRButtonUp);
  336. break;
  337. case WM_MOUSEMOVE:
  338. lResult = (LRESULT) HANDLE_WM_MOUSEMOVE(hwnd, wParam, lParam, BScrollOnMouseMove);
  339. break;
  340. default:
  341. lResult = DefWindowProc(hwnd, msg, wParam, lParam);
  342. break;
  343. }
  344. return lResult;
  345. }
  346. // BScrollOnNCCreate - handler for WM_NCCREATE message
  347. //
  348. static BOOL BScrollOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
  349. {
  350. LPBSCROLL lpBScroll = (LPBSCROLL) lpCreateStruct->lpCreateParams;
  351. lpBScroll->hwndBScroll = hwnd;
  352. // store lpBScroll in window extra bytes
  353. //
  354. SetWindowLongPtr(hwnd, 0, (LONG_PTR) lpBScroll);
  355. return FORWARD_WM_NCCREATE(hwnd, lpCreateStruct, DefWindowProc);
  356. }
  357. // BScrollOnCreate - handler for WM_CREATE message
  358. //
  359. static BOOL BScrollOnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
  360. {
  361. BOOL fSuccess = TRUE;
  362. HDC hdc = NULL;
  363. LPBSCROLL lpBScroll;
  364. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  365. fSuccess = TraceFALSE(NULL);
  366. else if ((hdc = GetDC(hwnd)) == NULL)
  367. fSuccess = TraceFALSE(NULL);
  368. else if ((lpBScroll->hdcMem = CreateCompatibleDC(hdc)) == NULL)
  369. fSuccess = TraceFALSE(NULL);
  370. // clean up
  371. //
  372. if (hdc != NULL)
  373. ReleaseDC(hwnd, hdc);
  374. return fSuccess;
  375. }
  376. // BScrollOnDestroy - handler for WM_DESTROY message
  377. //
  378. static void BScrollOnDestroy(HWND hwnd)
  379. {
  380. BOOL fSuccess = TRUE;
  381. LPBSCROLL lpBScroll;
  382. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  383. fSuccess = TraceFALSE(NULL);
  384. else
  385. {
  386. SelectObject(lpBScroll->hdcMem, lpBScroll->hbmpMemSave);
  387. if (lpBScroll->hbmpMem != NULL && !DeleteObject(lpBScroll->hbmpMem))
  388. fSuccess = TraceFALSE(NULL);
  389. else
  390. lpBScroll->hbmpMem = NULL;
  391. if (lpBScroll->hdcMem != NULL && !DeleteDC(lpBScroll->hdcMem))
  392. fSuccess = TraceFALSE(NULL);
  393. else
  394. lpBScroll->hdcMem = NULL;
  395. if (lpBScroll->hrgnLeft != NULL &&
  396. !DeleteObject(lpBScroll->hrgnLeft))
  397. fSuccess = TraceFALSE(NULL);
  398. else
  399. lpBScroll->hrgnLeft = NULL;
  400. if (lpBScroll->hrgnRight != NULL &&
  401. !DeleteObject(lpBScroll->hrgnRight))
  402. fSuccess = TraceFALSE(NULL);
  403. else
  404. lpBScroll->hrgnRight = NULL;
  405. if (lpBScroll->hrgnUp != NULL &&
  406. !DeleteObject(lpBScroll->hrgnUp))
  407. fSuccess = TraceFALSE(NULL);
  408. else
  409. lpBScroll->hrgnUp = NULL;
  410. if (lpBScroll->hrgnDown != NULL &&
  411. !DeleteObject(lpBScroll->hrgnDown))
  412. fSuccess = TraceFALSE(NULL);
  413. else
  414. lpBScroll->hrgnDown = NULL;
  415. }
  416. return;
  417. }
  418. // BScrollOnSize - handler for WM_SIZE message
  419. //
  420. static void BScrollOnSize(HWND hwnd, UINT state, int cx, int cy)
  421. {
  422. BOOL fSuccess = TRUE;
  423. LPBSCROLL lpBScroll;
  424. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  425. fSuccess = TraceFALSE(NULL);
  426. else switch (state)
  427. {
  428. case SIZE_RESTORED:
  429. case SIZE_MAXIMIZED:
  430. {
  431. HDC hdc = NULL;
  432. HBITMAP hbmpTemp = NULL;
  433. if ((hdc = GetDC(hwnd)) == NULL)
  434. fSuccess = TraceFALSE(NULL);
  435. else if ((hbmpTemp = CreateCompatibleBitmap(hdc, cx, cy)) == NULL)
  436. fSuccess = TraceFALSE(NULL);
  437. else
  438. {
  439. lpBScroll->hbmpMemSave = (HBITMAP)
  440. SelectObject(lpBScroll->hdcMem, hbmpTemp);
  441. if (lpBScroll->hbmpMem != NULL &&
  442. !DeleteObject(lpBScroll->hbmpMem))
  443. fSuccess = TraceFALSE(NULL);
  444. else
  445. lpBScroll->hbmpMem = hbmpTemp;
  446. }
  447. if (hdc != NULL)
  448. ReleaseDC(hwnd, hdc);
  449. if (1)
  450. {
  451. POINT aptLeft[5];
  452. POINT aptRight[5];
  453. POINT aptUp[5];
  454. POINT aptDown[5];
  455. aptLeft[0].x = cx / 2;
  456. aptLeft[0].y = cy / 2;
  457. aptLeft[1].x = cx / 4;
  458. aptLeft[1].y = 0;
  459. aptLeft[2].x = 0;
  460. aptLeft[2].y = 0;
  461. aptLeft[3].x = 0;
  462. aptLeft[3].y = cy;
  463. aptLeft[4].x = cx / 4;
  464. aptLeft[4].y = cy;
  465. aptRight[0].x = cx / 2;
  466. aptRight[0].y = cy / 2;
  467. aptRight[1].x = cx - (cx / 4);
  468. aptRight[1].y = 0;
  469. aptRight[2].x = cx;
  470. aptRight[2].y = 0;
  471. aptRight[3].x = cx;
  472. aptRight[3].y = cy;
  473. aptRight[4].x = cx - (cx / 4);
  474. aptRight[4].y = cy;
  475. aptUp[0].x = cx / 2;
  476. aptUp[0].y = cy / 2;
  477. aptUp[1].x = 0;
  478. aptUp[1].y = cy / 4;
  479. aptUp[2].x = 0;
  480. aptUp[2].y = 0;
  481. aptUp[3].x = cx;
  482. aptUp[3].y = 0;
  483. aptUp[4].x = cx;
  484. aptUp[4].y = cy / 4;
  485. aptDown[0].x = cx / 2;
  486. aptDown[0].y = cy / 2;
  487. aptDown[1].x = 0;
  488. aptDown[1].y = cy - (cy / 4);
  489. aptDown[2].x = 0;
  490. aptDown[2].y = cy;
  491. aptDown[3].x = cx;
  492. aptDown[3].y = cy;
  493. aptDown[4].x = cx;
  494. aptDown[4].y = cy - (cy / 4);
  495. if (lpBScroll->hrgnLeft != NULL &&
  496. !DeleteObject(lpBScroll->hrgnLeft))
  497. fSuccess = TraceFALSE(NULL);
  498. else if ((lpBScroll->hrgnLeft = CreatePolygonRgn(aptLeft,
  499. SIZEOFARRAY(aptLeft), WINDING)) == NULL)
  500. fSuccess = TraceFALSE(NULL);
  501. else if (lpBScroll->hrgnRight != NULL &&
  502. !DeleteObject(lpBScroll->hrgnRight))
  503. fSuccess = TraceFALSE(NULL);
  504. else if ((lpBScroll->hrgnRight = CreatePolygonRgn(aptRight,
  505. SIZEOFARRAY(aptRight), WINDING)) == NULL)
  506. fSuccess = TraceFALSE(NULL);
  507. else if (lpBScroll->hrgnUp != NULL &&
  508. !DeleteObject(lpBScroll->hrgnUp))
  509. fSuccess = TraceFALSE(NULL);
  510. else if ((lpBScroll->hrgnUp = CreatePolygonRgn(aptUp,
  511. SIZEOFARRAY(aptUp), WINDING)) == NULL)
  512. fSuccess = TraceFALSE(NULL);
  513. else if (lpBScroll->hrgnDown != NULL &&
  514. !DeleteObject(lpBScroll->hrgnDown))
  515. fSuccess = TraceFALSE(NULL);
  516. else if ((lpBScroll->hrgnDown = CreatePolygonRgn(aptDown,
  517. SIZEOFARRAY(aptDown), WINDING)) == NULL)
  518. fSuccess = TraceFALSE(NULL);
  519. }
  520. InvalidateRect(hwnd, NULL, FALSE);
  521. }
  522. break;
  523. default:
  524. break;
  525. }
  526. return;
  527. }
  528. // BScrollOnPaint - handler for WM_PAINT message
  529. //
  530. static void BScrollOnPaint(HWND hwnd)
  531. {
  532. BOOL fSuccess = TRUE;
  533. BOOL fBitBlt = TRUE;
  534. HDC hdc;
  535. PAINTSTRUCT ps;
  536. LPBSCROLL lpBScroll;
  537. #if 0
  538. DWORD msStartTimer = SysGetTimerCount();
  539. DWORD msStopTimer;
  540. #endif
  541. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  542. fSuccess = TraceFALSE(NULL);
  543. else if ((hdc = BeginPaint(hwnd, &ps)) == NULL)
  544. fSuccess = TraceFALSE(NULL);
  545. else if (lpBScroll->hPalette != NULL)
  546. {
  547. SelectPalette(hdc, lpBScroll->hPalette, FALSE);
  548. if (lpBScroll->hPalette != NULL &&
  549. RealizePalette(hdc) == GDI_ERROR)
  550. fSuccess = TraceFALSE(NULL);
  551. else if (fBitBlt)
  552. {
  553. SelectPalette(lpBScroll->hdcMem, lpBScroll->hPalette, FALSE);
  554. if (RealizePalette(lpBScroll->hdcMem) == GDI_ERROR)
  555. fSuccess = TraceFALSE(NULL);
  556. }
  557. }
  558. //
  559. // $FIXUP - BSCROLL_FOREGROUND not yet suppported
  560. //
  561. if (fSuccess && lpBScroll->hbmpBackground != NULL)
  562. {
  563. if (lpBScroll->dwState & BSCROLL_SCROLLING)
  564. {
  565. int dxScroll = 0;
  566. int dyScroll = 0;
  567. // calculate dx and dy for the scroll
  568. //
  569. if (lpBScroll->dwFlags & BSCROLL_LEFT)
  570. dxScroll = -1 * lpBScroll->pelScroll;
  571. else if (lpBScroll->dwFlags & BSCROLL_RIGHT)
  572. dxScroll = +1 * lpBScroll->pelScroll;
  573. if (lpBScroll->dwFlags & BSCROLL_UP)
  574. dyScroll = -1 * lpBScroll->pelScroll;
  575. else if (lpBScroll->dwFlags & BSCROLL_DOWN)
  576. dyScroll = +1 * lpBScroll->pelScroll;
  577. if (GfxBitmapScroll((fBitBlt ? lpBScroll->hdcMem : hdc),
  578. lpBScroll->hbmpBackground,
  579. dxScroll, dyScroll, BS_ROTATE) != 0)
  580. fSuccess = TraceFALSE(NULL);
  581. }
  582. else if (GfxBitmapDisplay((fBitBlt ? lpBScroll->hdcMem : hdc),
  583. lpBScroll->hbmpBackground, 0, 0, 0) != 0)
  584. fSuccess = TraceFALSE(NULL);
  585. }
  586. if (fSuccess && lpBScroll->hbmpForeground != NULL)
  587. {
  588. if (GfxBitmapDrawTransparent((fBitBlt ? lpBScroll->hdcMem : hdc),
  589. lpBScroll->hbmpForeground, 0, 0, lpBScroll->crTransparent, 0) != 0)
  590. fSuccess = TraceFALSE(NULL);
  591. }
  592. if (fSuccess && fBitBlt && !BitBlt(hdc,
  593. ps.rcPaint.left, ps.rcPaint.top,
  594. ps.rcPaint.right - ps.rcPaint.left,
  595. ps.rcPaint.bottom - ps.rcPaint.top,
  596. lpBScroll->hdcMem,
  597. ps.rcPaint.left, ps.rcPaint.top,
  598. SRCCOPY))
  599. fSuccess = TraceFALSE(NULL);
  600. //
  601. // We should call EndPaint just if we called BeginPaint
  602. // BeginPAint should succeded too?
  603. if((lpBScroll != NULL) && (hdc != NULL))
  604. EndPaint(hwnd, &ps);
  605. #if 0
  606. msStopTimer = SysGetTimerCount();
  607. TracePrintf_1(NULL, 8, TEXT("elapsed=%ld\n"),
  608. (long) (msStopTimer - msStartTimer));
  609. #endif
  610. return;
  611. }
  612. // BScrollOnTimer - handler for WM_TIMER message
  613. //
  614. static void BScrollOnTimer(HWND hwnd, UINT id)
  615. {
  616. BOOL fSuccess = TRUE;
  617. LPBSCROLL lpBScroll;
  618. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  619. fSuccess = TraceFALSE(NULL);
  620. else switch (id)
  621. {
  622. case ID_TIMER_SCROLL:
  623. {
  624. InvalidateRect(hwnd, NULL, FALSE);
  625. }
  626. break;
  627. default:
  628. break;
  629. }
  630. return;
  631. }
  632. // BScrollOnChar - handler for WM_CHAR message
  633. //
  634. static void BScrollOnChar(HWND hwnd, UINT ch, int cRepeat)
  635. {
  636. BOOL fSuccess = TRUE;
  637. LPBSCROLL lpBScroll;
  638. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  639. fSuccess = TraceFALSE(NULL);
  640. return;
  641. }
  642. // BScrollOnLButtonDown - handler for WM_LBUTTONDOWN message
  643. //
  644. static void BScrollOnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
  645. {
  646. BOOL fSuccess = TRUE;
  647. LPBSCROLL lpBScroll;
  648. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  649. fSuccess = TraceFALSE(NULL);
  650. else if (!(lpBScroll->dwState & BSCROLL_DRAGGING) &&
  651. !fDoubleClick && (lpBScroll->dwFlags & BSCROLL_DRAG))
  652. {
  653. lpBScroll->dwState |= BSCROLL_DRAGGING;
  654. lpBScroll->xDrag = x;
  655. lpBScroll->yDrag = y;
  656. SetCapture(lpBScroll->hwndBScroll);
  657. if (lpBScroll->dwState & BSCROLL_SCROLLING)
  658. {
  659. if (BScrollStop(BScrollGetHandle(lpBScroll)) != 0)
  660. fSuccess = TraceFALSE(NULL);
  661. else
  662. lpBScroll->dwState |= BSCROLL_PAUSED;
  663. }
  664. }
  665. if (fSuccess)
  666. FORWARD_WM_LBUTTONDOWN(lpBScroll->hwndParent, fDoubleClick, x, y, keyFlags, SendMessage);
  667. return;
  668. }
  669. // BScrollOnLButtonUp - handler for WM_LBUTTONUP message
  670. //
  671. static void BScrollOnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
  672. {
  673. BOOL fSuccess = TRUE;
  674. LPBSCROLL lpBScroll;
  675. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  676. fSuccess = TraceFALSE(NULL);
  677. else if (lpBScroll->dwState & BSCROLL_DRAGGING)
  678. {
  679. lpBScroll->dwState &= ~BSCROLL_DRAGGING;
  680. lpBScroll->xDrag = -1;
  681. lpBScroll->yDrag = -1;
  682. ReleaseCapture();
  683. if (lpBScroll->dwState & BSCROLL_PAUSED)
  684. {
  685. if (BScrollStart(BScrollGetHandle(lpBScroll)) != 0)
  686. fSuccess = TraceFALSE(NULL);
  687. else
  688. lpBScroll->dwState &= ~BSCROLL_PAUSED;
  689. }
  690. }
  691. if (fSuccess)
  692. FORWARD_WM_LBUTTONUP(lpBScroll->hwndParent, x, y, keyFlags, SendMessage);
  693. return;
  694. }
  695. // BScrollOnRButtonDown - handler for WM_LBUTTONDOWN message
  696. //
  697. static void BScrollOnRButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
  698. {
  699. BOOL fSuccess = TRUE;
  700. LPBSCROLL lpBScroll;
  701. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  702. fSuccess = TraceFALSE(NULL);
  703. if (fSuccess)
  704. FORWARD_WM_RBUTTONDOWN(lpBScroll->hwndParent, fDoubleClick, x, y, keyFlags, SendMessage);
  705. return;
  706. }
  707. // BScrollOnRButtonUp - handler for WM_RBUTTONUP message
  708. //
  709. static void BScrollOnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
  710. {
  711. BOOL fSuccess = TRUE;
  712. LPBSCROLL lpBScroll;
  713. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  714. fSuccess = TraceFALSE(NULL);
  715. if (fSuccess)
  716. FORWARD_WM_RBUTTONUP(lpBScroll->hwndParent, x, y, keyFlags, SendMessage);
  717. return;
  718. }
  719. static void BScrollOnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
  720. {
  721. BOOL fSuccess = TRUE;
  722. LPBSCROLL lpBScroll;
  723. if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
  724. fSuccess = TraceFALSE(NULL);
  725. else if (lpBScroll->dwState & BSCROLL_DRAGGING)
  726. {
  727. if (fSuccess && lpBScroll->hbmpBackground != NULL)
  728. {
  729. int dxScroll = x - lpBScroll->xDrag;
  730. int dyScroll = y - lpBScroll->yDrag;
  731. lpBScroll->xDrag = x;
  732. lpBScroll->yDrag = y;
  733. if (GfxBitmapScroll(lpBScroll->hdcMem,
  734. lpBScroll->hbmpBackground,
  735. dxScroll, dyScroll, BS_ROTATE) != 0)
  736. fSuccess = TraceFALSE(NULL);
  737. else
  738. {
  739. InvalidateRect(lpBScroll->hwndBScroll, NULL, FALSE);
  740. UpdateWindow(lpBScroll->hwndBScroll);
  741. }
  742. }
  743. }
  744. if (fSuccess && BScrollChangeDirection(lpBScroll, x, y, 0) != 0)
  745. fSuccess = TraceFALSE(NULL);
  746. return;
  747. }
  748. static int BScrollChangeDirection(LPBSCROLL lpBScroll, int x, int y, DWORD dwFlags)
  749. {
  750. BOOL fSuccess = TRUE;
  751. RECT rc;
  752. if (lpBScroll == NULL)
  753. fSuccess = TraceFALSE(NULL);
  754. else if (!(lpBScroll->dwState & BSCROLL_SCROLLING) &&
  755. !(lpBScroll->dwState & BSCROLL_DRAGGING))
  756. ; // nothing to do
  757. else if (!GetClientRect(lpBScroll->hwndBScroll, &rc))
  758. fSuccess = TraceFALSE(NULL);
  759. else if (x < 0 || x > rc.right - 1 || y < 0 || y > rc.bottom - 1)
  760. ; // outside the window; nothing to do
  761. else if ((lpBScroll->dwFlags & BSCROLL_MOUSEMOVE) ||
  762. (lpBScroll->dwState & BSCROLL_DRAGGING))
  763. {
  764. lpBScroll->dwFlags &= ~BSCROLL_LEFT;
  765. lpBScroll->dwFlags &= ~BSCROLL_RIGHT;
  766. lpBScroll->dwFlags &= ~BSCROLL_UP;
  767. lpBScroll->dwFlags &= ~BSCROLL_DOWN;
  768. if (lpBScroll->dwFlags & BSCROLL_FLIGHTSIM &&
  769. !(lpBScroll->dwState & BSCROLL_DRAGGING))
  770. {
  771. if (PtInRegion(lpBScroll->hrgnLeft, x, y))
  772. lpBScroll->dwFlags |= BSCROLL_RIGHT;
  773. if (PtInRegion(lpBScroll->hrgnRight, x, y))
  774. lpBScroll->dwFlags |= BSCROLL_LEFT;
  775. if (PtInRegion(lpBScroll->hrgnUp, x, y))
  776. lpBScroll->dwFlags |= BSCROLL_DOWN;
  777. if (PtInRegion(lpBScroll->hrgnDown, x, y))
  778. lpBScroll->dwFlags |= BSCROLL_UP;
  779. }
  780. else
  781. {
  782. if (PtInRegion(lpBScroll->hrgnLeft, x, y))
  783. lpBScroll->dwFlags |= BSCROLL_LEFT;
  784. if (PtInRegion(lpBScroll->hrgnRight, x, y))
  785. lpBScroll->dwFlags |= BSCROLL_RIGHT;
  786. if (PtInRegion(lpBScroll->hrgnUp, x, y))
  787. lpBScroll->dwFlags |= BSCROLL_UP;
  788. if (PtInRegion(lpBScroll->hrgnDown, x, y))
  789. lpBScroll->dwFlags |= BSCROLL_DOWN;
  790. }
  791. }
  792. return fSuccess ? 0 : -1;
  793. }
  794. // BScrollGetPtr - verify that bscroll handle is valid,
  795. // <hBScroll> (i) handle returned from BScrollInit
  796. // return corresponding bscroll pointer (NULL if error)
  797. //
  798. static LPBSCROLL BScrollGetPtr(HBSCROLL hBScroll)
  799. {
  800. BOOL fSuccess = TRUE;
  801. LPBSCROLL lpBScroll;
  802. if ((lpBScroll = (LPBSCROLL) hBScroll) == NULL)
  803. fSuccess = TraceFALSE(NULL);
  804. else if (IsBadWritePtr(lpBScroll, sizeof(BSCROLL)))
  805. fSuccess = TraceFALSE(NULL);
  806. #ifdef CHECKTASK
  807. // make sure current task owns the bscroll handle
  808. //
  809. else if (lpBScroll->hTask != GetCurrentTask())
  810. fSuccess = TraceFALSE(NULL);
  811. #endif
  812. return fSuccess ? lpBScroll : NULL;
  813. }
  814. // BScrollGetHandle - verify that bscroll pointer is valid,
  815. // <lpBScroll> (i) pointer to BSCROLL struct
  816. // return corresponding bscroll handle (NULL if error)
  817. //
  818. static HBSCROLL BScrollGetHandle(LPBSCROLL lpBScroll)
  819. {
  820. BOOL fSuccess = TRUE;
  821. HBSCROLL hBScroll;
  822. if ((hBScroll = (HBSCROLL) lpBScroll) == NULL)
  823. fSuccess = TraceFALSE(NULL);
  824. return fSuccess ? hBScroll : NULL;
  825. }