win32_winproc.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:19k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Nate Robins, 1997, 2001. */
  2. /* portions Copyright (c) Mark Kilgard, 1997, 1998. */
  3. /* 
  4. This program is freely distributable without licensing fees 
  5. and is provided without guarantee or warrantee expressed or 
  6. implied. This program is -not- in the public domain. 
  7. */
  8. #include "glutint.h"
  9. #if defined(__CYGWIN32__)
  10. typedef MINMAXINFO* LPMINMAXINFO;
  11. #else
  12. #include <sys/timeb.h>
  13. #endif
  14. #ifdef _WIN32
  15. #include <assert.h>
  16. #include <crtdbg.h>
  17. #include <windowsx.h>
  18. #include <mmsystem.h>  /* Win32 Multimedia API header. */
  19. #endif
  20. extern unsigned __glutMenuButton;
  21. extern GLUTidleCB __glutIdleFunc;
  22. extern GLUTtimer *__glutTimerList;
  23. extern void handleTimeouts(void);
  24. extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique);
  25. static HMENU __glutHMenu;
  26. static int __glutOnCreate( HWND hwnd, LPCREATESTRUCT createStruct )
  27. {
  28. return TRUE;
  29. }
  30. static void __glutOnClose( HWND hwnd )
  31. {
  32. if ( __glutExitFunc )
  33. {
  34. __glutExitFunc( 0 );
  35. }
  36. DestroyWindow( hwnd );
  37. }
  38. static void __glutOnDestroy( HWND hwnd )
  39. {
  40. GLUTwindow* window = __glutGetWindow( hwnd );
  41. if ( window )
  42. {
  43. if ( window->ctx )
  44. {
  45. wglMakeCurrent( NULL, NULL );
  46. wglDeleteContext( window->ctx );
  47. }
  48. }
  49. }
  50. static void __glutOnPaint( HWND hwnd )
  51. {
  52. GLUTwindow* window = __glutGetWindow( hwnd );
  53. PAINTSTRUCT ps;
  54. BeginPaint( hwnd, &ps );
  55. EndPaint( hwnd, &ps );
  56. if ( window )
  57. {
  58. if ( window->win == hwnd ) 
  59. {
  60. __glutPostRedisplay(window, GLUT_REPAIR_WORK);
  61. }
  62. }
  63. static void __glutOnSize( HWND hwnd, UINT state, int width, int height )
  64. {
  65. GLUTwindow* window = __glutGetWindow( hwnd );
  66. if ( window )
  67. {
  68. if ( window->width != width || window->height != height )
  69. {
  70. window->width = width;
  71. window->height = height;
  72. __glutSetWindow( window );
  73. /* Do not execute OpenGL out of sequence with respect to the 
  74. SetWindowPos request! */
  75. GdiFlush();
  76. window->reshape( width, height );
  77. window->forceReshape = FALSE;
  78. /* A reshape should be considered like posting a repair request. */
  79. __glutPostRedisplay( window, GLUT_REPAIR_WORK );
  80. }
  81. }
  82. }
  83. static void updateWindowState( GLUTwindow *window, int visState )
  84. {
  85. GLUTwindow* child;
  86. /* XXX shownState and visState are the same in Win32. */
  87. window->shownState = visState;
  88. if ( visState != window->visState ) 
  89. {
  90. if ( window->windowStatus ) 
  91. {
  92. window->visState = visState;
  93. __glutSetWindow( window );
  94. window->windowStatus( visState );
  95. }
  96. }
  97. /* Since Win32 only sends an activate for the toplevel window,
  98. update the visibility for all the child windows. */
  99. child = window->children;
  100. while ( child ) 
  101. {
  102. updateWindowState( child, visState );
  103. child = child->siblings;
  104. }
  105. }
  106. static void __glutOnActivate( HWND hwnd, UINT state, HWND hWndPrev, BOOL minimized )
  107. {
  108. GLUTwindow* window = __glutGetWindow( hwnd );
  109. if ( window ) 
  110. {
  111. int visState = ! minimized;
  112. updateWindowState( window, visState );
  113. }
  114. /* Just in case there is a palette, make sure we re-select it if the 
  115. window is being activated. */
  116. if ( state != WA_INACTIVE )
  117. {
  118. PostMessage( hwnd, WM_PALETTECHANGED, 0, 0 );
  119. }
  120. }
  121. static void __glutOnSetFocus( HWND hwnd, HWND hwndOldFocus )
  122. {
  123. GLUTwindow* window = __glutGetWindow( hwnd );
  124. if ( window )
  125. {
  126. window->entryState = WM_SETFOCUS;
  127. if ( window->entry )
  128. {
  129. __glutSetWindow( window );
  130. window->entry( GLUT_ENTERED );
  131. /* XXX Generation of fake passive notify?  See how much
  132. work the X11 code does to support fake passive notify
  133. callbacks. */
  134. }
  135. if ( window->joystick && __glutCurrentWindow )
  136. {
  137. if ( __glutCurrentWindow->joyPollInterval > 0 ) 
  138. {
  139. /* Because Win32 will only let one window capture the
  140. joystick at a time, we must capture it when we get the
  141. focus and release it when we lose the focus. */
  142. MMRESULT result = joySetCapture( __glutCurrentWindow->win, JOYSTICKID1, 0, TRUE );
  143. if ( result == JOYERR_NOERROR )
  144. {
  145. joySetThreshold( JOYSTICKID1, __glutCurrentWindow->joyPollInterval );
  146. }
  147. }
  148. }
  149. }
  150. }
  151. static void __glutOnKillFocus( HWND hwnd, HWND hwndNewFocus )
  152. {
  153. GLUTwindow* window = __glutGetWindow( hwnd );
  154. if ( window )
  155. {
  156. window->entryState = WM_KILLFOCUS;
  157. if ( window->entry ) 
  158. {
  159. __glutSetWindow( window );
  160. window->entry( GLUT_LEFT );
  161. }
  162. if ( window->joystick && __glutCurrentWindow ) 
  163. {
  164. if ( __glutCurrentWindow->joyPollInterval > 0 )
  165. {
  166. joyReleaseCapture( JOYSTICKID1 );
  167. }
  168. }
  169. }
  170. }
  171. static void __glutOnGetMinMaxInfo( HWND hwnd, LPMINMAXINFO mmi )
  172. {
  173. GLUTwindow* window = __glutGetWindow( hwnd );
  174. if ( window )
  175. {
  176. RECT r;
  177. /* set it to as small as possible, although it doesn't seem to allow 
  178. the decorations to be munged. */
  179. r.top    = 0;
  180. r.left   = 0;
  181. r.bottom = 1;
  182. r.right  = 1;
  183. /* get window coordinates from the client coordinates. */
  184. AdjustWindowRect( &r, GetWindowLong( hwnd, GWL_STYLE ), FALSE );
  185. mmi->ptMinTrackSize.x = r.right - r.left;
  186. mmi->ptMinTrackSize.y = r.bottom - r.top;
  187. mmi->ptMaxTrackSize.x = __glutScreenWidth;
  188. mmi->ptMaxTrackSize.y = __glutScreenHeight;
  189. }
  190. }
  191. static GLUTwindow* getWindowUnderCursor( HWND hwndParent, GLUTwindow* windowParent )
  192. {
  193. /* It seems that some messages are sent to the parent window only.  Since 
  194. GLUT wants to send information to the "current" window, descend the 
  195. heirarchy until the window with the cursor in it is found. */
  196. assert( windowParent );
  197. if ( windowParent->children ) 
  198. {
  199. HWND hwndChild;
  200. POINT p;
  201. GetCursorPos( &p );
  202. ScreenToClient( hwndParent, &p );
  203. hwndChild = ChildWindowFromPoint( hwndParent, p );
  204. if ( hwndChild && hwndChild != hwndParent )
  205. {
  206. GLUTwindow* windowChild = __glutGetWindow( hwndChild );
  207. if ( windowChild )
  208. {
  209. windowParent = getWindowUnderCursor( hwndChild, windowChild );
  210. }
  211. }
  212. }
  213. return windowParent;
  214. }
  215. static unsigned int getModifierMask( void )
  216. {
  217. unsigned int mask = 0;
  218. if ( ( GetKeyState( VK_SHIFT ) & 0xFF00 ) )
  219. {
  220. mask |= ShiftMask;
  221. }
  222. if ( ( GetKeyState( VK_CONTROL ) & 0xFF00 ) )
  223. {
  224. mask |= ControlMask;
  225. }
  226. if ( ( GetKeyState( VK_MENU ) & 0xFF00 ) )
  227. {
  228. mask |= Mod1Mask;
  229. }
  230. return mask;
  231. }
  232. static int vkToSpecial( UINT vk )
  233. {
  234. switch ( vk )
  235. {
  236. case VK_F1: return -GLUT_KEY_F1;
  237. case VK_F2: return -GLUT_KEY_F2;
  238. case VK_F3: return -GLUT_KEY_F3;
  239. case VK_F4: return -GLUT_KEY_F4;
  240. case VK_F5: return -GLUT_KEY_F5;
  241. case VK_F6: return -GLUT_KEY_F6;
  242. case VK_F7: return -GLUT_KEY_F7;
  243. case VK_F8: return -GLUT_KEY_F8;
  244. case VK_F9: return -GLUT_KEY_F9;
  245. case VK_F10: return -GLUT_KEY_F10;
  246. case VK_F11: return -GLUT_KEY_F11;
  247. case VK_F12: return -GLUT_KEY_F12;
  248. case VK_LEFT: return -GLUT_KEY_LEFT;
  249. case VK_UP: return -GLUT_KEY_UP;
  250. case VK_RIGHT: return -GLUT_KEY_RIGHT;
  251. case VK_DOWN: return -GLUT_KEY_DOWN;
  252. case VK_PRIOR: return -GLUT_KEY_PAGE_UP;
  253. case VK_NEXT: return -GLUT_KEY_PAGE_DOWN;
  254. case VK_HOME: return -GLUT_KEY_HOME;
  255. case VK_END: return -GLUT_KEY_END;
  256. case VK_INSERT: return -GLUT_KEY_INSERT;
  257. default: return 0;
  258. }
  259. }
  260. static int getKey( UINT vk )
  261. {
  262. BYTE keyState[ 256 ];
  263. WORD c[ 2 ];
  264. GetKeyboardState( keyState );
  265. if ( ToAscii( vk, 0, keyState, c, 0 ) == 1 )
  266. {
  267. return c[ 0 ];
  268. }
  269. else
  270. {
  271. if ( vk == VK_DELETE )
  272. {
  273. return 127; /* 127 = DEL in ascii */
  274. }
  275. else
  276. {
  277. return vkToSpecial( vk );
  278. }
  279. }
  280. }
  281. static void __glutOnKey( HWND hwnd, UINT vk, BOOL down, int repeats, UINT flags )
  282. {
  283. int key;
  284. POINT point;
  285. GLUTwindow* window = __glutGetWindow( hwnd );
  286. if ( window )
  287. {
  288. window = getWindowUnderCursor( hwnd, window );
  289. /* If we are ignoring auto repeated key strokes for the window, 
  290. and this keystroke is an autorepeat generated one, bail. */ 
  291. if ( down )
  292. {
  293. BOOL autorepeat = ( ( flags >> 14 ) & 0x1 ) == 1;
  294. if ( window->ignoreKeyRepeat && autorepeat )
  295. {
  296. return;
  297. }
  298. }
  299. GetCursorPos( &point );
  300. ScreenToClient( window->win, &point );
  301. __glutModifierMask = getModifierMask();
  302. key = getKey( vk );
  303. if ( key < 0 ) 
  304. {
  305. /* special */
  306. if ( down )
  307. {
  308. if ( window->special )
  309. {
  310. __glutSetWindow( window );
  311. window->special( -key, point.x, point.y );
  312. }
  313. }
  314. else
  315. {
  316. if ( window->specialUp )
  317. {
  318. __glutSetWindow( window );
  319. window->specialUp( -key, point.x, point.y );
  320. }
  321. }
  322. }
  323. else if ( key > 0 )
  324. {
  325. /* ascii */
  326. if ( down )
  327. {
  328. if ( window->keyboard )
  329. {
  330. __glutSetWindow( window );
  331. window->keyboard( ( unsigned char )key, point.x, point.y );
  332. }
  333. }
  334. else
  335. {
  336. if ( window->keyboardUp )
  337. {
  338. __glutSetWindow( window );
  339. window->keyboardUp( ( unsigned char )key, point.x, point.y );
  340. }
  341. }
  342. }
  343. __glutModifierMask = ( unsigned int )~0;
  344. }
  345. }
  346. static void __glutOnButtonDn( HWND hwnd, int x, int y, int button )
  347. {
  348. GLUTmenu* menu;
  349. GLUTwindow* window = __glutGetWindow( hwnd );
  350. // !!! - look at this more closely sometime
  351. // !!! - look at this more closely sometime
  352. // !!! - look at this more closely sometime
  353. /* finish the menu if we get a button down message (user must have
  354. cancelled the menu). */
  355. if ( __glutMappedMenu ) 
  356. {
  357. POINT point;
  358. /* TODO: take this out once the menu on middle mouse stuff works
  359. properly. */
  360. if (button == GLUT_MIDDLE_BUTTON)
  361. return;
  362. GetCursorPos(&point);
  363. ScreenToClient(hwnd, &point);
  364. __glutItemSelected = NULL;
  365. __glutFinishMenu(hwnd, point.x, point.y);
  366. return;
  367. }
  368. // !!!
  369. // !!!
  370. // !!!
  371. /* Set the capture so we can get mouse events outside the window. */
  372. SetCapture( hwnd );
  373. if ( window )
  374. {
  375. menu = __glutGetMenuByNum( window->menu[ button ] );
  376. if ( menu ) 
  377. {
  378. POINT point;
  379. point.x = x; point.y = y;
  380. ClientToScreen(window->win, &point);
  381. __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
  382. button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :
  383. 0x0001;
  384. __glutStartMenu(menu, window, point.x, point.y, x, y);
  385. else if ( window->mouse ) 
  386. {
  387. __glutModifierMask = getModifierMask();
  388. __glutSetWindow( window );
  389. window->mouse( button, GLUT_DOWN, x, y );
  390. __glutModifierMask = ( unsigned int )~0;
  391. }
  392. }
  393. }
  394. static void __glutOnButtonUp( HWND hwnd, int x, int y, int button )
  395. {
  396. GLUTwindow* window = __glutGetWindow( hwnd );
  397. // !!! - look at this more closely sometime
  398. // !!! - look at this more closely sometime
  399. // !!! - look at this more closely sometime
  400. /* Bail out if we're processing a menu. */
  401. if (__glutMappedMenu) {
  402. POINT point;
  403. GetCursorPos(&point);
  404. ScreenToClient(hwnd, &point);
  405. /* if we're getting the middle button up signal, then something
  406. on the menu was selected. */
  407. if (button == GLUT_MIDDLE_BUTTON) {
  408. return;
  409. /* For some reason, the code below always returns -1 even
  410. though the point IS IN THE ITEM!  Therefore, just bail out if
  411. we get a middle mouse up.  The user must select using the
  412. left mouse button.  Stupid Win32. */
  413. #if 0
  414. int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
  415. if (item != -1)
  416. __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
  417. else
  418. __glutItemSelected = NULL;
  419. __glutFinishMenu(hwnd, point.x, point.y);
  420. #endif
  421. } else {
  422. __glutItemSelected = NULL;
  423. __glutFinishMenu(hwnd, point.x, point.y);
  424. }
  425. return;
  426. }
  427. // !!!
  428. // !!!
  429. // !!!
  430. /* Release the mouse capture. */
  431. ReleaseCapture();
  432. if ( window )
  433. {
  434. if ( window->mouse ) 
  435. {
  436. __glutModifierMask = getModifierMask();
  437. __glutSetWindow( window );
  438. window->mouse( button, GLUT_UP, x, y );
  439. __glutModifierMask = ( unsigned int )~0;
  440. }
  441. }
  442. }
  443. static void __glutOnLButtonDn( HWND hwnd, BOOL doubleClick, int x, int y, UINT flags )
  444. {
  445. __glutOnButtonDn( hwnd, x, y, GLUT_LEFT_BUTTON );
  446. }
  447. static void __glutOnRButtonDn( HWND hwnd, BOOL doubleClick, int x, int y, UINT flags )
  448. {
  449. __glutOnButtonDn( hwnd, x, y, GLUT_RIGHT_BUTTON );
  450. }
  451. static void __glutOnMButtonDn( HWND hwnd, BOOL doubleClick, int x, int y, UINT flags )
  452. {
  453. __glutOnButtonDn( hwnd, x, y, GLUT_MIDDLE_BUTTON );
  454. }
  455. static void __glutOnLButtonUp( HWND hwnd, int x, int y, UINT flags )
  456. {
  457. __glutOnButtonUp( hwnd, x, y, GLUT_LEFT_BUTTON );
  458. }
  459. static void __glutOnRButtonUp( HWND hwnd, int x, int y, UINT flags )
  460. {
  461. __glutOnButtonUp( hwnd, x, y, GLUT_RIGHT_BUTTON );
  462. }
  463. static void __glutOnMButtonUp( HWND hwnd, int x, int y, UINT flags )
  464. {
  465. __glutOnButtonUp( hwnd, x, y, GLUT_MIDDLE_BUTTON );
  466. }
  467. static void __glutOnMouseMove( HWND hwnd, int x, int y, UINT flags )
  468. {
  469. GLUTwindow* window = __glutGetWindow( hwnd );
  470. if ( __glutMappedMenu )
  471. {
  472. return;
  473. }
  474. if ( window )
  475. {
  476. BOOL down = ( flags & MK_LBUTTON ) || ( flags & MK_RBUTTON ) || ( flags & MK_MBUTTON );
  477. if ( window->motion && down )
  478. {
  479. __glutSetWindow( window );
  480. window->motion( x, y );
  481. }
  482. if ( window->passive && ! down )
  483. {
  484. __glutSetWindow( window );
  485. window->passive( x, y );
  486. }
  487. }
  488. }
  489. static BOOL __glutOnEnterMenuLoop( HWND hwnd )
  490. {
  491. /* KLUDGE: create a timer that fires every 100 ms when we start a
  492. menu so that we can still process the idle & timer events (that
  493. way, the timers will fire during a menu pick and so will the
  494. idle func. */
  495. SetTimer( hwnd, 'MENU', 1, NULL );
  496. return FALSE;
  497. }
  498. static BOOL __glutOnExitMenuLoop( HWND hwnd )
  499. {
  500. /* nuke the above created timer...we don't need it anymore, since
  501. the menu is gone now. */
  502. KillTimer( hwnd, 'MENU' );
  503. return FALSE;
  504. }
  505. static void __glutOnMenuSelect( HWND hwnd, HMENU hmenu, int item, HMENU hmenuPopup, UINT flags )
  506. {
  507. if ( hmenu != 0 )
  508. {
  509. __glutHMenu = hmenu;
  510. }
  511. }
  512. static void __glutOnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify )
  513. {
  514. if ( __glutMappedMenu ) 
  515. {
  516. POINT point;
  517. #if 0
  518. if ( GetSubMenu( __glutHMenu, id ) )
  519. {
  520. __glutItemSelected = NULL;
  521. }
  522. else
  523. #endif
  524. {
  525. __glutItemSelected = __glutGetUniqueMenuItem( __glutMappedMenu, id );
  526. }
  527. GetCursorPos( &point );
  528. ScreenToClient( hwnd, &point );
  529. __glutFinishMenu( hwnd, point.x, point.y );
  530. }
  531. static void __glutOnTimer( HWND hwnd, UINT id )
  532. {
  533. /* only worry about the idle function and the timeouts, since
  534. these are the only events we expect to process during
  535. processing of a menu. */
  536. /* we no longer process the idle functions (as outlined in the
  537. README), since drawing can't be done until the menu has
  538. finished...it's pretty lame when the animation goes on, but
  539. doesn't update, so you get this weird jerkiness. */
  540. #if 0
  541. if ( __glutIdleFunc )
  542. {
  543. __glutIdleFunc();
  544. }
  545. #endif
  546. if ( __glutTimerList )
  547. {
  548. handleTimeouts();
  549. }
  550. }
  551. static BOOL __glutOnSetCursor( HWND hwnd, HWND hWndCursor, UINT codeHitTest, UINT msg )
  552. {
  553. GLUTwindow* window = __glutGetWindow( hwnd );
  554. if ( window )
  555. {
  556. __glutSetCursor( window );
  557. }
  558. return FALSE;
  559. }
  560. static BOOL __glutOnPalette( HWND hwnd )
  561. {
  562. GLUTwindow* window = __glutGetWindow( hwnd );
  563. if ( window && window->colormap ) 
  564. {
  565. UnrealizeObject( window->colormap->cmap );
  566. SelectPalette( window->hdc, window->colormap->cmap, FALSE );
  567. RealizePalette( window->hdc );
  568. return TRUE;
  569. }
  570. return FALSE;
  571. }
  572. static BOOL __glutOnJoystick( HWND hwnd )
  573. {
  574. GLUTwindow* window = __glutGetWindow( hwnd );
  575. if ( window->joystick ) 
  576. {
  577. JOYINFOEX jix;
  578. int x, y, z;
  579. /* Because WIN32 only supports messages for X, Y, and Z
  580. translations, we must poll for the rest */
  581. jix.dwSize = sizeof( jix );
  582. jix.dwFlags = JOY_RETURNALL;
  583. joyGetPosEx( JOYSTICKID1, &jix );
  584. #define SCALE( v )  ( ( int )( ( v - 32767 ) / 32.768 ) )
  585. /* Convert to integer for scaling. */
  586. x = jix.dwXpos;
  587. y = jix.dwYpos;
  588. z = jix.dwZpos;
  589. window->joystick( jix.dwButtons, SCALE( x ), SCALE( y ), SCALE( z ) );
  590. return TRUE;
  591. }
  592. return FALSE;
  593. }
  594. LONG WINAPI __glutWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
  595. {
  596. switch ( msg ) 
  597. {
  598. case WM_CREATE: return HANDLE_WM_CREATE  ( hwnd, wparam, lparam, __glutOnCreate );
  599. case WM_CLOSE:  return HANDLE_WM_CLOSE ( hwnd, wparam, lparam, __glutOnClose );
  600. case WM_DESTROY: return HANDLE_WM_DESTROY ( hwnd, wparam, lparam, __glutOnDestroy  );
  601. case WM_PAINT:  return HANDLE_WM_PAINT ( hwnd, wparam, lparam, __glutOnPaint );
  602. case WM_SIZE: return HANDLE_WM_SIZE ( hwnd, wparam, lparam, __glutOnSize  );
  603. case WM_ACTIVATE:  return HANDLE_WM_ACTIVATE ( hwnd, wparam, lparam, __glutOnActivate );
  604. case WM_SETFOCUS:  return HANDLE_WM_SETFOCUS ( hwnd, wparam, lparam, __glutOnSetFocus );
  605. case WM_KILLFOCUS: return HANDLE_WM_KILLFOCUS  ( hwnd, wparam, lparam, __glutOnKillFocus );
  606. case WM_GETMINMAXINFO: return HANDLE_WM_GETMINMAXINFO  ( hwnd, wparam, lparam, __glutOnGetMinMaxInfo   );
  607. case WM_KEYDOWN: return HANDLE_WM_KEYDOWN ( hwnd, wparam, lparam, __glutOnKey );
  608. case WM_KEYUP:  return HANDLE_WM_KEYUP ( hwnd, wparam, lparam, __glutOnKey );
  609. case WM_SYSKEYDOWN: return HANDLE_WM_KEYDOWN ( hwnd, wparam, lparam, __glutOnKey );
  610. case WM_SYSKEYUP:  return HANDLE_WM_KEYUP ( hwnd, wparam, lparam, __glutOnKey );
  611. case WM_LBUTTONDOWN:  return HANDLE_WM_LBUTTONDOWN ( hwnd, wparam, lparam, __glutOnLButtonDn );
  612. case WM_RBUTTONDOWN:  return HANDLE_WM_RBUTTONDOWN ( hwnd, wparam, lparam, __glutOnRButtonDn );
  613. case WM_MBUTTONDOWN:  return HANDLE_WM_MBUTTONDOWN ( hwnd, wparam, lparam, __glutOnMButtonDn );
  614. case WM_LBUTTONUP: return HANDLE_WM_LBUTTONUP  ( hwnd, wparam, lparam, __glutOnLButtonUp );
  615. case WM_RBUTTONUP: return HANDLE_WM_RBUTTONUP  ( hwnd, wparam, lparam, __glutOnRButtonUp );
  616. case WM_MBUTTONUP: return HANDLE_WM_MBUTTONUP  ( hwnd, wparam, lparam, __glutOnMButtonUp );
  617. case WM_MOUSEMOVE: return HANDLE_WM_MOUSEMOVE  ( hwnd, wparam, lparam, __glutOnMouseMove );
  618. case WM_ENTERMENULOOP: return __glutOnEnterMenuLoop( hwnd );
  619. case WM_EXITMENULOOP: return __glutOnExitMenuLoop( hwnd );
  620. case WM_COMMAND: return HANDLE_WM_COMMAND        ( hwnd, wparam, lparam, __glutOnCommand         );
  621. case WM_TIMER: return HANDLE_WM_TIMER          ( hwnd, wparam, lparam, __glutOnTimer           );
  622. case WM_SETCURSOR:
  623. if ( LOWORD( lparam ) != HTCLIENT )
  624. {
  625. /* Let the default window proc handle cursors outside the client area */
  626. break;
  627. }
  628. else
  629. {
  630. return HANDLE_WM_SETCURSOR( hwnd, wparam, lparam, __glutOnSetCursor );
  631. }
  632. case WM_PALETTECHANGED:
  633. if ( ( HWND )wparam == hwnd ) 
  634. {
  635. /* Don't respond to the message that we sent! */
  636. break;
  637. }
  638. /* Fall through to WM_QUERYNEWPALETTE */
  639. case WM_QUERYNEWPALETTE:
  640. return __glutOnPalette( hwnd );
  641. case MM_JOY1MOVE:
  642. case MM_JOY1ZMOVE:
  643. case MM_JOY1BUTTONDOWN:
  644. case MM_JOY1BUTTONUP:
  645. return __glutOnJoystick( hwnd );
  646. default:
  647. break;
  648. }
  649. return DefWindowProc( hwnd, msg, wparam, lparam );
  650. }