home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / open32 / hiworld2 / hiworld.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  25KB  |  548 lines

  1. /*************************************************************************
  2.  *
  3.  * HIWORLD is a simple Win32 application that displays the text
  4.  * "Hello, World" centered in the client area of the main window.
  5.  *
  6.  * The HIWORLD window contains a menu with two selections:
  7.  *
  8.  *      Information: Displays popup allowing user to:
  9.  *                      view time (local and system up time)
  10.  *                      view screen dimensions (mm and pixels)
  11.  *                      manipulate colors (change, view, and restore menu colors)
  12.  *                      exit the application
  13.  *
  14.  *      Beep: Displays a dialog in which the user selects a frequency
  15.  *                      and a duration via sliders.  When the user clicks on the
  16.  *                      BEEP button, the system beeps using the specified duration
  17.  *                      and frequency.  When the user clicks on DONE or double-clicks
  18.  *                      on the title bar icon, the dialog box terminates.
  19.  *
  20.  *************************************************************************/
  21.  
  22.  
  23. /* include files */
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include "hiworld.h"
  27.  
  28. // under OS/2 you must include os2win.h in place of windows.h
  29. #ifdef WIN32
  30. #include <windows.h>
  31. #else
  32. #include <os2win.h>
  33. #endif
  34.  
  35. /* function prototypes */
  36. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  37. BOOL WINAPI BeepDiaProc(HWND, UINT, WPARAM, LPARAM);
  38. void RGB2Text(DWORD , char *);
  39.  
  40.  
  41.  
  42. /* variables needed by all of the routines */
  43. char szClassName[] = "HiClass";       // class name
  44. char szProgName[] = "Hi, World";      // name of this progam
  45. char lpstrHiWorld[] = "Hello, World!";// text to be placed in window
  46. int newX = 100;                       // x coordinate for window
  47. int newY = 100;                       // y coordinate for window
  48.  
  49. //
  50. // accelerator table.  There are 3 accelerators: (chars can be upper or lower)
  51. //      F2 - generates an IDM_UPTIME message to display the uptime message box
  52. //      ALT+L - generates an IDM_LOCALTIME message to display the local time
  53. //      ALT+X - exits the program
  54. //
  55. #define NUMBER_OF_ACCELTABLE_ENTRIES 5
  56. ACCEL accelTable[NUMBER_OF_ACCELTABLE_ENTRIES] = {
  57.       {FVIRTKEY,VK_F2,IDM_UPTIME}, // F2 = up time display
  58.       {FALT,'L',IDM_LOCALTIME},    // alt+L = local time
  59.       {FALT,'l',IDM_LOCALTIME},    // alt+l = local time
  60.       {FALT,'X',IDM_EXIT},         // alt+X = exit
  61.       {FALT,'x',IDM_EXIT}};        // alt+x = exit
  62. HACCEL hMyAccelTable;              // pointer to accelerator table
  63.  
  64.  
  65.  
  66.  
  67. /*
  68.  * WinMain - main program
  69.  */
  70.  
  71. int WINAPI WinMain (HINSTANCE hInst,
  72.                     HINSTANCE hPreInst,
  73.                     LPSTR lpszCmdLine,
  74.                     int nCmdShow)
  75. {
  76.         MSG lpMsg;
  77.         WNDCLASS wcApp;
  78.         ATOM classAtom;
  79.                 HWND hMainWindow;
  80.  
  81.  
  82.         if (!hPreInst) {
  83.            wcApp.lpszClassName = szClassName;   // name of this class
  84.            wcApp.hInstance = hInst;             // instance handle
  85.            wcApp.lpfnWndProc = WndProc;         // window procedure
  86.            wcApp.hCursor =                      // load custom cursor
  87.                   LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR1));
  88.            wcApp.hIcon =                        // load custom icon
  89.               LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON2));
  90.            wcApp.lpszMenuName =
  91.               MAKEINTRESOURCE(HIWORLDMENU);     // menu identifier
  92.            wcApp.hbrBackground =                // background is white
  93.               GetStockObject(WHITE_BRUSH);
  94.            wcApp.cbClsExtra = 0;                // no class words
  95.            wcApp.cbWndExtra = 0;                // no window words
  96.            wcApp.style = CS_HREDRAW|CS_VREDRAW; // redraw on horizontal and vertical changes
  97.  
  98.            classAtom = RegisterClass(&wcApp);   // register the window class
  99.            if (classAtom==0) {                  // was the register successful?
  100.               return FALSE;                     // return to caller
  101.                   }
  102.         }
  103.  
  104.         hMainWindow = CreateWindow(szClassName, // class name
  105.                             szProgName,         // window name
  106.                             WS_OVERLAPPEDWINDOW,// window style
  107.                             newX,               // x position
  108.                             newY,               // y position
  109.                             3*newX,             // width
  110.                             3*newY,             // height
  111.                             (HWND) NULL,        // parent handle - not used
  112.                             (HMENU) NULL,       // menu handle - use class menu
  113.                             (HANDLE) hInst,     // instance handle
  114.                             (LPVOID) NULL);     // window creation data - not used
  115.  
  116.         ShowWindow(hMainWindow,nCmdShow);       // set show state
  117.         UpdateWindow(hMainWindow);              // update client area of the window
  118.  
  119.         hMyAccelTable =                         // create accel table
  120.            CreateAcceleratorTable(accelTable,NUMBER_OF_ACCELTABLE_ENTRIES);
  121.  
  122.         // standard message loop with accelerator handling
  123.         while (GetMessage(&lpMsg,NULL,0,0)) {
  124.                 if (!TranslateAccelerator(hMainWindow,hMyAccelTable,&lpMsg)) {
  125.                         TranslateMessage(&lpMsg);
  126.                         DispatchMessage(&lpMsg);
  127.                 }
  128.         }
  129.  
  130.         DestroyAcceleratorTable(hMyAccelTable); // cleanup accel table
  131.  
  132.         return (lpMsg.wParam);                  // return to caller
  133. }
  134.  
  135.  
  136.  
  137. /*********************************************************************************************
  138.  *
  139.  * This is the window procedure for the main window.
  140.  *
  141.  *      Message:                Action:
  142.  *      ========                =======
  143.  *      WM_CREATE               save hInst for dialog box calls, and save menu and window colors
  144.  *      WM_DESTROY              indicate that the window proc is complete
  145.  *      WM_PAINT                print output message centered in client area
  146.  *      WM_SIZE                 save new client dimensions
  147.  *      WM_COMMAND              IDM_LOCALTIME: display message box with local time
  148.  *                              IDM_UPTIME: display message box with time system has been up
  149.  *                              IDM_SHOWCOLORS: display message box with text representation of
  150.  *                                         menu text and background colors
  151.  *                              IDM_CHANGECOLORS: change menu text and background colors
  152.  *                              IDM_RESTORECOLORS: restore menu text and background colors to their
  153.  *                                         original values
  154.  *                              IDM_SCRDIM: display message box with screen dimensions
  155.  *                              IDM_BEEP: display beep dialog
  156.  *                              IDM_EXIT: leave the program
  157.  *
  158.  *********************************************************************************************/
  159. LRESULT CALLBACK WndProc(HWND hWnd,
  160.                  UINT messg,
  161.                  WPARAM wParam,
  162.                  LPARAM lParam)
  163. {
  164.     static HINSTANCE hInst;           // used for dialog box
  165.     static BOOL bNeedToRestoreColors; // flag to do cleanup
  166.     HDC hdc;                          // device context for painting
  167.     PAINTSTRUCT ps;                   // paint structure for painting
  168.     DWORD dElapsedTimeSysHasBeenUp;   // time (ms) since system was booted
  169.     DWORD dOtherTime;                 // another variable to hold time
  170.     char lpstrOutString[256];         // string for message boxes
  171.     SIZE mySize, *lpSize=&mySize;     // used to calculate coordinates to center text
  172.     SYSTEMTIME SysTime;               // system time
  173.     SYSTEMTIME *lpSysTime = &SysTime; // pointer to previous
  174.     DWORD dwCheckColorInfo[2];        // holds color information
  175.     DWORD dwNewColorInfo[2] =         // colors to change (red windows, green menus)
  176.         {RGB(255,0,0),RGB(0,255,0)};
  177.     static DWORD dwSavedColorInfo[2]= // saved colors
  178.         {0,0};
  179.     static int iDisplayElements[2] =  // elements to change
  180.         {COLOR_MENUTEXT, COLOR_MENU};
  181.     int i;                            // temp
  182.     int hsize,vsize,hres,vres;        // screen dimensions
  183.  
  184.     switch (messg) {
  185.         /*
  186.          * WM_CREATE: get instance handle for later use putting up
  187.          *            dialog box.  Get initial colors for windows and menus
  188.          *            so they can be restored upon exit (unless the user
  189.          *            remembers to do it).
  190.          */
  191.         case WM_CREATE:
  192.             hInst = ((LPCREATESTRUCT) lParam) -> hInstance;
  193.             dwSavedColorInfo[0] = GetSysColor(COLOR_MENUTEXT);
  194.             dwSavedColorInfo[1] = GetSysColor(COLOR_MENU);
  195.             bNeedToRestoreColors = FALSE;
  196.             break;
  197.         /*
  198.          * WM_DESTROY: If user forgot to restore colors, do it.  Then
  199.          *                         terminate this window.
  200.          */
  201.         case WM_DESTROY:
  202.             if (bNeedToRestoreColors) {
  203.                 SetSysColors(2,iDisplayElements,dwSavedColorInfo);
  204.                 bNeedToRestoreColors = FALSE;
  205.             }
  206.             PostQuitMessage(0);
  207.             break;
  208.         /*
  209.          * WM_PAINT: Put the text string into the window, at the center
  210.          *           of the client area.
  211.          */
  212.         case WM_PAINT:
  213.             hdc = BeginPaint(hWnd,&ps);
  214.             GetTextExtentPoint(hdc,lpstrHiWorld,strlen(lpstrHiWorld),lpSize);
  215.             TextOut(hdc,(newX-(lpSize->cx))/2, (newY-(lpSize->cy))/2, lpstrHiWorld,strlen(lpstrHiWorld));
  216.             EndPaint(hWnd,&ps);
  217.             break;
  218.         /*
  219.          * WM_SIZE: save new x and y coordinates to use later in
  220.          *          centering
  221.          */
  222.         case WM_SIZE:
  223.             newX = LOWORD(lParam);
  224.             newY = HIWORD(lParam);
  225.             break;
  226.         /*
  227.          * WM_COMMAND: see individual items
  228.          */
  229.         case WM_COMMAND:
  230.             switch (LOWORD(wParam)) {
  231.                 /*
  232.                  * IDM_LOCALTIME: Get the local time, put it into a string,
  233.                  *                then output it via a message box
  234.                  */
  235.                 case IDM_LOCALTIME:
  236.                     GetLocalTime(lpSysTime);
  237.                     sprintf(lpstrOutString,"Today is \n\t%02d/%02d/%02d\n and the time is \n\t%02d:%02d:%02d",
  238.                             lpSysTime->wMonth,
  239.                             lpSysTime->wDay,
  240.                             lpSysTime->wYear-1900,
  241.                             lpSysTime->wHour,
  242.                             lpSysTime->wMinute,
  243.                             lpSysTime->wSecond);
  244.                     MessageBox(hWnd,lpstrOutString,"Local time",MB_OK);
  245.                     break;
  246.                 /*
  247.                  * IDM_UPTIME: Get the current time, put it into a string,
  248.                  *             then output it via a message box
  249.                  */
  250.                 case IDM_UPTIME:
  251.                     dElapsedTimeSysHasBeenUp = GetCurrentTime();
  252.                     dOtherTime = timeGetTime();
  253.                     sprintf(lpstrOutString,"System has been up for:\n\t%d milliseconds (GetCurrentTime)\n\t%d milliseconds (timeGetTime)",
  254.                             dElapsedTimeSysHasBeenUp,dOtherTime);
  255.                     MessageBox(hWnd,lpstrOutString,"Time since system was booted",MB_OK);
  256.                     break;
  257.                 /*
  258.                  * IDM_SHOWCOLORS: Get the current menu text and menu background
  259.                  *                 colors.  Put them into a text string then
  260.                  *                 output them via a message box.
  261.                  */
  262.                 case IDM_SHOWCOLORS:
  263.                     i = 0;
  264.                     dwCheckColorInfo[0] = GetSysColor(COLOR_MENUTEXT);
  265.                     strcpy(lpstrOutString,"Menu text is ");
  266.                     i += strlen(lpstrOutString);
  267.                     RGB2Text(dwCheckColorInfo[0],&lpstrOutString[i]);
  268.                     dwCheckColorInfo[1] = GetSysColor(COLOR_MENU);
  269.                     strcat(lpstrOutString,"Menu background is ");
  270.                     i = strlen(lpstrOutString);
  271.                     RGB2Text(dwCheckColorInfo[1],&lpstrOutString[i]);
  272.                     MessageBox(hWnd,lpstrOutString,"Color Information",MB_OK);
  273.                     break;
  274.                 /*
  275.                  * IDM_CHANGECOLORS: Enable the "restore" menu item.  Set flag to
  276.                  *                   ensure that we clean up, then change the
  277.                  *                   menu text and menu background colors.
  278.                  */
  279.                 case IDM_CHANGECOLORS:
  280.                     EnableMenuItem(GetMenu(hWnd),IDM_RESTORECOLORS,MF_ENABLED|MF_BYCOMMAND);
  281.                     bNeedToRestoreColors = TRUE;
  282.                     SetSysColors(2,iDisplayElements,dwNewColorInfo);
  283.                     break;
  284.                 /*
  285.                  * IDM_RESTORECOLORS: Disable the "restore" menu item.  Clear the
  286.                  *                    cleanup flag, then change the
  287.                  *                    menu text and menu background colors
  288.                  *                    back to their original values.
  289.                  */
  290.                 case IDM_RESTORECOLORS:
  291.                     EnableMenuItem(GetMenu(hWnd),IDM_RESTORECOLORS,MF_GRAYED|MF_BYCOMMAND);
  292.                     bNeedToRestoreColors = FALSE;
  293.                     SetSysColors(2,iDisplayElements,dwSavedColorInfo);
  294.                     break;
  295.                 /*
  296.                  * IDM_SCRDIM: Get the screen dimensions, put them into a string,
  297.                  *             then output it via a message box
  298.                  */
  299.                 case IDM_SCRDIM:
  300.                     hdc = GetDC(hWnd);
  301.                     hsize = GetDeviceCaps(hdc,HORZSIZE);
  302.                     vsize = GetDeviceCaps(hdc,VERTSIZE);
  303.                     hres = GetDeviceCaps(hdc,HORZRES);
  304.                     vres = GetDeviceCaps(hdc,VERTRES);
  305.                     sprintf(lpstrOutString,
  306.                             "Horizontal size:\t\t%d mm\nVertical Size:\t\t%d mm\nHorizontal resolution:\t%d pixels\nVertical Resolution:\t%d pixels",
  307.                             hsize,vsize,hres,vres);
  308.                     ReleaseDC(hWnd,hdc);
  309.                     MessageBox(hWnd,lpstrOutString,"Screen Dimensions",MB_OK);
  310.                     break;
  311.                 /*
  312.                  * IDM_BEEP: Display beep dialog box.
  313.                  */
  314.                 case IDM_BEEP:
  315.                     DialogBox(hInst,MAKEINTRESOURCE(BEEPDIALOG),hWnd,BeepDiaProc);
  316.                     break;
  317.                 /*
  318.                  * WM_DESTROY: If user forgot to restore colors, do it.  Then
  319.                  *                 terminate this window.
  320.                  */
  321.                 case IDM_EXIT:
  322.                     if (bNeedToRestoreColors) {
  323.                         SetSysColors(2,iDisplayElements,dwSavedColorInfo);
  324.                         bNeedToRestoreColors = FALSE;
  325.                     }
  326.                     PostQuitMessage(0);
  327.                     break;
  328.                 default:
  329.                     return(DefWindowProc(hWnd,messg,wParam,lParam));
  330.                 }
  331.                 break;
  332.         default:
  333.             return(DefWindowProc(hWnd,messg,wParam,lParam));
  334.         }
  335.         return(0L);
  336. }
  337.  
  338. /*********************************************************************************************
  339.  *
  340.  * This utility routine changes an RGB value into a character string.
  341.  *
  342.  *********************************************************************************************/
  343.  
  344. void RGB2Text(DWORD dwRGB, char *str)
  345. {
  346.  
  347.         DWORD Red, Green, Blue;
  348.  
  349.     Red =   GetRValue(dwRGB);
  350.     Green = GetGValue(dwRGB);
  351.     Blue =  GetBValue(dwRGB);
  352.     if ((Red!=0) && (Blue==0) && (Green==0)) {
  353.         strcpy(str,"Red\n");
  354.     } else if ((Red==0) && (Blue!=0) && (Green==0)) {
  355.         strcpy(str,"Blue\n");
  356.     } else if ((Red==0) && (Blue==0) && (Green!=0)) {
  357.         strcpy(str,"Green\n");
  358.     } else if ((Red!=0) && (Blue!=0) && (Green==0)) {
  359.         strcpy(str,"Purpleish\n");
  360.     } else if ((Red!=0) && (Blue==0) && (Green!=0)) {
  361.         strcpy(str,"Yellowish\n");
  362.     } else if ((Red==0) && (Blue!=0) && (Green!=0)) {
  363.         strcpy(str,"Aquaish\n");
  364.     } else if ((Red!=0) && (Red==Blue) && (Blue==Green)) {
  365.         strcpy(str,"White\n");
  366.     } else if (Red+Blue+Green==0) {
  367.         strcpy(str,"Black\n");
  368.     } else {
  369.         strcpy(str,"Mixed\n");
  370.     }
  371. }
  372.  
  373. /*********************************************************************************************
  374.  *
  375.  * This is the dialog procedure for the beep dialog.
  376.  *
  377.  *      Message:                Action:
  378.  *      ========                =======
  379.  *      WM_INITDIALOG           initialize beep duration and frequency
  380.  *      WM_CLOSE                end this dialog
  381.  *      WM_PAINT                display text strings under each scroll bar to represent
  382.  *                              the value of the slider
  383.  *      WM_HSCROLL              adjust scroll bars and duration/frequency values
  384.  *      WM_COMMAND              ID_BEEPNOW:  beep with the specified frequency/duration
  385.  *                              ID_DONE: dismiss dialog box
  386.  *
  387.  *********************************************************************************************/
  388. BOOL WINAPI BeepDiaProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
  389. {
  390.  
  391.         char lpstrOutString[256];        // string used to display text in dialog box
  392.     RECT rect;
  393.     HDC hdc;                                         // device context for painting
  394.     PAINTSTRUCT ps;                          // paint structure for painting
  395.     SIZE mySize;                 // used to place text in dialog box
  396.     ULONG ulDlgUnitsToPixels;        // used to place text in dialog box
  397.     static LONG ulBeepDuration; // beep duration - selected by slider
  398.     static LONG ulBeepFreq;     // beep frequency - selected by slider
  399.     LONG *pscrollpos;           // current slider value
  400.     int id;                      // determines which slider
  401.     char *templateStringMS = "Selected Value: %5d ms   ";
  402.     char *templateStringHZ = "Selected Value: %5d hz   ";
  403.  
  404.     switch (messg) {
  405.         /*
  406.          * WM_INITDIALOG: initialize duration and frequency variables
  407.          */
  408.         case WM_INITDIALOG:
  409.             ulBeepDuration = MINDURATION;
  410.             ulBeepFreq = MINFREQ;
  411.             break;
  412.         /*
  413.          * WM_CLOSE: Dismiss this dialog
  414.          */
  415.         case WM_CLOSE:
  416.             EndDialog(hDlg,FALSE);
  417.             break;
  418.         /*
  419.          * WM_PAINT: Determine position in dialog box for text output and
  420.                  *           put the text strings there
  421.          */
  422.         case WM_PAINT:
  423.             hdc = BeginPaint(hDlg,&ps);
  424.             ulDlgUnitsToPixels = GetDialogBaseUnits();
  425.             sprintf(lpstrOutString,templateStringHZ,ulBeepFreq*FREQSTEP);
  426.             TextOut(hdc,(40*LOWORD(ulDlgUnitsToPixels))/4,(40*HIWORD(ulDlgUnitsToPixels))/8,lpstrOutString,strlen(lpstrOutString));
  427.             sprintf(lpstrOutString,templateStringMS,ulBeepDuration*DURATIONSTEP);
  428.             TextOut(hdc,(40*LOWORD(ulDlgUnitsToPixels))/4,(100*HIWORD(ulDlgUnitsToPixels))/8,lpstrOutString,strlen(lpstrOutString));
  429.             EndPaint(hDlg,&ps);
  430.             break;
  431.         /*
  432.          * WM_HSCROLL: handle horizontal scrolling.  For all scroll
  433.          *             messages, determine which scroll bar this is (via GetDlgCtrlId)
  434.          *             and set a pointer to the scroll value (pscrollpos).
  435.          */
  436.         case WM_HSCROLL:
  437.             ulDlgUnitsToPixels = GetDialogBaseUnits();
  438.             id = GetDlgCtrlID((HWND)lParam);
  439.             hdc = GetDC(hDlg);
  440.             GetTextExtentPoint(hdc,templateStringHZ,strlen(templateStringHZ),&mySize);
  441.             DeleteDC(hdc);
  442.             if (id==ID_FREQBAR) {
  443.                 SetScrollRange((HWND)lParam,SB_CTL,MINFREQ,MAXFREQ,TRUE);
  444.                 pscrollpos = &ulBeepFreq;
  445.                 rect.top = (40*HIWORD(ulDlgUnitsToPixels))/8;
  446.                 rect.bottom = rect.top + mySize.cy;
  447.                 rect.left = (40*LOWORD(ulDlgUnitsToPixels))/4;
  448.                 rect.right = rect.left + mySize.cx;
  449.             } else {
  450.                 SetScrollRange((HWND)lParam,SB_CTL,MINDURATION,MAXDURATION,TRUE);
  451.                 pscrollpos = &ulBeepDuration;
  452.                 rect.top = (100*HIWORD(ulDlgUnitsToPixels))/8;
  453.                 rect.bottom = rect.top + mySize.cy;
  454.                 rect.left = (40*LOWORD(ulDlgUnitsToPixels))/4;
  455.                 rect.right = rect.left + mySize.cx;
  456.             }
  457.             switch(LOWORD(wParam)) {
  458.                 /*
  459.                  * SB_LINERIGHT: user incremented by 1.  Update scroll
  460.                  *               position and redraw.
  461.                  */
  462.                 case SB_LINERIGHT:
  463.                     (*pscrollpos)++;
  464.                     if ((id==ID_FREQBAR) && (*pscrollpos > MAXFREQ)) {
  465.                        *pscrollpos = MAXFREQ;
  466.                     } else if ((id==ID_DURBAR) && (*pscrollpos > MAXDURATION)){
  467.                        *pscrollpos = MAXDURATION;
  468.                     }
  469.                     SetScrollPos((HWND)lParam,SB_CTL,*pscrollpos,TRUE);
  470.                     break;
  471.                 /*
  472.                  * SB_LINELEFT: user decremented by 1.  Update scroll
  473.                  *              position and redraw.
  474.                  */
  475.                 case SB_LINELEFT:
  476.                     (*pscrollpos)--;
  477.                     if ((id==ID_FREQBAR) && (*pscrollpos < MINFREQ)) {
  478.                        *pscrollpos = MINFREQ;
  479.                     } else if ((id=ID_DURBAR) && (*pscrollpos < MINDURATION)) {
  480.                        *pscrollpos = MINDURATION;
  481.                     }
  482.                     SetScrollPos((HWND)lParam,SB_CTL,*pscrollpos,TRUE);
  483.                     break;
  484.                 /*
  485.                  * SB_LINELEFT: user decremented by 1 "page".  Update scroll
  486.                  *              position and redraw.
  487.                  */
  488.                 case SB_PAGELEFT:
  489.                     *pscrollpos -= BEEPSCROLLWIDTH;
  490.                     if ((id==ID_FREQBAR) && (*pscrollpos < MINFREQ)) {
  491.                        *pscrollpos = MINFREQ;
  492.                     } else if ((id=ID_DURBAR) && (*pscrollpos < MINDURATION)) {
  493.                        *pscrollpos = MINDURATION;
  494.                     }
  495.                     SetScrollPos((HWND)lParam,SB_CTL,*pscrollpos,TRUE);
  496.                     break;
  497.                 /*
  498.                  * SB_LINERIGHT: user incremented by 1 "page".  Update scroll
  499.                  *               position and redraw.
  500.                  */
  501.                 case SB_PAGERIGHT:
  502.                     *pscrollpos += BEEPSCROLLWIDTH;
  503.                     if ((id==ID_FREQBAR) && (*pscrollpos > MAXFREQ)) {
  504.                        *pscrollpos = MAXFREQ;
  505.                     } else if ((id==ID_DURBAR) && (*pscrollpos > MAXDURATION)){
  506.                        *pscrollpos = MAXDURATION;
  507.                     }
  508.                     SetScrollPos((HWND)lParam,SB_CTL,*pscrollpos,TRUE);
  509.                     break;
  510.                 /*
  511.                  * SB_THUMBPOSITION: user moved to a specified position.  Update scroll
  512.                  *                   position and redraw.
  513.                  * SB_THUMBTRACK: same as SB_THUMBPOSITION
  514.                  */
  515.                 case SB_THUMBPOSITION:
  516.                 case SB_THUMBTRACK:
  517.                     *pscrollpos = HIWORD(wParam);
  518.                     SetScrollPos((HWND)lParam,SB_CTL,*pscrollpos,TRUE);
  519.                     break;
  520.             }
  521.             InvalidateRect(hDlg,&rect,FALSE);
  522.             break;
  523.         /*
  524.          * WM_COMMAND: see individual actions
  525.          */
  526.         case WM_COMMAND:
  527.             switch (LOWORD(wParam)) {
  528.                 /*
  529.                  * ID_BEEPNOW: use Beep API to make the sound!
  530.                  */
  531.                 case ID_BEEPNOW:
  532.                     Beep(ulBeepFreq*FREQSTEP,ulBeepDuration*DURATIONSTEP);
  533.                     break;
  534.                 /*
  535.                  * ID_DONE: dismiss this dialog
  536.                  */
  537.                 case ID_DONE:
  538.                     EndDialog(hDlg,TRUE);
  539.                     break;
  540.                 default:
  541.                     return FALSE;
  542.             }
  543.             default:
  544.                 return FALSE;
  545.         }
  546.         return TRUE;
  547. }
  548.