Ignore:
Timestamp:
Oct 23, 2001, 11:25:46 PM (24 years ago)
Author:
umoeller
Message:

Misc updates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/apps.c

    r108 r113  
    4747#include "helpers\prfh.h"
    4848#include "helpers\stringh.h"
     49#include "helpers\winh.h"
    4950#include "helpers\xstring.h"
    5051
     
    797798 *          from the shell.
    798799 *
    799  +      --  However, if you specify an environment, you _must_
    800  *          specify a complemete environment. This function
     800 *      --  However, if you specify an environment, you _must_
     801 *          specify a complete environment. This function
    801802 *          will not merge environments. Use
    802803 *          appSetEnvironmentVar to change environment
     
    808809 *          See appQueryDefaultWin31Environment.
    809810 *
    810  *      --  WARNING: Since this uses WinStartApp internally,
    811  *          and WinStartApp completely hangs PM if a Win-OS/2
    812  *          full-screen session is started from a thread that
    813  *          is NOT thread1, THIS SHOULD ONLY BE CALLED ON
    814  *          THREAD 1 of your application.
    815  *
    816811 *      Even though this isn't clearly said in PMREF,
    817812 *      PROGDETAILS.swpInitial is important:
     
    823818 *         This flag is now in the newer toolkit headers.
    824819 *
     820 *      In addition, this supports the following session
     821 *      flags with ulFlags if PROG_DEFAULT is specified:
     822 *
     823 *      --  APP_RUN_FULLSCREEN
     824 *
     825 *      --  APP_RUN_ENHANCED
     826 *
     827 *      --  APP_RUN_STANDARD
     828 *
     829 *      --  APP_RUN_SEPARATE
     830 *
    825831 *      Since this calls WinStartApp in turn, this
    826832 *      requires a message queue on the calling thread.
     833 *
     834 *      Note that this also does minimal checking on
     835 *      the specified parameters so it can return something
     836 *      more meaningful than FALSE like WinStartApp.
     837 *      As a result, you get a DOS error code now (V0.9.16).
     838 *
     839 *      Most importantly:
     840 *
     841 *      --  ERROR_INVALID_THREADID: not running on thread 1.
     842 *          Since this uses WinStartApp internally and
     843 *          WinStartApp completely hangs the session manager
     844 *          if a Win-OS/2 full-screen session is started from
     845 *          a thread that is NOT thread1, this will fail
     846 *          with an error for safety (V0.9.16).
     847 *
     848 *      --  ERROR_INVALID_PARAMETER: pcProgDetails or
     849 *          phapp is NULL; or PROGDETAILS.pszExecutable is NULL.
     850 *
     851 *      --  ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND:
     852 *          PROGDETAILS.pszExecutable and/or PROGDETAILS.pszStartupDir
     853 *          are invalid.
     854 *          A NULL PROGDETAILS.pszStartupDir is supported though.
     855 *
     856 *      --  ERROR_NOT_ENOUGH_MEMORY
    827857 *
    828858 *@@added V0.9.6 (2000-10-16) [umoeller]
     
    834864 *@@changed V0.9.14 (2001-08-07) [pr]: removed some env. strings for Win. apps.
    835865 *@@changed V0.9.14 (2001-08-23) [pr]: added session type options
    836  */
    837 
    838 HAPP appStartApp(HWND hwndNotify,                  // in: notify window (as with WinStartApp)
    839                  const PROGDETAILS *pcProgDetails, // in: program data
    840                  ULONG ulFlags)                    // in: session type options
    841 {
    842     HAPP            happ = NULLHANDLE;
    843     XSTRING         strParamsPatched;
     866 *@@changed V0.9.16 (2001-10-19) [umoeller]: added prototype to return APIRET
     867 *@@changed V0.9.16 (2001-10-19) [umoeller]: added thread-1 check
     868 */
     869
     870APIRET appStartApp(HWND hwndNotify,        // in: notify window or NULLHANDLE
     871                   const PROGDETAILS *pcProgDetails, // in: program spec (req.)
     872                   ULONG ulFlags,          // in: APP_RUN_* flags
     873                   HAPP *phapp)            // out: application handle if NO_ERROR is returned
     874{
     875    APIRET          arc = NO_ERROR;
    844876    PROGDETAILS     ProgDetails;
    845877
    846     PSZ             pszWinOS2Env = 0;
     878    if (!pcProgDetails || !phapp)
     879        return (ERROR_INVALID_PARAMETER);
    847880
    848881    memcpy(&ProgDetails, pcProgDetails, sizeof(PROGDETAILS));
     
    850883    ProgDetails.Length = sizeof(PROGDETAILS);
    851884    ProgDetails.progt.fbVisible = SHE_VISIBLE;
    852     // ProgDetails.pszEnvironment = 0;
    853885
    854886    // all this only makes sense if this contains something...
    855887    // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller]
    856     if (ProgDetails.pszExecutable)
    857     {
    858         ULONG ulIsWinApp;
     888    if (!ProgDetails.pszExecutable)
     889        arc = ERROR_INVALID_PARAMETER;
     890    else if (doshMyTID() != 1)          // V0.9.16 (2001-10-19) [umoeller]
     891        arc = ERROR_INVALID_THREADID;
     892    else
     893    {
     894        ULONG           ulIsWinApp;
     895
     896        XSTRING         strParamsPatched;
     897        PSZ             pszWinOS2Env = 0;
    859898
    860899        // memset(&ProgDetails.swpInitial, 0, sizeof(SWP));
     
    891930        }
    892931
    893         // Set session type from option flags
     932        // set session type from option flags
    894933        if (ulFlags & APP_RUN_FULLSCREEN)
    895934        {
     
    919958                                                : PROG_31_ENHSEAMLESSCOMMON;
    920959            }
     960
     961            // re-run V0.9.16 (2001-10-19) [umoeller]
     962            ulIsWinApp = appIsWindowsApp(ProgDetails.progt.progc);
    921963        }
    922964
     
    9681010        else
    9691011        {
    970             PSZ pszExtension;
    971             switch (ProgDetails.progt.progc)
    972             {
    973                 /*
    974                  *  .CMD files fixups
    975                  *
    976                  */
    977 
    978                 case PROG_FULLSCREEN:       // OS/2 fullscreen
    979                 case PROG_WINDOWABLEVIO:    // OS/2 window
     1012            // now check if the executable is valid
     1013            // V0.9.16 (2001-10-19) [umoeller]
     1014            ULONG ulAttr;
     1015            _Pmpf(("  %d now, checking %s", arc, ProgDetails.pszExecutable));
     1016            if (!(arc = doshQueryPathAttr(ProgDetails.pszExecutable,
     1017                                          &ulAttr)))
     1018            {
     1019                // make sure startup dir is really a directory
     1020                if (ProgDetails.pszStartupDir)
    9801021                {
    981                     if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
    982                          && (!stricmp(pszExtension, "CMD"))
     1022                    _Pmpf(("  checking %s", ProgDetails.pszStartupDir));
     1023                    if (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir,
     1024                                                  &ulAttr)))
     1025                        if (!(ulAttr & FILE_DIRECTORY))
     1026                            arc = ERROR_PATH_NOT_FOUND;
     1027                                        // @@todo
     1028                }
     1029            }
     1030
     1031            _Pmpf(("  after checking %d", arc));
     1032
     1033            if (!arc)
     1034            {
     1035                PSZ pszExtension;
     1036                switch (ProgDetails.progt.progc)
     1037                {
     1038                    /*
     1039                     *  .CMD files fixups
     1040                     *
     1041                     */
     1042
     1043                    case PROG_FULLSCREEN:       // OS/2 fullscreen
     1044                    case PROG_WINDOWABLEVIO:    // OS/2 window
     1045                    {
     1046                        if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
     1047                             && (!stricmp(pszExtension, "CMD"))
     1048                           )
     1049                        {
     1050                            CallBatchCorrectly(&ProgDetails,
     1051                                               &strParamsPatched,
     1052                                               "OS2_SHELL",
     1053                                               "CMD.EXE");
     1054                        }
     1055                    break; }
     1056
     1057                    case PROG_VDM:              // DOS fullscreen
     1058                    case PROG_WINDOWEDVDM:      // DOS window
     1059                    {
     1060                        if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
     1061                             && (!stricmp(pszExtension, "BAT"))
     1062                           )
     1063                        {
     1064                            CallBatchCorrectly(&ProgDetails,
     1065                                               &strParamsPatched,
     1066                                               NULL,
     1067                                               "COMMAND.COM");
     1068                        }
     1069                    break; }
     1070                } // end switch (ProgDetails.progt.progc)
     1071            }
     1072        }
     1073
     1074        if (!arc)
     1075        {
     1076            if (    (ulIsWinApp)
     1077                 && (    (ProgDetails.pszEnvironment == NULL)
     1078                      || (!strlen(ProgDetails.pszEnvironment))
     1079                    )
     1080               )
     1081            {
     1082                // this is a windoze app, and caller didn't bother
     1083                // to give us an environment:
     1084                // we MUST set one then, or we'll get the strangest
     1085                // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller]
     1086
     1087                DOSENVIRONMENT Env = {0};
     1088
     1089                // get standard WIN-OS/2 environment
     1090                PSZ pszTemp = appQueryDefaultWin31Environment();
     1091
     1092                if (!(arc = appParseEnvironment(pszTemp,
     1093                                                &Env)))
     1094                {
     1095                    // now override KBD_CTRL_BYPASS=CTRL_ESC
     1096                    if (    (!(arc = appSetEnvironmentVar(&Env,
     1097                                                          "KBD_CTRL_BYPASS=CTRL_ESC",
     1098                                                          FALSE)))        // add last
     1099                         && (!(arc = appConvertEnvironment(&Env,
     1100                                                           &pszWinOS2Env,   // freed at bottom
     1101                                                           NULL)))
    9831102                       )
     1103                        ProgDetails.pszEnvironment = pszWinOS2Env;
     1104
     1105                    appFreeEnvironment(&Env);
     1106                }
     1107
     1108                free(pszTemp);
     1109            }
     1110
     1111            if (!arc)
     1112            {
     1113                if (!ProgDetails.pszTitle)
     1114                    ProgDetails.pszTitle = ProgDetails.pszExecutable;
     1115
     1116                ProgDetails.pszParameters = strParamsPatched.psz;
     1117
     1118                /*  _Pmpf(("progt.progc: %d", ProgDetails.progt.progc));
     1119                _Pmpf(("progt.fbVisible: 0x%lX", ProgDetails.progt.fbVisible));
     1120                _Pmpf(("progt.pszTitle: \"%s\"", (ProgDetails.pszTitle) ? ProgDetails.pszTitle : "NULL"));
     1121                _Pmpf(("exec: \"%s\"", (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL"));
     1122                _Pmpf(("params: \"%s\"", (ProgDetails.pszParameters) ? ProgDetails.pszParameters : "NULL"));
     1123                _Pmpf(("startup: \"%s\"", (ProgDetails.pszStartupDir) ? ProgDetails.pszStartupDir : "NULL"));
     1124                _Pmpf(("pszIcon: \"%s\"", (ProgDetails.pszIcon) ? ProgDetails.pszIcon : "NULL"));
     1125                _Pmpf(("environment: "));
     1126                {
     1127                    PSZ pszThis = ProgDetails.pszEnvironment;
     1128                    while (pszThis && *pszThis)
    9841129                    {
    985                         CallBatchCorrectly(&ProgDetails,
    986                                            &strParamsPatched,
    987                                            "OS2_SHELL",
    988                                            "CMD.EXE");
     1130                        _Pmpf(("  \"%s\"", pszThis));
     1131                        pszThis += strlen(pszThis) + 1;
    9891132                    }
    990                 break; }
    991 
    992                 case PROG_VDM:              // DOS fullscreen
    993                 case PROG_WINDOWEDVDM:      // DOS window
    994                 {
    995                     if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
    996                          && (!stricmp(pszExtension, "BAT"))
    997                        )
    998                     {
    999                         CallBatchCorrectly(&ProgDetails,
    1000                                            &strParamsPatched,
    1001                                            NULL,
    1002                                            "COMMAND.COM");
    1003                     }
    1004                 break; }
    1005             } // end switch (ProgDetails.progt.progc)
    1006         }
    1007 
    1008         if (    (ulIsWinApp)
    1009              && (    (ProgDetails.pszEnvironment == NULL)
    1010                   || (!strlen(ProgDetails.pszEnvironment))
    1011                 )
    1012            )
    1013         {
    1014             // this is a windoze app, and caller didn't bother
    1015             // to give us an environment:
    1016             // we MUST set one then, or we'll get the strangest
    1017             // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller]
    1018 
    1019             DOSENVIRONMENT Env = {0};
    1020 
    1021             // get standard WIN-OS/2 environment
    1022             PSZ pszTemp = appQueryDefaultWin31Environment();
    1023 
    1024             if (!appParseEnvironment(pszTemp,
    1025                                      &Env))
    1026             {
    1027                 // now override KBD_CTRL_BYPASS=CTRL_ESC
    1028                 appSetEnvironmentVar(&Env,
    1029                                      "KBD_CTRL_BYPASS=CTRL_ESC",
    1030                                      FALSE);        // add last
    1031                 /*
    1032                  * These should be set by the default environment. It is
    1033                  * not our business to override them really. V0.9.14
    1034                  *
    1035                 appSetEnvironmentVar(&Env,
    1036                                      "KBD_ALTHOME_BYPASS=1",
    1037                                      FALSE);        // add last
    1038                 appSetEnvironmentVar(&Env,
    1039                                      "INT_DURING_IO=1",
    1040                                      FALSE);        // add last
    1041                 appSetEnvironmentVar(&Env,
    1042                                      "HW_TIMER=1",
    1043                                      FALSE);        // add last
    1044                 appSetEnvironmentVar(&Env,
    1045                                      "MOUSE_EXCLUSIVE_ACCESS=0",
    1046                                      FALSE);        // add last
    1047                 appSetEnvironmentVar(&Env,
    1048                                      "VIDEO_RETRACE_EMULATION=1",
    1049                                      FALSE);        // add last
    1050                 appSetEnvironmentVar(&Env,
    1051                                      "VIDEO_SWITCH_NOTIFICATION=1",
    1052                                      FALSE);        // add last
    1053                 appSetEnvironmentVar(&Env,
    1054                                      "VIDEO_8514A_XGA_IOTRAP=0",
    1055                                      FALSE);        // add last
    1056                  */
    1057 
    1058                 if (!appConvertEnvironment(&Env,
    1059                                            &pszWinOS2Env,   // freed at bottom
    1060                                            NULL))
    1061                     ProgDetails.pszEnvironment = pszWinOS2Env;
    1062 
    1063                 appFreeEnvironment(&Env);
    1064             }
    1065 
    1066             free(pszTemp);
    1067         }
    1068 
    1069         if (!ProgDetails.pszTitle)
    1070             ProgDetails.pszTitle = ProgDetails.pszExecutable;
    1071 
    1072         ProgDetails.pszParameters = strParamsPatched.psz;
    1073 
    1074         /*  _Pmpf(("progt.progc: %d", ProgDetails.progt.progc));
    1075         _Pmpf(("progt.fbVisible: 0x%lX", ProgDetails.progt.fbVisible));
    1076         _Pmpf(("progt.pszTitle: \"%s\"", (ProgDetails.pszTitle) ? ProgDetails.pszTitle : "NULL"));
    1077         _Pmpf(("exec: \"%s\"", (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL"));
    1078         _Pmpf(("params: \"%s\"", (ProgDetails.pszParameters) ? ProgDetails.pszParameters : "NULL"));
    1079         _Pmpf(("startup: \"%s\"", (ProgDetails.pszStartupDir) ? ProgDetails.pszStartupDir : "NULL"));
    1080         _Pmpf(("pszIcon: \"%s\"", (ProgDetails.pszIcon) ? ProgDetails.pszIcon : "NULL"));
    1081         _Pmpf(("environment: "));
    1082         {
    1083             PSZ pszThis = ProgDetails.pszEnvironment;
    1084             while (pszThis && *pszThis)
    1085             {
    1086                 _Pmpf(("  \"%s\"", pszThis));
    1087                 pszThis += strlen(pszThis) + 1;
    1088             }
    1089         }
    1090 
    1091         _Pmpf(("swpInitial.fl = 0x%lX, x = %d, y = %d, cx = %d, cy = %d:",
    1092                     ProgDetails.swpInitial.fl,
    1093                     ProgDetails.swpInitial.x,
    1094                     ProgDetails.swpInitial.y,
    1095                     ProgDetails.swpInitial.cx,
    1096                     ProgDetails.swpInitial.cy));
    1097         _Pmpf(("  behind = %d, hwnd = %d, res1 = %d, res2 = %d",
    1098                     ProgDetails.swpInitial.hwndInsertBehind,
    1099                     ProgDetails.swpInitial.hwnd,
    1100                     ProgDetails.swpInitial.ulReserved1,
    1101                     ProgDetails.swpInitial.ulReserved2));
    1102             */
    1103 
    1104         /* if (WinMessageBox(HWND_DESKTOP,
    1105                           NULLHANDLE,
    1106                           (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL",
    1107                           "Start?",
    1108                           0,
    1109                           MB_YESNO | MB_MOVEABLE)
    1110                   == MBID_YES) */
    1111         happ = WinStartApp(hwndNotify,
    1112                                     // receives WM_APPTERMINATENOTIFY
    1113                            &ProgDetails,
    1114                            strParamsPatched.psz,
    1115                            NULL,            // "reserved", PMREF says...
    1116                            SAF_INSTALLEDCMDLINE);
    1117                                 // we MUST use SAF_INSTALLEDCMDLINE
    1118                                 // or no Win-OS/2 session will start...
    1119                                 // whatever is going on here... Warp 4 FP11
    1120 
    1121                                 // do not use SAF_STARTCHILDAPP, or the
    1122                                 // app will be terminated automatically
    1123                                 // when the WPS terminates!
    1124 
    1125         // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
     1133                }
     1134
     1135                _Pmpf(("swpInitial.fl = 0x%lX, x = %d, y = %d, cx = %d, cy = %d:",
     1136                            ProgDetails.swpInitial.fl,
     1137                            ProgDetails.swpInitial.x,
     1138                            ProgDetails.swpInitial.y,
     1139                            ProgDetails.swpInitial.cx,
     1140                            ProgDetails.swpInitial.cy));
     1141                _Pmpf(("  behind = %d, hwnd = %d, res1 = %d, res2 = %d",
     1142                            ProgDetails.swpInitial.hwndInsertBehind,
     1143                            ProgDetails.swpInitial.hwnd,
     1144                            ProgDetails.swpInitial.ulReserved1,
     1145                            ProgDetails.swpInitial.ulReserved2));
     1146                    */
     1147
     1148                /* if (WinMessageBox(HWND_DESKTOP,
     1149                                  NULLHANDLE,
     1150                                  (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL",
     1151                                  "Start?",
     1152                                  0,
     1153                                  MB_YESNO | MB_MOVEABLE)
     1154                          == MBID_YES) */
     1155                if (!(*phapp = WinStartApp(hwndNotify,
     1156                                                    // receives WM_APPTERMINATENOTIFY
     1157                                           &ProgDetails,
     1158                                           strParamsPatched.psz,
     1159                                           NULL,            // "reserved", PMREF says...
     1160                                           SAF_INSTALLEDCMDLINE)))
     1161                                                // we MUST use SAF_INSTALLEDCMDLINE
     1162                                                // or no Win-OS/2 session will start...
     1163                                                // whatever is going on here... Warp 4 FP11
     1164
     1165                                                // do not use SAF_STARTCHILDAPP, or the
     1166                                                // app will be terminated automatically
     1167                                                // when the WPS terminates!
     1168                    arc = ERROR_BAD_FORMAT;
     1169                            // @@todo we can probably do better
     1170                            // V0.9.16 (2001-10-19) [umoeller]
     1171
     1172                // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
     1173            }
     1174        }
    11261175
    11271176        xstrClear(&strParamsPatched);
     
    11301179    } // end if (ProgDetails.pszExecutable)
    11311180
    1132     return (happ);
    1133 }
    1134 
    1135 
     1181    _Pmpf((__FUNCTION__ ": returning %d", arc));
     1182
     1183    return (arc);
     1184}
     1185
     1186/*
     1187 *@@ appWaitForApp:
     1188 *      waits for the specified application to terminate
     1189 *      and returns its exit code.
     1190 *
     1191 *@@added V0.9.9 (2001-03-07) [umoeller]
     1192 */
     1193
     1194BOOL appWaitForApp(HWND hwndNotify,     // in: notify window
     1195                   HAPP happ,           // in: app to wait for
     1196                   PULONG pulExitCode)  // out: exit code (ptr can be NULL)
     1197{
     1198    BOOL brc = FALSE;
     1199
     1200    if (happ)
     1201    {
     1202        // app started:
     1203        // enter a modal message loop until we get the
     1204        // WM_APPTERMINATENOTIFY for happ. Then we
     1205        // know the app is done.
     1206        HAB     hab = WinQueryAnchorBlock(hwndNotify);
     1207        QMSG    qmsg;
     1208        // ULONG   ulXFixReturnCode = 0;
     1209        while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
     1210        {
     1211            if (    (qmsg.msg == WM_APPTERMINATENOTIFY)
     1212                 && (qmsg.hwnd == hwndNotify)
     1213                 && (qmsg.mp1 == (MPARAM)happ)
     1214               )
     1215            {
     1216                // xfix has terminated:
     1217                // get xfix return code from mp2... this is:
     1218                // -- 0: everything's OK, continue.
     1219                // -- 1: handle section was rewritten, restart Desktop
     1220                //       now.
     1221                if (pulExitCode)
     1222                    *pulExitCode = (ULONG)qmsg.mp2;
     1223                brc = TRUE;
     1224                // do not dispatch this
     1225                break;
     1226            }
     1227
     1228            WinDispatchMsg(hab, &qmsg);
     1229        }
     1230    }
     1231
     1232    return (brc);
     1233}
     1234
     1235/*
     1236 *@@ appQuickStartApp:
     1237 *      shortcut for simply starting an app and
     1238 *      waiting until it's finished.
     1239 *
     1240 *      On errors, NULLHANDLE is returned.
     1241 *
     1242 *      If pulReturnCode != NULL, it receives the
     1243 *      return code of the app.
     1244 *
     1245 *@@added V0.9.16 (2001-10-19) [umoeller]
     1246 */
     1247
     1248HAPP appQuickStartApp(const char *pcszFile,
     1249                      ULONG ulProgType,         // e.g. PROG_PM
     1250                      const char *pcszArgs,
     1251                      PULONG pulExitCode)
     1252{
     1253    PROGDETAILS    pd = {0};
     1254    HAPP           happ,
     1255                   happReturn = NULLHANDLE;
     1256    CHAR           szDir[CCHMAXPATH] = "";
     1257    PCSZ           p;
     1258    HWND           hwndObject;
     1259
     1260    pd.Length = sizeof(pd);
     1261    pd.progt.progc = ulProgType;
     1262    pd.progt.fbVisible = SHE_VISIBLE;
     1263    pd.pszExecutable = (PSZ)pcszFile;
     1264    pd.pszParameters = (PSZ)pcszArgs;
     1265    if (p = strrchr(pcszFile, '\\'))
     1266    {
     1267       strhncpy0(szDir,
     1268                 pcszFile,
     1269                 p - pcszFile);
     1270       pd.pszStartupDir = szDir;
     1271    }
     1272
     1273    if (    (hwndObject = winhCreateObjectWindow(WC_STATIC, NULL))
     1274         && (!appStartApp(hwndObject,
     1275                          &pd,
     1276                          0,
     1277                          &happ))
     1278       )
     1279    {
     1280        if (appWaitForApp(hwndObject,
     1281                          happ,
     1282                          pulExitCode))
     1283            happReturn = happ;
     1284    }
     1285
     1286    return (happReturn);
     1287}
Note: See TracChangeset for help on using the changeset viewer.