Source code of Windows XP (NT5)
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.

285 lines
8.6 KiB

  1. /*-----------------------------------------------------------------------------+
  2. | ARROW.C |
  3. | |
  4. | Control panel arrow code - stolen from WINCOM |
  5. | |
  6. | (C) Copyright Microsoft Corporation 1991. All rights reserved. |
  7. | |
  8. | Revision History |
  9. | Oct-1992 MikeTri Ported to WIN32/WIN16 Common code |
  10. | |
  11. +-----------------------------------------------------------------------------*/
  12. #include <windows.h>
  13. #include <stdlib.h>
  14. #include "mplayer.h"
  15. #define SHIFT_TO_DOUBLE 1
  16. #define DOUBLECLICK 0
  17. #define POINTSPERARROW 3
  18. #define ARROWXAXIS 15
  19. #define ARROWYAXIS 15
  20. POINT ArrowUp[POINTSPERARROW] = {7,1, 3,5, 11,5};
  21. POINT ArrowDown[POINTSPERARROW] = {7,13, 3,9, 11,9};
  22. static BOOL bRight;
  23. static RECT rUp, rDown;
  24. static LPRECT lpUpDown;
  25. static FARPROC lpArrowProc;
  26. static HANDLE hParent;
  27. BOOL fInTimer;
  28. #define TEMP_BUFF_SIZE 32
  29. #define SENDSCROLL(hwnd, msg, a, b, h) \
  30. SendMessage(hwnd, msg, (UINT_PTR)MAKELONG(a,b), (LONG_PTR)(h))
  31. #define SCROLLMSG(hwndTo, msg, code, hwndId) \
  32. SENDSCROLL(hwndTo, msg, code, GETWINDOWID(hwndId), hwndId)
  33. UINT NEAR PASCAL UpOrDown()
  34. {
  35. LONG pos;
  36. UINT retval;
  37. POINT pt;
  38. pos = GetMessagePos();
  39. LONG2POINT(pos,pt);
  40. if (PtInRect((LPRECT)&rUp, pt))
  41. retval = SB_LINEUP;
  42. else if (PtInRect((LPRECT)&rDown, pt))
  43. retval = SB_LINEDOWN;
  44. else
  45. retval = (UINT)(-1); /* -1, because SB_LINEUP == 0 */
  46. return(retval);
  47. }
  48. UINT FAR PASCAL ArrowTimerProc(HANDLE hWnd, UINT wMsg, short nID, DWORD dwTime)
  49. {
  50. UINT wScroll;
  51. if ((wScroll = UpOrDown()) != -1)
  52. {
  53. if (bRight == WM_RBUTTONDOWN)
  54. wScroll += SB_PAGEUP - SB_LINEUP;
  55. SCROLLMSG( hParent, WM_VSCROLL, wScroll, hWnd);
  56. }
  57. /* Don't need to call KillTimer(), because SetTimer will reset the right one */
  58. SetTimer(hWnd, nID, 50, (TIMERPROC)lpArrowProc);
  59. return(0);
  60. }
  61. void InvertArrow(HANDLE hArrow, UINT wScroll)
  62. {
  63. HDC hDC;
  64. lpUpDown = (wScroll == SB_LINEUP) ? &rUp : &rDown;
  65. hDC = GetDC(hArrow);
  66. ScreenToClient(hArrow, (LPPOINT)&(lpUpDown->left));
  67. ScreenToClient(hArrow, (LPPOINT)&(lpUpDown->right));
  68. InvertRect(hDC, lpUpDown);
  69. ClientToScreen(hArrow, (LPPOINT)&(lpUpDown->left));
  70. ClientToScreen(hArrow, (LPPOINT)&(lpUpDown->right));
  71. ReleaseDC(hArrow, hDC);
  72. ValidateRect(hArrow, lpUpDown);
  73. return;
  74. }
  75. LONG_PTR FAR PASCAL _EXPORT ArrowControlProc(HWND hArrow, unsigned message,
  76. WPARAM wParam, LPARAM lParam)
  77. {
  78. PAINTSTRUCT ps;
  79. RECT rArrow;
  80. HBRUSH hbr;
  81. short fUpDownOut;
  82. UINT wScroll;
  83. switch (message) {
  84. /*
  85. case WM_CREATE:
  86. break;
  87. case WM_DESTROY:
  88. break;
  89. */
  90. case WM_MOUSEMOVE:
  91. if (!bRight) /* If not captured, don't worry about it */
  92. break;
  93. if (lpUpDown == &rUp)
  94. fUpDownOut = SB_LINEUP;
  95. else if (lpUpDown == &rDown)
  96. fUpDownOut = SB_LINEDOWN;
  97. else
  98. fUpDownOut = -1;
  99. switch (wScroll = UpOrDown()) {
  100. case SB_LINEUP:
  101. if (fUpDownOut == SB_LINEDOWN)
  102. InvertArrow(hArrow, SB_LINEDOWN);
  103. if (fUpDownOut != SB_LINEUP)
  104. InvertArrow(hArrow, wScroll);
  105. break;
  106. case SB_LINEDOWN:
  107. if (fUpDownOut == SB_LINEUP)
  108. InvertArrow(hArrow, SB_LINEUP);
  109. if (fUpDownOut != SB_LINEDOWN)
  110. InvertArrow(hArrow, wScroll);
  111. break;
  112. default:
  113. if (lpUpDown) {
  114. InvertArrow(hArrow, fUpDownOut);
  115. lpUpDown = 0;
  116. }
  117. }
  118. break;
  119. case WM_RBUTTONDOWN:
  120. case WM_LBUTTONDOWN:
  121. if (bRight)
  122. break;
  123. bRight = message;
  124. SetCapture(hArrow);
  125. hParent = GetParent(hArrow);
  126. GetWindowRect(hArrow, (LPRECT) &rUp);
  127. CopyRect((LPRECT)&rDown, (LPRECT) &rUp);
  128. rUp.bottom = (rUp.top + rUp.bottom) / 2;
  129. rDown.top = rUp.bottom + 1;
  130. wScroll = UpOrDown();
  131. InvertArrow(hArrow, wScroll);
  132. #if SHIFT_TO_DOUBLE
  133. if (wParam & MK_SHIFT) {
  134. if (message != WM_RBUTTONDOWN)
  135. goto ShiftLClick;
  136. else
  137. goto ShiftRClick;
  138. }
  139. #endif
  140. if (message == WM_RBUTTONDOWN)
  141. wScroll += SB_PAGEUP - SB_LINEUP;
  142. SCROLLMSG(hParent, WM_VSCROLL, wScroll, hArrow);
  143. lpArrowProc = MakeProcInstance((FARPROC) ArrowTimerProc,ghInst);
  144. SetTimer(hArrow, GETWINDOWID(hArrow), 200, (TIMERPROC)lpArrowProc);
  145. break;
  146. case WM_LBUTTONUP:
  147. case WM_RBUTTONUP:
  148. if ((bRight - WM_LBUTTONDOWN + WM_LBUTTONUP) == (int)message) {
  149. bRight = 0;
  150. ReleaseCapture();
  151. if (lpUpDown)
  152. InvertArrow(hArrow,(UINT)(lpUpDown==&rUp)?
  153. SB_LINEUP:SB_LINEDOWN);
  154. if (lpArrowProc) {
  155. SCROLLMSG(hParent, WM_VSCROLL, SB_ENDSCROLL, hArrow);
  156. KillTimer(hArrow, GETWINDOWID(hArrow));
  157. ReleaseCapture();
  158. lpArrowProc = 0;
  159. }
  160. }
  161. break;
  162. case WM_LBUTTONDBLCLK:
  163. ShiftLClick:
  164. wScroll = UpOrDown() + SB_TOP - SB_LINEUP;
  165. SCROLLMSG(hParent, WM_VSCROLL, wScroll, hArrow);
  166. SCROLLMSG(hParent, WM_VSCROLL, SB_ENDSCROLL, hArrow);
  167. break;
  168. case WM_RBUTTONDBLCLK:
  169. ShiftRClick:
  170. wScroll = UpOrDown() + SB_THUMBPOSITION - SB_LINEUP;
  171. SCROLLMSG(hParent, WM_VSCROLL, wScroll, hArrow);
  172. SCROLLMSG(hParent, WM_VSCROLL, SB_ENDSCROLL, hArrow);
  173. /*
  174. hDC = GetDC(hArrow);
  175. InvertRect(hDC, (LPRECT) &rArrow);
  176. ReleaseDC(hArrow, hDC);
  177. ValidateRect(hArrow, (LPRECT) &rArrow);
  178. */
  179. break;
  180. case WM_PAINT:
  181. BeginPaint(hArrow, &ps);
  182. GetClientRect(hArrow, (LPRECT) &rArrow);
  183. hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  184. FillRect(ps.hdc, (LPRECT)&rArrow, hbr);
  185. DeleteObject(hbr);
  186. hbr = SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
  187. SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWFRAME));
  188. SetMapMode(ps.hdc, MM_ANISOTROPIC);
  189. MSetViewportOrg(ps.hdc, rArrow.left, rArrow.top);
  190. MSetViewportExt(ps.hdc, rArrow.right - rArrow.left,
  191. rArrow.bottom - rArrow.top);
  192. MSetWindowOrg(ps.hdc, 0, 0);
  193. MSetWindowExt(ps.hdc, ARROWXAXIS, ARROWYAXIS);
  194. MMoveTo(ps.hdc, 0, (ARROWYAXIS / 2));
  195. LineTo(ps.hdc, ARROWXAXIS, (ARROWYAXIS / 2));
  196. /*
  197. Polygon(ps.hdc, (LPPOINT) Arrow, 10);
  198. */
  199. Polygon(ps.hdc, (LPPOINT) ArrowUp, POINTSPERARROW);
  200. Polygon(ps.hdc, (LPPOINT) ArrowDown, POINTSPERARROW);
  201. SelectObject(ps.hdc, hbr);
  202. EndPaint(hArrow, &ps);
  203. break;
  204. default:
  205. return(DefWindowProc(hArrow, message, wParam, lParam));
  206. break;
  207. }
  208. return(0L);
  209. }
  210. BOOL FAR PASCAL ArrowInit(HANDLE hInst)
  211. {
  212. static SZCODE aszComArrow[] = TEXT("ComArrow");
  213. WNDCLASS wcArrow;
  214. wcArrow.lpszClassName = aszComArrow;
  215. wcArrow.hInstance = hInst;
  216. wcArrow.lpfnWndProc = ArrowControlProc;
  217. wcArrow.hCursor = LoadCursor(NULL, IDC_ARROW);
  218. wcArrow.hIcon = NULL;
  219. wcArrow.lpszMenuName = NULL;
  220. wcArrow.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  221. wcArrow.style = CS_HREDRAW | CS_VREDRAW;
  222. #if DOUBLECLICK
  223. wcArrow.style |= CS_DBLCLKS;
  224. #endif
  225. wcArrow.cbClsExtra = 0;
  226. wcArrow.cbWndExtra = 0;
  227. if (!RegisterClass(&wcArrow))
  228. return FALSE;
  229. return TRUE;
  230. }
  231.