scroll.c
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:10k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. /*
  2. COW : Character Oriented Windows
  3. scroll.c : scroll bar control
  4. */
  5. #define COW
  6. #include <cow.h>
  7. #define SCROLL
  8. #include <uscroll.h>
  9. #include <uwindow.h>
  10. #include <uscreen.h>
  11. #include <uisa.h>
  12. #include <uevent.h>
  13. #include <kinput.h>
  14. #include "dialog.h"
  15. #include "event.h"
  16. #include "util.h"
  17. #include "screen.h"
  18. #include "scroll.h"
  19. #include "_scroll.h"
  20. /*
  21. scroll bar slots
  22. ptCurSb current logical position in range 
  23. ptMinSb minimum logical position in scroll range 
  24. ptMaxSb maximum logical position in scroll range 
  25. wSb extra word for info defined below
  26. */
  27. /* ScrollBarWndProc(pwnd, message, wParam, lParam) - 
  28. *  Process scroll bar messages.
  29. *  Purpose:
  30. * Handles user interaction with scroll bars.
  31. *
  32. * Scroll Bar:
  33. * ^ <--- Up Arrow
  34. * + <-------------------
  35. * +     ^                     ^
  36. * +     |                     |
  37. * +     |                     |
  38. * +     +--- Page Up Area     |
  39. * +     |                     |
  40. * +     |                     |
  41. * +     v                     |
  42. * +  <---                     |
  43. * # <------ Elevator         +--- Scroll range
  44. * +  <---                     |
  45. * +     ^                     |
  46. * +     |                     |
  47. * +     |                     |
  48. * +     +--- Page Down Area   |
  49. * +     |                     |
  50. * +     |                     |
  51. * +     v                     v
  52. * + <-------------------
  53. * v <--- Down Arrow
  54. *
  55. * The scroll bar manager sends WM_VSCROLL or WM_HSCROLL messages to
  56. * its Parent when a scroll bar event is detected.
  57. * The value of the wParam and lParam parameters of this
  58. *       message determine what event has occured.
  59. *
  60. * wParam Event
  61. * ------ -----
  62. * SB_LINEUP The mouse was clicked on the Up Arrow
  63. * SB_LINEDOWN The mouse was clicked on the Down Arrow
  64. * SB_PAGEUP The mouse was clicked in the Page Up Area
  65. * SB_PAGEDOWN The mouse was clicked in the Page Down Area
  66. * SB_THUMBPOSITION The elevator was dragged to a new position.
  67. * SB_THUMBTRACK The elevator has moved but the mousebutton
  68. * is still down.
  69. *
  70. * The Application sees the elevator as being in the logical range
  71. * ptMin..ptMax. These logical values are used for communication between
  72. * the Scroll Bar Manager, and the Application. 
  73. *
  74. *
  75. *****************************************************************************/
  76. PUBLIC DWORD FARPUBLIC 
  77. ScrollBarWndProc(pwnd, message, wParam, lParam)
  78. /*
  79.   -- the real scroll bar Wnd Proc
  80. */
  81. REGISTER PWND pwnd;
  82. DWORD lParam;
  83. WORD message, wParam;
  84. {
  85. StartPublic();
  86. RRC rrc;
  87. BYTE ptDownLine, ptElevator;
  88. short ptNew;
  89. MSP msp;
  90. WORD messageScroll;
  91. WORD wNonClient; /* value to mask for non-client */
  92. BOOL fSmallScroll;
  93. /* statics for the scroll bar with capture */
  94. static WORD wParamScroll;
  95. static BOOL fInWindow = TRUE;
  96. static BYTE ptStartElevator;
  97. static BYTE ptMouse;
  98. BYTE pt; /* the position if a mouse message */
  99. GetClientRrc(pwnd, &rrc);
  100. /* set up parameter based on whether horizontal or vertical scroll */
  101. ptElevator = PtElevatorSb(pwnd);
  102. msp.lParam = lParam;
  103. if (pwnd->style & SBS_VERT)
  104. {
  105. messageScroll = WM_VSCROLL;
  106. ptDownLine = rrc.ryBottom-rrc.ryTop-1;
  107. pt = msp.s.ry;
  108. wNonClient = MK_NONCLIENT_Y;
  109. fSmallScroll = rrc.ryBottom - rrc.ryTop == dyScrollMin;
  110. }
  111. else 
  112. {
  113. messageScroll = WM_HSCROLL;
  114. ptDownLine = rrc.rxRight-rrc.rxLeft-1;
  115. pt = msp.s.rx;
  116. wNonClient = MK_NONCLIENT_X;
  117. fSmallScroll = rrc.rxRight - rrc.rxLeft == dxScrollMin;
  118. }
  119. switch (message) 
  120. {
  121. default:
  122. break;
  123. case WM_PAINT:
  124. /* draw the scroll bar */
  125. #ifdef DEBUG
  126. if (pwnd->style & SBS_VERT)
  127. {
  128. AssertSz(rrc.ryBottom - rrc.ryTop >= dyScrollMin,
  129.     "Scroll bars too small");
  130. }
  131. else
  132. {
  133. AssertSz(rrc.rxRight - rrc.rxLeft >= dxScrollMin,
  134.     "Scroll bars too small");
  135. }
  136. #endif /*DEBUG*/
  137. #ifndef REMOVE_LATER
  138. if (pwnd->style & SBS_VERT)
  139. {
  140. rrc.ryTop++;
  141. rrc.ryBottom--;
  142. }
  143. else
  144. {
  145. rrc.rxLeft++;
  146. rrc.rxRight--;
  147. }
  148. #endif
  149. BeginDraw();
  150. FillRrc(pwnd, &rrc, (ACHAR) chScrollbar, DiNormal(isaScrollbar));
  151. if (pwnd->style & SBS_VERT)
  152. {
  153. CharOut(pwnd, 0, 0, chUpArrow,
  154.     DiNormal(isaScrollbar));
  155. CharOut(pwnd, 0, ptDownLine, chDownArrow,
  156.     DiNormal(isaScrollbar));
  157. if (!fSmallScroll)
  158. CharOut(pwnd, 0, ptElevator, chElevator,
  159.     DiNormal(isaElevator));
  160. }
  161. else 
  162. {
  163. CharOut(pwnd, 0, 0, chLeftArrow,
  164.     DiNormal(isaScrollbar));
  165. CharOut(pwnd, ptDownLine, 0, chRightArrow,
  166.     DiNormal(isaScrollbar));
  167. if (!fSmallScroll)
  168. CharOut(pwnd, ptElevator, 0, chElevator,
  169.     DiNormal(isaElevator));
  170. }
  171. EndDraw();
  172. break;
  173. case WM_LBUTTONDOWN:
  174. case WM_LBUTTONDBLCLK:
  175. fInWindow = TRUE;
  176. /* capture mouse for repeated scrolling or thumbtrack */
  177. SetCapture(pwnd);
  178. if ((ptMouse = pt) == 0)
  179. wParamScroll = SB_LINEUP;
  180. else if (ptMouse == ptDownLine)
  181. wParamScroll = SB_LINEDOWN;
  182. else if (ptMouse > ptElevator)
  183. wParamScroll = SB_PAGEDOWN;
  184. else if (ptMouse < ptElevator)
  185. wParamScroll = SB_PAGEUP;
  186. else 
  187. {
  188. /* capturing the elevator */
  189. wParamScroll = SB_THUMBPOSITION;
  190. ptStartElevator = ptElevator;
  191. break; /* do not set alarm or send message */
  192. }
  193. SetAlarm(pwnd, ctickRepScrollStart);
  194. SendMessage(pwnd->pwndParent, messageScroll,
  195.     wParamScroll, MAKELONG(0, (WORD) pwnd));
  196. break;
  197. case WM_MOUSEMOVE:
  198. /* mouse movements are only used for Thumb-tracking */
  199. /* see if mouse is still in the window */
  200. fInWindow = FCaptured(pwnd) && !(wParam & wNonClient);
  201. if (fSmallScroll)
  202. break; /* not thumbtrack possible */
  203. ptMouse = pt;
  204. if (wParamScroll == SB_THUMBPOSITION) 
  205. {
  206. if (!fInWindow)
  207. /* reset thumb */
  208. ptMouse = ptStartElevator;
  209. if (ptMouse != ptElevator &&
  210.     ptMouse > 0 && 
  211.     ptMouse < ptDownLine)
  212. {
  213. /* change thumbposition */
  214. SetPtElevatorSb(pwnd, ptMouse);
  215. /* ??? efficiency ??? */
  216. if (pwnd->style & SBS_VERT)
  217. {
  218. CharOut(pwnd, 0, ptElevator, 
  219.     (ACHAR) chScrollbar,
  220.     DiNormal(isaScrollbar));
  221. /*maybe*/CharOut(pwnd, 0, ptMouse,
  222.     chElevator, DiNormal(isaElevator));
  223. }
  224. else 
  225. {
  226. CharOut(pwnd, ptElevator, 0, 
  227.     (ACHAR) chScrollbar,
  228.     DiNormal(isaScrollbar));
  229. /*maybe*/CharOut(pwnd, ptMouse, 0,
  230.     chElevator, DiNormal(isaElevator));
  231. }
  232. /* translate physical to logical; round up */
  233. ptNew = TranslatePosition(ptMouse, 
  234.     1, ptDownLine-1,
  235.     pwnd->ptMinSb, pwnd->ptMaxSb, TRUE);
  236. pwnd->ptCurSb = ptNew;
  237. SendMessage(pwnd->pwndParent, messageScroll,
  238.     SB_THUMBTRACK,
  239.     MAKELONG(ptNew, (WORD) pwnd));
  240. }
  241. }
  242. break;
  243. case WM_ALARM:
  244. if (FCaptured(pwnd))
  245. {
  246. SetAlarm(pwnd, pwnd->ctickRepSb);
  247. if (fInWindow) 
  248. {
  249. switch (wParamScroll) 
  250. {
  251. default:
  252. goto ReturnFalse;
  253. case SB_LINEUP:
  254. if (ptMouse != 0)
  255. goto ReturnFalse;
  256. break;
  257. case SB_LINEDOWN:
  258. if (ptMouse != ptDownLine)
  259. goto ReturnFalse;
  260. break;
  261. case SB_PAGEUP:
  262. if (ptMouse == 0 || 
  263.     ptMouse >= ptElevator)
  264. goto ReturnFalse;
  265. break;
  266. case SB_PAGEDOWN:
  267. if (ptMouse == ptDownLine ||
  268.     ptMouse <= ptElevator)
  269. goto ReturnFalse;
  270. break;
  271. }
  272. SendMessage(pwnd->pwndParent, messageScroll,
  273.     wParamScroll, MAKELONG(0, (WORD) pwnd));
  274. }
  275. }
  276. break;
  277. case WM_LBUTTONUP:
  278. if (wParamScroll == SB_THUMBPOSITION && !fSmallScroll)
  279. {
  280. /* end tracking elevator */
  281. ptNew = TranslatePosition(ptElevator, 1, ptDownLine-1, 
  282.     pwnd->ptMinSb, pwnd->ptMaxSb, TRUE);
  283. if (ptNew != -1) /* -1 if calculation error */
  284. {
  285. SendMessage(pwnd->pwndParent, messageScroll,
  286.     SB_THUMBPOSITION,
  287.     MAKELONG(ptNew, (WORD) pwnd));
  288. SendMessage(pwnd->pwndParent, messageScroll,
  289.     SB_ENDSCROLL,
  290.     MAKELONG(ptNew, (WORD) pwnd));
  291. }
  292. }
  293. SendMessage(pwnd->pwndParent, messageScroll, SB_UPCLICK, 0L);
  294. wParamScroll = 0;
  295. if (FCaptured(pwnd))
  296. {
  297. ReleaseCapture();
  298. KillAlarm();
  299. }
  300. break;
  301. #ifdef DEBUG
  302. case WM_KEYDOWN:
  303. case WM_KEYUP:
  304. case WM_CHAR: /* just an extra check */
  305. Assert(FALSE);
  306. #endif
  307. }
  308. ReturnFalse:
  309. ReturnPublic(0L, DWORD);
  310. }
  311. PUBLIC VOID FARPUBLIC
  312. SetScrollRange(pwnd, ptMin, ptMax, fRedraw)
  313. /*
  314.   -- set the scroll range for the scrollbar window "pwnd"
  315.   -- 
  316. */
  317. PWND pwnd;
  318. short ptMin, ptMax;
  319. BOOL fRedraw;
  320. {
  321. StartPublic();
  322. AssertSz(ptMax > ptMin, "SetScrollRange : invalid range");
  323. pwnd->ptCurSb = pwnd->ptMinSb = ptMin;
  324. pwnd->ptMaxSb = ptMax;
  325. if (PtElevatorSb(pwnd) == 0)
  326. SetPtElevatorSb(pwnd, 1);
  327. if (fRedraw)
  328. DrawWindow(pwnd);
  329. StopPublic();
  330. }
  331. PUBLIC short FARPUBLIC
  332. SetScrollPos(pwnd, ptNew, fRedraw)
  333. /*
  334.   -- set the scroll position for the scrollbar window "pwnd"
  335.   -- useless operation if scroll-bar is 2-wide
  336. */
  337. PWND pwnd;
  338. short ptNew;
  339. BOOL fRedraw;
  340. {
  341. StartPublic();
  342. short ptOld = pwnd->ptCurSb;
  343. RRC rrc;
  344. WORD ptMax;
  345. AssertSz((short) pwnd->ptMaxSb >= (short) pwnd->ptMinSb, "SetScrollPos : invalid range");
  346. AssertSz(ptNew >= pwnd->ptMinSb && ptNew <= pwnd->ptMaxSb,
  347.     "SetScrollPos : out of range");
  348. GetClientRrc(pwnd, &rrc);
  349. pwnd->ptCurSb = ptNew;
  350. if (pwnd->style & SBS_VERT)
  351. {
  352. ptMax = rrc.ryBottom - 2; /* one position for downline */
  353. if (rrc.ryBottom - rrc.ryTop == dyScrollMin)
  354. ReturnPublic(ptOld, short);
  355. }
  356. else
  357. {
  358. ptMax = rrc.rxRight - 2; /* one position for downline */
  359. if (rrc.rxRight - rrc.rxLeft == dxScrollMin)
  360. ReturnPublic(ptOld, short);
  361. }
  362. /* translate from logical to physical range, round down */
  363. ptNew = TranslatePosition(ptNew, pwnd->ptMinSb, pwnd->ptMaxSb,
  364.   1, ptMax, FALSE);
  365. Assert(!(ptNew & 0xff00));
  366.    SetPtElevatorSb(pwnd, ptNew);
  367. /* redraw elevator */
  368. if (fRedraw)
  369. DrawWindow(pwnd);
  370. ReturnPublic(ptOld, short);
  371. }
  372. PUBLIC short FARPUBLIC
  373. GetScrollPos(pwnd)
  374. PWND pwnd;
  375. {
  376. StartPublic();
  377. ReturnPublic(pwnd->ptCurSb, short);
  378. }