home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / slider / slider.c next >
C/C++ Source or Header  |  1992-07-28  |  17KB  |  419 lines

  1. // slider.c -- Sample program to demonstrate slider
  2.  
  3. //--------------------------------------------------------------
  4. //  slider.c
  5. //
  6. //      Sample program to demonstrate sliders.  
  7. //
  8. //  By: Guy Scharf                      (415) 948-9186
  9. //      Software Architects, Inc.       FAX: (415) 948-1620
  10. //      2163 Jardin Drive               
  11. //      Mountain View, CA   94040       
  12. //      CompuServe: 76702,557
  13. //      Internet: 76702.557@compuserve.com
  14. //  (c) Copyright 1992 Software Architects, Inc.  
  15. //
  16. //      All Rights Reserved.
  17. //
  18. //  Software Architects, Inc. develops software products for 
  19. //  independent software vendors using OS/2 and Presentation 
  20. //  Manager.
  21. //--------------------------------------------------------------
  22.  
  23. #define INCL_PM                         // Basic OS/2 PM
  24. #define INCL_BASE                       // components
  25. #include <OS2.H>
  26.  
  27. #include <stdlib.h>                     // C runtime library
  28. #include <string.h>
  29.  
  30. #include "slider.h"                     // Slider demo defs
  31.  
  32. //  Prototypes of dialog procedures
  33.  
  34. static MRESULT EXPENTRY GetAmountDlgProc (HWND, MSGID, MPARAM,
  35.                                           MPARAM);
  36. static MRESULT EXPENTRY ProgressDlgProc (HWND, MSGID, MPARAM,
  37.                                          MPARAM);
  38.  
  39. //--------------------------------------------------------------
  40. //                                                                          
  41. //  Main program to drive slider example
  42. //                                                                          
  43. //--------------------------------------------------------------
  44.  
  45. int main (void)
  46. {
  47.     HAB        hab;                        // Handle to anchor block
  48.     HMQ        hmqMsgQueue;                // Handle to msg queue
  49. #ifndef OS220
  50.     HMODULE hmodSlider;                 // Handle to slider mod
  51. #endif
  52.  
  53.     hab = WinInitialize (0);            // Initialize PM
  54.  
  55.     hmqMsgQueue = WinCreateMsgQueue (hab, 0); // Create msg queue
  56.  
  57. #ifndef OS220
  58.     if (DosLoadModule (NULL, 0, CCL_SLIDER_DLL, &hmodSlider))
  59.         return FALSE;
  60. #endif
  61.  
  62.     WinDlgBox (HWND_DESKTOP, HWND_DESKTOP, GetAmountDlgProc, 0,
  63.                IDLG_SETTIME, NULL);
  64.  
  65. #ifndef OS220
  66.     DosFreeModule (hmodSlider);
  67. #endif
  68.  
  69.     WinDestroyMsgQueue (hmqMsgQueue);   // Shutdown
  70.     WinTerminate       (hab);
  71.     return 0;
  72. }
  73.  
  74. //--------------------------------------------------------------
  75. //                                                                          
  76. //  GetAmountDlgProc() -- Determine time delay desired
  77. //                                                                          
  78. //--------------------------------------------------------------
  79.  
  80. static MRESULT EXPENTRY GetAmountDlgProc (
  81. HWND    hwndDlg,
  82. MSGID   msg,
  83. MPARAM  mp1,
  84. MPARAM  mp2)
  85. {
  86.     USHORT  usTime;                     // Time for progress
  87.  
  88.     switch(msg)
  89.     {
  90.         //------------------------------------------------------
  91.         //  Initialize dialog by setting labels, ticks, detents,
  92.         //  etc.  This must all be done programmatically.
  93.         //------------------------------------------------------
  94.         case WM_INITDLG:
  95.  
  96.             //--------------------------------------------------
  97.             //  Set the marks, detents, and labels
  98.             //  Set small tick marks every 1 second
  99.             //  Set large tick marks every 10 seconds
  100.             //  Set detent every 15 seconds
  101.             //--------------------------------------------------
  102.             InitSlider (hwndDlg, IDSL_SETTIME_TIME, 0,
  103.                         1,  4,
  104.                         10, 8,
  105.                         30, 30,
  106.                         "8.Courier");
  107.  
  108.             return 0;
  109.  
  110.         //------------------------------------------------------
  111.         //  Process pushbuttons.  Enter starts a progress bar.
  112.         //  Cancel (ESC) just quits quietly.
  113.         //------------------------------------------------------
  114.         case WM_COMMAND:
  115.             switch (SHORT1FROMMP(mp1))
  116.             {
  117.                                         // Cancel pressed
  118.                                         // Dismiss dialog
  119.                 case DID_CANCEL:
  120.                     WinDismissDlg (hwndDlg, FALSE);
  121.                     return 0;
  122.  
  123.                                         // OK button pressed
  124.                 case DID_OK:            // Read slider position
  125.                                         // from slider
  126.                     usTime = SHORT1FROMMR(WinSendDlgItemMsg(
  127.                                hwndDlg,
  128.                                IDSL_SETTIME_TIME,
  129.                                SLM_QUERYSLIDERINFO,
  130.                                MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  131.                                             SMA_INCREMENTVALUE),
  132.                                0));
  133.                                         // Start progress bar
  134.                                         // dialog
  135.                     if (usTime > 0)
  136.                         WinDlgBox (HWND_DESKTOP, HWND_DESKTOP,
  137.                                    ProgressDlgProc, 0,
  138.                                    IDLG_PROGRESS, &usTime);
  139.                     return 0;
  140.             }
  141.             return 0;
  142.                                
  143.         //------------------------------------------------------
  144.         //  All other messages go to default window procedure
  145.         //------------------------------------------------------
  146.         default:
  147.             return (WinDefDlgProc (hwndDlg, msg, mp1, mp2));
  148.     }
  149.     return FALSE;
  150. }
  151.  
  152.  
  153. //--------------------------------------------------------------
  154. //                                                                          
  155. //  ProgressDlgProc() -- Show progress bar.  This is a minimal
  156. //  function dialog.  It just moves the progress bar along
  157. //  without reflecting any particular activity.
  158. //                                                                          
  159. //--------------------------------------------------------------
  160.  
  161. typedef struct
  162. {
  163.     USHORT  usTotalUnits;               // # units to count
  164.     USHORT  usUnitsSoFar;               // count so far
  165.     USHORT  usPctDone;                  // Last reported % done
  166. } PROG, *PPROG;
  167.  
  168. #define TIMERINTERVAL    4              // Timer checks per sec
  169.  
  170. static MRESULT EXPENTRY ProgressDlgProc (
  171. HWND    hwndDlg,
  172. MSGID   msg,
  173. MPARAM  mp1,
  174. MPARAM  mp2)
  175. {
  176.     PPROG   pprog;                      // Progress data
  177.  
  178.     switch(msg)
  179.     {
  180.         //------------------------------------------------------
  181.         //  Initialize dialog by constructing a work area and
  182.         //  establishing a pointer to it in the dialog window
  183.         //  word.  Set initial values to 0 and compute the
  184.         //  number of ticks desired from the passed value
  185.         //  (which is in seconds)
  186.         //------------------------------------------------------
  187.         case WM_INITDLG:                // Initialize data
  188.             pprog = malloc (sizeof (PROG));
  189.             WinSetWindowPtr (hwndDlg, QWL_USER, pprog);
  190.  
  191.             pprog->usUnitsSoFar = 0;    // Ticks so far
  192.             pprog->usPctDone = 0;       // Start at 0
  193.             pprog->usTotalUnits = (USHORT)(*(PUSHORT)mp2
  194.                                           * TIMERINTERVAL);
  195.  
  196.             //--------------------------------------------------
  197.             //  Set 2x wide slider, 
  198.             //  No small tick
  199.             //  No large ticks
  200.             //  No detents
  201.             //  0, 50, 100% complete
  202.             //--------------------------------------------------
  203.             InitSlider (hwndDlg, IDSL_PROGRESS_BAR, 2,
  204.                         0, 4,
  205.                         0, 8,
  206.                         0, 50,
  207.                         NULL);
  208.  
  209.             //--------------------------------------------------
  210.             //  Start the timer for periodic display
  211.             //--------------------------------------------------
  212.             WinStartTimer (WinQueryAnchorBlock (hwndDlg),
  213.                            hwndDlg, ID_TIMER,
  214.                            1000/TIMERINTERVAL);
  215.  
  216.             return 0;
  217.  
  218.         //------------------------------------------------------
  219.         //  When dialog is destroyed, we release any data
  220.         //  we have allocated.  This prevents memory leakage.
  221.         //------------------------------------------------------
  222.         case WM_DESTROY:                
  223.             pprog = WinQueryWindowPtr (hwndDlg, QWL_USER);
  224.                                         // Stop the timer
  225.             WinStopTimer (WinQueryAnchorBlock (hwndDlg),
  226.                           hwndDlg, ID_TIMER);
  227.             if (pprog != NULL)          // If data exists,
  228.                 free (pprog);           // free it
  229.             WinSetWindowPtr (hwndDlg, QWL_USER, NULL);
  230.  
  231.             return 0;
  232.  
  233.         //------------------------------------------------------
  234.         //  We support only a Cancel pushbutton
  235.         //------------------------------------------------------
  236.         case WM_COMMAND:
  237.             switch (SHORT1FROMMP(mp1))
  238.             {                           // Cancel key pressed
  239.                 case DID_CANCEL:        // Just quit quietly
  240.                     WinDismissDlg (hwndDlg, FALSE);
  241.                     return 0;
  242.             }
  243.             return 0;
  244.                      
  245.           
  246.         //------------------------------------------------------
  247.         //  On every timer tick, we computer the percent
  248.         //  complete.  If different than on the last timer
  249.         //  click, we update the progress bar.
  250.         //------------------------------------------------------
  251.         case WM_TIMER:
  252.         {
  253.             USHORT  usNewPctDone = 0;   // Percent complete
  254.  
  255.                                         // Get ptr to dialog data
  256.             pprog = WinQueryWindowPtr (hwndDlg, QWL_USER);
  257.  
  258.                                         // Compute % complete
  259.                                         // and update the slider
  260.             pprog->usUnitsSoFar++;
  261.                                         // Don't allow over 100
  262.             usNewPctDone = (USHORT)min((100*pprog->usUnitsSoFar)
  263.                                 / pprog->usTotalUnits, 100);
  264.  
  265.                                         // If % done is changed,
  266.                                         // update slider
  267.             if (usNewPctDone != pprog->usPctDone)
  268.             {
  269.                 pprog->usPctDone = usNewPctDone;
  270.                 
  271.                 WinSendDlgItemMsg (hwndDlg, IDSL_PROGRESS_BAR,
  272.                             SLM_SETSLIDERINFO,
  273.                             MPFROM2SHORT (SMA_SLIDERARMPOSITION,
  274.                                             SMA_INCREMENTVALUE),
  275.                             MPFROMSHORT (usNewPctDone));
  276.             }
  277.  
  278.                                         // If all done, quit
  279.             if (pprog->usUnitsSoFar > pprog->usTotalUnits)
  280.                 WinSendMsg (hwndDlg, WM_CLOSE, 0, 0);
  281.  
  282.             return 0;
  283.         }
  284.  
  285.         //------------------------------------------------------
  286.         //  All other messages go to default window procedure
  287.         //------------------------------------------------------
  288.         default:
  289.             return (WinDefDlgProc (hwndDlg, msg, mp1, mp2));
  290.     }
  291.  
  292.     return FALSE;
  293. }
  294.  
  295. //--------------------------------------------------------------
  296. // Function: InitSlider                                         
  297. // Outputs:  none                                               
  298. //                                                              
  299. // This function receives all parameters for configuring a
  300. // slider.  It sets tick marks, tick text, and detents 
  301. // according to the input parameters.  The scale text font is 
  302. // changed if requested.  This function works only on scale 1.
  303. //--------------------------------------------------------------
  304.  
  305. VOID InitSlider (                       // Initialize slider
  306. HWND    hwndDlg,                        // Handle of dialog
  307. ULONG   idSlider,                       // ID of slider control
  308. USHORT  usSizeMultiplier,               // Size multiplier
  309. USHORT  usMinorTickSpacing,             // Minor tick spacing
  310. USHORT  usMinorTickSize,                // Size of minor ticks
  311. USHORT  usMajorTickSpacing,             // Major tick spacing
  312. USHORT  usMajorTickSize,                // Size of major ticks
  313. USHORT  usDetentSpacing,                // Detent spacing
  314. USHORT  usTextSpacing,                  // Text label spacing
  315. PSZ     pszFont)                        // Font for text or NULL
  316. {
  317.     USHORT  i;                          // Loop index
  318.     CHAR    buffer[20];                 // String buffer
  319.     USHORT  usIncrements = 0;           // Number of increments
  320.     USHORT  usSpacing = 0;              // Spacing
  321.  
  322.     WNDPARAMS   wprm;                   // Window parameters ct;
  323.     SLDCDATA    sldcd;                  // Slider control data
  324.  
  325.     HWND    hwndSlider = WinWindowFromID (hwndDlg, idSlider);
  326.  
  327.     //----------------------------------------------------------
  328.     // Get original slider dimensions in increments for future
  329.     // calls.  (My thanks to Wayne Kovsky for this sample code.)
  330.     //----------------------------------------------------------
  331.     wprm.fsStatus   = WPM_CTLDATA;      // Request control data
  332.     wprm.cbCtlData  = sizeof (SLDCDATA);
  333.     wprm.pCtlData   = &sldcd;
  334.  
  335.     if (WinSendMsg (hwndSlider, WM_QUERYWINDOWPARAMS,
  336.                      MPFROMP(&wprm), 0))
  337.     {                                   // Copy fields we need
  338.         usIncrements = sldcd.usScale1Increments;
  339.         usSpacing    = sldcd.usScale1Spacing;
  340.     }
  341.     
  342.     //----------------------------------------------------------
  343.     //  If requested, change dimensions of the slider
  344.     //----------------------------------------------------------
  345.     if (usSizeMultiplier > 1)
  346.     {
  347.         MRESULT mr;
  348.         mr = WinSendMsg (hwndSlider,
  349.                          SLM_QUERYSLIDERINFO,
  350.                          MPFROMSHORT(SMA_SHAFTDIMENSIONS), 0);
  351.  
  352.         WinSendMsg (hwndSlider,
  353.                     SLM_SETSLIDERINFO,
  354.                     MPFROMSHORT(SMA_SHAFTDIMENSIONS),
  355.                     MPFROMSHORT (SHORT2FROMMR(mr) *
  356.                                              usSizeMultiplier));
  357.  
  358.     }
  359.  
  360.     //----------------------------------------------------------
  361.     //  If requested, set minor ticks along axis
  362.     //----------------------------------------------------------
  363.     if (usMinorTickSpacing != 0)
  364.         for (i = 0; i <= usIncrements; i += usMinorTickSpacing)
  365.         {
  366.             WinSendMsg (hwndSlider,     // Set minor tick
  367.                         SLM_SETTICKSIZE,
  368.                         MPFROM2SHORT(i, usMinorTickSize),
  369.                         NULL);
  370.         }
  371.  
  372.     //----------------------------------------------------------
  373.     //  If requested, set major ticks along axis
  374.     //----------------------------------------------------------
  375.     if (usMajorTickSpacing != 0)
  376.         for (i = 0; i <= usIncrements; i += usMajorTickSpacing)
  377.         {
  378.             WinSendMsg (hwndSlider,     // Set major tick
  379.                         SLM_SETTICKSIZE,
  380.                         MPFROM2SHORT(i, usMajorTickSize),
  381.                         NULL);
  382.         }
  383.  
  384.     //----------------------------------------------------------
  385.     //  If requested, set detents
  386.     //----------------------------------------------------------
  387.     if (usDetentSpacing != 0)
  388.         for (i = 0; i <= usIncrements; i += usDetentSpacing)
  389.         {
  390.             WinSendMsg (hwndSlider,     // Set the detent
  391.                    SLM_ADDDETENT,
  392.                    MPFROM2SHORT((i*usSpacing), usDetentSpacing),
  393.                    NULL);
  394.         }
  395.  
  396.     //----------------------------------------------------------
  397.     //  If requested, set text labels.  Also change font if
  398.     //  requested
  399.     //----------------------------------------------------------
  400.     if (usTextSpacing != 0)
  401.     {
  402.         if (pszFont != NULL)
  403.             WinSetPresParam (hwndSlider,
  404.                              PP_FONTNAMESIZE,
  405.                              (strlen(pszFont)+1),
  406.                              pszFont);
  407.         for (i = 0; i <= usIncrements; i += usTextSpacing)
  408.         {
  409.             itoa (i, buffer, 10);       // Convert to string
  410.             WinSendMsg (hwndSlider,     // Place in slider scale
  411.                         SLM_SETSCALETEXT,
  412.                         MPFROMSHORT(i),
  413.                         MPFROMP(buffer));
  414.         }
  415.     }
  416.  
  417.     return;
  418. }
  419.