home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / wps / carpp / carpp.cpp < prev    next >
C/C++ Source or Header  |  1999-05-11  |  67KB  |  2,044 lines

  1. /******************************************************************************
  2. *
  3. *  Module Name: CARPP.CPP
  4. *
  5. *  OS/2 WorkPlace Shell Sample Program - SOM 2.0 / IDL Version
  6. *
  7. *  Copyright (C) 1992-1995 IBM Corporation
  8. *
  9. *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  10. *      sample code created by IBM Corporation. This sample code is not
  11. *      part of any standard or IBM product and is provided to you solely
  12. *      for  the purpose of assisting you in the development of your
  13. *      applications.  The code is provided "AS IS", without
  14. *      warranty of any kind.  IBM shall not be liable for any damages
  15. *      arising out of your use of the sample code, even if they have been
  16. *      advised of the possibility of such damages.                                                    *
  17. *
  18. *  Entry Points:
  19. *
  20. *     Class Methods:
  21. *
  22. *        carppM_QueryModuleHandle
  23. *
  24. *     Overridden Class Methods:
  25. *
  26. *        carppM_wpclsInitData
  27. *        carppM_wpclsQueryDefaultHelp
  28. *        carppM_wpclsQueryDefaultView
  29. *        carppM_wpclsQueryDetailsInfo
  30. *        carppM_wpclsQueryIconData
  31. *        carppM_wpclsQueryStyle
  32. *        carppM_wpclsQueryTitle
  33. *        carppM_wpclsUnInitData
  34. *
  35. *     Instance Methods:
  36. *
  37. *        carpp_AddDashboardPage
  38. *        carpp_AddHornBeepPage
  39. *
  40. *     Overridden Instance Methods:
  41. *
  42. *        carpp_wpAddSettingsPages
  43. *        carpp_wpFilterPopupMenu
  44. *        carpp_wpInitData
  45. *        carpp_wpMenuItemHelpSelected
  46. *        carpp_wpMenuItemSelected
  47. *        carpp_wpModifyPopupMenu
  48. *        carpp_wpViewObject
  49. *        carpp_wpQueryDetailsData
  50. *        carpp_wpRestoreState
  51. *        carpp_wpSaveState
  52. *        carpp_wpUnInitData
  53. *
  54. *     Non-Method Functions:
  55. *
  56. *        CarInit
  57. *        CarWndProc
  58. *        DashBoardDlgProc
  59. *        HornBeepDlgProc
  60. *
  61. ******************************************************************************/
  62.  
  63. #define Carpp_Class_Source
  64. #define M_Carpp_Class_Source
  65.  
  66. #include "carpp.xih"          /* implementation header emitted from carpp.idl */
  67.  
  68. #include <string.h>
  69. #include <stdio.h>
  70. #include <memory.h>
  71. #include <stdlib.h>
  72. #include <setjmp.h>
  73.  
  74. /*
  75.  *   Non-Method function prototypes
  76.  */
  77.  
  78. HWND             CarInit (Carpp*);
  79. MRESULT EXPENTRY DashBoardDlgProc( HWND hwnd, ULONG msg,
  80.                                    MPARAM mp1, MPARAM mp2 );
  81. MRESULT EXPENTRY HornBeepDlgProc( HWND hwnd, ULONG msg,
  82.                                    MPARAM mp1, MPARAM mp2 );
  83. MRESULT EXPENTRY CarWndProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  84.  
  85. ULONG _System _Exception(EXCEPTIONREPORTRECORD       *parg,
  86.                  EXCEPTIONREGISTRATIONRECORD *pRegisRecord,
  87.                  PCONTEXTRECORD               pContextRecord,
  88.                  PVOID                        pvSpare);
  89.  
  90.  
  91.  
  92. /***************** GLOBAL/STATIC (NON-INSTANCE) DATA SECTION ******************
  93. *****                                                                     *****
  94. *****    This data shouldn't be changed by instance methods or it will    *****
  95. *****    affect all instances!  Any variables that are specific (unique   *****
  96. *****    values) for each instance of this object should be declared as   *****
  97. *****  instance data or dynamically allocated and stored as window data.  *****
  98. *****                                                                     *****
  99. *****      This global data should be declared as class instance data     *****
  100. *****    if it will change after initialization.  In this case, it will   *****
  101. *****                  be accessed through class methods.                 *****
  102. *****                                                                     *****
  103. ******************************************************************************/
  104.  
  105.    CHAR       szCarWindowClass[] =    "CARSAMPPP";
  106.    CHAR       szCarInstanceFilter[] = "*.CAR";
  107.    CHAR       szHelpLibrary[] =       "carpp.hlp";
  108.    CHAR       szCarClassTitle[CCHMAXPATH] = "";
  109.    HMODULE    hmod = NULLHANDLE;
  110.  
  111.    PCSZ       pcszDefaultText ="\
  112.                                \n\
  113.      Bill of Sale              \n\
  114.    =========================   \n\
  115.                                \n\
  116.    Make........ Toyota         \n\
  117.                                \n\
  118.    Model....... Camry          \n\
  119.                                \n\
  120.    Color....... Blue           \n\
  121.                                \n\
  122.    Sale Date... 3/31/92        \n\
  123.                                \n\
  124.    Price....... 14,995         \n";
  125.  
  126.    /*
  127.     *   Globals required for Exception handling
  128.     */
  129.  
  130.    jmp_buf jmpState;
  131.  
  132.    PCSZ pcszTrapMessage =                        "\
  133. \
  134. A Memory Access Violation occurred.  The Car \
  135. sample's exception handler has transferred \
  136. control back to the cleanup code in the method \
  137. where the exception occurred.\n";
  138.  
  139.    /*
  140.     *   Statics required for FIELDINFO structures needed for DETAILS view are
  141.     *   handled in the three functions:
  142.     *
  143.     *   carpp_wpclsInitData, carpp_wpQueryDetailsData, carpp_wpQueryClassDetailsInfo
  144.     */
  145.  
  146.    #define NUM_CAR_FIELDS    5
  147.  
  148.    CLASSFIELDINFO fieldinfo[NUM_CAR_FIELDS];      /* structure in wpobject.h */
  149.  
  150.    PCSZ apszCarColTitles[] =
  151.    {
  152.       "Make",           /* details column 1 */
  153.       "Model",          /* details column 2 */
  154.       "Color",          /* details column 3 */
  155.       "Sale date",      /* details column 4 */
  156.       "Price ($)"       /* details column 5 */
  157.    };
  158.  
  159.  
  160. /*************************  INSTANCE METHODS SECTION  *************************
  161. *****                                                                     *****
  162. *****              Do not put any code in this section unless             *****
  163. *****                   it is an object INSTANCE method                   *****
  164. *****                                                                     *****
  165. ******************************************************************************/
  166. #undef SOM_CurrentClass
  167. #define SOM_CurrentClass SOMInstance
  168.  
  169. /*
  170.  *
  171.  * METHOD: AddDashboardPage                               ( ) PRIVATE
  172.  *                                                        (X) PUBLIC
  173.  * DESCRIPTION:
  174.  *
  175.  *   This method adds the dashboard page to the settings notebook.
  176.  *
  177.  * RETURN:
  178.  *
  179.  *   0              Unsuccessful
  180.  *   ulPageId       Identifier for the inserted page
  181.  *
  182.  * HOW TO OVERRIDE:
  183.  *
  184.  *   Method should always be overridden in order to replace or remove
  185.  *   the dashboard page from an object which is a descendant of Car.
  186.  *   In most cases, an override of this method will not call the parent.
  187.  */
  188.  
  189. SOM_Scope ULONG SOMLINK carpp_AddDashboardPage(Carpp *somSelf, HWND hwndNotebook)
  190. {
  191.     PAGEINFO pageinfo;
  192.     ULONG versionData[2], dlgId;
  193.  
  194.     DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MINOR, versionData, 8);
  195.     if ( (versionData[0] <= 20 ) && (versionData[1] < 40) )
  196.        dlgId = IDD_DASHBOARD;
  197.     else
  198.        dlgId = IDD_DASHBOARD2;
  199.  
  200.     CarppData *somThis = CarppGetData(somSelf);
  201.     CarppMethodDebug("Carpp","carpp_AddDashboardPage");
  202.  
  203.     memset((PCH)&pageinfo,0,sizeof(PAGEINFO));
  204.     pageinfo.cb                 = sizeof(PAGEINFO);
  205.     pageinfo.hwndPage           = NULLHANDLE;
  206.     pageinfo.usPageStyleFlags   = BKA_MAJOR;
  207.     pageinfo.usPageInsertFlags  = BKA_FIRST;
  208.     pageinfo.pfnwp              = DashBoardDlgProc;
  209.     pageinfo.resid              = hmod;
  210.     pageinfo.dlgid              = dlgId;
  211.     pageinfo.pszName            = "Dashboard";
  212.     pageinfo.pCreateParams      = somSelf;
  213.     pageinfo.idDefaultHelpPanel = ID_HELP_DASHBOARD;
  214.     pageinfo.pszHelpLibraryName = szHelpLibrary;
  215.  
  216.     return somSelf->wpInsertSettingsPage( hwndNotebook, &pageinfo );
  217.  
  218. }   /* end carpp_AddDashboardPage() */
  219.  
  220.  
  221. /*
  222.  *
  223.  * METHOD: AddHornBeepPage                                ( ) PRIVATE
  224.  *                                                        (X) PUBLIC
  225.  * DESCRIPTION:
  226.  *
  227.  *   This method adds the horn beep page to the settings
  228.  *   notebook.
  229.  *
  230.  * RETURN:
  231.  *
  232.  *   0              Unsuccessful
  233.  *   ulPageId       Identifier for the inserted page
  234.  *
  235.  * HOW TO OVERRIDE:
  236.  *
  237.  *   Method should always be overridden in order to replace or remove
  238.  *   the horn beep page from an object which is a descendant of Car.
  239.  *   In most cases, an override of this method will not call the parent.
  240.  */
  241.  
  242. SOM_Scope ULONG SOMLINK carpp_AddHornBeepPage(Carpp *somSelf, HWND hwndNotebook)
  243. {
  244.     PAGEINFO pageinfo;
  245.     ULONG versionData[2], dlgId;
  246.  
  247.     CarppData *somThis = CarppGetData(somSelf);
  248.     CarppMethodDebug("Carpp","carpp_AddHornBeepPage");
  249.  
  250.     DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MINOR, versionData, 8);
  251.     if ( (versionData[0] <= 20 ) && (versionData[1] < 40) )
  252.        dlgId = IDD_HORNBEEP;
  253.     else
  254.        dlgId = IDD_HORNBEEP2;
  255.  
  256.     /* Insert the settings pages for a car
  257.      */
  258.     memset((PCH)&pageinfo,0,sizeof(PAGEINFO));
  259.     pageinfo.cb                 = sizeof(PAGEINFO);
  260.     pageinfo.hwndPage           = NULLHANDLE;
  261.     pageinfo.usPageStyleFlags   = BKA_MAJOR;
  262.     pageinfo.usPageInsertFlags  = BKA_FIRST;
  263.     pageinfo.pfnwp              = HornBeepDlgProc;
  264.     pageinfo.resid              = hmod;
  265.     pageinfo.dlgid              = dlgId;
  266.     pageinfo.pszName            = "Horn Beep";
  267.     pageinfo.pCreateParams      = somSelf;
  268.     pageinfo.idDefaultHelpPanel = ID_HELP_HORNBEEP;
  269.     pageinfo.pszHelpLibraryName = szHelpLibrary;
  270.  
  271.     return somSelf->wpInsertSettingsPage( hwndNotebook, &pageinfo );
  272.  
  273. }   /* end carpp_AddHornBeepPage() */
  274.  
  275. /*
  276.  *
  277.  *  OVERRIDE: wpInitData                                   ( ) PRIVATE
  278.  *                                                         (X) PUBLIC
  279.  *  DESCRIPTION:
  280.  *
  281.  *    Initialize our state variables. Allocate any extra memory that
  282.  *    we might need.
  283.  *
  284.  */
  285.  
  286. SOM_Scope void  SOMLINK carpp_wpInitData(Carpp *somSelf)
  287. {
  288.     CarppData *somThis = CarppGetData(somSelf);
  289.     CarppMethodDebug("Carpp","carpp_wpInitData");
  290.  
  291.     /*
  292.      *   We can initialize our instance data to 0's by using the somThis
  293.      *   pointer and the size of the CarppData structure created by SOM.
  294.      *
  295.      *   SOM stores instance data in a data structure named by prefixing
  296.      *   the name "Data" with the class name, in this case, "Carpp".
  297.      */
  298.  
  299.     memset((PVOID)somThis, 0, sizeof(CarppData));
  300.  
  301.     /*
  302.      *   And/or we can explicitly initialize our instance variables.
  303.      */
  304.  
  305.     somThis->carBrake   = new Brake;
  306.     somThis->carHorn    = new Horn;
  307.     somThis->carRPM     = new RPM;
  308.  
  309.     parent_wpInitData(somSelf);
  310.  
  311. }   /* end carpp_wpInitData() */
  312.  
  313. /*
  314.  *
  315.  *  OVERRIDE: wpUnInitData                                 ( ) PRIVATE
  316.  *                                                         (X) PUBLIC
  317.  *  DESCRIPTION:
  318.  *
  319.  *    Clear up memory that was allocated on wpInitData.
  320.  *
  321.  */
  322.  
  323. SOM_Scope void  SOMLINK carpp_wpUnInitData(Carpp *somSelf)
  324. {
  325.     CarppData *somThis = CarppGetData(somSelf);
  326.     CarppMethodDebug("Carpp","carpp_wpUnInitData");
  327.  
  328.     parent_wpUnInitData(somSelf);
  329.  
  330. }   /* end carpp_wpUnInitData() */
  331.  
  332.  
  333. /*
  334.  *
  335.  *  METHOD: wpSaveState                                    ( ) PRIVATE
  336.  *                                                         (X) PUBLIC
  337.  *  DESCRIPTION:
  338.  *
  339.  *    Save our state variables (pitch and duration).
  340.  *
  341.  */
  342.  
  343. SOM_Scope BOOL SOMLINK carpp_wpSaveState(Carpp *somSelf)
  344. {
  345.     CarppData *somThis = CarppGetData(somSelf);
  346.     CarppMethodDebug("Carpp","carpp_wpSaveState");
  347.  
  348.     somThis->carBrake->SaveState(somSelf, szCarClassTitle);
  349.     somThis->carHorn->SaveState(somSelf, szCarClassTitle);
  350.     somThis->carRPM->SaveState(somSelf, szCarClassTitle);
  351.  
  352.     return (parent_wpSaveState(somSelf));
  353.  
  354. }   /* end carpp_wpSaveState() */
  355.  
  356. /*
  357.  *
  358.  *  METHOD: wpRestoreState                                 ( ) PRIVATE
  359.  *                                                         (X) PUBLIC
  360.  *  DESCRIPTION:
  361.  *
  362.  *    Retrieve our saved state variables (pitch and duration).
  363.  *
  364.  */
  365.  
  366. SOM_Scope BOOL SOMLINK carpp_wpRestoreState(Carpp *somSelf, ULONG ulReserved)
  367. {
  368.     CarppData *somThis = CarppGetData(somSelf);
  369.     CarppMethodDebug("Carpp","carpp_wpRestoreState");
  370.  
  371.     somThis->carBrake->RestoreState(somSelf, szCarClassTitle);
  372.     somThis->carHorn->RestoreState(somSelf, szCarClassTitle);
  373.     somThis->carRPM->RestoreState(somSelf, szCarClassTitle);
  374.  
  375.     return (parent_wpRestoreState(somSelf,ulReserved));
  376.  
  377. }   /* carpp_wpRestoreState() */
  378.  
  379. /*
  380.  *
  381.  *  METHOD: wpAddSettingsPages                             ( ) PRIVATE
  382.  *                                                         (X) PUBLIC
  383.  *  DESCRIPTION:
  384.  *
  385.  *    Add our own settings page to let the user alter the pitch
  386.  *    and duration of the car's beep.
  387.  *
  388.  */
  389.  
  390. SOM_Scope BOOL SOMLINK carpp_wpAddSettingsPages(Carpp *somSelf, HWND hwndNotebook)
  391. {
  392.     CarppData *somThis = CarppGetData(somSelf);
  393.     CarppMethodDebug("Carpp","carpp_wpAddSettingsPages");
  394.  
  395.     if (parent_wpAddSettingsPages(somSelf, hwndNotebook)
  396.              && somSelf->AddHornBeepPage( hwndNotebook)
  397.              && somSelf->AddDashboardPage( hwndNotebook))
  398.     {
  399.         return(TRUE);
  400.     }
  401.     else
  402.     {
  403.         DebugBox("carpp_wpAddSettingsPages", " Failed to add a settings page.");
  404.         return( FALSE );
  405.     }
  406.  
  407. }   /* carpp_wpAddSettingsPages() */
  408.  
  409. /*
  410.  *
  411.  *  METHOD: wpFilterPopupMenu                              ( ) PRIVATE
  412.  *                                                         (X) PUBLIC
  413.  *  DESCRIPTION:
  414.  *
  415.  *    Filter out any options from the context that don't apply.
  416.  *
  417.  *  HOW TO OVERRIDE:
  418.  *
  419.  *    No restrictions.
  420.  *
  421.  */
  422.  
  423. SOM_Scope ULONG SOMLINK carpp_wpFilterPopupMenu(Carpp *somSelf,
  424.                 ULONG ulFlags,
  425.                 HWND hwndCnr,
  426.                 BOOL fMultiSelect)
  427. {
  428.     CarppData *somThis = CarppGetData(somSelf);
  429.     CarppMethodDebug("Carpp","carpp_wpFilterPopupMenu");
  430.  
  431.     /*
  432.      *   This method allows you to filter which menus to include in the
  433.      *   popup menu.  Note: wpclsQueryStyle is overridden to disallow
  434.      *   linking (creating shadow) as well.
  435.      */
  436.     return( parent_wpFilterPopupMenu(somSelf,ulFlags,hwndCnr,
  437.                     fMultiSelect) & ~CTXT_LINK );
  438.  
  439. }   /* end carpp_wpFilterPopupMenu() */
  440.  
  441. /*
  442.  *
  443.  *  METHOD: wpModifyPopupMenu                              ( ) PRIVATE
  444.  *                                                         (X) PUBLIC
  445.  *  DESCRIPTION:
  446.  *
  447.  *    Add our extra option to the context menu to beep the horn
  448.  *
  449.  */
  450.  
  451. SOM_Scope BOOL SOMLINK carpp_wpModifyPopupMenu(Carpp *somSelf,
  452.                 HWND hwndMenu,
  453.                 HWND hwndCnr,
  454.                 ULONG iPosition)
  455. {
  456.     CarppData *somThis = CarppGetData(somSelf);
  457.     CarppMethodDebug("Carpp","carpp_wpModifyPopupMenu");
  458.  
  459.     /*
  460.      *   Put in our special "open car" submenu item under the "open" menu
  461.      */
  462.     somSelf->wpInsertPopupMenuItems( hwndMenu, 0,
  463.                                hmod, ID_OPENMENU, WPMENUID_OPEN);
  464.     /*
  465.      *   insert a "beep horn" menu item at the end of the list.
  466.      */
  467.     somSelf->wpInsertPopupMenuItems( hwndMenu, iPosition,
  468.                                hmod, ID_BEEPMENU, 0 );
  469.  
  470.     /*
  471.      *   insert a "TRAP-D" menu item at the end of the list.
  472.      */
  473.     somSelf->wpInsertPopupMenuItems( hwndMenu, 0,
  474.                                hmod, ID_TRAPMENU, 0 );
  475.  
  476.     return (parent_wpModifyPopupMenu(somSelf,hwndMenu,hwndCnr,iPosition));
  477.  
  478. }   /* end carpp_wpModifyPopupMenu() */
  479.  
  480. /*
  481.  *
  482.  *  METHOD: wpMenuItemSelected                             ( ) PRIVATE
  483.  *                                                         (X) PUBLIC
  484.  *  DESCRIPTION:
  485.  *
  486.  *    Process input from the extra menu option that we added.
  487.  *
  488.  */
  489.  
  490. SOM_Scope BOOL SOMLINK carpp_wpMenuItemSelected(Carpp *somSelf,
  491.                 HWND hwndFrame,
  492.                 ULONG MenuId)
  493. {
  494.     CarppData *somThis = CarppGetData(somSelf);
  495.     CarppMethodDebug("Carpp","carpp_wpMenuItemSelected");
  496.  
  497.     /* Which of our menu items was selected ?
  498.      */
  499.     switch( MenuId )
  500.     {
  501.        case IDM_OPENCAR:
  502.           /*
  503.            *   We could call wpOpen here, but, if the object is already opened,
  504.            *   the following API determines whether the object should be
  505.            *   resurfaced, or if multiple views are desired.
  506.            */
  507.           somSelf->wpViewObject( NULLHANDLE, OPEN_CAR, 0);
  508.           break;
  509.  
  510.        case IDM_BEEPHORN:
  511.           somThis->carHorn->Beep();
  512.           break;
  513.  
  514.        case IDM_TRAPCAR:
  515.           somSelf->TrapTest();
  516.           break;
  517.  
  518.        default:
  519.           return parent_wpMenuItemSelected(somSelf, hwndFrame, MenuId);
  520.           break;
  521.     }
  522.     return TRUE;                                          /* we processed it */
  523.  
  524. }   /* end carpp_wpMenuItemSelected() */
  525.  
  526. /*
  527.  *
  528.  *  METHOD: wpMenuItemHelpSelected                         ( ) PRIVATE
  529.  *                                                         (X) PUBLIC
  530.  *  DESCRIPTION:
  531.  *
  532.  *    Process input from the extra menu option that we added.
  533.  *
  534.  */
  535.  
  536. SOM_Scope BOOL SOMLINK carpp_wpMenuItemHelpSelected(Carpp *somSelf,ULONG MenuId)
  537. {
  538.     CarppData *somThis = CarppGetData(somSelf);
  539.     CarppMethodDebug("Carpp","carpp_wpMenuItemHelpSelected");
  540.  
  541.     /* Which of our menu items was selected ?
  542.      */
  543.    switch( MenuId )
  544.    {
  545.       case IDM_BEEPHORN:
  546.  
  547.          return(somSelf->wpDisplayHelp( ID_HELP_BEEPHORN, szHelpLibrary));
  548.          break;
  549.  
  550.       case IDM_OPENCAR:
  551.  
  552.          return(somSelf->wpDisplayHelp( ID_HELP_OPENCAR, szHelpLibrary));
  553.          break;
  554.  
  555.       case IDM_TRAPCAR:
  556.  
  557.          return(somSelf->wpDisplayHelp( ID_HELP_TRAPCAR, szHelpLibrary));
  558.          break;
  559.  
  560.       default:
  561.          break;
  562.    }
  563.  
  564.    return FALSE;
  565.  
  566. }   /* end carpp_wpMenuItemHelpSelected() */
  567.  
  568. /*
  569.  *
  570.  *  METHOD: wpQueryDetailsData                             ( ) PRIVATE
  571.  *                                                         (X) PUBLIC
  572.  *  DESCRIPTION:
  573.  *
  574.  *    Returns the car specific data for the details view of this object.
  575.  *    Sets the pointer (*ppDetailsData) to the beginning of the buffer
  576.  *    into which the data is written.
  577.  *
  578.  */
  579.  
  580. SOM_Scope ULONG SOMLINK carpp_wpQueryDetailsData(Carpp *somSelf,
  581.                 PVOID *ppDetailsData,
  582.                 PULONG pcp)
  583. {
  584.    PCARDETAILS pCarDetails;
  585.    PBYTE       pSize;
  586.     CarppData *somThis = CarppGetData(somSelf);
  587.     CarppMethodDebug("Carpp","carpp_wpQueryDetailsData");
  588.  
  589.    parent_wpQueryDetailsData(somSelf,ppDetailsData, pcp);
  590.  
  591.    if (ppDetailsData)                                          /* query data */
  592.    {
  593.       pCarDetails                  = (PCARDETAILS) *ppDetailsData;
  594.       pCarDetails->pszMake         = "Toyota";               /* Manufacturer */
  595.       pCarDetails->pszModel        = "Camry";                  /* Model name */
  596.       pCarDetails->pszColor        = "BLUE";             /* Color of the car */
  597.       pCarDetails->cdateSale.day   = 24;                     /* Date of sale */
  598.       pCarDetails->cdateSale.month = 12;
  599.       pCarDetails->cdateSale.year  = 91;
  600.       pCarDetails->ulPrice         = 14000;              /* Price in dollars */
  601.  
  602.       /* point to buffer location after our details data */
  603.       *ppDetailsData = ((PBYTE) (*ppDetailsData)) + sizeof(*pCarDetails);
  604.  
  605.    }   /* end if (ppDetailsData) */
  606.    else                                                /* query size of data */
  607.    {
  608.       *pcp += sizeof(*pCarDetails);     /* caller is querying size of buffer */
  609.    }
  610.  
  611.    return(TRUE);
  612.  
  613. }   /* end carpp_wpQueryDetailsData() */
  614.  
  615. /*
  616.  *
  617.  *   METHOD: wpOpen                                         ( ) PRIVATE
  618.  *                                                          (X) PUBLIC
  619.  *   DESCRIPTION:
  620.  *
  621.  *     Opens the car window.
  622.  *
  623.  */
  624.  
  625. SOM_Scope HWND SOMLINK carpp_wpOpen(Carpp *somSelf,
  626.                 HWND hwndCnr,
  627.                 ULONG ulView,
  628.                 ULONG param)
  629. {
  630.  
  631.  HWND hwnd = NULLHANDLE;
  632.  CarppData *somThis = CarppGetData(somSelf);
  633.  CarppMethodDebug("Carpp","carpp_wpOpen");
  634.  
  635.    switch (ulView)
  636.    {
  637.       case OPEN_CAR:
  638.  
  639.          if (!(somSelf->wpSwitchTo( ulView )))
  640.          {
  641.             /*
  642.              *   Create a basic Frame and Client window for this instance.
  643.              */
  644.             hwnd = CarInit(somSelf);
  645.          }
  646.          break;
  647.  
  648.       default:
  649.          hwnd = parent_wpOpen(somSelf,hwndCnr,ulView,param);
  650.          break;
  651.  
  652.    }   /* end switch (ulView) */
  653.  
  654.    return( hwnd );
  655. }   /* end carpp_wpOpen() */
  656.  
  657.  
  658. /*
  659.  *
  660.  *  METHOD: wpSetup                                        ( ) PRIVATE
  661.  *                                                         (X) PUBLIC
  662.  *  DESCRIPTION:
  663.  *
  664.  *    Specify Setup strings and do some initialization.  This method is
  665.  *    invoked once an object is completely created.
  666.  *
  667.  *  Note:  We're overriding this method to write some default data to the
  668.  *         object's real filename.  This will give us something to look at
  669.  *         if the user drag/drops us on an editor or selects the open/editor
  670.  *         view.
  671.  */
  672.  
  673. SOM_Scope BOOL   SOMLINK carpp_wpSetup(Carpp *somSelf,
  674.                 PSZ pszSetupString)
  675. {
  676.  ULONG cbBytesWritten;           /* pointer to variable receiving byte count */
  677.  APIRET rc;
  678.  BOOL fSuccess;
  679.  HFILE hf;                            /* pointer to variable for file handle */
  680.  ULONG ulAction;                     /* pointer to variable for action taken */
  681.  CHAR szObjectFilename[CCHMAXPATH];          /* buffer for wpQueryRealName() */
  682.  ULONG cb  = sizeof(szObjectFilename);
  683.  
  684.  
  685.     CarppData *somThis = CarppGetData(somSelf);
  686.     CarppMethodDebug("Carpp","carpp_wpSetup");
  687.  
  688.    /*
  689.     *   Write an initial bill-of-sale to the object data file
  690.     */
  691.  
  692.    fSuccess =
  693.    somSelf->wpQueryRealName(                 /* query full-pathname of object's file */
  694.       szObjectFilename,                                     /* return buffer */
  695.       &cb,                                                  /* sizeof buffer */
  696.       TRUE);                            /* request fully qualified pathname? */
  697.  
  698.    if (fSuccess)
  699.    {
  700.       rc =
  701.       DosOpen(szObjectFilename, &hf, &ulAction,
  702.          0,                             /* file size if created or truncated */
  703.          FILE_NORMAL,                                      /* file attribute */
  704.          FILE_OPEN             /* action taken if file exists/does not exist */
  705.             | FILE_CREATE,
  706.          OPEN_ACCESS_READWRITE                          /* open mode of file */
  707.             | OPEN_SHARE_DENYNONE,
  708.          NULL);              /* pointer to structure for extended attributes */
  709.  
  710.       if (rc)
  711.       {
  712.        CHAR ach[10];
  713.  
  714.          _ltoa(rc, ach, 10);
  715.          DebugBox("carpp_wpSetup:DosOpen failed rc =", ach);
  716.       }
  717.       else
  718.       {
  719.          DosWrite(hf,
  720.                   (PVOID)pcszDefaultText,
  721.                   strlen(pcszDefaultText),
  722.                   &cbBytesWritten);
  723.          DosClose(hf);
  724.       }
  725.    }   /* end if (fSuccess) */
  726.  
  727.    return (parent_wpSetup(somSelf,pszSetupString));
  728.  
  729. }   /* end carpp_wpSetup() */
  730.  
  731. /*
  732.  *
  733.  *  METHOD: TrapTest                                        ( ) PRIVATE
  734.  *                                                          (X) PUBLIC
  735.  *  DESCRIPTION:
  736.  *
  737.  *    Specify Setup strings and do some initialization.  This method is
  738.  *    invoked once an object is completely created.
  739.  *
  740.  *  Note:  The variable used to communicate the current state to the
  741.  *         exception handler is global.  If an exception occurs in more than
  742.  *         one instance of this object at the same time, the results will
  743.  *         be unpredictable.
  744.  */
  745.  
  746. #pragma handler (carpp_TrapTest)
  747. /*
  748.  *
  749.  * METHOD: TrapTest                                       ( ) PRIVATE
  750.  *                                                        (X) PUBLIC
  751.  * DESCRIPTION:
  752.  *
  753.  *   This method tests the exception handling in this sample.
  754.  *
  755.  * RETURN:
  756.  *
  757.  *   nothing
  758.  *
  759.  * HOW TO OVERRIDE:
  760.  *
  761.  *   n/a
  762.  *
  763.  *
  764.  *   Methods from the WPObject class
  765.  */
  766.  
  767. SOM_Scope void  SOMLINK carpp_TrapTest(Carpp *somSelf)
  768. {
  769.   PSZ      pszTrap = NULL;
  770.   jmp_buf  saveState;
  771.   CarppData *somThis = CarppGetData(somSelf);
  772.   CarppMethodDebug("Carpp","carpp_TrapTest");
  773.  
  774.    memcpy(saveState, jmpState, sizeof(jmpState));
  775.    if (!setjmp(jmpState))   /* no exception?*/
  776.    {
  777.       /*
  778.        *   Normal code for this method goes here
  779.        */
  780.  
  781.       *pszTrap = 'a';
  782.    }
  783.    else   /* we just returned from exception handler */
  784.    {
  785.       /*
  786.        *   An exception just occurred in this method.  We should put any
  787.        *   cleanup/recovery code in this code block and then return the
  788.        *   error to the caller.
  789.        */
  790.  
  791.       WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, pcszTrapMessage,
  792.                       "Exception Handler Test",
  793.                       999, MB_MOVEABLE | MB_OK | MB_ERROR);
  794.    }
  795.  
  796.    memcpy(jmpState, saveState, sizeof(jmpState));
  797.  
  798. }   /* end carpp_TrapTest() */
  799.  
  800. /**************************  CLASS METHODS SECTION  ***************************
  801. *****                                                                     *****
  802. *****              Do not put any code in this section unless             *****
  803. *****                     it is an object CLASS method                    *****
  804. *****                                                                     *****
  805. ******************************************************************************/
  806. #undef SOM_CurrentClass
  807. #define SOM_CurrentClass SOMMeta
  808.  
  809.  
  810. /*
  811.  *
  812.  *  METHOD: clsQueryModuleHandle                           ( ) PRIVATE
  813.  *                                                         (X) PUBLIC
  814.  *  DESCRIPTION:
  815.  *
  816.  *    This method returns the module handle of this class.  If this is the
  817.  *    first invocation, DosQueryModuleHandle is called to save the handle
  818.  *    for future invocations.
  819.  *
  820.  *  RETURN:
  821.  *
  822.  *    0              Unsuccessful
  823.  *    non-zero       module handle
  824.  *
  825.  */
  826.  
  827. /*
  828.  * METHOD: clsQueryModuleHandle                           ( ) PRIVATE
  829.  *                                                        (X) PUBLIC
  830.  * DESCRIPTION:
  831.  *
  832.  *   This method returns the module handle of this class.  If this is the
  833.  *   first invocation, DosQueryModuleHandle is called to save the handle
  834.  *   for future invocations.
  835.  *
  836.  * RETURN:
  837.  *
  838.  *   0              Unsuccessful
  839.  *   non-zero       module handle
  840.  */
  841.  
  842. SOM_Scope HMODULE   SOMLINK carppM_clsQueryModuleHandle(M_Carpp *somSelf)
  843. {
  844.  APIRET rc;
  845.  
  846.     /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  847.     M_CarppMethodDebug("M_Carpp","carppM_clsQueryModuleHandle");
  848.  
  849.    /*
  850.     *   Make sure we already have module handle
  851.     */
  852.  
  853.  
  854.     if (hmod == NULLHANDLE)
  855.     {
  856.      zString zsPathName;
  857.        /*
  858.         *   Retrieve registered pathname of our module (DLL) and query the
  859.         *   module handle.
  860.         */
  861.        zsPathName =
  862.        (SOMClassMgrObject->somLocateClassFile(  SOM_IdFromString("Carpp"),
  863.                                               Carpp_MajorVersion, Carpp_MinorVersion));
  864.        rc =
  865.        DosQueryModuleHandle( zsPathName, &hmod);
  866.        if (rc)
  867.        {
  868.           DebugBox("carppM_wpclsInitData", "Failed to load module");
  869.           return 0L;
  870.        }
  871.  
  872.     }   /* end if (hmod == NULLHANDLE) */
  873.  
  874.     return (hmod);
  875.  
  876. }   /* end carppM_clsQueryModuleHandle() */
  877.  
  878. /*
  879.  *
  880.  *  METHOD: wpclsQueryStyle                                ( ) PRIVATE
  881.  *                                                         (X) PUBLIC
  882.  *  DESCRIPTION:
  883.  *
  884.  *     The wpclsQueryStyle method is called to allow the class object
  885.  *     to specify the default object class style for its instances.
  886.  *
  887.  *  REMARKS:
  888.  *
  889.  *     This method can be called at any time in order to determine the
  890.  *     default style for instances of this class.
  891.  *
  892.  *     This method should be overridden in order to modify the default
  893.  *     object style for instances of this class.
  894.  *
  895.  */
  896.  
  897. SOM_Scope ULONG   SOMLINK carppM_wpclsQueryStyle(M_Carpp *somSelf)
  898. {
  899.     /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  900.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryStyle");
  901.  
  902.     /*
  903.      *   Modify style bits as described in programming reference.  This
  904.      *   particular style (link) is also disabled in wpFilterPopupMenu()
  905.      */
  906.     return (parent_wpclsQueryStyle(somSelf) | CLSSTYLE_NEVERLINK);
  907. }
  908.  
  909. /*
  910.  *
  911.  *  METHOD: wpclsInitData                                  ( ) PRIVATE
  912.  *                                                         (X) PUBLIC
  913.  *  DESCRIPTION:
  914.  *
  915.  *    Initialize the class data
  916.  *
  917.  */
  918.  
  919. SOM_Scope void  SOMLINK carppM_wpclsInitData(M_Carpp *somSelf)
  920. {
  921.  ULONG rc, i;
  922.  PCLASSFIELDINFO pCFI;
  923.  
  924.     /* M_CarppData *somThis  = M_CarppGetData(somSelf); */
  925.     M_CarppMethodDebug("M_Carpp","carppM_wpclsInitData");
  926.  
  927.     /*
  928.      *   Call the parent class method first
  929.      */
  930.     parent_wpclsInitData(somSelf);
  931.  
  932.     /*
  933.      *   Get class title
  934.      */
  935.     if (!WinLoadString(WinQueryAnchorBlock(HWND_DESKTOP), somSelf->clsQueryModuleHandle(), ID_TITLE,
  936.                          sizeof(szCarClassTitle), szCarClassTitle))
  937.                               /* Load string failed: use the parent's string */
  938.        strcpy(szCarClassTitle, parent_wpclsQueryTitle(somSelf));
  939.  
  940.    /*
  941.     *   Initialize everything needed for the CLASSFIELDINFO structures
  942.     *   for the Car object class
  943.     */
  944.  
  945.    for (i=0, pCFI=fieldinfo; i < NUM_CAR_FIELDS; i++, pCFI++)
  946.    {
  947.       memset((PCH) pCFI, 0, sizeof(CLASSFIELDINFO));               /* zero's */
  948.  
  949.       pCFI->cb        = sizeof(CLASSFIELDINFO);
  950.       pCFI->flData    = CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
  951.       pCFI->flTitle   = CFA_CENTER | CFA_SEPARATOR | CFA_HORZSEPARATOR |
  952.                         CFA_STRING | CFA_FITITLEREADONLY;
  953.       pCFI->pNextFieldInfo = pCFI + 1;       /* point to next CLASSFIELDINFO */
  954.       pCFI->pTitleData = (PVOID) apszCarColTitles[i];
  955.       pCFI->flCompare  = COMPARE_SUPPORTED | SORTBY_SUPPORTED;
  956.  
  957.  
  958. /*******************************************************/
  959. /* KLUDGE - w/o the ULONG typecast there is an error */
  960. /******************************************************* */
  961. /* Calculate the byte offset of a field in a structure of type type. */
  962. #define LFIELDOFFSET(type, field)    ((ULONG)&(((type *)0)->field))
  963.  
  964.       switch (i)
  965.       {
  966.          case INDEX_MAKE:
  967.  
  968.             pCFI->flData           |= CFA_STRING;
  969.             pCFI->offFieldData      = (ULONG)(LFIELDOFFSET(CARDETAILS,pszMake));
  970.             pCFI->ulLenFieldData    = sizeof(PSZ);
  971.             pCFI->DefaultComparison = CMP_EQUAL;
  972.  
  973.             break;
  974.  
  975.          case INDEX_MODEL:
  976.  
  977.             pCFI->flData           |= CFA_STRING;
  978.             pCFI->offFieldData      = (ULONG)(LFIELDOFFSET(CARDETAILS,pszModel));
  979.             pCFI->ulLenFieldData    = sizeof(PSZ);
  980.             pCFI->DefaultComparison = CMP_EQUAL;
  981.  
  982.             break;
  983.  
  984.          case INDEX_COLOR:
  985.  
  986.             pCFI->flData           |= CFA_STRING;
  987.             pCFI->offFieldData      = (ULONG)(LFIELDOFFSET(CARDETAILS,pszColor));
  988.             pCFI->ulLenFieldData    = sizeof(PSZ);
  989.             pCFI->DefaultComparison = CMP_EQUAL;
  990.  
  991.             break;
  992.  
  993.          case INDEX_SALE_DATE:
  994.  
  995.             pCFI->flData           |= CFA_DATE;
  996.             pCFI->offFieldData      = (ULONG)(LFIELDOFFSET(CARDETAILS,cdateSale));
  997.             pCFI->ulLenFieldData    = sizeof(CDATE);
  998.             pCFI->ulLenCompareValue = sizeof(CDATE);
  999.             pCFI->DefaultComparison = CMP_GREATER;
  1000.  
  1001.             break;
  1002.  
  1003.          case INDEX_PRICE:
  1004.  
  1005.             pCFI->flData           |= CFA_ULONG;
  1006.             pCFI->offFieldData      = (ULONG)(LFIELDOFFSET(CARDETAILS,ulPrice));
  1007.             pCFI->ulLenFieldData    = sizeof(ULONG);
  1008.             pCFI->ulLenCompareValue = sizeof(ULONG);
  1009.             pCFI->DefaultComparison = CMP_GREATER;
  1010.  
  1011.             break;
  1012.  
  1013.       }   /* end switch(i) */
  1014.  
  1015.    }   /* end for (i=0, pCFI=fieldinfo; i < NUM_CAR_FIELDS; i++, pCFI++)  */
  1016.  
  1017.    fieldinfo[NUM_CAR_FIELDS-1].pNextFieldInfo = NULL;/* terminate linked list */
  1018.  
  1019. }   /* end carppM_ wpclsInitData() */
  1020.  
  1021. /*
  1022.  *
  1023.  *  METHOD: wpclsUnInitData                                ( ) PRIVATE
  1024.  *                                                         (X) PUBLIC
  1025.  *  DESCRIPTION:
  1026.  *
  1027.  *    Free any class data
  1028.  *
  1029.  */
  1030.  
  1031. SOM_Scope void SOMLINK carppM_wpclsUnInitData(M_Carpp *somSelf)
  1032. {
  1033.     M_CarppMethodDebug("M_Carpp","carppM_wpclsUnInitData");
  1034.  
  1035.     parent_wpclsUnInitData(somSelf);
  1036.  
  1037. }   /* end carppM_wpclsUnInitData() */
  1038.  
  1039. /*
  1040.  *
  1041.  *  METHOD: wpclsQueryTitle                                ( ) PRIVATE
  1042.  *                                                         (X) PUBLIC
  1043.  *  DESCRIPTION:
  1044.  *
  1045.  *    Return the string "New car".
  1046.  *
  1047.  */
  1048.  
  1049. SOM_Scope PSZ SOMLINK carppM_wpclsQueryTitle(M_Carpp *somSelf)
  1050. {
  1051.                               /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  1052.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryTitle");
  1053.  
  1054.     /*
  1055.      *   Return the class title for a car
  1056.      */
  1057.  
  1058.     if (*szCarClassTitle )
  1059.        return( szCarClassTitle );
  1060.     else
  1061.        return( parent_wpclsQueryTitle(somSelf));
  1062.  
  1063. }   /* end carppM_wpclsQueryTitle() */
  1064.  
  1065. /*
  1066.  *
  1067.  *  METHOD: wpclsQueryIconDdata                            ( ) PRIVATE
  1068.  *                                                         (X) PUBLIC
  1069.  *  DESCRIPTION:
  1070.  *
  1071.  *    Return the class icon
  1072.  *
  1073.  */
  1074.  
  1075. SOM_Scope ULONG SOMLINK carppM_wpclsQueryIconData(M_Carpp *somSelf,
  1076.                   PICONINFO pIconInfo)
  1077. {
  1078.    APIRET rc;
  1079.  
  1080.    M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryIconData");
  1081.  
  1082.    if (pIconInfo)
  1083.    {
  1084.       /*
  1085.        *   fill in icon information
  1086.        */
  1087.       pIconInfo->fFormat = ICON_RESOURCE;
  1088.       pIconInfo->hmod= somSelf->clsQueryModuleHandle();
  1089.       pIconInfo->resid= ID_ICON;
  1090.    }
  1091.  
  1092.    return (sizeof(ICONINFO));
  1093.  
  1094. }   /* end carppM_wpclsQueryIconData() */
  1095.  
  1096. /*
  1097.  *
  1098.  *  METHOD: wpclsQueryDefaultHelp                          ( ) PRIVATE
  1099.  *                                                         (X) PUBLIC
  1100.  *  DESCRIPTION:
  1101.  *
  1102.  *    Process input from the extra menu option that we added.
  1103.  *
  1104.  */
  1105.  
  1106. SOM_Scope BOOL SOMLINK carppM_wpclsQueryDefaultHelp(M_Carpp *somSelf,
  1107.                 PULONG pHelpPanelId,
  1108.                 PSZ pszHelpLibrary)
  1109. {
  1110.                               /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  1111.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryDefaultHelp");
  1112.  
  1113.     if (pHelpPanelId)                           /* set default help panel id */
  1114.        *pHelpPanelId   = ID_HELP_DEFAULT;
  1115.  
  1116.     if (pszHelpLibrary)                                /* copy help filename */
  1117.        strcpy(pszHelpLibrary, szHelpLibrary);
  1118.  
  1119.     return (TRUE);
  1120.  
  1121. }   /* end carppM_wpclsQueryDefaultHelp() */
  1122.  
  1123. /*
  1124.  *
  1125.  *  METHOD: wpclsQueryDefaultView                          ( ) PRIVATE
  1126.  *                                                         (X) PUBLIC
  1127.  *  DESCRIPTION:
  1128.  *
  1129.  *    Returns the default view for a new instance of this object.
  1130.  *
  1131.  *  REMARKS:
  1132.  *
  1133.  *    Tell the system what our default open view is...
  1134.  *
  1135.  */
  1136.  
  1137. SOM_Scope ULONG SOMLINK carppM_wpclsQueryDefaultView(M_Carpp *somSelf)
  1138. {
  1139.                               /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  1140.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryDefaultView");
  1141.  
  1142.     return OPEN_CAR;
  1143.  
  1144. }   /* end carppM_wpclsQueryDefaultView() */
  1145.  
  1146. /*
  1147.  *
  1148.  *  METHOD: wpclsQueryDetailsInfo                          ( ) PRIVATE
  1149.  *                                                         (X) PUBLIC
  1150.  *  DESCRIPTION:
  1151.  *
  1152.  *    Appends the car specific chain of FIELDINFO structures describing the
  1153.  *    details data of this object to *ppClassFieldInfo (if ppClassFieldInfo
  1154.  *    is NON-NULL).  In this case it also sets *ppClassFieldInfo to the
  1155.  *    head of the linked list.
  1156.  *
  1157.  *    Adds the number of bytes required by the details data for car to *pSize
  1158.  *    (if pSize is NON-NULL).
  1159.  *
  1160.  *  REMARKS:
  1161.  *
  1162.  *    Add details data for this object.
  1163.  *
  1164.  */
  1165.  
  1166. SOM_Scope ULONG SOMLINK carppM_wpclsQueryDetailsInfo(M_Carpp *somSelf,
  1167.                 PCLASSFIELDINFO *ppClassFieldInfo,
  1168.                 PULONG pSize)
  1169. {
  1170.  ULONG           cParentColumns;
  1171.  PCLASSFIELDINFO pCFI;
  1172.  ULONG           i;
  1173.  
  1174.     /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  1175.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryDetailsInfo");
  1176.  
  1177.    /*
  1178.     *   Always call the parent method first to retrieve number of details
  1179.     *   columns and parent's data already defined in details buffer.
  1180.     */
  1181.  
  1182.    cParentColumns =
  1183.    parent_wpclsQueryDetailsInfo(somSelf, ppClassFieldInfo, pSize);
  1184.  
  1185.    /*
  1186.     *   If pSize is non-NULL, we must add the size of our deatils column
  1187.     *   data structure.
  1188.     */
  1189.  
  1190.    if (pSize)
  1191.       *pSize += sizeof(CARDETAILS);                           /* adjust size */
  1192.  
  1193.    /*
  1194.     *   If the request was for the chained fieldinfo structures
  1195.     *   (ppClassFieldInfo is non-NULL), link them in
  1196.     *
  1197.     *   eventually the chain will look like
  1198.     *
  1199.     *   Grandad - Dad - Me - Kid - Grandkid
  1200.     *
  1201.     *   I will be getting the pointer to the beginning of the chain
  1202.     *
  1203.     *   If the beginning of the chain is 0, I will assign the address
  1204.     *   of my first CLASSFIELDINFO structure to *ppClassFieldInfo.
  1205.     *   Otherwise *pp points to the first column description in the
  1206.     *   chain.  We need to walk the chain and link our CLASSFIELDINFO
  1207.     *   structures at the end.
  1208.     */
  1209.  
  1210.    if (ppClassFieldInfo)
  1211.    {
  1212.       /*
  1213.        *   Find the last link in the chain;  Then link our CLASSFIELDINFO
  1214.        *   structures to the chain.
  1215.        */
  1216.  
  1217.       if (*ppClassFieldInfo)
  1218.       {
  1219.          pCFI = *ppClassFieldInfo;
  1220.          for (i=0;i<cParentColumns;i++)
  1221.             pCFI = (pCFI->pNextFieldInfo) ? pCFI->pNextFieldInfo : pCFI;
  1222.  
  1223.          pCFI->pNextFieldInfo = fieldinfo;
  1224.       }
  1225.       else
  1226.          *ppClassFieldInfo = fieldinfo;
  1227.    }
  1228.    return ((ULONG) (cParentColumns + NUM_CAR_FIELDS));
  1229.  
  1230. }   /* end carppM_wpclsQueryDetailsInfo() */
  1231.  
  1232. /*
  1233.  *
  1234.  *  METHOD: wpclsQueryInstanceFilter                       ( ) PRIVATE
  1235.  *                                                         (X) PUBLIC
  1236.  *  DESCRIPTION:
  1237.  *
  1238.  *     The wpclsQueryInstanceFilter method is called to allow the class
  1239.  *     object to specify the file title filters for instances of its
  1240.  *     class.
  1241.  *
  1242.  *  REMARKS:
  1243.  *
  1244.  *     A pointer to a string containing file title filter(s).  This
  1245.  *     string can contain several file title filters separated by a
  1246.  *     comma.  Example: "*.TXT, *.DOC"
  1247.  *
  1248.  *  Note:  Overriding this method will cause any data file with the extension
  1249.  *         ".CAR" to become a data object of the class "Car."
  1250.  *
  1251.  */
  1252.  
  1253. SOM_Scope PSZ   SOMLINK carppM_wpclsQueryInstanceFilter(M_Carpp *somSelf)
  1254. {
  1255.     /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  1256.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryInstanceFilter");
  1257.  
  1258.     return (szCarInstanceFilter);
  1259. }
  1260.  
  1261.  
  1262. /*
  1263.  *
  1264.  *  METHOD: wpclsQueryDetails                              ( ) PRIVATE
  1265.  *                                                         (X) PUBLIC
  1266.  *  DESCRIPTION:
  1267.  *
  1268.  *     Specify default details to display in details view
  1269.  *
  1270.  *  REMARKS:
  1271.  *
  1272.  *     A pointer details structure is modified and returned.
  1273.  *     Note: this is purely virtual at the moment (parent class doesn't
  1274.  *     do anything).
  1275.  */
  1276.  
  1277. SOM_Scope PCLASSDETAILS   SOMLINK carppM_wpclsQueryDetails(M_Carpp *somSelf)
  1278. {
  1279.     /* M_CarppData *somThis = M_CarppGetData(somSelf); */
  1280.     M_CarppMethodDebug("M_Carpp","carppM_wpclsQueryDetails");
  1281.  
  1282.     return (parent_wpclsQueryDetails(somSelf));
  1283. }
  1284.  
  1285.  
  1286. /**************************  ORDINARY CODE SECTION  ***************************
  1287. *****                                                                     *****
  1288. *****                  Any non-method code should go here.                *****
  1289. *****                                                                     *****
  1290. ******************************************************************************/
  1291. #undef SOM_CurrentClass
  1292.  
  1293.  
  1294. /***************************************************************************
  1295. *                                                                          *
  1296. *       ROUTINE:    CarInit ( )                                            *
  1297. *                                                                          *
  1298. *       DESCRIPTION:    Car Initialization                                 *
  1299. *                                                                          *
  1300. *       RETURNS:    Handle of car frame window, NULL if error              *
  1301. *                                                                          *
  1302. ***************************************************************************/
  1303. HWND CarInit (Carpp* somSelf)
  1304. {
  1305.    HAB  hab;                                       /* PM anchor block handle */
  1306.    HWND hwndFrame = NULLHANDLE;                       /* Frame window handle */
  1307.    HWND hwndClient = NULLHANDLE;
  1308.    PWINDOWDATA pWindowData;
  1309.    BOOL fSuccess;
  1310.    SWCNTRL    swcEntry;                                      /* Switch Entry */
  1311.    FRAMECDATA flFrameCtlData;                              /* Frame Ctl Data */
  1312.  
  1313.    hab = WinQueryAnchorBlock(HWND_DESKTOP);
  1314.    if (!WinRegisterClass( hab , szCarWindowClass, (PFNWP)CarWndProc ,
  1315.                             CS_SIZEREDRAW | CS_SYNCPAINT, sizeof(pWindowData)))
  1316.    {
  1317.       DebugBox("CarInit", "Failure in WinRegisterClass");
  1318.       return NULLHANDLE ;
  1319.    }
  1320.  
  1321.    /*
  1322.     *   Allocate some instance specific data in Window words of Frame window.
  1323.     *   This will ensure our window procedure can use this object's methods
  1324.     *   (our window proc isn't passed a * somSelf pointer).
  1325.     */
  1326.    pWindowData = (PWINDOWDATA) somSelf->wpAllocMem( sizeof(*pWindowData), NULL);
  1327.  
  1328.    if (!pWindowData)
  1329.    {
  1330.       DebugBox("CarInit", "wpAllocMem failed to allocate pWindowData");
  1331.       return NULLHANDLE;
  1332.    }
  1333.  
  1334.    memset((PVOID) pWindowData, 0, sizeof(*pWindowData));
  1335.    pWindowData->cb = sizeof(*pWindowData);             /* first field = size */
  1336.    pWindowData->somSelf = somSelf;
  1337.  
  1338.    /* Create a frame window
  1339.     */
  1340.    flFrameCtlData.cb            = sizeof( flFrameCtlData );
  1341.    flFrameCtlData.flCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
  1342.                                   FCF_MINMAX ;
  1343.    flFrameCtlData.hmodResources = hmod;
  1344.    flFrameCtlData.idResources   = ID_ICON;
  1345.  
  1346.    hwndFrame =                                        /* create frame window */
  1347.    WinCreateWindow(
  1348.       HWND_DESKTOP,               /* parent-window handle                    */
  1349.       WC_FRAME,                   /* pointer to registered class name        */
  1350.       somSelf->wpQueryTitle(),     /* pointer to window text                  */
  1351.       0,                          /* window style                            */
  1352.       0, 0, 0, 0,                 /* position of window                      */
  1353.       NULLHANDLE,                 /* owner-window handle                     */
  1354.       HWND_TOP,                   /* handle to sibling window                */
  1355.       (USHORT) ID_FRAME,          /* window identifier                       */
  1356.       (PVOID) &flFrameCtlData,    /* pointer to buffer                       */
  1357.       NULL);      ;               /* pointer to structure with pres. params. */
  1358.  
  1359.    if (!hwndFrame)
  1360.    {
  1361.       DebugBox("CarInit", "Failure in WinCreateWindow");
  1362.       return NULLHANDLE;
  1363.    }
  1364.    hwndClient =         /* use WinCreateWindow so we can pass pres params */
  1365.    WinCreateWindow(
  1366.       hwndFrame,               /* parent-window handle                    */
  1367.       szCarWindowClass,        /* pointer to registered class name        */
  1368.       NULL,                    /* pointer to window text                  */
  1369.       0,                       /* window style                            */
  1370.       0, 0, 0, 0,              /* position of window                      */
  1371.       hwndFrame,               /* owner-window handle                     */
  1372.       HWND_TOP,                /* handle to sibling window                */
  1373.       (USHORT)FID_CLIENT,      /* window identifier                       */
  1374.       pWindowData,             /* pointer to buffer                       */
  1375.       NULL);                   /* pointer to structure with pres. params. */
  1376.  
  1377.    if (!hwndClient)
  1378.    {
  1379.       WinDestroyWindow(hwndFrame);
  1380.       return NULLHANDLE;
  1381.    }
  1382.  
  1383.    WinSendMsg(hwndFrame, WM_SETICON, MPFROMP(somSelf->wpQueryIcon()), NULL);
  1384.    WinSetWindowText(WinWindowFromID(hwndFrame,(USHORT)FID_TITLEBAR),
  1385.                                                          somSelf->wpQueryTitle());
  1386.  
  1387.    /*
  1388.     * Restore the Window Position
  1389.     */
  1390.    fSuccess =
  1391.    WinRestoreWindowPos(
  1392.       szCarClassTitle,                                        /* class title */
  1393.       somSelf->wpQueryTitle(),                                /* object title */
  1394.       hwndFrame);
  1395.  
  1396.    if (!fSuccess)
  1397.    {
  1398.     SWP        swp;
  1399.  
  1400.       /* Get the dimensions and the shell's suggested
  1401.        * location for the window
  1402.        */
  1403.       WinQueryTaskSizePos(hab,0,&swp);
  1404.  
  1405.       /* Set the frame window position
  1406.        */
  1407.      swp.fl               = SWP_SIZE|SWP_MOVE|SWP_RESTORE|SWP_ZORDER;
  1408.      WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy, swp.fl);
  1409.    }
  1410.  
  1411.    WinShowWindow(hwndFrame,TRUE);
  1412.    WinStartTimer(hab, hwndClient, CAR_TIMER, (ULONG)100);
  1413.  
  1414.    return hwndFrame;                                              /* success */
  1415.  
  1416. }   /* end CarInit() */
  1417.  
  1418.  
  1419. /******************************************************************************
  1420. *
  1421. *   CarWndProc()
  1422. *
  1423. *   DESCRIPTION: Car Window Procedure
  1424. *
  1425. ******************************************************************************/
  1426. MRESULT EXPENTRY CarWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1427. {
  1428.   ULONG    MenuId;
  1429.   PWINDOWDATA pWindowData;
  1430.   CarppData *somThis;
  1431.   HWND     hwndFrame;
  1432.   CHAR     acBuffer[10];
  1433.   BOOL     fSuccess;
  1434.  
  1435.    hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
  1436.  
  1437.    switch( msg )
  1438.    {
  1439.       case WM_CREATE:
  1440.  
  1441.         pWindowData = (PWINDOWDATA) mp1;
  1442.  
  1443.         if (pWindowData == NULL)
  1444.         {
  1445.            DebugBox("CarWndProc:WM_CREATE", "couldn't get window words");
  1446.            return FALSE;
  1447.         }
  1448.         /*
  1449.          *   Fill in the class view/usage details and window specific data
  1450.          *   for this instance.
  1451.          */
  1452.         pWindowData->UseItem.type    = USAGE_OPENVIEW;
  1453.         pWindowData->ViewItem.view   = OPEN_CAR;
  1454.         pWindowData->ViewItem.handle = hwndFrame;
  1455.         pWindowData->x               = 10;
  1456.         pWindowData->y               = 10;
  1457.         pWindowData->xDir            = CAR_RIGHT;
  1458.         pWindowData->yDir            = CAR_UP;
  1459.  
  1460.         /*
  1461.          *   Set window pointer with object pointer and instance view info.
  1462.          *   Then add view to the in-use list so wpSwitchTo works.
  1463.          */
  1464.         WinSetWindowPtr(hwnd, QWL_USER, pWindowData);
  1465.         pWindowData->somSelf->wpAddToObjUseList( &pWindowData->UseItem);
  1466.         pWindowData->somSelf->wpRegisterView( hwndFrame,
  1467.                                              pWindowData->somSelf->wpQueryTitle());
  1468.         WinSetFocus( HWND_DESKTOP, hwndFrame);
  1469.  
  1470.         break;
  1471.  
  1472.       case WM_COMMAND:
  1473.  
  1474.         break;
  1475.  
  1476.       case WM_TIMER:
  1477.  
  1478.          pWindowData = (PWINDOWDATA) WinQueryWindowPtr(hwnd, QWL_USER);
  1479.  
  1480.          if (pWindowData == NULL)
  1481.          {
  1482.             DebugBox("CarWndProc:WM_TIMER", "couldn't get window words");
  1483.             return FALSE;
  1484.          }
  1485.          else
  1486.          {
  1487.           RECTL  rectl;
  1488.           somThis = CarppGetData(pWindowData->somSelf);
  1489.  
  1490.             /*
  1491.              *   If the car's brakes are off, we move the car by modifying it's
  1492.              *   x,y position.  Direction (xDir, yDir) changes when the car's
  1493.              *   position reaches a border of the window.  The distance it
  1494.              *   moves is based on the speed contained in an instance variable.
  1495.              */
  1496.  
  1497.             if (somThis->carBrake->IsSet() == FALSE)
  1498.             {
  1499.                WinQueryWindowRect(hwnd,&rectl);
  1500.  
  1501.                if (pWindowData->x <= 0)                   /* at left border? */
  1502.                   pWindowData->xDir = CAR_RIGHT;              /* mult. by  1 */
  1503.                else
  1504.                   if (pWindowData->x >= rectl.xRight - ICON_WIDTH)
  1505.                      pWindowData->xDir = CAR_LEFT;            /* mult. by -1 */
  1506.  
  1507.                if (pWindowData->y <= 0)                 /* at bottom border? */
  1508.                   pWindowData->yDir = CAR_UP;                 /* mult. by  1 */
  1509.                else
  1510.                   if (pWindowData->y >= rectl.yTop - ICON_HEIGHT)
  1511.                      pWindowData->yDir = CAR_DOWN;            /* mult. by -1 */
  1512.  
  1513.                pWindowData->x +=
  1514.                   pWindowData->xDir * (somThis->carRPM->Query());
  1515.  
  1516.                pWindowData->y +=
  1517.                   pWindowData->yDir * (somThis->carRPM->Query());
  1518.  
  1519.                WinInvalidateRect(hwnd, &rectl, TRUE);  /* invalidate car region */
  1520.             }
  1521.          }
  1522.          break;
  1523.  
  1524.       case WM_PAINT:
  1525.          pWindowData = (PWINDOWDATA) WinQueryWindowPtr(hwnd, QWL_USER);
  1526.  
  1527.          if (pWindowData == NULL)
  1528.          {
  1529.             DebugBox("CarWndProc:WM_PAINT", "couldn't get window words");
  1530.             return FALSE;
  1531.          }
  1532.          else
  1533.          {
  1534.           HPS    hps;
  1535.           RECTL  rectl;
  1536.  
  1537.            hps = WinBeginPaint( hwnd, (HPS)NULLHANDLE, &rectl);
  1538.            WinFillRect( hps, &rectl, SYSCLR_WINDOW);
  1539.            WinDrawPointer(hps, pWindowData->x, pWindowData->y,
  1540.                           pWindowData->somSelf->wpQueryIcon(), DP_NORMAL);
  1541.            WinEndPaint( hps );
  1542.          }
  1543.          break;
  1544.  
  1545.       case WM_CLOSE:
  1546.          {
  1547.           HAB hab;
  1548.  
  1549.             hab = WinQueryAnchorBlock(HWND_DESKTOP);
  1550.             WinStopTimer(hab,hwnd,CAR_TIMER);
  1551.  
  1552.             pWindowData = (PWINDOWDATA) WinQueryWindowPtr(hwnd, QWL_USER);
  1553.  
  1554.             if (pWindowData == NULL)
  1555.             {
  1556.                DebugBox("CarWndProc:WM_CLOSE", "couldn't get window words");
  1557.                return FALSE;
  1558.             }
  1559.             fSuccess =
  1560.             WinStoreWindowPos(szCarClassTitle,pWindowData->somSelf->wpQueryTitle(),
  1561.                                                                         hwndFrame);
  1562.             pWindowData->somSelf->wpDeleteFromObjUseList( &pWindowData->UseItem );
  1563.             pWindowData->somSelf->wpFreeMem( (PBYTE)pWindowData );
  1564.  
  1565.             WinPostMsg( hwnd, WM_QUIT, 0, 0 );
  1566.             WinDestroyWindow ( hwndFrame ) ;
  1567.          }
  1568.          break;
  1569.  
  1570.       default:
  1571.          return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  1572.    }
  1573.    return FALSE;
  1574.  
  1575. }   /* end CarWndProc() */
  1576.  
  1577. /******************************************************************************
  1578. *
  1579. *   DashBoardDlgProc()
  1580. *
  1581. *   DESCRIPTION: Dialog Procedure for Dashboaard settings page
  1582. *
  1583. ******************************************************************************/
  1584. MRESULT EXPENTRY DashBoardDlgProc(HWND hwndDlg, ULONG msg,
  1585.                                   MPARAM mp1, MPARAM mp2)
  1586. {
  1587.  DASHDLGDATA * pDashDlgData;
  1588.  CarppData *somThis;
  1589.  CHAR          acBuffer[10];
  1590.  
  1591.    switch (msg)
  1592.    {
  1593.       case WM_INITDLG:
  1594.       {
  1595.          USHORT    usCount;
  1596.          SLDCDATA  SliderData;
  1597.          WNDPARAMS wprm;
  1598.  
  1599.          /*
  1600.           *   Store some instance specific data in Window words of this dialog.
  1601.           *   This will ensure our dialog procedure can access this objects
  1602.           *   data (our dialog proc isn't always passed a *somSelf pointer).
  1603.           */
  1604.          pDashDlgData =
  1605.             (PDASHDLGDATA) (((Carpp *)mp2)->wpAllocMem(sizeof(*pDashDlgData), NULL));
  1606.          if (pDashDlgData)
  1607.          {
  1608.             memset((PVOID) pDashDlgData, 0, sizeof(*pDashDlgData));
  1609.             pDashDlgData->cb = sizeof(*pDashDlgData);
  1610.             pDashDlgData->somSelf = (Carpp *) mp2;   /* pointer to this object */
  1611.             somThis = CarppGetData(pDashDlgData->somSelf);
  1612.             pDashDlgData->PrevBrakes = somThis->carBrake->IsSet();
  1613.             pDashDlgData->PrevSpeed  = somThis->carRPM->Query();
  1614.          }
  1615.          else
  1616.          {
  1617.             DebugBox("DashboardDlgProc:WM_INITDLG", "Couldn't allocate window words");
  1618.             break;
  1619.          }
  1620.  
  1621.          WinSetWindowPtr(hwndDlg, QWL_USER, pDashDlgData);
  1622.  
  1623.          SliderData.cbSize = sizeof(SLDCDATA);
  1624.          SliderData.usScale1Increments = 10;
  1625.          SliderData.usScale1Spacing = 20;
  1626.          SliderData.usScale2Increments = 10;
  1627.          SliderData.usScale2Spacing = 20;
  1628.  
  1629.          wprm.fsStatus = WPM_CTLDATA;
  1630.          wprm.cchText = 0;
  1631.          wprm.cbPresParams = 0;
  1632.          wprm.cbCtlData = 0;
  1633.          wprm.pCtlData = &SliderData;
  1634.          WinSendDlgItemMsg(hwndDlg,ID_SPEEDSLIDER,
  1635.                           WM_SETWINDOWPARAMS,(MPARAM)&wprm,(MPARAM)NULL ) ;
  1636.  
  1637.          for (usCount = 0; usCount < 10; usCount++ )
  1638.          {
  1639.             WinSendDlgItemMsg(hwndDlg,ID_SPEEDSLIDER,
  1640.                 SLM_SETTICKSIZE,MPFROM2SHORT(usCount,5),NULL);
  1641.  
  1642.            _itoa((usCount*10),acBuffer,10);
  1643.             WinSendDlgItemMsg(hwndDlg, ID_SPEEDSLIDER, SLM_SETSCALETEXT,
  1644.                MPFROMSHORT(usCount), MPFROMP(acBuffer));
  1645.          }
  1646.          WinSendDlgItemMsg(hwndDlg,ID_SPEEDSLIDER,SLM_SETSLIDERINFO,
  1647.             MPFROM2SHORT(SMA_SLIDERARMDIMENSIONS,NULL),
  1648.             MPFROM2SHORT(20,40));
  1649.  
  1650.          WinSendDlgItemMsg(hwndDlg,ID_SPEEDSLIDER,SLM_SETSLIDERINFO,
  1651.             MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE),
  1652.             MPFROMSHORT((SHORT)(somThis->carRPM->Query())/10));
  1653.  
  1654.          WinSetDlgItemText(hwndDlg,ID_SPEEDDATA,
  1655.             _ltoa(somThis->carRPM->Query(),acBuffer,10));
  1656.  
  1657.          if (somThis->carBrake->IsSet() == FALSE)
  1658.          {
  1659.             WinSendDlgItemMsg(hwndDlg,ID_GO,BM_SETCHECK,(MPARAM)1L, MPVOID);
  1660.          }
  1661.          else
  1662.          {
  1663.             WinSendDlgItemMsg(hwndDlg,ID_STOP,BM_SETCHECK,(MPARAM)1L, MPVOID);
  1664.          }
  1665.  
  1666.          return (MRESULT) TRUE;
  1667.  
  1668.       }   /* end case WM_INITDLG: */
  1669.  
  1670.       case WM_DESTROY:
  1671.  
  1672.          pDashDlgData = (PDASHDLGDATA)WinQueryWindowPtr(hwndDlg, QWL_USER);
  1673.          if (pDashDlgData == NULL)
  1674.          {
  1675.             DebugBox("DashboardDlgProc:WM_DESTROY", "couldn't get window words");
  1676.             break;
  1677.          }
  1678.          pDashDlgData->somSelf->wpFreeMem((PBYTE)pDashDlgData);
  1679.          return (WinDefDlgProc(hwndDlg, msg, mp1, mp2) );
  1680.  
  1681.       case WM_COMMAND:
  1682.  
  1683.          pDashDlgData = (PDASHDLGDATA)WinQueryWindowPtr(hwndDlg, QWL_USER);
  1684.          somThis = CarppGetData(pDashDlgData->somSelf);
  1685.          if (pDashDlgData == NULL)
  1686.          {
  1687.             DebugBox("DashboardDlgProc:WM_COMMAND", "couldn't get window words");
  1688.             break;
  1689.          }
  1690.  
  1691.          switch (SHORT1FROMMP(mp1))
  1692.          {
  1693.             case ID_UNDO:
  1694.                if (pDashDlgData->PrevBrakes == TRUE)
  1695.                {
  1696.                  somThis->carBrake->Set();
  1697.                }
  1698.                else
  1699.                {
  1700.                  somThis->carBrake->Release();
  1701.                }
  1702.  
  1703.                somThis->carRPM->Set( pDashDlgData->PrevSpeed);
  1704.  
  1705.                WinSendDlgItemMsg(hwndDlg,ID_SPEEDSLIDER,SLM_SETSLIDERINFO,
  1706.                   MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE),
  1707.                   MPFROMSHORT((SHORT)(somThis->carRPM->Query()/10)));
  1708.  
  1709.                WinSetDlgItemText(hwndDlg,ID_SPEEDDATA,
  1710.                   _ltoa(somThis->carRPM->Query(),acBuffer,10));
  1711.  
  1712.                if (somThis->carBrake->IsSet() == FALSE)
  1713.                {
  1714.                   WinSendDlgItemMsg(hwndDlg,ID_GO,BM_SETCHECK,
  1715.                      (MPARAM)1L, MPVOID);
  1716.                }
  1717.                else
  1718.                {
  1719.                   WinSendDlgItemMsg(hwndDlg,ID_STOP,BM_SETCHECK,
  1720.                      (MPARAM)1L, MPVOID);
  1721.                }
  1722.  
  1723.                break;
  1724.  
  1725.             case ID_DEFAULT:
  1726.                /*
  1727.                 *   preserve previous values
  1728.                 */
  1729.                pDashDlgData->PrevBrakes = somThis->carBrake->IsSet();
  1730.                pDashDlgData->PrevSpeed  = somThis->carRPM->Query();
  1731.  
  1732.                somThis->carBrake->SetToDefault();
  1733.                somThis->carRPM->SetToDefault();
  1734.  
  1735.                WinSendDlgItemMsg(hwndDlg,ID_SPEEDSLIDER,SLM_SETSLIDERINFO,
  1736.                   MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE),
  1737.                   MPFROMSHORT((SHORT)(somThis->carRPM->Query()/10)));
  1738.  
  1739.                WinSetDlgItemText(hwndDlg,ID_SPEEDDATA,
  1740.                   _ltoa(somThis->carRPM->Query(), acBuffer,10));
  1741.  
  1742.                WinSendDlgItemMsg(hwndDlg,ID_GO,BM_SETCHECK,
  1743.                   (MPARAM)1L, MPVOID);
  1744.  
  1745.                break;
  1746.  
  1747.             case ID_HELP:
  1748.  
  1749.                break;
  1750.  
  1751.          }   /* end switch (SHORT1FROMMP(mp1)) */
  1752.  
  1753.          return (MRESULT) TRUE;
  1754.  
  1755.       case WM_CONTROL:
  1756.       {
  1757.          ULONG temp;
  1758.  
  1759.          pDashDlgData = (PDASHDLGDATA)WinQueryWindowPtr(hwndDlg, QWL_USER);
  1760.          somThis = CarppGetData(pDashDlgData->somSelf);
  1761.  
  1762.          if (pDashDlgData == NULL)
  1763.          {
  1764.             DebugBox("DashboardDlgProc:WM_CONTROL", "couldn't get window words");
  1765.             break;
  1766.          }
  1767.  
  1768.          switch (SHORT1FROMMP(mp1))
  1769.          {
  1770.             case ID_GO:
  1771.                if ((USHORT) SHORT2FROMMP(mp1) == BN_CLICKED)
  1772.                {
  1773.                   pDashDlgData->PrevBrakes = somThis->carBrake->IsSet();
  1774.                   somThis->carBrake->Release();
  1775.                }
  1776.                break;
  1777.  
  1778.             case ID_STOP:
  1779.                if ((USHORT) SHORT2FROMMP(mp1) == BN_CLICKED)
  1780.                {
  1781.                   pDashDlgData->PrevBrakes = somThis->carBrake->IsSet();
  1782.                   somThis->carBrake->Set();
  1783.                }
  1784.                break;
  1785.  
  1786.             case ID_SPEEDSLIDER:
  1787.                if ((USHORT) SHORT2FROMMP(mp1) == SLN_CHANGE)
  1788.                {
  1789.                   pDashDlgData->PrevSpeed  = somThis->carRPM->Query();
  1790.                   temp = (ULONG) WinSendDlgItemMsg(hwndDlg, ID_SPEEDSLIDER,
  1791.                      SLM_QUERYSLIDERINFO,
  1792.                      MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_INCREMENTVALUE),
  1793.                      NULL);
  1794.                   temp = temp * 10;
  1795.                   WinSetDlgItemText(hwndDlg,ID_SPEEDDATA,
  1796.                                    _ltoa(temp,acBuffer,10));
  1797.                   somThis->carRPM->Set( temp);
  1798.                }
  1799.                break;
  1800.  
  1801.          }   /* end switch (SHORT1FROMMP(mp1)) */
  1802.  
  1803.          return (MRESULT) TRUE;
  1804.          break;
  1805.  
  1806.       }   /* end case WM_CONTROL: */
  1807.  
  1808.    }   /* end switch (msg) */
  1809.  
  1810.    return (WinDefDlgProc(hwndDlg, msg, mp1, mp2) );
  1811.  
  1812. }   /* end DashBoardDlgProc() */
  1813.  
  1814. /******************************************************************************
  1815. *
  1816. *   HornBeepDlgProc()
  1817. *
  1818. *   DESCRIPTION:  Dialog Procedure for Horn Beep settings page
  1819. *
  1820. ******************************************************************************/
  1821. MRESULT EXPENTRY HornBeepDlgProc(HWND hwndDlg, ULONG msg,
  1822.                                   MPARAM mp1, MPARAM mp2)
  1823. {
  1824.  HORNDLGDATA * pHornDlgData;
  1825.  CarppData *somThis;
  1826.  CHAR acBuffer[10];
  1827.  
  1828.    switch (msg)
  1829.    {
  1830.       case WM_INITDLG:
  1831.       {
  1832.          /*
  1833.           *   Store some instance specific data in Window words of this dialog.
  1834.           *   This will ensure our dialog procedure can access this objects
  1835.           *   data (our dialog proc isn't always passed a *somSelf pointer).
  1836.           */
  1837.          pHornDlgData =
  1838.             (PHORNDLGDATA) (((Carpp *)mp2)->wpAllocMem(sizeof(*pHornDlgData), NULL));
  1839.          if (pHornDlgData)
  1840.          {
  1841.             memset((PVOID) pHornDlgData, 0, sizeof(*pHornDlgData));
  1842.             pHornDlgData->cb = sizeof(*pHornDlgData);
  1843.             pHornDlgData->somSelf = (Carpp *) mp2;  /* pointer to this object */
  1844.             somThis = CarppGetData(pHornDlgData->somSelf);
  1845.             pHornDlgData->PrevDuration = somThis->carHorn->QueryDuration();
  1846.             pHornDlgData->PrevHighTone = somThis->carHorn->QueryHighTone();
  1847.             pHornDlgData->PrevLowTone  = somThis->carHorn->QueryLowTone();
  1848.          }
  1849.          else
  1850.          {
  1851.             DebugBox("HornBeepDlgProc", "Couldn't allocate window words");
  1852.             break;
  1853.          }
  1854.  
  1855.          WinSetWindowPtr(hwndDlg, QWL_USER, pHornDlgData);
  1856.  
  1857.          WinSendDlgItemMsg( hwndDlg, ID_HITONE, SPBM_SETLIMITS,
  1858.             MPFROMLONG(1000), MPFROMLONG(0));
  1859.  
  1860.          WinSendDlgItemMsg( hwndDlg, ID_HITONE, SPBM_SETCURRENTVALUE,
  1861.             MPFROMLONG(pHornDlgData->PrevHighTone), MPFROMLONG(0));
  1862.  
  1863.          WinSendDlgItemMsg( hwndDlg, ID_LOTONE, SPBM_SETLIMITS,
  1864.             MPFROMLONG(1000), MPFROMLONG(0));
  1865.  
  1866.          WinSendDlgItemMsg( hwndDlg, ID_LOTONE, SPBM_SETCURRENTVALUE,
  1867.             MPFROMLONG(pHornDlgData->PrevLowTone), MPFROMLONG(0));
  1868.  
  1869.          return (MRESULT) TRUE;
  1870.          break;
  1871.  
  1872.       }   /* end case WM_INITDLG: */
  1873.  
  1874.       case WM_DESTROY:
  1875.  
  1876.          pHornDlgData = (PHORNDLGDATA) WinQueryWindowPtr(hwndDlg, QWL_USER);
  1877.  
  1878.          if (pHornDlgData == NULL)
  1879.          {
  1880.             DebugBox("HornBeepDlgProc", "Couldn't get window words");
  1881.             break;
  1882.          }
  1883.  
  1884.          pHornDlgData->somSelf->wpFreeMem((PBYTE)pHornDlgData);
  1885.          return (WinDefDlgProc(hwndDlg, msg, mp1, mp2) );
  1886.  
  1887.       case WM_COMMAND:
  1888.  
  1889.          pHornDlgData = (PHORNDLGDATA) WinQueryWindowPtr(hwndDlg, QWL_USER);
  1890.          somThis = CarppGetData(pHornDlgData->somSelf);
  1891.          if (pHornDlgData == NULL)
  1892.          {
  1893.             DebugBox("HornBeepDlgProc", "Couldn't get window words");
  1894.             break;
  1895.          }
  1896.  
  1897.          switch (SHORT1FROMMP(mp1))
  1898.          {
  1899.             case ID_UNDO:
  1900.  
  1901.                WinSendDlgItemMsg( hwndDlg, ID_HITONE, SPBM_SETCURRENTVALUE,
  1902.                   MPFROMLONG(pHornDlgData->PrevHighTone),
  1903.                   MPFROMLONG(0));
  1904.  
  1905.                WinSendDlgItemMsg( hwndDlg, ID_LOTONE, SPBM_SETCURRENTVALUE,
  1906.                   MPFROMLONG(pHornDlgData->PrevLowTone),
  1907.                   MPFROMLONG(0));
  1908.  
  1909.                break;
  1910.  
  1911.             case ID_DEFAULT:
  1912.                /*
  1913.                 *   preserve previous values
  1914.                 */
  1915.                pHornDlgData->PrevHighTone =
  1916.                   somThis->carHorn->QueryHighTone();
  1917.                pHornDlgData->PrevLowTone =
  1918.                   somThis->carHorn->QueryLowTone();
  1919.  
  1920.                somThis->carHorn->SetToDefault();
  1921.  
  1922.                WinSendDlgItemMsg( hwndDlg, ID_HITONE, SPBM_SETCURRENTVALUE,
  1923.                   MPFROMLONG(somThis->carHorn->QueryHighTone()), MPFROMLONG(0));
  1924.  
  1925.                WinSendDlgItemMsg( hwndDlg, ID_LOTONE, SPBM_SETCURRENTVALUE,
  1926.                   MPFROMLONG(somThis->carHorn->QueryLowTone()), MPFROMLONG(0));
  1927.                break;
  1928.  
  1929.             case ID_HELP:
  1930.                break;
  1931.  
  1932.          }   /* end switch (SHORT1FROMMP(mp1)) */
  1933.  
  1934.          return (MRESULT) TRUE;
  1935.          break;
  1936.  
  1937.       case WM_CONTROL:
  1938.       {
  1939.        ULONG temp;
  1940.  
  1941.          pHornDlgData = (PHORNDLGDATA) WinQueryWindowPtr(hwndDlg, QWL_USER);
  1942.          somThis = CarppGetData(pHornDlgData->somSelf);
  1943.  
  1944.          if (pHornDlgData == NULL)
  1945.          {
  1946.             DebugBox("HornBeepDlgProc", "Couldn't get window words");
  1947.             break;
  1948.          }
  1949.  
  1950.          switch (SHORT2FROMMP(mp1))
  1951.          {
  1952.             /************************************************************** */
  1953.             /* When the value of either of the tones change, set the new values in the */
  1954.             /* car object after saving the current settings for "undo" purposes             */
  1955.             /***************************************************************/
  1956.             case SPBN_ENDSPIN:
  1957.  
  1958.                /*
  1959.                 *   preserve previous values
  1960.                 */
  1961.                pHornDlgData->PrevHighTone =
  1962.                   somThis->carHorn->QueryHighTone();
  1963.                pHornDlgData->PrevLowTone =
  1964.                   somThis->carHorn->QueryLowTone();
  1965.  
  1966.                WinSendDlgItemMsg( hwndDlg, ID_HITONE, SPBM_QUERYVALUE,
  1967.                   (MPARAM)&temp, MPFROM2SHORT(0,SPBQ_UPDATEIFVALID));
  1968.  
  1969.                somThis->carHorn->SetHighTone( temp);
  1970.  
  1971.                WinSendDlgItemMsg( hwndDlg, ID_LOTONE, SPBM_QUERYVALUE,
  1972.                   (MPARAM)&temp, MPFROM2SHORT(0,SPBQ_UPDATEIFVALID));
  1973.  
  1974.                somThis->carHorn->SetLowTone( temp);
  1975.  
  1976.                break;
  1977.  
  1978.          }   /* end switch (SHORT2FROMMP(mp1)) */
  1979.  
  1980.       }   /* end case WM_CONTROL: */
  1981.  
  1982.       return (MRESULT) TRUE;
  1983.       break;
  1984.  
  1985.    }   /* end switch(msg) */
  1986.  
  1987.    return (WinDefDlgProc(hwndDlg, msg, mp1, mp2) );
  1988.  
  1989. }   /* end HornBeepDlgProc() */
  1990.  
  1991. /******************************************************************************
  1992. *
  1993. *   _Exception()
  1994. *
  1995. *   DESCRIPTION:  Exception handler routine for this object.
  1996. *
  1997. *   PURPOSE: To notify user when an illegal memory access is made
  1998. *
  1999. *   METHOD:  Whenever a memory protection exception occurs, a message
  2000. *            box is put on the screen to inform the user.
  2001. *
  2002. *   RETURNS: Returns HANDLED if memory exception,
  2003. *            otherwise, returns NOT_HANDLED
  2004. *
  2005. ******************************************************************************/
  2006. ULONG _Exception(EXCEPTIONREPORTRECORD       *parg,
  2007.                  EXCEPTIONREGISTRATIONRECORD *pRegisRecord,
  2008.                  PCONTEXTRECORD               pContextRecord,
  2009.                  PVOID                        pvSpare)
  2010. {
  2011.    LONG  rc;
  2012.    CHAR  szText[CCHMAXPATH];
  2013.  
  2014.    switch (parg->ExceptionNum)
  2015.    {
  2016.       case XCPT_ACCESS_VIOLATION:
  2017.  
  2018.          /*
  2019.           *   Notify the user when memory access violation occurs.
  2020.           */
  2021.          WinAlarm(HWND_DESKTOP, WA_ERROR);
  2022.          longjmp(jmpState, ERROR_PROTECTION_VIOLATION);
  2023.          break;
  2024.  
  2025.       case XCPT_PROCESS_TERMINATE:
  2026.       case XCPT_ASYNC_PROCESS_TERMINATE:
  2027.       case XCPT_SIGNAL:
  2028.       default:
  2029.          /*
  2030.           *   For more exceptions, see the header files or the programming
  2031.           *   reference(s).
  2032.           */
  2033.          break;
  2034.  
  2035.    }   /* end switch (parg->ExceptionNum) */
  2036.  
  2037.    return(XCPT_CONTINUE_SEARCH);
  2038.  
  2039. }   /* end _Exception() */
  2040.  
  2041. /********************************  END carpp.cpp  ********************************/
  2042.  
  2043.  
  2044.