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.

306 lines
11 KiB

  1. /*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
  2. **
  3. ** FILE: POV.CPP
  4. ** DATE: 3/31/97
  5. ** PROJ: ATLAS
  6. ** PROG: JKH
  7. ** COMMENTS:
  8. **
  9. ** DESCRIPTION: Window class for a 360 degree Point Of View control
  10. **
  11. **
  12. **
  13. ** NOTE: There are some issues with using extern "C" in this file.
  14. ** If you don't understand why they are there, you're not
  15. ** alone. For now, and probably for a while they will be
  16. ** here though, because I can't get this file and others
  17. ** that use these services to compile without them.
  18. ** Unfortunately the dynamics of this project don't really
  19. ** afford me the time at present to figure this out.
  20. ** TODO: figure this out
  21. **
  22. ** HISTORY:
  23. ** DATE WHO WHAT
  24. ** ---- --- ----
  25. ** 3/31/97 a-kirkh Wrote it.
  26. **
  27. **
  28. **
  29. **
  30. ** Copyright (C) Microsoft 1997. All Rights Reserved.
  31. **
  32. **~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=*/
  33. #include "cplsvr1.h" // for ghInst
  34. #include "dicputil.h" // for MAX_POVS
  35. #include "POV.H" //This module's stuff.
  36. #include <malloc.h> // for _alloca
  37. #include "resrc1.h"
  38. //static HWND hPOVWnd = NULL;
  39. #define NUM_ARROW_POINTS 8
  40. //static VERTICEINFO *paptVInfo;
  41. static const VERTICEINFO VInfo[] = {XARROWPOINT, YARROWPOINT, XARROWRIGHTOUT, YARROWRIGHTOUT, XARROWRIGHTIN, YARROWRIGHTIN,
  42. XARROWRIGHTBOTTOM, YARROWRIGHTBOTTOM, XARROWLEFTBOTTOM, YARROWLEFTBOTTOM, XARROWLEFTIN,
  43. YARROWLEFTIN, XARROWLEFTOUT, YARROWLEFTOUT, XARROWPOINT, YARROWPOINT};
  44. static LPRECT prcOldRegionBox[MAX_POVS];
  45. static LPRECT prcNewRegionBox[MAX_POVS];
  46. #define DEF_POV_POS -1
  47. static double degrees[MAX_POVS] = {DEF_POV_POS, DEF_POV_POS, DEF_POV_POS, DEF_POV_POS};
  48. static BYTE nPOV = MAX_POVS;
  49. static HBRUSH hBrush[MAX_POVS];
  50. static HRGN hRegion[MAX_POVS];
  51. extern HINSTANCE ghInst;
  52. void SetDegrees(BYTE nPov, short *nDegrees, HWND hPOVWnd)
  53. {
  54. nPOV = nPov -= 1;
  55. LPPOINT paptPoints = (LPPOINT)_alloca(sizeof(POINT[NUM_ARROW_POINTS]));
  56. assert (paptPoints);
  57. // Create the proper brush for the axis!
  58. do {
  59. degrees[nPov] = (double)nDegrees[nPov] / DI_DEGREES; // if angle == 180, degrees comes in as 18000
  60. paptPoints[0].x = GETXCOORD(VInfo[0].y, VInfo[0].x, degrees[nPov]);
  61. paptPoints[0].y = GETYCOORD(VInfo[0].y, VInfo[0].x, degrees[nPov]);
  62. paptPoints[1].x = GETXCOORD(VInfo[1].y, VInfo[1].x, degrees[nPov]);
  63. paptPoints[1].y = GETYCOORD(VInfo[1].y, VInfo[1].x, degrees[nPov]);
  64. paptPoints[2].x = GETXCOORD(VInfo[2].y, VInfo[2].x, degrees[nPov]);
  65. paptPoints[2].y = GETYCOORD(VInfo[2].y, VInfo[2].x, degrees[nPov]);
  66. paptPoints[3].x = GETXCOORD(VInfo[3].y, VInfo[3].x, degrees[nPov]);
  67. paptPoints[3].y = GETYCOORD(VInfo[3].y, VInfo[3].x, degrees[nPov]);
  68. paptPoints[4].x = GETXCOORD(VInfo[4].y, VInfo[4].x, degrees[nPov]);
  69. paptPoints[4].y = GETYCOORD(VInfo[4].y, VInfo[4].x, degrees[nPov]);
  70. paptPoints[5].x = GETXCOORD(VInfo[5].y, VInfo[5].x, degrees[nPov]);
  71. paptPoints[5].y = GETYCOORD(VInfo[5].y, VInfo[5].x, degrees[nPov]);
  72. paptPoints[6].x = GETXCOORD(VInfo[6].y, VInfo[6].x, degrees[nPov]);
  73. paptPoints[6].y = GETYCOORD(VInfo[6].y, VInfo[6].x, degrees[nPov]);
  74. paptPoints[7].x = GETXCOORD(VInfo[7].y, VInfo[7].x, degrees[nPov]);
  75. paptPoints[7].y = GETYCOORD(VInfo[7].y, VInfo[7].x, degrees[nPov]);
  76. if(hRegion[nPov])
  77. {
  78. DeleteObject(hRegion[nPov]);
  79. hRegion[nPov]=NULL;
  80. }
  81. hRegion[nPov] = CreatePolygonRgn(paptPoints, NUM_ARROW_POINTS, WINDING);
  82. //hBrush[nPov] = CreateSolidBrush((nPov < 1) ? POV1_COLOUR :
  83. // (nPov < 2) ? POV2_COLOUR :
  84. // (nPov < 3) ? POV3_COLOUR : POV4_COLOUR); */
  85. //if (hRegion[nPov] && hBrush[nPov])
  86. //{
  87. // GetRgnBox(hRegion[nPov], prcNewRegionBox[nPov]);
  88. //
  89. // //RedrawWindow(hPOVWnd, NULL, NULL, RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_ERASE);
  90. // InvalidateRect(hPOVWnd, prcOldRegionBox[nPov], TRUE);
  91. // InvalidateRect(hPOVWnd, prcNewRegionBox[nPov], TRUE);
  92. //}
  93. RECT R;
  94. GetClientRect(hPOVWnd,&R);
  95. POINT Pnt[2];
  96. Pnt[0].x=R.left;
  97. Pnt[0].y=R.top;
  98. Pnt[1].x=R.right;
  99. Pnt[1].y=R.bottom;
  100. MapWindowPoints(hPOVWnd,GetParent(hPOVWnd),Pnt,2);
  101. R.left=Pnt[0].x;
  102. R.top=Pnt[0].y;
  103. R.right=Pnt[1].x;
  104. R.bottom=Pnt[1].y;
  105. InvalidateRect(GetParent(hPOVWnd), &R, TRUE);
  106. } while( nPov-- );
  107. }
  108. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  109. //
  110. // FUNCTION : POVWndProc
  111. // REMARKS : The callback function for the POVHat Window.
  112. //
  113. // PARAMS : The usual callback funcs for message handling
  114. //
  115. // RETURNS : LRESULT - Depends on the message
  116. // CALLS :
  117. // NOTES :
  118. // WM_PAINT - Just calls DrawControl
  119. //
  120. // PM_MYJOYPOSCHANGED - This is a private (WM_USER) message that is
  121. // called whenever a change in the POV hat occurs.
  122. //
  123. LRESULT CALLBACK POVWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  124. {
  125. switch( iMsg ) {
  126. // case WM_CREATE:
  127. // hPOVWnd = hWnd;
  128. // return FALSE;
  129. // case WM_DESTROY:
  130. // return FALSE;
  131. case WM_DESTROY:
  132. {
  133. BYTE nPov=nPOV;
  134. do
  135. {
  136. if(hRegion[nPov])
  137. {
  138. DeleteObject(hRegion[nPov]);
  139. hRegion[nPov]=NULL;
  140. }
  141. }while(nPov--);
  142. }
  143. return 0;
  144. case WM_PAINT:
  145. {
  146. PAINTSTRUCT ps;
  147. HDC hDC = BeginPaint(hWnd, &ps);
  148. // 1) Get client size information
  149. SetMapMode(hDC, MM_TEXT);
  150. RECT rClient;
  151. GetClientRect(hWnd, &rClient);
  152. BYTE nSizeX = (BYTE)rClient.right>>1;
  153. BYTE nSizeY = (BYTE)rClient.bottom>>1;
  154. // 2) Load the hub bitmap and display it
  155. //PREFIX #WI226648. False positive. There is no leak. DeleteObject frees.
  156. HBITMAP hPOVHubBitmap = (HBITMAP)LoadImage(ghInst, MAKEINTRESOURCE(IDB_POVHUB), IMAGE_BITMAP, 0, 0, NULL);
  157. assert(hPOVHubBitmap);
  158. DrawBitmap(hDC, hPOVHubBitmap, nSizeX-8, nSizeY-8);
  159. DeleteObject(hPOVHubBitmap);
  160. // 3) Setup the window to use symmetrical units on a 1000 X 1000 cartesian grid
  161. SetMapMode(hDC, MM_ISOTROPIC);
  162. SetWindowExtEx (hDC, 1000, 1000, NULL);
  163. SetViewportExtEx(hDC, nSizeX, -nSizeY, NULL);
  164. SetViewportOrgEx(hDC, nSizeX, nSizeY, NULL);
  165. // 4) Draw the circle upon which the arrow seems to rotate
  166. SelectObject(hDC, (HBRUSH)GetStockObject(NULL_BRUSH));
  167. HPEN hPenOld = (HPEN)SelectObject(hDC, (HGDIOBJ)GetStockObject(DC_PEN));
  168. SetDCPenColor( hDC, GetSysColor(COLOR_WINDOWTEXT) );
  169. Ellipse(hDC, -CIRCLERADIUS, CIRCLERADIUS, CIRCLERADIUS, -CIRCLERADIUS);
  170. SelectObject(hDC, hPenOld);
  171. // 5) Paint the Arrow at the correct angle if POV active
  172. BYTE nPov = nPOV;
  173. HBRUSH hBrushOld;
  174. do {
  175. if( degrees[nPov] >= 0 ) {
  176. hBrush[nPov] = CreateSolidBrush((nPov < 1) ? POV1_COLOUR :
  177. (nPov < 2) ? POV2_COLOUR :
  178. (nPov < 3) ? POV3_COLOUR : POV4_COLOUR);
  179. hBrushOld = (HBRUSH)SelectObject(hDC, (HGDIOBJ)hBrush[nPov]);
  180. assert(hBrushOld);
  181. PaintRgn(hDC, hRegion[nPov]);
  182. // GetRgnBox returns zero if it fails...
  183. GetRgnBox(hRegion[nPov], prcOldRegionBox[nPov]);
  184. SelectObject(hDC, hBrushOld);
  185. if(hRegion[nPov])
  186. {
  187. DeleteObject(hRegion[nPov]);
  188. hRegion[nPov]=NULL;
  189. }
  190. DeleteObject(hBrush[nPov] );
  191. }
  192. } while( nPov-- );
  193. EndPaint(hWnd, &ps);
  194. }
  195. //PREFIX #WI226648. False positive. See above.
  196. return(0);
  197. default:
  198. return(DefWindowProc(hWnd, iMsg,wParam, lParam));
  199. }
  200. }
  201. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  202. //
  203. // FUNCTION : RegisterPOVClass
  204. // REMARKS : Registers the POV Hat window.
  205. //
  206. // PARAMS : hInstance - Used for the call to RegisterClassEx
  207. //
  208. // RETURNS : TRUE - if successfully registered
  209. // FALSE - failed to register
  210. // CALLS : RegisterClassEx
  211. // NOTES :
  212. //
  213. extern ATOM RegisterPOVClass()
  214. {
  215. LPWNDCLASSEX pPOVWndClass = (LPWNDCLASSEX)_alloca(sizeof(WNDCLASSEX));
  216. assert (pPOVWndClass);
  217. ZeroMemory(pPOVWndClass, sizeof(WNDCLASSEX));
  218. pPOVWndClass->cbSize = sizeof(WNDCLASSEX);
  219. pPOVWndClass->style = CS_HREDRAW; // | CS_VREDRAW;
  220. pPOVWndClass->lpfnWndProc = POVWndProc;
  221. pPOVWndClass->hInstance = ghInst;
  222. pPOVWndClass->hbrBackground = NULL;
  223. pPOVWndClass->lpszClassName = TEXT("POVHAT");
  224. return(RegisterClassEx( pPOVWndClass ));
  225. }
  226. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  227. //
  228. // FUNCTION : DrawBitmap
  229. // REMARKS : Copied verbatim from Petzold (WIN95 pg 190)
  230. // PARAMS : HDC - dc for drawing
  231. // HBITMAP - bitmap to draw
  232. // int xstart, ystart - where to place the bitmap
  233. //
  234. // RETURNS : void
  235. // CALLS :
  236. // NOTES :
  237. //
  238. void DrawBitmap(HDC hDC, HBITMAP hBitmap, BYTE xStart, BYTE yStart)
  239. {
  240. HDC hdcMem = CreateCompatibleDC(hDC);
  241. // Found by prefix: Millen Bug129155. manbugs 29339
  242. // If CreateCompatibleDC fails, we should'nt proceed.
  243. if( hdcMem == NULL ) return;
  244. SelectObject(hdcMem, hBitmap);
  245. SetMapMode(hdcMem,GetMapMode(hDC));
  246. // Be aware! This is the size of the current BITMAP...
  247. // IF IT CHANGES THIS WILL FAIL!!!
  248. POINT ptSize = {16, 16};
  249. DPtoLP(hDC, &ptSize, 1);
  250. POINT ptOrg = {0,0};
  251. DPtoLP(hdcMem, &ptOrg, 1);
  252. BitBlt(hDC, xStart, yStart, ptSize.x, ptSize.y, hdcMem, ptOrg.x, ptOrg.y, SRCAND);
  253. DeleteDC(hdcMem);
  254. }
  255. //~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=EOF=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=