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.

344 lines
12 KiB

  1. /** FILE: arrowin.c ******** Module Header ********************************
  2. *
  3. * Control panel arrow window class routines. This file contains the
  4. * window procedure and utility functions for managing the "cpArrow"
  5. * window class/spinner control for use by Control Panel applet dialogs.
  6. *
  7. * History:
  8. * 15:30 on Thur 25 Apr 1991 -by- Steve Cathcart [stevecat]
  9. * Took base code from Win 3.1 source
  10. *
  11. * Copyright (C) 1990-1991 Microsoft Corporation
  12. *
  13. *************************************************************************/
  14. //==========================================================================
  15. // Include files
  16. //==========================================================================
  17. // C Runtime
  18. #include <stddef.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. // Windows SDK
  22. /* cut out unnec stuff from windows.h */
  23. #define NOCLIPBOARD
  24. #define NOMETAFILE
  25. #define NOREGION
  26. #define NOSYSCOMMANDS
  27. #define NOATOM
  28. #define NOGDICAPMASKS
  29. #include <windows.h>
  30. //==========================================================================
  31. // Local Definitions
  32. //==========================================================================
  33. #define SHIFT_TO_DOUBLE 1
  34. #define DOUBLECLICK 0
  35. #define PRESSINVERT 1
  36. #define POINTSPERARROW 3
  37. #define ARROWXAXIS 15
  38. #define ARROWYAXIS 15
  39. //==========================================================================
  40. // External Declarations
  41. //==========================================================================
  42. extern HANDLE hModule;
  43. //==========================================================================
  44. // Local Data Declarations
  45. //==========================================================================
  46. #if 0
  47. POINT Arrow[11] = { 16, 1, 2, 14, 12, 14, 12, 20, 2, 20, 16, 33,
  48. 29, 20, 20, 20, 20, 14, 29, 14/*, 16,1*/};
  49. #endif
  50. #if 0
  51. POINT ArrowUp[7] = {5, 2, 8, 5, 6, 5, 6, 7, 4, 7, 4, 5, 2, 5};
  52. POINT ArrowDown[7] = { 4, 10, 6, 10, 6, 12, 8, 12, 5, 15, 2, 12, 4, 12};
  53. #endif
  54. POINT ArrowUp[POINTSPERARROW] = {7, 1, 3, 5, 11, 5};
  55. POINT ArrowDown[POINTSPERARROW] = {7, 13, 3, 9, 11, 9};
  56. BOOL bRight;
  57. RECT rUp, rDown;
  58. LPRECT lpUpDown;
  59. FARPROC lpArrowProc;
  60. HANDLE hParent;
  61. //==========================================================================
  62. // Local Function Prototypes
  63. //==========================================================================
  64. //==========================================================================
  65. // Functions
  66. //==========================================================================
  67. WORD UpOrDown()
  68. {
  69. LONG l;
  70. WORD retval;
  71. POINT pt;
  72. l = GetMessagePos();
  73. pt.y = (int) HIWORD(l);
  74. pt.x = (int) LOWORD(l);
  75. if (PtInRect((LPRECT) &rUp, pt))
  76. retval = SB_LINEUP;
  77. else if (PtInRect((LPRECT) &rDown, pt))
  78. retval = SB_LINEDOWN;
  79. else
  80. retval = (WORD)-1; /* -1, because SB_LINEUP == 0 */
  81. return(retval);
  82. }
  83. WORD ArrowTimerProc(hWnd, wMsg, nID, dwTime)
  84. HANDLE hWnd;
  85. WORD wMsg;
  86. short nID;
  87. DWORD dwTime;
  88. {
  89. WORD wScroll;
  90. if ((wScroll = UpOrDown()) != -1)
  91. {
  92. if (bRight == WM_RBUTTONDOWN)
  93. wScroll += SB_PAGEUP - SB_LINEUP;
  94. // [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
  95. SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
  96. GetWindowLong(hWnd, GWL_ID)), (LONG) hWnd);
  97. }
  98. /* Don't need to call KillTimer(), because SetTimer will reset the right one */
  99. SetTimer(hWnd, nID, 50, (TIMERPROC)lpArrowProc);
  100. return(0);
  101. #if 0
  102. wMsg = wMsg;
  103. dwTime = dwTime;
  104. #endif
  105. }
  106. #if PRESSINVERT
  107. void InvertArrow(HANDLE hArrow, WORD wScroll)
  108. {
  109. HDC hDC;
  110. lpUpDown = (wScroll == SB_LINEUP) ? &rUp : &rDown;
  111. hDC = GetDC(hArrow);
  112. ScreenToClient(hArrow, (LPPOINT) &(lpUpDown->left));
  113. ScreenToClient(hArrow, (LPPOINT) &(lpUpDown->right));
  114. InvertRect(hDC, lpUpDown);
  115. ClientToScreen(hArrow, (LPPOINT) &(lpUpDown->left));
  116. ClientToScreen(hArrow, (LPPOINT) &(lpUpDown->right));
  117. ReleaseDC(hArrow, hDC);
  118. ValidateRect(hArrow, lpUpDown);
  119. return;
  120. }
  121. #endif
  122. LONG ArrowControlProc(HWND hArrow, UINT message, UINT wParam, LONG lParam)
  123. {
  124. PAINTSTRUCT ps;
  125. RECT rArrow;
  126. HBRUSH hbr;
  127. short fUpDownOut;
  128. WORD wScroll;
  129. POINT tPoint;
  130. SIZE tSize;
  131. switch (message)
  132. {
  133. /*
  134. case WM_CREATE:
  135. break;
  136. case WM_DESTROY:
  137. break;
  138. */
  139. case WM_MOUSEMOVE:
  140. if (!bRight) /* If not captured, don't worry about it */
  141. break;
  142. if (lpUpDown == &rUp)
  143. fUpDownOut = SB_LINEUP;
  144. else if (lpUpDown == &rDown)
  145. fUpDownOut = SB_LINEDOWN;
  146. else
  147. fUpDownOut = -1;
  148. switch (wScroll = UpOrDown())
  149. {
  150. case SB_LINEUP:
  151. if (fUpDownOut == SB_LINEDOWN)
  152. InvertArrow(hArrow, SB_LINEDOWN);
  153. if (fUpDownOut != SB_LINEUP)
  154. InvertArrow(hArrow, wScroll);
  155. break;
  156. case SB_LINEDOWN:
  157. if (fUpDownOut == SB_LINEUP)
  158. InvertArrow(hArrow, SB_LINEUP);
  159. if (fUpDownOut != SB_LINEDOWN)
  160. InvertArrow(hArrow, wScroll);
  161. break;
  162. default:
  163. if (lpUpDown)
  164. {
  165. InvertArrow(hArrow, fUpDownOut);
  166. lpUpDown = 0;
  167. }
  168. }
  169. break;
  170. case WM_RBUTTONDOWN:
  171. case WM_LBUTTONDOWN:
  172. if (bRight)
  173. break;
  174. bRight = message;
  175. SetCapture(hArrow);
  176. hParent = GetParent(hArrow);
  177. GetWindowRect(hArrow, (LPRECT) &rUp);
  178. CopyRect((LPRECT) &rDown, (LPRECT) &rUp);
  179. rUp.bottom = (rUp.top + rUp.bottom) / 2;
  180. rDown.top = rUp.bottom + 1;
  181. wScroll = UpOrDown();
  182. #if PRESSINVERT
  183. InvertArrow(hArrow, wScroll);
  184. #endif
  185. #if SHIFT_TO_DOUBLE
  186. if (wParam & MK_SHIFT)
  187. {
  188. if (message != WM_RBUTTONDOWN)
  189. goto ShiftLClick;
  190. else
  191. goto ShiftRClick;
  192. }
  193. #endif
  194. if (message == WM_RBUTTONDOWN)
  195. wScroll += SB_PAGEUP - SB_LINEUP;
  196. // [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
  197. SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
  198. GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
  199. lpArrowProc = MakeProcInstance((FARPROC) ArrowTimerProc, hModule);
  200. SetTimer(hArrow, GetWindowLong(hArrow, GWL_ID), 200, (TIMERPROC)lpArrowProc);
  201. break;
  202. case WM_LBUTTONUP:
  203. case WM_RBUTTONUP:
  204. if ((UINT) (bRight - WM_LBUTTONDOWN + WM_LBUTTONUP) == message)
  205. {
  206. bRight = 0;
  207. ReleaseCapture();
  208. #if PRESSINVERT
  209. if (lpUpDown)
  210. InvertArrow(hArrow, (WORD)((lpUpDown == &rUp) ? SB_LINEUP : SB_LINEDOWN));
  211. #endif
  212. if (lpArrowProc)
  213. {
  214. // [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
  215. SendMessage(hParent, WM_VSCROLL, MAKELONG(SB_ENDSCROLL,
  216. GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
  217. KillTimer(hArrow, GetWindowLong(hArrow, GWL_ID));
  218. FreeProcInstance(lpArrowProc);
  219. ReleaseCapture();
  220. lpArrowProc = 0;
  221. }
  222. }
  223. break;
  224. case WM_LBUTTONDBLCLK:
  225. ShiftLClick:
  226. wScroll = UpOrDown() + (WORD) (SB_TOP - SB_LINEUP);
  227. // [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
  228. SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
  229. GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
  230. SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
  231. GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
  232. break;
  233. case WM_RBUTTONDBLCLK:
  234. ShiftRClick:
  235. wScroll = UpOrDown() + (WORD) (SB_THUMBPOSITION - SB_LINEUP);
  236. // [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
  237. SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
  238. GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
  239. SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
  240. GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
  241. /*
  242. hDC = GetDC(hArrow);
  243. InvertRect(hDC, (LPRECT) &rArrow);
  244. ReleaseDC(hArrow, hDC);
  245. ValidateRect(hArrow, (LPRECT) &rArrow);
  246. */
  247. break;
  248. case WM_PAINT:
  249. BeginPaint(hArrow, &ps);
  250. GetClientRect(hArrow, (LPRECT) &rArrow);
  251. if (hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)))
  252. {
  253. FillRect(ps.hdc, (LPRECT) &rArrow, hbr);
  254. DeleteObject(hbr);
  255. }
  256. hbr = SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
  257. SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWFRAME));
  258. SetMapMode(ps.hdc, MM_ANISOTROPIC);
  259. SetViewportOrgEx(ps.hdc, rArrow.left, rArrow.top, &tPoint);
  260. SetViewportExtEx(ps.hdc, rArrow.right - rArrow.left,
  261. rArrow.bottom - rArrow.top, &tSize);
  262. SetWindowOrgEx(ps.hdc, 0, 0, &tPoint);
  263. SetWindowExtEx(ps.hdc, ARROWXAXIS, ARROWYAXIS, &tSize);
  264. MoveToEx(ps.hdc, 0, (ARROWYAXIS / 2), &tPoint);
  265. LineTo(ps.hdc, ARROWXAXIS, (ARROWYAXIS / 2));
  266. /*
  267. Polygon(ps.hdc, (LPPOINT) Arrow, 10);
  268. */
  269. Polygon(ps.hdc, (LPPOINT) ArrowUp, POINTSPERARROW);
  270. Polygon(ps.hdc, (LPPOINT) ArrowDown, POINTSPERARROW);
  271. SelectObject(ps.hdc, hbr);
  272. EndPaint(hArrow, &ps);
  273. break;
  274. default:
  275. return(DefWindowProc(hArrow, message, wParam, lParam));
  276. break;
  277. }
  278. return(0L);
  279. }
  280. BOOL RegisterArrowClass (HANDLE hModule)
  281. {
  282. WNDCLASS wcArrow;
  283. wcArrow.lpszClassName = "cpArrow";
  284. wcArrow.hInstance = hModule;
  285. wcArrow.lpfnWndProc = ArrowControlProc;
  286. wcArrow.hCursor = LoadCursor(NULL, IDC_ARROW);
  287. wcArrow.hIcon = NULL;
  288. wcArrow.lpszMenuName = NULL;
  289. wcArrow.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  290. wcArrow.style = CS_HREDRAW | CS_VREDRAW;
  291. #if DOUBLECLICK
  292. wcArrow.style |= CS_DBLCLKS;
  293. #endif
  294. wcArrow.cbClsExtra = 0;
  295. wcArrow.cbWndExtra = 0;
  296. return(RegisterClass((LPWNDCLASS) &wcArrow));
  297. }