home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / input / joytoy / joytoy.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  9KB  |  294 lines

  1. /* joytoy.c - WinMain() and WndProc() for JOYTOY, along with
  2.  *      initialization and support code.
  3.  *
  4.  * JOYTOY is a Windows with Multimedia application that illustrates
  5.  *  how to use the joystick services. When run, it presents the user
  6.  *  with a crosshair cursor. When the joystick or the mouse is moved,
  7.  *  the cursor follows. When a joystick button is pressed, JOYTOY
  8.  *  produces a sound and draws a bullet hole icon onto the screen.
  9.  *
  10.  *
  11.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  12.  *  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  13.  *  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
  14.  *  A PARTICULAR PURPOSE.
  15.  *
  16.  *  Copyright (C) 1993 - 1997 Microsoft Corporation. All Rights Reserved.
  17.  */
  18.  
  19. #include <windows.h>
  20. #include <mmsystem.h>
  21. #include "joytoy.h"
  22.  
  23.  
  24. char szAppName[] = "JoyToy";     
  25. HANDLE hSound1, hSound2;
  26. HANDLE hHole;
  27. LPSTR lpSound1, lpSound2;
  28.  
  29.  
  30. /* WinMain - Entry point for JOYTOY.
  31.  */
  32. int PASCAL WinMain(hInstance,hPrevInstance,lpszCmdLine,cmdShow)
  33. HANDLE hInstance,hPrevInstance;
  34. LPSTR lpszCmdLine;
  35. int cmdShow;
  36. {
  37.     MSG msg;
  38.  
  39.     /* Initialize the application.
  40.      */
  41.     if(! InitJoyToy(hInstance,hPrevInstance))
  42.         return FALSE;
  43.  
  44.     /* Standard Windows message processing loop.  We don't drop out of
  45.      * this loop until the user quits the application.
  46.      */
  47.     while(GetMessage(&msg, NULL, 0, 0))
  48.     {
  49.         TranslateMessage(&msg);
  50.         DispatchMessage(&msg);
  51.     }
  52.  
  53.     /* Unlock and free resources allocated by InitJoyToy().
  54.      */
  55.     UnlockResource(hSound1);
  56.     UnlockResource(hSound2);
  57.     FreeResource(hSound1);
  58.     FreeResource(hSound2);
  59.     FreeResource(hHole);
  60.  
  61.     return (msg.wParam);
  62. }
  63.  
  64. /* DrawSight - Takes the new joystick position and moves the 
  65.  *  mouse cursor accordingly.
  66.  *
  67.  * Params:  lParam - Specifies the new joystick position. The
  68.  *  high-order word is the y position and the low-order word is
  69.  *  the x position.
  70.  *
  71.  * Returns: void
  72.  */
  73. void DrawSight(DWORD lParam)
  74. {
  75.     WORD x, y;
  76.     POINT pt;
  77.  
  78.     /* Get the current cursor position in screen coordinates.
  79.      */
  80.     GetCursorPos(&pt);
  81.  
  82.     /* Joystick positions are expressed in a coordinate system with the
  83.      * origin in the upper left corner and with coordinate ranges from
  84.      * 0 to 65535. Take the 5 most significant bits, so the position is 
  85.      * expressed in the range of 0 to 31.
  86.      */
  87.     x = LOWORD(lParam) >> 11;
  88.     y = HIWORD(lParam) >> 11;
  89.  
  90.     /* If the joystick is to the left of the center position, then move
  91.      * the cursor position to the left. Otherwise, if the joystick is to 
  92.      * the right of the center position, then move the cursor position 
  93.      * to the right.
  94.      */
  95.     if(x <= 12)
  96.         pt.x = pt.x + x - 17;
  97.     else if(x >= 20)
  98.         pt.x = pt.x + x - 15;
  99.  
  100.     /* If the joystick is below the center position, then move the cursor 
  101.      * position down. Otherwise, if the joystick is above the center 
  102.      * position, then move the cursor position up.
  103.      */
  104.     if(y <= 12)
  105.         pt.y = pt.y + y - 17;
  106.     else if(y >= 20)
  107.         pt.y = pt.y + y - 15;
  108.  
  109.     /* Set the new cursor position.
  110.      */
  111.     SetCursorPos(pt.x, pt.y);
  112. }
  113.  
  114. /* DrawHole - Draws an icon representing a hole in the given window at the 
  115.  * current cursor position.
  116.  *
  117.  * Params:  hWnd - Specifies the handle to the window to draw in.
  118.  *
  119.  * Returns: void
  120.  */
  121. void DrawHole(HWND hWnd)
  122. {
  123.     HDC hDC;
  124.     POINT pt;
  125.  
  126.     /* Get the current cursor position.
  127.      */
  128.     GetCursorPos(&pt);
  129.     
  130.     /* Get a DC, draw the icon, release DC.
  131.      */
  132.     hDC = GetDC(hWnd);
  133.     DrawIcon(hDC, pt.x - 16, pt.y - 16, hHole);
  134.     ReleaseDC(hWnd, hDC);
  135. }
  136.  
  137.  
  138. /* WndProc - Main window procedure function.
  139.  */
  140. LRESULT FAR PASCAL WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  141. {
  142.     switch(message)
  143.     {
  144.         case WM_CREATE:
  145.             /* Capture the joystick. If this fails, beep and display
  146.              * error, then quit.
  147.              */
  148.             if(joySetCapture(hWnd, JOYSTICKID1, 0, FALSE))
  149.             {
  150.                 MessageBeep(MB_ICONEXCLAMATION);
  151.                 MessageBox(hWnd, "Couldn't capture the joystick", NULL, 
  152.                            MB_OK | MB_ICONEXCLAMATION);
  153.                 return -1;
  154.             }            
  155.             break;
  156.  
  157.         case WM_ACTIVATE:
  158.         case WM_ACTIVATEAPP:
  159.             /* If app becomes inactive (wParam == 0), then we want to quit.
  160.              */
  161.             if(wParam)
  162.                 break;
  163.  
  164.         case WM_LBUTTONDOWN:
  165.         case WM_MBUTTONDOWN:
  166.         case WM_RBUTTONDOWN:
  167.         case WM_KEYDOWN:
  168.         case WM_CHAR:
  169.             /* Also, any keystrokes or mouse buttons cause us to quit.
  170.              */
  171.             PostMessage(hWnd,WM_CLOSE,0,0L);
  172.             break;
  173.  
  174.         case WM_ERASEBKGND:
  175.             /* Process this message to keep Windows from erasing background.
  176.              */
  177.             return 0l;
  178.  
  179.         case MM_JOY1BUTTONDOWN :
  180.             /* Joystick button pressed. Detect which button, play appropriate
  181.              * sound, then draw bullet hole. To play sound, pass 
  182.              * sndPlaySound() a pointer to an in-memory WAVE file and 
  183.              * specify the SND_MEMORY flag. Specify SND_LOOP and SND_ASYNC
  184.              * so that sound keeps playing until it's turned off after 
  185.              * joystick button is released.
  186.              */
  187.             if (wParam & JOY_BUTTON1CHG)
  188.             {
  189.                 sndPlaySound(lpSound1, SND_LOOP | SND_ASYNC | SND_MEMORY);
  190.                 DrawHole(hWnd);
  191.             }
  192.             else if (wParam & JOY_BUTTON2CHG)
  193.             {
  194.                 sndPlaySound(lpSound2, SND_LOOP | SND_ASYNC | SND_MEMORY);
  195.                 DrawHole(hWnd);
  196.             }
  197.             break;
  198.  
  199.         case MM_JOY1BUTTONUP :
  200.             /* Stop playing looped sound.
  201.              */
  202.             if (wParam & JOY_BUTTON1)
  203.                 sndPlaySound(lpSound1, SND_LOOP | SND_ASYNC | SND_MEMORY);
  204.             else if (wParam & JOY_BUTTON2)
  205.                 sndPlaySound(lpSound2, SND_LOOP | SND_ASYNC | SND_MEMORY);
  206.             else
  207.                 sndPlaySound(NULL, 0);
  208.             break;
  209.  
  210.         case MM_JOY1MOVE :
  211.             /* If joystick buttons are pressed, draw bullet holes
  212.              * while joystick is moved.
  213.              */
  214.             if(wParam & (JOY_BUTTON1 | JOY_BUTTON2))
  215.                 DrawHole(hWnd);
  216.  
  217.             /* Redraw the crosshair in its new position.
  218.              */
  219.             DrawSight(lParam);
  220.             break;
  221.  
  222.  
  223.         case WM_DESTROY:
  224.             /* We're shutting down. Release capture on the joystick, 
  225.              * make sure any sounds that are playing are stopped.
  226.              */
  227.             joyReleaseCapture(JOYSTICKID1);
  228.             sndPlaySound(NULL, 0);
  229.             PostQuitMessage(0);
  230.             break;
  231.     }
  232.     return DefWindowProc(hWnd, message, wParam, lParam);
  233. }
  234.  
  235.  
  236. /* InitJoyToy - Application initialization routine.
  237.  *
  238.  * Params:  hInstance - App's instance handle.
  239.  *
  240.  * Returns: TRUE if initialization is successful, FALSE otherwise.
  241.  */
  242. BOOL InitJoyToy(HANDLE hInstance, HANDLE hPrevInstance)
  243. {
  244.     WNDCLASS wc;
  245.     HWND     hWnd;
  246.  
  247.     /* Make sure there is a joystick device installed.
  248.      */
  249.     if (!joyGetNumDevs())
  250.     {
  251.         MessageBox(NULL, "There are no joystick devices installed. Exiting.",
  252.                    NULL, MB_OK | MB_ICONEXCLAMATION);
  253.         return FALSE;
  254.     }
  255.    
  256.     /* Load bullet hole icon.
  257.      */
  258.     hHole = LoadIcon(hInstance, "HoleIcon");
  259.  
  260.     if (hPrevInstance == NULL) {
  261.         /* Setup and register a window class for our main window.
  262.          */
  263.         wc.hCursor          = LoadCursor(NULL, IDC_CROSS);
  264.         wc.hIcon            = NULL;
  265.         wc.lpszMenuName     = NULL;
  266.         wc.lpszClassName    = szAppName;
  267.         wc.hbrBackground    = GetStockObject(BLACK_BRUSH);
  268.         wc.hInstance        = hInstance;
  269.         wc.style            = CS_HREDRAW | CS_VREDRAW;
  270.         wc.lpfnWndProc      = WndProc;
  271.         wc.cbClsExtra       = 0;
  272.         wc.cbWndExtra       = 0;
  273.     
  274.         if(! RegisterClass(&wc))
  275.             return FALSE;   
  276.     }
  277.  
  278.     /* Create a full-screen window with no title bar or scroll bars.
  279.      */
  280.     hWnd = CreateWindow(szAppName, szAppName, WS_POPUP | WS_VISIBLE, 0, 0,
  281.         GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
  282.         NULL, NULL, hInstance, NULL);
  283.  
  284.     if (hWnd != NULL) {
  285.         /* Load and lock sound resources.
  286.          */
  287.         hSound1 = LoadResource(hInstance, FindResource(hInstance, "SOUND1", "WAVE"));
  288.         hSound2 = LoadResource(hInstance, FindResource(hInstance, "SOUND2", "WAVE"));
  289.         lpSound1 = LockResource(hSound1);
  290.         lpSound2 = LockResource(hSound2);
  291.     }
  292.     return hWnd != NULL;
  293. }
  294.