home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / BOUNCER / BOUNCER.C_ / BOUNCER.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  15.0 KB  |  453 lines

  1. /*  BOUNCER.C - ScreenSaverProc(), RegisterDialogClasses(), 
  2.  *   ScreenSaverConfigureDialog() and other support code for 
  3.  *   BOUNCER.
  4.  *
  5.  *   BOUNCER is a sample screen saver application. It bounces a
  6.  *   bitmap across the display and produces a sound when the
  7.  *   bitmap image is at the bottom of the screen.
  8.  *
  9.  *    (C) Copyright Microsoft Corp. 1991.  All rights reserved.
  10.  *
  11.  *    You have a royalty-free right to use, modify, reproduce and 
  12.  *    distribute the Sample Files (and/or any modified version) in 
  13.  *    any way you find useful, provided that you agree that 
  14.  *    Microsoft has no warranty obligations or liability for any 
  15.  *    Sample Application Files which are modified. 
  16.  */
  17.  
  18. #include <windows.h> 
  19. #include <mmsystem.h>
  20.  
  21. #include "bouncer.h"
  22.  
  23.  
  24. /* Global used by SCRNSAVE.LIB. Required for all screen savers.
  25.  */
  26. char szAppName[40];
  27.  
  28.  
  29. /* Globals specific to BOUNCER.
  30.  */
  31. char szDIBName[] = "BounceDIB";
  32. char szSpeedName[] = "Speed";
  33. char szXPosName[] = "xPosition";
  34. char szYPosName[] = "yPosition";
  35. char szXVelocityName[] = "xVelocity";
  36. char szGravityName[] = "Gravity";
  37. char szSoundName[] = "Sound";
  38. char szDIBNumName[] = "DIBNum";
  39. char szPauseName[]= "Pause at bottom";
  40. char szName[]="Bounce a bitmap";
  41.  
  42. /* Externals defined in SCRNSAVE.LIB. Required for all screen savers.
  43.  */
  44.  
  45. HINSTANCE _cdecl hMainInstance;
  46. HWND _cdecl hMainWindow;
  47. char _cdecl szName[TITLEBARNAMELEN];
  48. char _cdecl szIsPassword[22];
  49. char _cdecl szIniFile[MAXFILELEN];
  50. char _cdecl szScreenSaver[22];
  51. char _cdecl szPassword[16];
  52. char _cdecl szDifferentPW[BUFFLEN];
  53. char _cdecl szChangePW[30];
  54. char _cdecl szBadOldPW[BUFFLEN];
  55. char _cdecl szHelpFile[MAXFILELEN];
  56. char _cdecl szNoHelpMemory[BUFFLEN];
  57. UINT _cdecl MyHelpMessage;
  58. HOOKPROC _cdecl fpMessageFilter;
  59.  
  60. HBITMAP hbmImage;                   // image handle
  61. WORD wElapse;                       // speed parameter
  62. WORD wTimer;                        // timer id
  63. BOOL bBottom;                       // TRUE if frog is at bottom of screen
  64. int xPos;                           // current x position
  65. int yPos;                           // current y position
  66. int xPosInit;                       // initial x position
  67. int yPosInit;                       // initial y position
  68. int xVelocInit;                     // x initial velocity
  69. int nGravity;                       // acceleration factor
  70. BOOL bSound;                        // sound on/off flag
  71. BOOL bPause;                        // stick at bottom of screen?
  72. BOOL bPassword;                     // password protected?
  73. HANDLE hresWave;                    // handle to sound resource
  74. LPSTR lpWave;                       // pointer to wave resource
  75.  
  76.  
  77. /* ScreenSaverProc - Main entry point for screen saver messages.
  78.  *  This function is required for all screen savers.
  79.  *
  80.  * Params:  Standard window message handler parameters.
  81.  *
  82.  * Return:  The return value depends on the message.
  83.  *
  84.  *  Note that all messages go to the DefScreenSaverProc(), except
  85.  *  for ones we process.
  86.  */
  87. LONG FAR PASCAL __export ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  88. {
  89.     RECT rc;
  90.     static WORD wBottomCount;
  91.     switch (msg)
  92.     {
  93.         case WM_CREATE:                             // BOUNCER-specific
  94.         {
  95.             HANDLE hResInfo;
  96.  
  97.             /* Load the strings from the STRINGTABLE
  98.              */
  99.             GetIniEntries();
  100.  
  101.             /* Load the initial bounce settings.
  102.              */
  103.             GetIniSettings();
  104.  
  105.             /* Load the DIB image we want to use.
  106.              */
  107.             hbmImage = LoadBitmap(hMainInstance, szDIBName);
  108.  
  109.             /* Load and lock the sound resource
  110.              */
  111.             if( hResInfo = FindResource(hMainInstance, "Sound", "WAVE") )
  112.             {
  113.                 if( hresWave = LoadResource(hMainInstance, hResInfo) )
  114.                 {
  115.                     lpWave = LockResource(hresWave);
  116.                 }
  117.             }
  118.  
  119.             /* Create a timer to move the image
  120.              */
  121.             wTimer = SetTimer(hWnd, ID_TIMER, wElapse, NULL);
  122.  
  123.             xPos = xPosInit;
  124.             yPos = yPosInit;
  125.  
  126.             break;
  127.         }
  128.  
  129.         case WM_TIMER:                              // BOUNCER-specific
  130.             if(bPause && bBottom)
  131.             {
  132.                 if(++wBottomCount == 10)
  133.                 {
  134.                     wBottomCount = 0;
  135.                     bBottom = FALSE;
  136.                 }
  137.                 break;
  138.             }
  139.  
  140.             /* Move the image around a bit
  141.              */
  142.             MoveImage(hWnd);
  143.  
  144.             break;
  145.  
  146.         case WM_DESTROY:                            // BOUNCER-specific
  147.  
  148.             /* Destroy any objects we created
  149.              */
  150.             if( hbmImage ) DeleteObject(hbmImage);
  151.             if( wTimer )   KillTimer(hWnd, ID_TIMER);
  152.             sndPlaySound(NULL, 0);
  153.             if( lpWave )   UnlockResource(hresWave);
  154.             if( hresWave ) FreeResource(hresWave);
  155.  
  156.             break;
  157.  
  158.         case WM_ERASEBKGND:
  159.             GetClientRect(hWnd,&rc);
  160.             FillRect((HDC)wParam,&rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
  161.             return 0L;
  162.  
  163.         default:
  164.             break;
  165.         }
  166.  
  167.     return DefScreenSaverProc(hWnd, msg, wParam, lParam);
  168. }
  169.  
  170. /* RegisterDialogClasses -- Entry point for registering window
  171.  * classes required by configuration dialog box.
  172.  *
  173.  * Params:  hWnd -- Handle to window
  174.  *
  175.  * Return:  None
  176.  */
  177. BOOL RegisterDialogClasses(HINSTANCE hInst)
  178. {
  179.     return TRUE;
  180. }
  181.  
  182.  
  183. /* ScreenSaverConfigureDialog -- Dialog box function for configuration
  184.  * dialog.
  185.  *
  186.  * Params:  hWnd -- Handle to window
  187.  *
  188.  * Return:  None
  189.  */
  190. BOOL FAR PASCAL __export ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  191. {
  192.   static HWND hIDOK;
  193.   static HWND hSetPassword;
  194.  
  195.     switch (msg)
  196.     {
  197.         case WM_INITDIALOG:                         // BOUNCER-specific
  198.             GetIniEntries();
  199.             GetIniSettings();
  200.             SetDlgItemInt(hDlg, ID_SPEED,    wElapse,    FALSE);
  201.             SetDlgItemInt(hDlg, ID_XPOS,     xPosInit,   TRUE);
  202.             SetDlgItemInt(hDlg, ID_YPOS,     yPosInit,   TRUE);
  203.             SetDlgItemInt(hDlg, ID_VELOCITY, xVelocInit, TRUE);
  204.             SetDlgItemInt(hDlg, ID_GRAVITY,  nGravity,   TRUE);
  205.             SendDlgItemMessage(hDlg, ID_SOUND, BM_SETCHECK, bSound, NULL);
  206.             SendDlgItemMessage(hDlg, ID_PAUSE, BM_SETCHECK, bPause, NULL);
  207.             SendDlgItemMessage(hDlg, ID_PASSWORDPROTECTED, BM_SETCHECK,
  208.                 bPassword, NULL);
  209.             hSetPassword=GetDlgItem(hDlg, ID_SETPASSWORD);
  210.             EnableWindow(hSetPassword, bPassword);
  211.             hIDOK=GetDlgItem(hDlg, IDOK);
  212.             return TRUE;
  213.  
  214.         case WM_COMMAND:                            // BOUNCER-specific
  215.             switch (wParam)
  216.             {
  217.                 case IDOK:
  218.                     wElapse    = GetDlgItemInt(hDlg, ID_SPEED,    NULL, FALSE);
  219.                     xPosInit   = GetDlgItemInt(hDlg, ID_XPOS,     NULL, TRUE);
  220.                     yPosInit   = GetDlgItemInt(hDlg, ID_YPOS,     NULL, TRUE);
  221.                     xVelocInit = GetDlgItemInt(hDlg, ID_VELOCITY, NULL, TRUE);
  222.                     nGravity   = GetDlgItemInt(hDlg, ID_GRAVITY,  NULL, TRUE);
  223.                     bSound     = IsDlgButtonChecked(hDlg, ID_SOUND);
  224.                     bPause     = IsDlgButtonChecked(hDlg, ID_PAUSE);
  225.                     bPassword  = IsDlgButtonChecked(hDlg, ID_PASSWORDPROTECTED);
  226.  
  227.                     WriteProfileInt(szAppName, szSpeedName, wElapse);
  228.                     WriteProfileInt(szAppName, szXPosName, xPosInit);
  229.                     WriteProfileInt(szAppName, szYPosName, yPosInit);
  230.                     WriteProfileInt(szAppName, szXVelocityName, xVelocInit);
  231.                     WriteProfileInt(szAppName, szGravityName, nGravity);
  232.                     WriteProfileInt(szAppName, szSoundName, bSound);
  233.                     WriteProfileInt(szAppName, szPauseName, bPause);
  234.                     WriteProfileInt(szAppName, szIsPassword, bPassword);
  235.  
  236.                     EndDialog(hDlg, TRUE);
  237.                     return TRUE;
  238.  
  239.                 case IDCANCEL:
  240.                     EndDialog(hDlg, FALSE);
  241.                     return TRUE;
  242.  
  243.                 case ID_SETPASSWORD:
  244.                 {
  245.                     FARPROC fpDialog;
  246.  
  247.                     if((fpDialog = MakeProcInstance(DlgChangePassword,hMainInstance)) == NULL)
  248.                         return FALSE;
  249.                     DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_CHANGEPASSWORD), 
  250.                               hDlg, fpDialog);
  251.                     FreeProcInstance(fpDialog);
  252.                     SendMessage(hDlg, WM_NEXTDLGCTL, hIDOK, 1l);
  253.                     break;
  254.                 }
  255.  
  256.                 case ID_PASSWORDPROTECTED:
  257.                     bPassword ^= 1;
  258.                     CheckDlgButton(hDlg, wParam, bPassword);
  259.                     EnableWindow(hSetPassword, bPassword);
  260.                     break;
  261.  
  262.                 case ID_HELP:
  263. DoHelp:
  264. #if 0
  265.                     bHelpActive=WinHelp(hDlg, szHelpFile, HELP_CONTEXT, IDH_DLG_BOUNCER);
  266.                     if (!bHelpActive)
  267.                         MessageBox(hDlg, szNoHelpMemory, szName, MB_OK);
  268. #else
  269.                     MessageBox(hDlg, "Insert your call to WinHelp() here.",
  270.                         szName, MB_OK);
  271. #endif
  272.                     break;
  273.             }
  274.             break;
  275.         default:
  276.             if (msg==MyHelpMessage)     // Context sensitive help msg.
  277.                 goto DoHelp;
  278.     }
  279.     return FALSE;
  280. }
  281.  
  282.  
  283. /* THE REST OF THIS FILE IS SPECIFIC TO BOUNCER.
  284.  *
  285.  * Replace it with your own screen saver code.
  286.  */
  287.  
  288.  
  289. /* GetIniSettings -- Get initial bounce settings from WIN.INI
  290.  *
  291.  * Params:  hWnd -- Handle to window
  292.  *
  293.  * Return:  None
  294.  */
  295. static void GetIniSettings()
  296. {
  297.     wElapse =    GetPrivateProfileInt(szAppName, szSpeedName, DEF_SPEED, szIniFile);
  298.     xPosInit =   GetPrivateProfileInt(szAppName, szXPosName, DEF_INIT_XPOS, szIniFile);
  299.     yPosInit =   GetPrivateProfileInt(szAppName, szYPosName, DEF_INIT_YPOS, szIniFile);
  300.     xVelocInit = GetPrivateProfileInt(szAppName, szXVelocityName, DEF_INIT_VELOC, szIniFile);
  301.     nGravity =   GetPrivateProfileInt(szAppName, szGravityName, DEF_INIT_GRAVITY, szIniFile);
  302.     bSound =     GetPrivateProfileInt(szAppName, szSoundName, DEF_SOUND, szIniFile);
  303.     bPause =     GetPrivateProfileInt(szAppName, szPauseName, DEF_PAUSE, szIniFile);
  304.     bPassword =  GetPrivateProfileInt(szAppName, szIsPassword, FALSE, szIniFile);
  305. }
  306.  
  307. /* MoveImage -- Move image around the screen
  308.  *
  309.  * Params:  hWnd -- Handle to window
  310.  *
  311.  * Return:  None
  312.  */
  313. static void MoveImage(HWND hWnd) 
  314. {
  315. //    static int xPos = 10000;            // Current x value (force a reset)
  316. //    static int yPos = 0;                // Current y value
  317.     static int yVeloc = 0;              // Current y velocity
  318.  
  319.     int xPosOld, yPosOld;
  320.  
  321.     HDC hDC;                            // Handle to our window DC
  322.     HDC hMemDC;                         // Handle to a memory DC
  323.     BITMAP bm;                          // Bitmap info
  324.     HBITMAP hbmOld;
  325.     RECT rcWnd, rcFill;
  326.  
  327.     /* Get window size
  328.      */
  329.     GetClientRect(hWnd, &rcWnd);
  330.  
  331.     /* Get bitmap size
  332.      */
  333.     GetObject(hbmImage, sizeof(bm), (LPSTR)&bm);
  334.  
  335.     /* Update x- and y-position values
  336.      */
  337.     xPosOld = xPos;
  338.     yPosOld = yPos;
  339.  
  340.     yVeloc += nGravity;
  341.  
  342.     xPos += xVelocInit;
  343.     yPos += yVeloc;
  344.  
  345.     /* If we're at the bottom, BOUNCE!
  346.      */
  347.     if((yPos + bm.bmHeight > rcWnd.bottom) && (yVeloc > 0))
  348.     {
  349.         yVeloc = -yVeloc;                   // Reverse directions
  350.  
  351.         if (bSound && lpWave)               // Boing!!! 
  352.         {                
  353.             // do the multimedia bit
  354.             sndPlaySound(lpWave, SND_ASYNC | SND_MEMORY | SND_NODEFAULT);
  355.         }
  356.         bBottom = TRUE;
  357.     }
  358.  
  359.     /* If we're off the right of the screen, or off the bottom of the
  360.      * screen, start over at beginning position and zero y-velocity.
  361.      */
  362.     if((xPos > rcWnd.right) || (yPos > rcWnd.bottom))
  363.     {
  364.         yVeloc = 0;
  365.         xPos   = xPosInit;
  366.         yPos   = yPosInit;
  367.     }
  368.  
  369.     /* Get a DC to our window.  Create a compatible memory
  370.      * DC and select our image bitmap into it so we can blit
  371.      * it to the main window DC
  372.      */
  373.     hDC = GetDC(hWnd);
  374.     hMemDC = CreateCompatibleDC(hDC);
  375.     hbmOld = SelectObject(hMemDC, hbmImage);
  376.  
  377.     if(hbmOld)
  378.     {
  379.         /* Blit the image in the new position
  380.          */
  381.         BitBlt( hDC,                        // dest DC
  382.                 xPos,yPos,                  // dest origin
  383.                 bm.bmWidth,bm.bmHeight,     // dest extents
  384.                 hMemDC,                     // src DC
  385.                 0,0,                        // src origin
  386.                 SRCCOPY );                  // ROP code
  387.  
  388.         SelectObject(hMemDC, hbmOld);
  389.  
  390.         /* Tidy up where the old image was by filling exposed bits with
  391.          * the background color
  392.          *
  393.          * This code assumes the image always moves to the right
  394.          */
  395.         rcFill.left   = xPosOld;                        // Left bits
  396.         rcFill.top    = yPosOld;
  397.         rcFill.right  = xPos;
  398.         rcFill.bottom = rcFill.top + bm.bmHeight;
  399.  
  400.         FillRect(hDC, &rcFill, GetStockObject(BLACK_BRUSH));
  401.  
  402.         rcFill.right = rcFill.left + bm.bmWidth;        // Top or bottom bits
  403.         if( yPos > yPosOld )
  404.         {
  405.             rcFill.bottom = yPos;                       // Top bits
  406.         }
  407.         else
  408.         {
  409.             rcFill.top = yPos + bm.bmHeight;            // Bottom bits
  410.             rcFill.bottom = yPosOld + bm.bmHeight;
  411.         }
  412.         FillRect(hDC, &rcFill, GetStockObject(BLACK_BRUSH));
  413.     }
  414.     DeleteDC(hMemDC);
  415.     ReleaseDC(hWnd, hDC);
  416. }
  417.  
  418.  
  419.  
  420.  
  421. /* WriteProfileInt - Write an unsigned integer value to CONTROL.INI.
  422.  *
  423.  * Params:  name - szSection - [section] name in .INI file
  424.  *                 szKey     - key= in .INI file
  425.  *                 i         - value for key above
  426.  *
  427.  * Return:  None
  428.  */
  429. static void WriteProfileInt(LPSTR szSection, LPSTR szKey, int i) 
  430. {
  431.     char achBuf[40];
  432.  
  433.     /* write out as unsigned because GetPrivateProfileInt() can't
  434.      * cope with signed values!
  435.      */
  436.     wsprintf(achBuf, "%u", i);
  437.     WritePrivateProfileString(szSection, szKey, achBuf, szIniFile);
  438. }
  439.  
  440. void GetIniEntries(void)
  441. {
  442.   //Load Common Strings from stringtable...
  443.   LoadString(hMainInstance, idsIsPassword, szIsPassword, 22);
  444.   LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);
  445.   LoadString(hMainInstance, idsScreenSaver, szScreenSaver, 22);
  446.   LoadString(hMainInstance, idsPassword, szPassword, 16);
  447.   LoadString(hMainInstance, idsDifferentPW, szDifferentPW, BUFFLEN);
  448.   LoadString(hMainInstance, idsChangePW, szChangePW, 30);
  449.   LoadString(hMainInstance, idsBadOldPW, szBadOldPW, 255);
  450.   LoadString(hMainInstance, idsHelpFile, szHelpFile, MAXFILELEN);
  451.   LoadString(hMainInstance, idsNoHelpMemory, szNoHelpMemory, BUFFLEN);
  452. }
  453.